Tk-TableMatrix-1.26/0000755000000000000000000000000013746047633012745 5ustar rootrootTk-TableMatrix-1.26/t/0000755000000000000000000000000013746050164013201 5ustar rootrootTk-TableMatrix-1.26/t/create.t0000644000000000000000000000720113745605157014640 0ustar rootroot# -*- perl -*- BEGIN { $|=1; $^W=1; } use strict; use Test; ## ## Almost all widget classes: load module, create, pack, and ## destory an instance. ## ## Menu stuff not tested up to now ## use vars '@class'; BEGIN { @class = ( # Tk core widgets qw( TableMatrix TableMatrix::Spreadsheet TableMatrix::SpreadsheetHideRows ) ); plan test => (13*@class+3); }; use constant HAVE_DISPLAY => $^O =~ /Win/ || defined $ENV{DISPLAY}; use constant SKIP => HAVE_DISPLAY ? 0 : 'Skip if no display'; eval { require Tk; }; ok($@, "", "loading Tk module"); my $mw; eval {$mw = Tk::MainWindow->new();}; skip(SKIP, $@, "", "can't create MainWindow"); skip(SKIP, Tk::Exists($mw), 1, "MainWindow creation failed"); eval { $mw->geometry('+10+10'); }; # This works for mwm and interactivePlacement my $w; foreach my $class (@class) { print "Testing $class\n"; undef($w); eval "require Tk::$class;"; ok($@, "", "Error loading Tk::$class"); ok("Tk::$class"->isa('Tk::Widget'),1,"Tk::$class is not a widget"); my $classCall = $class; # name of class, as it is called $classCall =~ s/.+?\:\://; eval { $w = $mw->$classCall(); }; skip(SKIP, $@, "", "can't create $class widget"); skip(SKIP || $@, Tk::Exists($w), 1, "$class instance does not exist"); if (Tk::Exists($w)) { if ($w->isa('Tk::Wm')) { # KDE-beta4 wm with policies: # 'interactive placement' # okay with geometry and positionfrom # 'manual placement' # geometry and positionfrom do not help eval { $w->positionfrom('user'); }; #eval { $w->geometry('+10+10'); }; ok ($@, "", 'Problem set postitionform to user'); eval { $w->Popup; }; ok ($@, "", "Can't Popup a $class widget") } else { ok(1); # dummy for above positionfrom test eval { $w->pack; }; ok ($@, "", "Can't pack a $class widget") } eval { $mw->update; }; ok ($@, "", "Error during 'update' for $class widget"); my @dummy; eval { @dummy = $w->configure; }; ok ($@, "", "Error: configure list for $class"); my $dummy; eval { $dummy = $w->configure; }; ok ($@, "", "Error: configure scalar for $class"); ok (scalar(@dummy),scalar(@$dummy), "Error: scalar config != list config"); eval { $mw->update; }; ok ($@, "", "Error: 'update' after configure for $class widget"); eval { $w->destroy; }; ok($@, "", "can't destroy $class widget"); ok(!Tk::Exists($w), 1, "$class: widget not really destroyed"); # XXX: destroy-destroy test disabled because nobody vote for this feature # Nick Ing-Simmmons wrote: # The only way to make test pass, is when Tk800 would fail, to specifcally look # and see if method is 'destroy', and ignore it. Can be done but is it worth it? # Note I cannot call tk's internal destroy as I have no way of relating # (now destroy has happened) the object back to interp/MainWindow that it used # to be associated with, and hence cannot create the args I need to pass # to the core. # since Tk8.0 a destroy on an already destroyed widget should # not complain #eval { $w->destroy; }; #ok($@, "", "Ooops, destroying a destroyed widget should not complain"); } else { # Widget $class couldn't be created: # Popup/pack, update, destroy skipped for (1..9) { skip (1,1,1, "skipped because widget could not be created"); } } } 1; __END__ Tk-TableMatrix-1.26/Changes0000644000000000000000000000712313746047570014243 0ustar rootrootSummary of Changes to Tk::TableMatrix See ChangeLog for detailed changes. Release 1.26 10/26/2020 * Fix RT #133587: improper handling of line endings differing from `$/` in pTk.exc files causes build failure (tries compiling known-uncompilable files—e.g. tkAppInit.c, tkTablePs.c) * Add GitHub repository to module metadata * Apply POD fixes (originally by Debian package maintainer Bart Martens) Release 1.25 10/19/2020 * add dependencies / RT #133557 * improve POD (incl. RT #75690) Release 1.24 10/17/2020 * pTk/Makefile.PL: fix RT #133547 * improve indentation of myConfig Release 1.23 1/9/2007 * Changed TableMatrix::Spreadsheet row/col resize behavior to be more spreadsheet-like. Release 1.22 3/23/06 * Misc Bugs fixed in Tk::TableMatrix::SpreadsheetHideRows Release 1.21 3/2/06 * Updated to make the row/size resize operation (that happens when you drag the row/col borders) apply to every row or column that is currently selected, instead of just the row/col border that was dragged. Release 1.2 1/26/05 * Fixed bug which was causing crashes on perl 5.8.4 on win32 when anything was copied into the clipboard (i.e. when control-c pressed). * Fixed row/col insert/deletes to work more reliably in TableMatrix::Spreadsheet Release 1.1: 2/12/04 * Updated to be compatible with the new Tk804 series. Release 1.01: 12/6/02 * Fixed Error where the rowHeight method was getting executed like a colWidth. This was introduced in the update of TkTable 2.5 to 2.6 Release 1.0: 12/2/02 * Updated core C-code for the changes made from TkTable 2.6 to 2.8. (Tk::TableMatrix is derived from the TkTable Tcl/Tk Widget. See tktable.sourceforge.net ) From the TkTable 2.7 and 2.8 Release Notes: * Corrected memory leaks in caching. * Added the ability to select borders with Button1. * Added global -justify option. * Added -ipadx/-ipady table options and swapped them with the old -padx/-pady. This gives better control over the cell padding. **** POTENTIAL INCOMPATABILITY **** * -borderwidth now takes up to 4 values to allow you to customize edge edge of a cell. * Added priorities to tags, so tags can be raised and lowered in priority. **** POTENTIAL INCOMPATABILITY **** * Numerous minor bugs fixed. Release 0.9: 5/22/02 * Added an experimental widget: SpreadsheetHideRows. This enables display of tabular info, with selectable hide/unhide of detail data. See demos/SpreadsheetHideRows * Numerous minor bugs fixed. Release 0.8: 10/5/01 * Removed un-needed dependencies on Data::Parse and Date::Format for TableMatrix::Spreadsheet * Fixed problem with the selection going nuts when dragging the selection out of the window. Release 0.71: 6/15/01 * Fixed to compile with the new Tk800.023 release. Release 0.7: 6/7/01 * Added TableMatrix::Spreadsheet widget. This is a TableMatrix Derived widget with Excel-like bindings. * Reverted back to the cell sorting method implemented in tktable 2.5 (and TableMatrix 0.3). The new cell sorting method didn't sort negative row/column indexes correctly, which caused the data from a copy/paste operation to be out-of-order, if the selection included multiple negative row/col indexes. * Fixed control +/- key bindings for modifying the column with. (Patch from Slaven) Release 0.5: 12/20/00 * Updated to be consistent with tkTable 2.6 Release 0.3 9/16/00 * Initial Release (based on tkTable 2.5) Tk-TableMatrix-1.26/ChangeLog0000644000000000000000000007161113742601451014513 0ustar rootroot2020-10-17 ASB * set up GitHub repository to have an auto-generated changelog: https://github.com/asb-capfan/Tk-TableMatrix 2007-01-11 20:26 tag TableMatrix_1_23 2007-01-11 20:26 A0182636 * Makefile.PL, pTk/Makefile.PL: Preparation for next release. 2007-01-09 14:00 cerney * Changes, TableMatrix.pm, TableMatrix/Spreadsheet.pm, TableMatrix/SpreadsheetHideRows.pm: Preparation for next release 2007-01-09 13:51 cerney * demos/TableMatrixSpreadsheetTest: Updated to be consistent with latest changes in the resizeborders behavoir 2007-01-09 13:50 cerney * TableMatrix/Spreadsheet.pm: Removed extra code that would print "location" when F2 was pressed. (This was debugging code that should have been removed earlier) 2007-01-09 13:46 cerney * TableMatrix/Spreadsheet.pm: Corrected behavoir that wasn't very spreadsheet-like. Now you can only resize row/cols thru the title row/cols. The previous behavoir created problems, because when a user would drag to selected several cells, sometimes the row or col would resize as well. 2006-03-24 13:12 tag TableMatrix_1_22 2006-03-24 13:12 cerney * Changes, Makefile.PL, TableMatrix.pm, TableMatrix/Spreadsheet.pm, TableMatrix/SpreadsheetHideRows.pm, pTk/Makefile.PL: Preparation for next release. 2006-03-11 11:14 cerney * TableMatrix/SpreadsheetHideRows.pm: Updated SpreadsheetHideRows to work properly when the table state is set to "disabled". 2006-03-09 16:05 cerney * TableMatrix/SpreadsheetHideRows.pm: Tweaked the anchor setting on the HideRows indicator (i.e the plus/minus thing) to be 'center'. This will keep any detail-level tags from over-riding if the detail tags have lower priority (e.g. using the tagLower method on them). 2006-03-09 15:52 cerney * TableMatrix/SpreadsheetHideRows.pm, demos/SpreadsheetHideRows: Fixed bug in SpreadSheetHideRows where spans weren't being properly applied when detail was hidden/showed. Added more spans to demo as a check for this condition. 2006-03-05 14:57 tag TableMatrix_1_21 2006-03-05 14:57 cerney * Changes, Makefile.PL, TableMatrix.pm, TableMatrix/Spreadsheet.pm, TableMatrix/SpreadsheetHideRows.pm, pTk/Makefile.PL: Preparation for next release. 2006-03-05 12:44 cerney * TableMatrix/Spreadsheet.pm: Updates to make the new row/col resize work on linux. 2006-03-05 12:35 A0182636 * TableMatrix/Spreadsheet.pm: Updated to make the row/size resize operation (that happens when you drag the row/col borders) apply to every row or column that is currently selected, instead of just the row/col border that was dragged. 2005-01-26 16:29 tag TableMatrix_1_2 2005-01-26 16:29 cerney * TableMatrix.pm: Preparation for next release. 2005-01-26 12:12 cerney * Changes, Makefile.PL, TableMatrix/Spreadsheet.pm, TableMatrix/SpreadsheetHideRows.pm, pTk/Makefile.PL: Preparation for next release. 2005-01-26 09:27 A0182636 * pTk/mTk/: Tktable/tkTable.c, Tktable800/tkTable.c: Updated to remove extraneous? Tcl_free that was causing crashes on win32 with perl5.8.4. This Tcl_Free is not used like this to free args to Tcl_ListObjGetElement anywhere else I can find examples in the TableMatrix and Tk source code, so it appears to be truly not needed. 2004-06-14 08:26 cerney * t/create.t: Incorporate Patch from Ed Avis to skip some tests if there is no DISPLAY environment set. This helps with automated build/tests on systems with no display. 2004-04-23 08:40 cerney * TableMatrix/Spreadsheet.pm: Fixed the row/col insert/deletes to work more reliably. 2004-04-06 11:41 cerney * TableMatrix.xs: Patch from Nick Ing-Simmons to correct max/min macro redefine warning messages when compiling. 2004-02-23 07:43 tag TableMatrix_1_1 2004-02-23 07:43 cerney * TableMatrix.xs: Mods to work on win32 with Tk804 ( Originally commited in remote repository by A0182636 on Sun Feb 22 19:10:28 2004 ) 2004-02-13 15:27 cerney * Changes, Makefile.PL, TableMatrix.pm, TableMatrix/Spreadsheet.pm, TableMatrix/SpreadsheetHideRows.pm, pTk/Makefile.PL: Preparation for next release. 2004-02-07 21:09 cerney * Makefile.PL, TableMatrix.xs, myConfig, demos/spreadsheet, pTk/Makefile.PL, pTk/mTk/README, pTk/mTk/Tktable/tkTable.c, pTk/mTk/Tktable/tkTable.h, pTk/mTk/Tktable/tkTableCell.c, pTk/mTk/Tktable/tkTableCellSort.c, pTk/mTk/Tktable/tkTableCmds.c, pTk/mTk/Tktable/tkTableEdit.c, pTk/mTk/Tktable/tkTableTag.c, pTk/mTk/Tktable/tkTableUtil.c, pTk/mTk/Tktable/tkTableWin.c, pTk/mTk/Tktable800/Makefile.in, pTk/mTk/Tktable800/confdefs.h, pTk/mTk/Tktable800/config.cache, pTk/mTk/Tktable800/config.log, pTk/mTk/Tktable800/configure, pTk/mTk/Tktable800/configure.in, pTk/mTk/Tktable800/mac_tkTable.mcp, pTk/mTk/Tktable800/mac_tkTable.r, pTk/mTk/Tktable800/mac_tkTable_prefix.h, pTk/mTk/Tktable800/makefile.vc, pTk/mTk/Tktable800/mm.h, pTk/mTk/Tktable800/pTk.exc, pTk/mTk/Tktable800/tkAppInit.c, pTk/mTk/Tktable800/tkTable.c, pTk/mTk/Tktable800/tkTable.h, pTk/mTk/Tktable800/tkTableCell.c, pTk/mTk/Tktable800/tkTableCellSort.c, pTk/mTk/Tktable800/tkTableCmds.c, pTk/mTk/Tktable800/tkTableEdit.c, pTk/mTk/Tktable800/tkTableInitScript.h, pTk/mTk/Tktable800/tkTablePs.c, pTk/mTk/Tktable800/tkTableTag.c, pTk/mTk/Tktable800/tkTableUtil.c, pTk/mTk/Tktable800/tkTableWin.c, pTk/mTk/Tktable800/tkTableversion.h, pTk/mTk/Tktable800/version.h: Merged Changes on Tk804update branch onto main branch. 2004-02-07 18:36 cerney * pTk/mTk/Tktable800/tkTable.h: file tkTable.h was initially added on branch Tk804update. 2004-02-07 18:36 cerney * pTk/mTk/Tktable800/tkTableCell.c: file tkTableCell.c was initially added on branch Tk804update. 2004-02-07 18:36 cerney * pTk/mTk/Tktable800/tkTableCellSort.c: file tkTableCellSort.c was initially added on branch Tk804update. 2004-02-07 18:36 cerney * pTk/mTk/Tktable800/tkTableCmds.c: file tkTableCmds.c was initially added on branch Tk804update. 2004-02-07 18:36 cerney * pTk/mTk/Tktable800/tkTableEdit.c: file tkTableEdit.c was initially added on branch Tk804update. 2004-02-07 18:36 cerney * pTk/mTk/Tktable800/tkTableInitScript.h: file tkTableInitScript.h was initially added on branch Tk804update. 2004-02-07 18:36 cerney * pTk/mTk/Tktable800/tkTablePs.c: file tkTablePs.c was initially added on branch Tk804update. 2004-02-07 18:36 cerney * pTk/mTk/Tktable800/tkTableTag.c: file tkTableTag.c was initially added on branch Tk804update. 2004-02-07 18:36 cerney * pTk/mTk/Tktable800/tkTableUtil.c: file tkTableUtil.c was initially added on branch Tk804update. 2004-02-07 18:36 cerney * pTk/mTk/Tktable800/tkTableWin.c: file tkTableWin.c was initially added on branch Tk804update. 2004-02-07 18:36 cerney * pTk/mTk/Tktable800/tkTableversion.h: file tkTableversion.h was initially added on branch Tk804update. 2004-02-07 18:36 cerney * pTk/mTk/Tktable800/version.h: file version.h was initially added on branch Tk804update. 2004-02-07 18:36 cerney * pTk/mTk/Tktable800/Makefile.in: file Makefile.in was initially added on branch Tk804update. 2004-02-07 18:36 cerney * pTk/mTk/Tktable800/confdefs.h: file confdefs.h was initially added on branch Tk804update. 2004-02-07 18:36 cerney * pTk/mTk/Tktable800/config.cache: file config.cache was initially added on branch Tk804update. 2004-02-07 18:36 cerney * pTk/mTk/Tktable800/config.log: file config.log was initially added on branch Tk804update. 2004-02-07 18:36 cerney * pTk/mTk/Tktable800/configure: file configure was initially added on branch Tk804update. 2004-02-07 18:36 cerney * pTk/mTk/Tktable800/configure.in: file configure.in was initially added on branch Tk804update. 2004-02-07 18:36 cerney * pTk/mTk/Tktable800/mac_tkTable.mcp: file mac_tkTable.mcp was initially added on branch Tk804update. 2004-02-07 18:36 cerney * pTk/mTk/Tktable800/mac_tkTable.r: file mac_tkTable.r was initially added on branch Tk804update. 2004-02-07 18:36 cerney * pTk/mTk/Tktable800/mac_tkTable_prefix.h: file mac_tkTable_prefix.h was initially added on branch Tk804update. 2004-02-07 18:36 cerney * pTk/mTk/Tktable800/makefile.vc: file makefile.vc was initially added on branch Tk804update. 2004-02-07 18:36 cerney * pTk/mTk/Tktable800/mm.h: file mm.h was initially added on branch Tk804update. 2004-02-07 18:36 cerney * pTk/mTk/Tktable800/pTk.exc: file pTk.exc was initially added on branch Tk804update. 2004-02-07 18:36 cerney * pTk/mTk/Tktable800/tkAppInit.c: file tkAppInit.c was initially added on branch Tk804update. 2004-02-07 18:36 cerney * pTk/mTk/Tktable800/tkTable.c: file tkTable.c was initially added on branch Tk804update. 2004-02-07 18:36 cerney * Makefile.PL, TableMatrix.xs, myConfig, pTk/Makefile.PL, pTk/mTk/README, pTk/mTk/Tktable800/Makefile.in, pTk/mTk/Tktable800/confdefs.h, pTk/mTk/Tktable800/config.cache, pTk/mTk/Tktable800/config.log, pTk/mTk/Tktable800/configure, pTk/mTk/Tktable800/configure.in, pTk/mTk/Tktable800/mac_tkTable.mcp, pTk/mTk/Tktable800/mac_tkTable.r, pTk/mTk/Tktable800/mac_tkTable_prefix.h, pTk/mTk/Tktable800/makefile.vc, pTk/mTk/Tktable800/mm.h, pTk/mTk/Tktable800/pTk.exc, pTk/mTk/Tktable800/tkAppInit.c, pTk/mTk/Tktable800/tkTable.c, pTk/mTk/Tktable800/tkTable.h, pTk/mTk/Tktable800/tkTableCell.c, pTk/mTk/Tktable800/tkTableCellSort.c, pTk/mTk/Tktable800/tkTableCmds.c, pTk/mTk/Tktable800/tkTableEdit.c, pTk/mTk/Tktable800/tkTableInitScript.h, pTk/mTk/Tktable800/tkTablePs.c, pTk/mTk/Tktable800/tkTableTag.c, pTk/mTk/Tktable800/tkTableUtil.c, pTk/mTk/Tktable800/tkTableWin.c, pTk/mTk/Tktable800/tkTableversion.h, pTk/mTk/Tktable800/version.h: Updated to make compatible with a Tk800.0xx build or a build using Tk804 2004-02-06 19:54 cerney * TableMatrix.xs, demos/spreadsheet, pTk/mTk/Tktable/tkTable.c, pTk/mTk/Tktable/tkTable.h, pTk/mTk/Tktable/tkTableCell.c, pTk/mTk/Tktable/tkTableCellSort.c, pTk/mTk/Tktable/tkTableCmds.c, pTk/mTk/Tktable/tkTableEdit.c, pTk/mTk/Tktable/tkTableTag.c, pTk/mTk/Tktable/tkTableUtil.c, pTk/mTk/Tktable/tkTableWin.c: Updates to compile with Tk804. Still need to resolve how to retain compatibility with tk800. 2003-12-05 16:24 cerney * TableMatrix/SpreadsheetHideRows.pm, demos/SpreadsheetHideRows: Updated SpreadsheetHideRows to properly hide detail of lower level details when a top-level detail is hidden. Modified demo to include this case. 2003-11-20 11:22 cerney * TableMatrix/Spreadsheet.pm: Doco fix. 2003-09-23 06:53 cerney * demos/edit_styles.pl: Added comments. Should have been added in jan 2003. 2003-01-24 07:14 cerney * Makefile.PL: Removed libpt from the list of libraries to look for, to be consistent with Tk800.024 2003-01-07 15:10 cerney * demos/embeddedWindows.pl: Initial Checkin 2003-01-07 11:51 cerney * demos/edit_styles.pl: Submitted demo from Eric Waldheim 2002-12-06 08:08 tag TableMatrix_1_01 2002-12-06 08:08 cerney * Changes, Makefile.PL, TableMatrix.pm, TableMatrix/Spreadsheet.pm, TableMatrix/SpreadsheetHideRows.pm, pTk/Makefile.PL: Prep for next release. 2002-12-03 13:48 cerney * pTk/mTk/Tktable/tkTable.c: Fixed Error where the rowHeight method was getting executed like a colWidth. This was introduced in the update of TkTable 2.5 to 2.6 2002-12-02 09:44 tag TableMatrix_1_0 2002-12-02 09:44 cerney * Changes, Makefile.PL, TableMatrix.pm, TableMatrix/Spreadsheet.pm, TableMatrix/SpreadsheetHideRows.pm, pTk/Makefile.PL, README: Preparation for next release. 2002-11-22 08:23 cerney * TableMatrix.pm: Completed Changes to TableMatrix.pm for the upgrade to Tktkable 2.8 2002-11-22 08:18 cerney * demos/spreadsheet: Modified to work again. (Didn't work because of update to perl5.6???) 2002-11-18 09:59 cerney * pod/TableMatrix.pod: Docs updated for changes to TkTable 2.7 to 2.8 2002-11-15 16:19 cerney * pTk/mTk/Tktable/: tkTable.h, tkTableTag.c, tkTableWin.c: Compiles with warnings on solaris. 2002-11-15 15:19 cerney * pTk/mTk/Tktable/: tkTable.c, tkTable.h, tkTableCell.c, tkTableCellSort.c, tkTableCmds.c, tkTableEdit.c, tkTableInitScript.h, tkTableTag.c, tkTableUtil.c, tkTableWin.c, version.h: Merged Changed from Stock version 2.7 to 2.8. Conflicts resolved, Not Tested Yet. 2002-11-08 11:52 tag stock-tktable2_8 2002-11-08 11:52 cerney * pTk/mTk/Tktable/: tkTable.c, tkTable.h, tkTableCell.c, tkTableCellSort.c, tkTableCmds.c, tkTableEdit.c, tkTableInitScript.h, tkTableTag.c, tkTableUtil.c, tkTableWin.c, version.h: tkTable2.8 Source update 2002-11-01 15:38 cerney * pTk/mTk/Tktable/: tkTable.c, tkTableTag.c: Mods to compile and run on linux. 2002-11-01 14:42 cerney * TableMatrix.pm, demos/tagBorderWidth, demos/tagMerge2, pTk/mTk/Tktable/tkTable.h, pTk/mTk/Tktable/tkTableTag.c, pTk/mTk/Tktable/tkTableversion.h: Updates for changes in the Version 2.7 tktable now fully functional on unix. Not tested on win32 yet. 2002-11-01 13:34 cerney * TableMatrix.pm: Updated for changes in the Version 2.7 tktable.tcl file 2002-11-01 12:58 cerney * pod/TableMatrix.pod: Updated for the doc changes from tktable 2.6 to 2.7 2002-11-01 10:48 cerney * pTk/mTk/Tktable/tkTable.c: Version 2.7 merges now are functional. 2002-11-01 10:08 cerney * pTk/mTk/Tktable/: pTk.exc, tkTable.c, tkTable.h, tkTableCell.c, tkTableCmds.c, tkTableTag.c, tkTableUtil.c: Now Compiles successfully with tktable2.8 changes, but core dumps when running. 2002-10-30 11:06 cerney * pTk/mTk/Tktable/cmd.c: Removed. Not Include in tktable 2.7 anymore. 2002-10-30 09:50 cerney * pTk/mTk/Tktable/: mac_tkTable.r, mac_tkTable_prefix.h, tkTable.c, tkTable.h, tkTableCell.c, tkTableCmds.c, tkTableEdit.c, tkTableTag.c, tkTableUtil.c, tkTableWin.c, version.h: Stock tktable changes from 2.6 to 2.7 merged with main branch. Conflicts Resolved. Compilation not tested yet. 2002-10-29 15:52 cerney * pTk/mTk/Tktable/tkTableUtil.c: file tkTableUtil.c was initially added on branch stock-tktable. 2002-10-29 15:52 cerney * pTk/mTk/Tktable/version.h: file version.h was initially added on branch stock-tktable. 2002-10-29 15:52 tag stock-tktable2_7 2002-10-29 15:52 cerney * pTk/mTk/Tktable/: mac_tkTable.r, mac_tkTable_prefix.h, tkTable.c, tkTable.h, tkTableCell.c, tkTableCmds.c, tkTableEdit.c, tkTableTag.c, tkTableUtil.c, tkTableWin.c, version.h: tktable2.7 Source update 2002-09-25 07:08 cerney * COPYING: Updated to be match reality. 2002-05-22 15:53 tag TableMatrix_0_9 2002-05-22 15:53 cerney * Changes, Makefile.PL, TableMatrix.pm, TableMatrix/Spreadsheet.pm, TableMatrix/SpreadsheetHideRows.pm, pTk/Makefile.PL: Preparation for next release 2002-04-11 15:17 cerney * demos/tagMerge, pTk/mTk/Tktable/tkTableTag.c: Mods to make tag merging work correctly when an option is also set in the option database. Also added test case tagMerge. 2002-04-09 12:07 cerney * pod/TableMatrix.pod: Added some clarification on how tags are merged 2002-03-18 11:01 cerney * t/create.t: Updated to include the new SpreadsheetHideRows widget. 2002-03-18 11:00 cerney * TableMatrix/SpreadsheetHideRows.pm, demos/SpreadsheetHideRows: Added new derived SpreadsheetHideRows widget. This enables display of tabular info, with selectable hide/unhide of detail data. 2002-02-28 08:23 cerney * pTk/mTk/Tktable/: tkTableCellSort.c, tkTableCmds.c: Removed Tcl_ArgResult Call from the code, since its use now gets a warning message under Tk800.023. Had to create a TableCellSortObj routine (equivalent to the existing TableCellSort routine) to accomodate this change. 2002-02-13 07:00 cerney * TableMatrix.pm: Fixed bug where selecting multiple times in title area created an error. (Submitted by Christian Becker) 2002-01-10 08:23 cerney * pTk/mTk/Tktable/tkTableCell.c: Updated to fix problem seen with inserting rows when tablecmd is active. Previously, the 'value' arg would get lost when being passed to the callback (garbace collection problem). Changing the call from char* to Arg appears to fix the problem. 2001-10-04 07:00 tag TableMatrix_0_8 2001-10-04 07:00 cerney * Changes, Makefile.PL, TableMatrix.pm, TableMatrix/Spreadsheet.pm, pTk/Makefile.PL: Preparation for the next release. 2001-10-02 12:55 cerney * TableMatrix.pm: Fixed bug where dragging the cursor outside of the window (when selecting some cells) would cause the selection to go nuts. 2001-07-09 14:59 cerney * pTk/mTk/Tktable/tkTable.c: Modified to redraw the entire window when on a expose event. The widget didn't not appear to update/refresh properly when updating what it thought was the invalid rectangle. 2001-06-15 15:19 tag TableMatrix_0_71 2001-06-15 15:19 cerney * Changes, Makefile.PL, TableMatrix.pm, TableMatrix/Spreadsheet.pm, pTk/Makefile.PL: Makeready for release 0.71 2001-06-15 15:04 cerney * Makefile.PL, pTk/Makefile.PL, pTk/mTk/Tktable/tkTable.c: Fixed to compile with Tk800.022 and Tk800.023 2001-06-12 18:11 cerney * pTk/mTk/Tktable/: tkTable.c, tkTablePs.c: Updated to work with Tk800.023 2001-06-06 15:57 tag TableMatrix_0_7 2001-06-06 15:57 cerney * Changes: Initial Checkin 2001-06-06 15:56 cerney * TableMatrix/Spreadsheet.pm: Added version to Spreadsheet.pm in preparation for release. 2001-06-06 11:58 cerney * TableMatrix.pm, Makefile.PL: Updated version in preparation for release. 2001-06-06 11:43 cerney * pTk/mTk/Tktable/: tkTableCell.c, tkTableCellSort.c, tkTableCmds.c, tkTableWin.c: Reverted back to the cell sorting method implemented in tktable 2.5 (and TableMatrix 0.3). The new cell sorting method didn't sort negative row/column indexes correctly, which caused the data from a copy/paste operation to be out-of-order, if the selection included multiple negative row/col indexes. 2001-06-05 12:12 cerney * TableMatrix/Spreadsheet.pm, demos/TableMatrixSpreadsheetTest, t/create.t: Added TableMatrix::Spreadsheet. TableMatrix Derived object with excel-like bindings 2001-06-01 06:43 cerney * TableMatrix.pm: Applied Slaven's patch to fix the control-+/- bindings for modifying the column width. 2000-12-24 13:01 cerney * pTk/: Makefile.PL, mTk/Tktable/tkTable.c: Fixed Version in pTk/Makefile.PL Removed the hard-coded forceupdate=1 in tkTable.c to reduce the flashing seen when updating the cursor. This may have other side effects... needs to be watched. 2000-12-20 07:38 cerney * Makefile.PL: Fixed Typo 2000-12-01 07:34 tag TableMatrix_0_5 2000-12-01 07:34 cerney * README: Fixed version called out in the file 2000-12-01 07:19 cerney * Makefile.PL: Fixed Version 2000-12-01 06:55 cerney * README, TableMatrix.pm: Changes before releasing version 0.5 2000-10-31 21:40 cerney * pTk/mTk/Tktable/tkTable.c: Modified to keep the selection around for incremental selection gets. This helps speed up getting the selection, esp for large area selects. Added setting the cursor to 'watch' when getting the selection. For large selection areas this can take some time, so setting the cursor to watch will at least notify the user that something is happening. 2000-10-26 16:14 cerney * pTk/mTk/Tktable/tkTableCellSort.c: Fixed the sorting routine to work with perl/tk 2000-10-26 11:41 cerney * pTk/mTk/Tktable/: tkTable.h, tkTableCellSort.c: Changed from tktable 2.6 are now incorporated and are fully functional! This looked like a very complicated job, but CVS branch management features made it easy. 2000-10-26 09:49 cerney * pTk/mTk/Tktable/: tkTable.c, tkTable.h, tkTableCell.c, tkTableCellSort.c, tkTableCmds.c, tkTableEdit.c, tkTableInitScript.h, tkTableTag.c, tkTableWin.c, tkTableversion.h: Merged Changes from tcl/tk's tktable2.5 to tktable2.6 from the stock-tktable branch. Resolved conflicts. Not functional yet. 2000-10-26 07:48 cerney * pTk/mTk/Tktable/tkTableCellSort.c: file tkTableCellSort.c was initially added on branch stock-tktable. 2000-10-26 07:48 tag stock-tktable2_6 2000-10-26 07:48 cerney * pTk/mTk/Tktable/: tkTable.c, tkTable.h, tkTableCell.c, tkTableCellSort.c, tkTableCmds.c, tkTableEdit.c, tkTableInitScript.h, tkTableTag.c, tkTableWin.c, tkTableversion.h: tktable2.6 Source update 2000-09-16 15:29 tag TableMatrix_0_3 2000-09-16 15:29 cerney * README, myConfig: Final updates before release 2000-09-13 11:30 cerney * pTk/Makefile.PL: Removed tkres section. W32 resources not needed. 2000-08-23 16:44 cerney * t/create.t: Modified for new name 'TableMatrix' 2000-08-23 16:39 cerney * pod/: TableMatrix.pod, tkTable.pod: Changes to make the name TableMatrix 2000-08-23 16:36 cerney * demos/: TableMatrixTest, basic, buttons, command, debug, dynarows, maxsize, spreadsheet, tktableTest: Changes for the new name 'TableMatrix' 2000-08-23 16:27 cerney * Makefile.PL, README, TableMatrix.pm, TableMatrix.xs, demos/tktableTest: Initial Changes for moving name from tktable to TableMatrix 2000-08-20 20:44 cerney * pTk/mTk/Tktable/tkTablePs.c: Fixed Compile warnings in tkTablePs.c 2000-08-19 11:19 cerney * README, pTk/mTk/Tktable/tkTablePs.c, t/create.t: Updated Readme. Added Test file in 't' directory. 2000-08-17 21:16 cerney * README, TableMatrix.xs, pTk/mTk/Tktable/tkTable.h, pTk/mTk/Tktable/tkTableCell.c, pTk/mTk/Tktable/tkTablePs.c: Added own routine to unset variable in the array hash (TCL_Unsetvar2 function) 2000-08-17 09:18 cerney * TableMatrix.pm: Modified to perform edit->cut properly 2000-08-14 21:07 cerney * pod/tkTable.pod: Doco Fix 2000-08-14 16:35 cerney * Makefile.PL, pTk/mTk/Tktable/tkTable.c, pTk/mTk/Tktable/tkTableCell.c, pTk/mTk/Tktable/tkTableTag.c, pTk/mTk/Tktable/tkTableWin.c: Incorporated Changes made while compiling under Win98 mingw32. 2000-07-25 15:48 cerney * demos/spreadsheet: Added spreadsheet demo 2000-07-24 15:54 cerney * demos/maxsize: Added maxsize demo script. 2000-07-24 06:52 cerney * demos/dynarows: Minor tweak. 2000-07-23 20:49 cerney * demos/basic, demos/command, demos/dynarows, demos/tktableTest, pTk/mTk/Tktable/tkTableCmds.c, pTk/mTk/Tktable/tkTableTag.c, pod/tkTable.pod: Got dynarows demo working 2000-07-22 21:28 cerney * demos/: command, debug: Misc Fixes 2000-07-22 17:16 cerney * demos/dynarows: initial revision 2000-07-21 16:28 cerney * pod/tkTable.pod: dynarows not working yet 2000-07-21 15:29 cerney * demos/debug: Added the debug demo 2000-07-21 14:37 cerney * demos/command, pTk/mTk/Tktable/perlPort.pod, pTk/mTk/Tktable/tkTable.c, pTk/mTk/Tktable/tkTableCell.c, pTk/mTk/Tktable/tkTableCmds.c, pod/tkTable.pod: Got the command demo working. 2000-07-20 21:28 cerney * demos/buttons: Changed Leave event to Focus out event. Leave caused the buttons to not work on Linux. 2000-07-20 14:11 cerney * demos/basic, demos/buttons, pTk/mTk/Tktable/tkTableCell.c, pTk/mTk/Tktable/tkTableCmds.c: Got buttons demo working. 2000-07-19 21:25 cerney * pTk/mTk/Tktable/: perlPort.pod, tkTableTag.c: Modified so the Tag calbacks would work. 2000-07-19 16:41 cerney * demos/basic: Fixed Col Width 2000-07-06 08:17 cerney * TableMatrix.pm, demos/basic, pTk/mTk/Tktable/tkTable.c, pTk/mTk/Tktable/tkTable.h, pTk/mTk/Tktable/tkTableCmds.c, pod/tkTable.pod: * Started Adding the converted tcl demos * Changed the width and heigth methods to colWidth and rowHeight 2000-07-05 07:18 cerney * pTk/mTk/Tktable/tkTableTag.c: Changed Tcl_NewBooleanObj to Tcl_NewIntObj. Tcl_NewBooleanObj didn't appear to be defined in the Lang.h interface. 2000-07-05 07:17 cerney * demos/tktableTest: Added demos directory 2000-07-04 18:33 cerney * pod/tkTable.pod: Added converted pod documentation file. 2000-07-02 20:15 cerney * Makefile.PL, pTk/mTk/Tktable/tkTable.h: Changed version.h to tktableversion.h 2000-07-02 19:32 cerney * Makefile.PL, myConfig, pTk/Makefile.PL: Successfull compilation after removing unnecesaary files. 2000-07-02 10:59 cerney * TableMatrix.pm, TableMatrix.xs, pTk/mTk/Tktable/tkTable.c: Fixed Problem with autoscanning. 2000-07-01 22:57 cerney * Makefile.PL, TableMatrix.pm, TableMatrix.xs, tkGlue.h, pTk/Makefile.PL, pTk/mTk/Tktable/tkTable.c, pod/Makefile.PL: Initial Success at compilation and demo run after splitting-off from Tk 2000-06-30 16:33 cerney * Makefile.PL, myConfig: Added necessary Files. Minor Mods to try to compile separate from Tk 2000-06-30 15:34 cerney * TableMatrix.pm, pTk/mTk/Tktable/tkTable.c: All Bindings appear to work. Check before splitting off into separate module 2000-06-30 14:04 cerney * TableMatrix.pm: Removed the tkTable prefix from subs. 2000-06-29 21:48 cerney * pTk/mTk/Tktable/tkTable.c, TableMatrix.pm: Removed referencing to XSetClipRectangles 2000-06-29 16:32 cerney * pTk/mTk/Tktable/perlPort.pod, pTk/mTk/Tktable/tkTable.c, pTk/mTk/Tktable/tkTable.h, pTk/mTk/Tktable/tkTableCell.c, pTk/mTk/Tktable/tkTableCmds.c, TableMatrix.pm: Now Functional, Some Bugs 2000-06-28 21:30 cerney * pTk/mTk/Tktable/: tkTable.c, tkTableCell.c: Tweaked files 2000-06-28 16:38 cerney * pTk/mTk/Tktable/perlPort.pod, pTk/mTk/Tktable/tkTable.c, pTk/mTk/Tktable/tkTableCell.c, pTk/mTk/Tktable/tkTablePs.c, pTk/mTk/Tktable/tkTableTag.c, TableMatrix.pm: Now Displays Table but some segfaults 2000-06-28 13:19 cerney * pTk/mTk/Tktable/: perlPort.pod, tkTable.c: Mods to Tk_TableObjCmd to be compatible with perltk 2000-06-28 06:52 cerney * TableMatrix.pm, TableMatrix.xs: Minor change to all lower case for the Tk_cmd 2000-06-27 21:24 cerney * TableMatrix.xs: Minor Mods 2000-06-27 16:33 cerney * pTk/mTk/Tktable/: cmd.c, tkTable.c: Latest Updates 2000-06-27 14:04 cerney * pTk/mTk/Tktable/tkTable.c, pTk/mTk/Tktable/tkTable.h, TableMatrix.pm, TableMatrix.xs: Intermediate check-in while trying to get tkTable.so to autoload 2000-06-27 09:11 cerney * myConfig, pTk/mTk/Tktable/tkTableTag.c, TableMatrix.pm, TableMatrix.xs: Added tkTable.pm and associated files (translated from tkTable.tcl) Minor mods for compilation. 2000-06-23 17:43 cerney * myConfig, pTk/mTk/Tktable/cmd.c, pTk/mTk/Tktable/mm.h, pTk/mTk/Tktable/tkTable.h, pTk/mTk/Tktable/tkTableCell.c, pTk/mTk/Tktable/tkTableCmds.c, pTk/mTk/Tktable/tkTablePs.c, pTk/mTk/Tktable/tkTableTag.c, pTk/mTk/Tktable/tkTableWin.c: 1st sucessfull compile. 2000-06-22 21:43 cerney * pTk/mTk/Tktable/: perlPort.pod, tkTable.c, tkTable.h: Almost got tktable.c to compile. 2000-06-22 16:34 cerney * pTk/mTk/Tktable/: cmd.c, mm.h, perlPort.pod, tkTable.c, tkTable.h: Daily Snapshot of work. Currently working to sort out the calling of expandpercents in tktable.c 2000-06-21 21:40 cerney * pTk/mTk/Tktable/: cmd.c, mm.h, tkTable.c: Started modifying char* to Args in cmd structure routines. 2000-06-21 16:35 cerney * pTk/: Makefile.PL, mTk/Tktable/pTk.exc, mTk/Tktable/perlPort.pod, mTk/Tktable/tkTable.c, mTk/Tktable/tkTable.h, mTk/Tktable/tkTableCell.c, mTk/Tktable/tkTableCmds.c, mTk/Tktable/tkTableEdit.c, mTk/Tktable/tkTablePs.c, mTk/Tktable/tkTableTag.c, mTk/Tktable/tkTableWin.c: Initial Try at getting tktable to compile 2000-06-21 07:36 tag stock-tktable2_5 2000-06-21 07:36 cerney * pTk/mTk/Tktable/pTk.exc: pTk exclude file 2000-06-21 07:36 cerney * pTk/mTk/Tktable/: Makefile.in, cmd.c, confdefs.h, config.cache, config.log, configure, configure.in, mac_tkTable.mcp, mac_tkTable.r, mac_tkTable_prefix.h, makefile.vc, mm.h, perlPort.pod, tkAppInit.c, tkTable.c, tkTable.h, tkTableCell.c, tkTableCmds.c, tkTableEdit.c, tkTableInitScript.h, tkTablePs.c, tkTableTag.c, tkTableWin.c, tkTableversion.h: Stock Tktable source upload 2000-06-20 18:55 tag Tk_800_022 2000-06-20 18:55 cerney * COPYING, Makefile.PL, README, debug, debug.bat, myConfig, tkGlue.h, pTk/Makefile.PL, pTk/Tcl-pTk, pTk/chext, pTk/counts, pTk/defs, pTk/fakeld, pTk/findX, pTk/findcore, pTk/findstrings, pTk/from, pTk/genexc, pTk/license.html_lib, pTk/license.terms, pTk/makeenglish, pTk/mkXinfo, pTk/mkmethods, pTk/mkneed, pTk/p4e, pTk/process_object, pTk/refs, pTk/tdiff, pTk/why, pTk/mTk/README, pTk/mTk/license.terms: Initial revision 2000-06-20 18:55 cerney * COPYING, Makefile.PL, README, debug, debug.bat, myConfig, tkGlue.h, pTk/Makefile.PL, pTk/Tcl-pTk, pTk/chext, pTk/counts, pTk/defs, pTk/fakeld, pTk/findX, pTk/findcore, pTk/findstrings, pTk/from, pTk/genexc, pTk/license.html_lib, pTk/license.terms, pTk/makeenglish, pTk/mkXinfo, pTk/mkmethods, pTk/mkneed, pTk/p4e, pTk/process_object, pTk/refs, pTk/tdiff, pTk/why, pTk/mTk/README, pTk/mTk/license.terms: Tk Stock 800.022 Tk-TableMatrix-1.26/TableMatrix/0000755000000000000000000000000013746050164015152 5ustar rootrootTk-TableMatrix-1.26/TableMatrix/Spreadsheet.pm0000644000000000000000000005514513746047570020000 0ustar rootroot =head1 NAME Tk::TableMatrix::Spreadsheet - Table Display with Spreadsheet-like bindings. =head1 SYNOPSIS use Tk; use Tk::TableMatrix::Spreadsheet; my $t = $top->Scrolled('Spreadsheet', -rows => 21, -cols => 11, -width => 6, -height => 6, -titlerows => 1, -titlecols => 1, -variable => $arrayVar, -selectmode => 'extended', -bg => 'white', ); =head1 DESCRIPTION L is a L-derived widget that implements some bindings so the resulting widget behaves more like a spreadsheet. B =over 1 =item * Row/Col resize handles appear when the cursor is placed over a row/col border line in the rol/col title area. Dragging these handles will resize the row or column. If multiple rows or columns are selected, then the new row/col size will apply to all row/cols selected. Note: With the base Tk::TableMatrix, it is possible to resize the row/cols by dragging on any cell border. To be more spreadsheet-like, Tk::TableMatrix::Spreadsheet defaults to enable row/col resizing only thru the title row/col dragging. To override this default behavoir, set the -resizeborder option to 'both' at startup. =item * A popup menu for row/col insert/delete appears when the mouse is right-clicked in the row/col title areas. =item * Cells activate (i.e. the contents become edit-able) only when the cell is double-clicked or the F2 button is pressed. The default L behavior is for the cell to be activated when the cell is single-clicked. =item * The Escape key causes any changes made to a cell to be canceled and the current selection cleared. =item * The return key causes the the current cell to move down. =item * The tab (or shift tab) key causes the current cell to be moved to the right (left). =item * The delete key will delete the current selection, if no cell is currently active. =item * The Mouse button 2 (middle button) paste from the PRIMARY. (Control-v pastes from the clipboard). =back =head1 Additional Information Widget methods, options, etc, are inherited from the L widget. See its docs for additional information. =cut package Tk::TableMatrix::Spreadsheet; use Carp; use Tk; use Tk::TableMatrix; use Tk::Derived; use base qw/ Tk::Derived Tk::TableMatrix/; $VERSION = '1.26'; Tk::Widget->Construct("Spreadsheet"); sub ClassInit{ my ($class,$mw) = @_; $class->SUPER::ClassInit($mw); # Bind our motion routine to change cursors for row/column resize $mw->bind($class,'',['GeneralMotion',$mw]); # Over-ride default button release binding # so a cell won't activate by just clicking $mw->bind($class,'',['Button1Release', $mw]); # Edit (activate) a cell if it is double-clicked # Or F2 is pressed $mw->bind($class,'', sub { my $w = shift; my $Ev = $w->XEvent; if ($w->exists) { $w->CancelRepeat; $w->activate('@' . $Ev->x.",".$Ev->y); } } ); $mw->bind($class,'', sub { my $w = shift; my $Ev = $w->XEvent; if ($w->exists) { $w->CancelRepeat; my $location = '@' . $Ev->x.",".$Ev->y; #print "location = $location\n"; if( $w->selectionIncludes($location)){ $w->activate('@' . $Ev->x.",".$Ev->y); } } } ); $mw->bind($class,'', sub { my $w = shift; $w->reread; # undo any changes if editing a cell my $upperLeft = $w->cget(-roworigin).",".$w->cget(-colorigin); $w->activate($upperLeft); $w->selectionClear('all'); } ); # Make the return key enter and move down $mw->bind($class,'',['MoveCell',1,0]); $mw->bind($class,'',['MoveCell',1,0]); # Make the tab key enter and move right $mw->bind($class,'', sub{ my $w = shift; $w->MoveCell(0,1); Tk->break; } ); $mw->bind($class,'',['MoveCell',0,-1]); # Make the delete key delete the selection, if no active cell $mw->bind($class,'', sub{ my $self = shift; my $active; # Get the current active cell, if one exists eval { $active = $self->index('active'); }; $active = '' if( $@); # No Active cell found; # No Active cell if it is set to the upper left column (esc key pressed) my $upperLeft = $self->cget(-roworigin).",".$self->cget(-colorigin); $active = '' if( $active eq $upperLeft); # No Active cell found; if( $active eq ''){ # No Active Cell, delete the selection eval { $self->curselection(undef);# Clear whatever is selected $self->selectionClear(); } } else{ # There is a current active cell, perform delete in that $self->deleteActive('insert'); } } ); # Button2 release pastes from PRIMARY (control v pastes from clipboard $mw->bind($class,'', sub { my $w = shift; my $Ev = $w->XEvent; $w->Paste($w->index('@' . $Ev->x.",".$Ev->y),'PRIMARY') unless ($Tk::TableMatrix::tkPriv{'mouseMoved'}); } ); }; sub Populate { my ($cw, $args) = @_; # Set Default Args: $args->{-bg} = 'white' unless defined( $args->{-bg}); $args->{-colstretchmode} = 'unset' unless defined( $args->{-colstretchmode}); # Default behavior is to not allow cell resizing, just at the row/col titles (like Excel) $args->{-resizeborders} = 'none' unless defined( $args->{-resizeborders}); $cw->SUPER::Populate($args); # default Tags $cw->tagConfigure('active', -bg => 'gray90', -relief => 'sunken', -fg => 'black'); $cw->tagConfigure( 'title', -bg => 'gray85', -fg => 'black', -relief => 'sunken'); # setup Popup Menu (right mouse-button press) for common operations my $popup = $cw->Menu('-tearoff' => 0); $popup->command('-label' => 'Insert', -bg => 'gray85', '-command' => ['insertRowCol',$cw] ); $popup->command('-label' => 'Delete', -bg => 'gray85','-command' => ['deleteRowCol',$cw] ); $popup->command('-label' => 'Clear Contents', -bg => 'gray85','-command' => ['curselection', $cw,''] ); # Bind a sub for button 3 press $cw->bind('', sub { my $Ev = $cw->XEvent; # Don't Do anything if we are on a cell border # This keeps the right-click menu from pop-ing up # when starting a cell re-size my @border = $cw->border('mark',$Ev->x,$Ev->y); # print "border = ".join(", ",@border)." size = ".scalar(@stuff)."\n"; # return if on a border or if not in edit mode return if( scalar(@border) || ( $cw->cget(-state) =~ /disabled/i )); my $inTitleArea = 0; # Flag = 1 if we are in a title Area my $inSelectedArea = 0; # Flag = 1 if we are in a selected area my ($x,$y) = ($Ev->x, $Ev->y); my $pointerLoc = $cw->index('@'."$x,$y"); $cw->{pointerLoc} = $pointerLoc; # Save pointer location for the insert/delete row routines # After the local menu pops up and a item is selected, the pointer # location won't be valid anymore # print "Pointer over = '$pointerLoc'\n"; if( $cw->tagIncludes('title',$pointerLoc) && $pointerLoc ne '0,0' ){ # print "Pointer over a title area\n"; $inTitleArea = 1; } if( $cw->selectionIncludes($pointerLoc)){ $inSelectedArea = 1; # print "In Selected Area\n"; } if( $inTitleArea && !$inSelectedArea){ # select the row/col if # in title area and not selected $cw->BeginSelect($pointerLoc); } if( $inTitleArea ){ $popup->Popup('-popover' => 'cursor', '-popanchor' => 'nw'); } } ); } # Sub to insert row/cols sub insertRowCol{ my $cw = shift; my $pointerLoc = $cw->{pointerLoc}; # use the pointer locatin from before the popup window came up my ($r,$c) = split(",",$pointerLoc); #print "pointerLoc = $r, $c\n"; if( $r <= 0){ # Insert Col my %cols; @cols{map /(\d+)$/, $cw->tagCell('sel')} = 1; my @cols = sort {$a <=> $b} keys %cols; my $minCol = $cols[0]; my $colCount = $cols[-1] - $minCol + 1; $cw->insertCols($minCol,-$colCount); # Make selection and clear my $lastRow = $cw->index('end','row'); $cw->selectionSet("0,$minCol","$lastRow,".$cols[-1]); $cw->curselection(''); } elsif( $c <= 0 ){ my %rows; @rows{map /^(\d+)/, $cw->tagCell('sel')} = 1; my @rows = sort {$a <=> $b} keys %rows; my $minRow = $rows[0]; my $rowCount = $rows[-1] - $minRow + 1; $cw->insertRows($minRow,-$rowCount); # Make selection and clear my $lastCol = $cw->index('end','col'); $cw->selectionSet("$minRow,0",$rows[-1].",$lastCol"); $cw->curselection(''); } } # Sub to delete row/cols sub deleteRowCol{ my $cw = shift; my $pointerLoc = $cw->{pointerLoc}; # use the pointer locatin from before the popup window came up my ($r,$c) = split(",",$pointerLoc); #print "pointerLoc = $r, $c\n"; if( $r <= 0){ # Delete Col my %cols; @cols{map /(\d+)$/, $cw->tagCell('sel')} = 1; my @cols = sort {$a <=> $b} keys %cols; my $minCol = $cols[0]; my $colCount = $cols[-1] - $minCol + 1; $cw->deleteCols($minCol,$colCount); # Make selection my $lastRow = $cw->index('end','row'); $cw->selectionSet("0,$minCol","$lastRow,".$cols[-1]); } elsif( $c <= 0 ){ my %rows; @rows{map /^(\d+)/, $cw->tagCell('sel')} = 1; my @rows = sort {$a <=> $b} keys %rows; my $minRow = $rows[0]; my $rowCount = $rows[-1] - $minRow + 1; $cw->deleteRows($minRow,$rowCount); # Make selection my $lastCol = $cw->index('end','col'); $cw->selectionSet("$minRow,0",$rows[-1].",$lastCol"); } } # General Motion routine. Sets the border cursor to <-> if on a row border. # or vertical resize cursor if on a col border sub GeneralMotion{ my $self = shift; my $Ev = $self->XEvent; my $rc = $self->index('@' . $Ev->x.",".$Ev->y); return unless($rc); my ($row,$col) = split(',',$rc); my $rowColResize = $self->{rowColResize}; # Flag = 1 if cursor has been changed for a row/col resize my $rowColResizeOldCursor = $self->{rowColResizeOldCursor}; # name of old cursor that was changed; my $rowColResizeOldBDCursor = $self->{rowColResizeBDOldCursor}; # name of old BD cursor that was changed; my @border = $self->border('mark',$Ev->x,$Ev->y); if( scalar(@border) ){ # we are on a border my ($r,$c) = @border; # print "In motion $r, $c: $row, $col\n"; # my $currentBDCursor = $self->cget(-bordercursor); if( ($col <= 0) && ($r =~ /\d/) ){ # print "Row Border = $r\n"; # print "Setting Row Border \n"; unless($rowColResize){ $self->{rowColResizeOldCursor} = $self->cget(-cursor); $self->{rowColResizeBDOldCursor} = $self->cget(-bordercursor); $self->configure(-cursor => 'sb_v_double_arrow', -bordercursor => 'sb_v_double_arrow'); $self->{rowColResize} = 1; $self->{rowColResizeRow} = $r; $self->{rowColResizeCol} = undef; } } elsif( ($row <= 0) && ($c =~ /\d/) ){ # print "Col Border = $c\n"; unless($rowColResize){ $self->{rowColResizeOldCursor} = $self->cget(-cursor); $self->{rowColResizeBDOldCursor} = $self->cget(-bordercursor); $self->configure(-cursor => 'sb_h_double_arrow', -bordercursor => 'sb_h_double_arrow'); $self->{rowColResize} = 1; $self->{rowColResizeRow} = undef; $self->{rowColResizeCol} = $c; } } } else{ if( $rowColResize && !($self->{rowColResizeDrag}) ){ # Change cursor back if it has been changed, and # we aren't currently doing a row/col resize drag. #print "Setting to $oldCursor\n"; $self->configure(-cursor => $rowColResizeOldCursor, -bordercursor => $rowColResizeOldBDCursor); $self->{rowColResize} = 0; } } } ######################################################################3 ## Over-ridden beginselect. Sets the rowColResizeDrag to indicate ## that we are doing a row or column resize operation sub borderDragto{ my $self = shift; my @args = @_; if( !$self->{rowColResizeDrag}){ #print "StartDrag\n"; $self->{oldResizeBorders} = $self->cget(-resizeborders); # save the value of resizeborders so we can restore it later $self->configure(-resizeborders => 'both'); } $self->{rowColResizeDrag} = 1; # Flag = 1 if we are currently doing a row/col resize drag $self->SUPER::borderDragto(@args); } ################################################################## # Over-ridden Motion routine. Does a row/col resize if # row/col resize cursors are active # This is needed for linux for the row resize to work # Not sure why sub Motion{ my $self = shift; my $rc = shift; if( $self->{rowColResize}){ # Do a row/col resize if cursors active my $Ev = $self->XEvent; if( !$self->{rowColResizeDrag}){ # Same as the borderDragTo, somethings this gets called first #print "StartDrag\n"; $self->{oldResizeBorders} = $self->cget(-resizeborders); # save the value of resizeborders so we can restore it later $self->configure(-resizeborders => 'both'); } $self->{rowColResizeDrag} = 1; # Flag = 1 if we are currently doing a row/col resize drag $self->SUPER::borderDragto($Ev->x,$Ev->y); } else{ $self->SUPER::Motion($rc); } } ############################################################# ## Over-ridden beginselect. Doesn't select if we are doing a row/col resize sub BeginSelect{ my $self = shift; my $rc = shift; return if( $self->{rowColResize}); # Don't Select if currently doing a row/col resize # print "Calling inherited BeginSelect\n"; $self->SUPER::BeginSelect($rc); } ############################################################# ## Over-ridden TableInsert. ## If a key is pressed and a cell is not activated. Activate the ## current cell and insert the key pressed sub TableInsert{ my $self = shift; my $key = shift; # my $Ev = $self->XEvent; # Activate the current anchor position, if # key pressed, and no cell currently active # Get the current active cell, if one exists eval { $active = $self->index('active'); }; $active = '' if( $@); # No Active cell found; # No Active cell if it is set to the upper left column (esc key pressed) my $upperLeft = $self->cget(-roworigin).",".$self->cget(-colorigin); $active = '' if( $active eq $upperLeft); # No Active cell found; if( $key ne '' && $active eq '' ){ my $anchor = $self->index('anchor'); $self->activate($anchor); $self->deleteActive(0,'end'); # delete text from the cell } $self->SUPER::TableInsert($key); } ############################################################# ## Over-ridden MoveCell. ## This method performs moving cells in a more Excel-like way: ## 1) Moving cell when one is active unactivates the cell and then selects (not activates) ## the new cell ## 2) Moving cell when none is active moves the anchor point cell, if one exits. ## 3) Does nothing otherwise sub MoveCell{ my $w = shift; my $x = shift; # Delta X for moving my $y = shift; # Delta y for moving my $c; my $cell; # new cell index my $true; my $r; my $fromCell; # Cell to move from (Could be an active cell, if present, or selection anchor point # if present. my $active; # Current active cell # Get the current active cell, if one exists eval { $active = $w->index('active'); }; $active = '' if( $@); # No Active cell found; # No Active cell if it is set to the upper left column (i.e. esc key pressed) my $upperLeft = $w->cget(-roworigin).",".$w->cget(-colorigin); $active = '' if( $active eq $upperLeft); # No Active cell found; if( $active eq ''){ # no active cell found, see if there is a selection my $anchor = $w->index('anchor'); unless( defined($anchor) ){ # print "Anchor not defined\n"; return; } $fromCell = $anchor; } else{ $fromCell = $active; } ($r,$c) = split(',',$fromCell); # my $currentCell = "$r,$c"; $cell = $w->index(($r += $x).",".($c += $y)); $w->activate($upperLeft) if( $active ne ''); $w->see($cell); if ($w->cget('-selectmode') eq 'browse') { $w->selection('clear','all'); $w->selection('set',$cell); } elsif ($w->cget('-selectmode') eq 'extended') { $w->selection('clear','all'); $w->selection('set',$cell); $w->selection('anchor',$cell); $Tk::TableMatrix::tkPriv{'tablePrev'} = $cell; } } ############################################################# ## Over-ridden Paste. ## This method performs pasting cells in a more Excel-like way: ## Paste Data will be pasted into the current selection anchor point ## if no current cell is active, otherwise it pastes starting at the active ## cell. ## ## If no current active cell, and no anchor point, does nothing. sub Paste{ my $w = shift; my $cell = shift || ''; my $source = shift || 'CLIPBOARD'; # Default is to paste from the clipboard my $data; # Check for active cell or anchor cell: unless($cell){ my $active; # Current active cell # Get the current active cell, if one exists eval { $active = $w->index('active'); }; $active = '' if( $@); # No Active cell found; # No Active cell if it is set to the upper left column (i.e. esc key pressed) my $upperLeft = $w->cget(-roworigin).",".$w->cget(-colorigin); $active = '' if( $active eq $upperLeft); # No Active cell found; if( $active eq ''){ # no active cell found, see if there is a selection $cell = $w->index('anchor'); return unless( $cell); # don't paste if no anchor point and no active } else{ $cell = $active; } } eval{ $data = $w->SelectionGet(-selection => $source); }; return if($@); $w->PasteHandler($cell,$data); $w->focus if ($w->cget('-state') eq 'normal'); } ############################################################# # # Sub called when button 1 released. # Takes care or row/col border drags. # Also checks to see if more than one row/col is selected during # a row/col resize, so those row/cols will be resized as well sub Button1Release{ my $w = shift; my $Ev = $w->XEvent; #print "Button Release 1\n"; if ( $w->{rowColResizeDrag} ) { # Row/Col resize finishing up my @selRowCol = $w->curselection; if ( $w->{rowColResizeRow} ) { # Row risize, check for other rows selected my $row = $w->{rowColResizeRow}; my $newRowHeight = $w->rowHeight($row); #print "Resized row $row to height" . $newRowHeight . "\n"; # Find other selected rows (must be contiguous selected from the drag row) my $rowOrg = $w->cget( -roworigin ); my $colOrg = $w->cget( -colorigin ); my $rowMax = $rowOrg + $w->cget( -rows ) - 1; # max row in table my $firstDataRow = $rowOrg + $w->cget( -titlerows ); # first Data Row my $firstDataCol = $colOrg + $w->cget( -titlecols ); # first Data Col my @otherRowsSelected; foreach my $row ( ( $row + 1 ) .. $rowMax ) { # Increasing rows #print "Checking for inclusion of $row,$firstDataCol\n"; last unless ( $w->selectionIncludes("$row,$firstDataCol") ); push @otherRowsSelected, $row; } foreach my $row ( reverse( $firstDataRow .. ( $row - 1 ) ) ) { # Decreasing rows #print "Checking for inclusion of $row,$firstDataCol\n"; last unless ( $w->selectionIncludes("$row,$firstDataCol") ); push @otherRowsSelected, $row; } # Set New row height for other rows if (@otherRowsSelected) { # Set args to row => height, row => height ... my @rowHeightArgs = map { $_ => $newRowHeight } @otherRowsSelected; $w->rowHeight(@rowHeightArgs); } } elsif ( $w->{rowColResizeCol} ) { # Col risize, check for other Cols selected my $col = $w->{rowColResizeCol}; my $newColWidth = $w->colWidth($col); #print "Resized col $col to width" . $newColWidth . "\n"; # Find other selected cols (must be contiguous selected from the drag col) my $rowOrg = $w->cget( -roworigin ); my $colOrg = $w->cget( -colorigin ); my $colMax = $colOrg + $w->cget( -cols ) - 1; # max col in table my $firstDataRow = $rowOrg + $w->cget( -titlerows ); # first Data Row my $firstDataCol = $colOrg + $w->cget( -titlecols ); # first Data Col my @otherColsSelected; foreach my $col ( ( $col + 1 ) .. $colMax ) { # Increasing cols #print "Checking for inclusion of $firstDataRow,$col\n"; last unless ( $w->selectionIncludes("$firstDataRow,$col") ); push @otherColsSelected, $col; } foreach my $col ( reverse( $firstDataCol .. ( $col - 1 ) ) ) { # Decreasing rows #print "Checking for inclusion of $row,$firstDataCol\n"; last unless ( $w->selectionIncludes("$firstDataRow,$col") ); push @otherColsSelected, $col; } # Set Col width height for other rows if (@otherColsSelected) { # Set args to row => height, row => height ... my @colWidthArgs = map { $_ => $newColWidth } @otherColsSelected; $w->colWidth(@colWidthArgs); } } } if($w->{rowColResizeDrag}){ # restore the value of resize borders to what is was before if( my $oldResizeborders = $w->{oldResizeBorders}){ $w->configure(-resizeborders => $oldResizeborders); delete $w->{oldResizeBorders}; } #print "Drag Finished\n"; } $w->{rowColResizeDrag} = 0; # reset row/col resize dragging flag $w->{rowColResizeRow} = undef; # reset row resize flag $w->{rowColResizeCol} = undef; # reset col resize flag if ( $w->exists ) { $w->CancelRepeat; } } 1; Tk-TableMatrix-1.26/TableMatrix/SpreadsheetHideRows.pm0000644000000000000000000004412213746047570021436 0ustar rootroot=head1 NAME Tk::TableMatrix::SpreadsheetHideRows - Table Display with selectable hide/un-hide of rows =head1 SYNOPSIS use Tk; use Tk::TableMatrix::SpreadsheetHideRows my $t = $top->Scrolled('SpreadsheetHideRows', -selectorCol => 3, -expandData => $hashRef, -rows => 21, -cols => 11, -width => 6, -height => 6, -titlerows => 1, -titlecols => 1, -variable => $arrayVar, -selectmode => 'extended', -resizeborders => 'both', -bg => 'white', ); =head1 DESCRIPTION L is a L-derived widget that implements a Spreadsheet-like display of tabular information, where some of the rows in the table can be expanded/hidden by clicking a '+/-' selector in the row. This can be used to display top-level information in a table, while allowing the user to expand certain table rows to view detail-level information. See demos/SpreadsheetHideRows in the source distribution for a simple example of this widget =head1 Widget-specific Options In addition the standard L widget options. The following options are implemented: =over 1 =item -selectorCol Column number where the +/- selector will appear. Clicking on the +/- selector will expand/hide the detail information in the table for a particular row. =item -selectorColWidth Width of the column used to display the +/- selector. Defaults to 2 =item -expandData Hash ref defining the detail-level data displayed when a row is expanded (by clicking the +/- selector). This hash ref should have the following structure: $expandData = { row1 => { tag => 'detailDataTag', data => $detailData, spans=> $spanData, expandData => $subLevelData }, row2 => { . . } Where: row1, row2, ... Row numbers that will be expandable. tag => 'detailDataTag' Tag name that will be applied to the detail data. (optional) $detailData 2D Array of detail-data to be displayed when the row is expanded. e.g. [ [ r1c1, r1c2, r1c3 ], [ r2c1, r2c2, r2,c3] ] $spans 1D array of span information (optional) to be used for display of the detail information. e.g. [ col2 => "rows,cols", col4 => "rows,cols", ... ] $subLevelData Optional Recursive expandData used to hold detail-data of detail-data. =back =head1 MEMBER DATA The following items are stored as member data =over 1 =item defaultCursor Name of the mouse cursor pointer that is used for normal (i.e. non-title, non-indicator) cells in the widget. This is set to the value of the $widget->cget(-cursor) option when the widget is created. =item indRowCols Hash ref of Row/Cols indexes where there are indicators stores. This is a quick lookup hash built from I<_expandData>. =item _expandData Internal version of the I hash. Any sub-detail data (i.e. expand data that is at lower levels of I) that is visible is placed at the top level of this hash, for keeping track of the visible I. =back =head1 Widget Methods In addition the standard L widget method. The following methods are implemented: =cut package Tk::TableMatrix::SpreadsheetHideRows; use Carp; use Tk; use Tk::TableMatrix::Spreadsheet; use Tk::Derived; use base qw/ Tk::Derived Tk::TableMatrix::Spreadsheet/; $VERSION = '1.26'; Tk::Widget->Construct("SpreadsheetHideRows"); sub ClassInit{ my ($class,$mw) = @_; $class->SUPER::ClassInit($mw); }; sub Populate { my ($self, $args) = @_; $self->ConfigSpecs( -selectorCol => [qw/METHOD selectorCol SelectorCol/, undef], -selectorColWidth=> [qw/PASSIVE selectorColWidth SelectorColWidth/, 2], -expandData => [qw/METHOD expandData ExpandData/, {}], ); $self->SUPER::Populate($args); $self->tagConfigure('plus', -image => $self->Getimage("plus"), -showtext => 0, -anchor => 'center'); $self->tagConfigure('minus', -image => $self->Getimage("minus"), -showtext => 0, -anchor => 'center'); $self->{normalCursor} = $self->cget('-cursor'); # get the default cursor } =head2 showDetail Shows (i.e. expands the table) the detail data for a given row. This method is called when a user clicks on an indicator that is not already expanded. B $widget->showDetail($row); # Shows the detail data for row number $row =cut sub showDetail{ my $self = shift; my $row = shift; my $selectorCol = $self->cget(-selectorCol); my $index = "$row,$selectorCol"; # make index for the cell to be expanded my $indRowCols = $self->{indRowCols}; $self->tagCell('minus', $index); $indRowCols->{$index} = '-'; # Get the detail data and insert: my $expandData = $self->{'_expandData'}; my $detailData = $expandData->{$row}; my $detailArray = $detailData->{data}; my $noRows = scalar( @$detailArray); # InsertRows: # change state to normal if not already so we can insert my $currentState = $self->cget(-state); $self->configure(-state => 'normal') unless( $currentState eq 'normal'); $self->insertRows($row,$noRows); # Adjust Spans: $self->adjustSpans($row+1,$noRows); #insert data my $colorigin = $self->cget(-colorigin); my $rowNum = $row+1; foreach my $rowData( @$detailArray ){ #my @rowArray = @$rowData; #grep s/([\{\}])/\\$1/g, @rowArray; # backslash any existing '{' chars, so they don't get interpreted as field chars my $insertData = "{".join("}{", @$rowData)."}"; # make insert data look like tcl array, so it # gets put in different cells $self->set('row', "$rowNum,$colorigin", $insertData); $rowNum++; } # Apply Tags, if any: my $tag; if( defined( $detailData->{tag})){ $tag = $detailData->{tag}; my $startRow = $row+1; my $noRows = @$detailArray; my $stopRow = scalar(@$detailArray) + $startRow - 1; my @tagRows = ($startRow..$stopRow); $self->tagRow($tag,@tagRows); } # Apply Spans, if any: my $spans; if( defined( $detailData->{spans})){ $spans = $detailData->{spans}; my $spanSize = scalar(@$spans); #Error Checking, spans array should be a multiple of 2 if( ($spanSize % 2) < 1){ my $startRow = $row+1; my $noRows = @$detailArray; my $stopRow = scalar(@$detailArray) + $startRow - 1; foreach my $spanRow($startRow..$stopRow){ # build an array to feed to spans, change column number for row.col index # (every 2rd item in the array). my @spanArray = map $_ % 2 ? $spans->[$_] : "$spanRow,".$spans->[$_], (0..($spanSize-1)); $self->spans(@spanArray); } }else{ warn("Spans array for row $row, is not a multiple of 2\n"); } } # Now Update the internal arrays for the inserted rows ### my %expandDataNew; foreach my $rowIndex(keys %$expandData){ if($rowIndex > $row){ # adjust rows greater than the current row $expandDataNew{$rowIndex+$noRows} = $expandData->{$rowIndex}; } else{ $expandDataNew{$rowIndex} = $expandData->{$rowIndex}; } } # Copy new to existing: %$expandData = %expandDataNew; my %indRowColsNew; foreach my $rcindex(keys %$indRowCols){ my ($rowIndex,$colIndex) = split(',',$rcindex); if($rowIndex > $row){ # adjust rows greater than the current row my $newRow = $rowIndex+$noRows; $indRowColsNew{"$newRow,$colIndex"} = $indRowCols->{$rcindex}; } else{ $indRowColsNew{$rcindex} = $indRowCols->{$rcindex}; } } # Copy new to existing: %$indRowCols = %indRowColsNew; # Take care of any lower-level detail data: my $subDetail; if( defined( $detailData->{expandData})){ $subDetail = $detailData->{expandData}; foreach my $subRow( keys %$subDetail){ my $realRow = $row+$subRow; my $index = "$realRow,$selectorCol"; $self->tagCell('plus', $index); $indRowCols->{$index} = '+'; # update internal array # put subdetail data to top level, adjusting the relative row # numbers to real row numbers: #my %adjustedSubDetail; #foreach my $subKey(keys %$subDetail){ # $adjustedSubDetail{$subKey+$row} = $subDetail->{$subKey}; #} $expandData->{$realRow} = $subDetail->{$subRow}; } } # Put the state back $self->configure(-state => $currentState) unless( $currentState eq 'normal'); } =head2 hideDetail Hides the detail data for a given row. This method is called when a user clicks on an indicator that is already expanded. B $widget->hideDetail($row); # Hides the detail data for row number $row =cut sub hideDetail{ my $self = shift; my $row = shift; my $expandData = shift; my $detailData = $expandData->{$row}; my $selectorCol = $self->cget(-selectorCol); my $index = "$row,$selectorCol"; # make index for the cell to be hidden my $indRowCols = $self->{indRowCols}; # hide any sublevel data first: my $lowerLevelHideRows = 0; if( defined( $detailData->{expandData})){ # sublevel data exists my $subLevelData = $detailData->{expandData}; # convert sublevel data to absolute rows my $convertedSubData = {}; foreach my $rowNum(keys %$subLevelData){ $convertedSubData->{$rowNum+$row} = $subLevelData->{$rowNum}; } #Hide lower level data, if showing my $subLevelIndex; foreach my $rowNum (sort {$a<=>$b} keys %$convertedSubData){ $subLevelIndex = "$rowNum,$selectorCol"; if( $indRowCols->{$subLevelIndex} eq '-'){ # For lower-level hide-detail calls, we don't use any updates to the # expandData Arg, so we create an anonymous hash ref in this call $lowerLevelHideRows += $self->hideDetail($rowNum,{ %$convertedSubData} ); } } } $self->tagCell('plus', $index); $indRowCols->{$index} = '+'; # Get the detail data and hide: my $detailArray = $detailData->{data}; my $noRows = scalar( @$detailArray); # unapply any spans (This is not auto-handled by the row delete command, so we # have to do it here manually) my $spans; if( defined( $detailData->{spans})){ $spans = $detailData->{spans}; my $spanSize = scalar(@$spans); #Error Checking, spans array should be a multiple of 2 if( ($spanSize % 2) < 1){ my $startRow = $row+1; my $noRows = @$detailArray; my $stopRow = scalar(@$detailArray) + $startRow - 1; foreach my $spanRow($startRow..$stopRow){ # build an array to feed to spans, change column number for row.col index # (every 2rd item in the array). my @spanArray = map $_ % 2 ? '0,0' : "$spanRow,".$spans->[$_], (0..($spanSize-1)); $self->spans(@spanArray); } }else{ warn("Spans array for row $row, is not a multiple of 2\n"); } } # change state to normal if not already so we can modify the table my $currentState = $self->cget(-state); $self->configure(-state => 'normal') unless( $currentState eq 'normal'); # Move Any existing spans that are at rows > $row+$noRows to where the should be, now that rows # have been deleted $self->adjustSpans($row+$noRows,-$noRows); # deleteRows: $self->deleteRows($row+1,$noRows); my %indRowColsNew; foreach my $rcindex(keys %$indRowCols){ my ($rowIndex,$colIndex) = split(',',$rcindex); if($rowIndex > $row){ # adjust rows greater than the current row my $newRow = $rowIndex-$noRows; $indRowColsNew{"$newRow,$colIndex"} = $indRowCols->{$rcindex}; } else{ $indRowColsNew{$rcindex} = $indRowCols->{$rcindex}; } } # Copy new to existing: %$indRowCols = %indRowColsNew; $noRows += $lowerLevelHideRows; # Include the lower level detail rows hidden in the internall array update # Now Update the internal arrays for the deleted rows ### my %expandDataNew; foreach my $rowIndex(keys %$expandData){ if($rowIndex > ($row+$noRows)){ # adjust rows greater than the current row + detail data $expandDataNew{$rowIndex-$noRows} = $expandData->{$rowIndex}; } elsif($rowIndex<= $row){ # rows less than or equal just get copied $expandDataNew{$rowIndex} = $expandData->{$rowIndex}; } #else nothing, expand data that is in the detail data that is being hidden doesn't get copied } # Copy new to existing: %$expandData = %expandDataNew; # Put the state back $self->configure(-state => $currentState) unless( $currentState eq 'normal'); return $noRows; } #---------------------------------------------- # Sub called when -expandData option changes # sub expandData{ my ($self, $expandData) = @_; if(! defined($expandData)){ # Handle case where $widget->cget(-expandData) is called return $self->{Configure}{-expandData} } $self->clearSelectors; my $selectorCol = $self->cget(-selectorCol); # Create internal copy of expand Data for us to mess with my $expandData_int = {}; %$expandData_int = %$expandData; $self->{'_expandData'} = $expandData_int; # update the indRowCols quick lookup hash: $self->updateIndRowCols($expandData, $selectorCol); $self->setSelectors; } #---------------------------------------------- # Sub called when -selectorCol option changes # sub selectorCol{ my ($self, $selectorCol) = @_; if(! defined($selectorCol)){ # Handle case where $widget->cget(-selectorCol) is called # # Set default if not defined yet my $selCol; unless( defined($self->{Configure}{-selectorCol})){ $selCol = $self->{Configure}{-selectorCol} = 0; } else{ $selCol = $self->{Configure}{-selectorCol}; } return $selCol; } ###### Get Old Selector Col and undo Here ?????### $self->clearSelectors; my $expandData = $self->cget('-expandData'); # update the indRowCols quick lookup hash: $self->updateIndRowCols($expandData, $selectorCol); $self->setSelectors; } # Method used to clear the selectors defined in the current indRowCols hash sub setSelectors{ my $self = shift; my $indRowCols = $self->{indRowCols}; my @pluses = grep $indRowCols->{$_} eq '+', keys %$indRowCols; my @minuses = grep $indRowCols->{$_} eq '-', keys %$indRowCols; $self->tagCell('plus', @pluses); $self->tagCell('minus', @minuses); my $selectorCol = $self->cget('-selectorCol'); my $selectorColWidth = $self->cget(-selectorColWidth) || 2; # set to '2' (the default), incase this called before the defaults have been set $self->colWidth($selectorCol, $selectorColWidth); } # Method used to clear the selectors defined in the current indRowCols hash sub clearSelectors{ my $self = shift; my @indRowCols = keys %{$self->{indRowCols}}; if( @indRowCols){ $self->tagCell('', keys %{$self->{indRowCols}}); # Get selectorCol from first entry my ($row,$col) = split(',',$indRowCols[0]); $self->colWidth($col, 'default'); } } ### Method to update indRowCols, based on the expandData and selectorCol sub updateIndRowCols{ my $self = shift; my($expandData, $selectorCol) = @_; my $indRowCols = {}; foreach (keys %$expandData){ $indRowCols->{"$_,$selectorCol"} = '+'; } $self->{indRowCols} = $indRowCols; return $indRowCols; } # General Motion routine. Calls cellEnter if the pointer has entered another # cell. sub GeneralMotion{ my $self = shift; my $Ev = $self->XEvent; my $rc = $self->index('@' . $Ev->x.",".$Ev->y); $self->SUPER::GeneralMotion; my ($row,$col) = split(',',$rc); my @border = $self->border('mark',$Ev->x,$Ev->y); if( scalar(@border) == 0 && (!($self->{lastrc}) || $rc ne $self->{lastrc})){ # call cellEnter if cell number has changed and we aren't on a border $self->{lastrc} = $rc; $self->cellEnter($row,$col); } } # Method called with the pointer goes over a different cell # Sets the cursor to a top-right arrow if over # the selectorCol sub cellEnter{ my $self = shift; my ($row,$col) = @_; #print "Entered '$row,$col'\n"; my $rowColResizeDrag = $self->{rowColResizeDrag}; # Flag = 1 if cursor has been changed for a row/col resize unless($rowColResizeDrag){ my $indRowCols = $self->{indRowCols}; if( defined( $indRowCols->{"$row,$col"})){ #print "Setting ind cursor\n"; $self->configure(-cursor => 'top_left_arrow'); } else{ #print "Setting old cursor back '".$self->{normalCursor}."'\n"; $self->configure(-cursor => $self->{normalCursor}); } } } ############################################################# ## Over-ridden beginselect. Epands cell if +/- cell selected sub BeginSelect{ my $self = shift; my $rc = shift; my $indRowCols = $self->{indRowCols}; # get quick lookup hash my $state; if( defined($indRowCols->{$rc})) { $state = $indRowCols->{$rc}; my ($row,$col) = split(',',$rc); if( $state eq '-'){ $self->hideDetail($row, $self->{'_expandData'}); } else{ $self->showDetail($row); } return; } # print "Calling inherited BeginSelect\n"; $self->SUPER::BeginSelect($rc); } #------------------- # Method Called to adjust spans starting at $row by $noRows # # If noRows is greater than 0 then the spans are adjusted up by $noRows # If noRows is negative, then spans are adjusted down by $noRows # # This method is needed becase the rowinsert/delete methods of TableMatrix don't # automatically adjust the spans sub adjustSpans{ my $self = shift; my ($row,$noRows) = @_; my %spans = $self->spans; # Get All Spans my %spansFilterd; # filtered for row > $row my $minRowFiltered = $row; my @filteredIndexes = grep { my ($r,$c) = split(',',$_); $r >= $minRowFiltered} keys %spans; my %unapplySpans; # temp hash used to unapply spans: @unapplySpans{@filteredIndexes} = map '0,0', @filteredIndexes; $self->spans(%unapplySpans); # unapply the spans the filtered spans: my %adjustedSpans; foreach (@filteredIndexes){ my ($r,$c) = split(',',$_); $adjustedSpans{($r+$noRows).",$c"} = $spans{$_}; } # Apply adjusted Spans: $self->spans(%adjustedSpans); } 1; Tk-TableMatrix-1.26/pod/0000755000000000000000000000000013746050164013520 5ustar rootrootTk-TableMatrix-1.26/pod/TableMatrix.pod0000644000000000000000000016337013745605157016461 0ustar rootroot# See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # =head1 NAME TableMatrix - Create and manipulate tables =head1 Synopsis I<$table> = I<$parent>-EB(?I?); =head1 STANDARD OPTIONS B<-anchor -background -cursor -exportselection -font -foreground -highlightbackground -highlightcolor -highlightthickness -insertbackground -insertborderwidth -insertofftime -insertontime -insertwidth -invertselected -relief -takefocus -xscrollcommand -yscrollcommand> =head1 Widget-specific Options =over 1 =item Switch: B<-autoclear> =item Name: B =item Class: B A boolean value which specifies whether the first keypress in a cell will delete whatever text was previously there. Defaults to 0. =item Switch: B<-bordercursor> =item Name: B =item Class: B Specifies the name of the cursor to show when over borders, a visual indication that interactive resizing is allowed (it is thus affect by the value of -resizeborders). Defaults to I. =item Switch: B<-borderwidth or -bd> =item Name: B =item Class: B Specifies a non-negative pixel value or list of values indicating the width of the 3-D border to draw on interior table cells (if such a border is being drawn; the option typically determines this). If one value is specified, a rectangle of this width will be drawn. If two values are specified, then only the left and right edges of the cell will have borders. If four values are specified, then the values correspond to the {left right top bottom} edges. This can be overridden by the a tag's borderwidth option. It can also be affected by the defined B<-drawmode> for the table. Each value in the list must have one of the forms acceptable to B. =item Switch: B<-browsecommand or -browsecmd> =item Name: B =item Class: B Specifies a command (callback) which will be evaluated anytime the active cell changes. The Previous Index and the Current index is passed to this command as arguments. =item Switch: B<-cache> =item Name: B =item Class: B A boolean value that specifies whether an internal cache of the table contents should be kept. This greatly enhances speed performance when used with B<-command> but uses extra memory. Can maintain state when both B<-command> and B<-variable> are empty. The cache is automatically flushed whenever the value of B<-cache> or B<-variable> changes, otherwise you have to explicitly call B on it. Defaults to off. =item Switch: B<-colorigin> =item Name: B =item Class: B Specifies what column index to interpret as the leftmost column in the table. This value is used for user indices in the table. Defaults to 0. =item Switch: B<-cols> =item Name: B =item Class: B Number of cols in the table. Defaults to 10. =item Switch: B<-colseparator> =item Name: B =item Class: B Specifies a separator character that will be interpreted as the column separator when cutting or pasting data in a table. By default, columns are separated as elements of a tcl list. =item Switch: B<-colstretchmode> =item Name: B =item Class: B Specifies one of the following stretch modes for columns to fill extra allocated window space: =back =over 2 =item B Columns will not stretch to fill the assigned window space. If the columns are too narrow, there will be a blank space at the right of the table. This is the default. =item B Only columns that do not have a specific width set will be stretched. =item B All columns will be stretched by the same number of pixels to fill the window space allocated to the table. This mode can interfere with interactive border resizing which tries to force column width. =item B The last column will be stretched to fill the window space allocated to the table. =item B (only valid for B<-rowstretch> currently) The table will get more or less columns according to the window space allocated to the table. This mode has numerous quirks and may disappear in the future. =back =over 1 =item Switch: B<-coltagcommand> =item Name: B =item Class: B Provides the name of a procedure that will be evaluated by the widget to determine the tag to be used for a given column. When displaying a cell, the table widget will first check to see if a tag has been defined using the B widget method. If no tag is found, it will evaluate the named procedure passing the column number in question as the sole argument. The procedure is expected to return the name of a tag to use, or a null string. Errors occuring during the evaluation of the procedure, or the return of an invalid tag name are silently ignored. The Current column number is passed as an argument to the col command. =item Switch: B<-colwidth> =item Name: B =item Class: B Default column width, interpreted as characters in the default font when the number is positive, or pixels if it is negative. Defaults to 10. =item Switch: B<-command> =item Name: B =item Class: B Specified a command to use as a procedural interface to cell values. If B<-usecommand> is true, this command will be used instead of any reference to the B<-variable> array. When retrieving cell values, the return value of the command is used as the value for the cell. Args passed to this callback: The Set Flag (=1 if setting, else retrieving), the current row, the current col, the cell value (if setting). =item Switch: B<-drawmode> =item Name: B =item Class: B Sets the table drawing mode to one of the following options: =back =over 2 =item B The table is drawn to an offscreen pixmap using the Tk bordering functions (double-buffering). This means there will be no flashing, but this mode is slow for larger tables. =item B The table is drawn directly to the screen using the Tk border functions. It is faster, but the screen may flash on update. This is the default. =item B The table is drawn directly to the screen and the borders are done with fast X calls, so they are always one pixel wide only. As a side effect, it restricts B<-borderwidth> to a range of 0 or 1. This mode provides best performance for large tables, but can flash on redraw and is not 100% Tk compatible on the border mode. =item B The table is drawn to the screen as in fast mode, but only single pixel lines are drawn (not square borders). =back =over 1 =item Switch: B<-flashmode> =item Name: B =item Class: B A boolean value which specifies whether cells should flash when their value changes. The table tag B will be applied to these cells for the duration specified by B<-flashtime>. Defaults to 0. =item Switch: B<-flashtime> =item Name: B =item Class: B The amount of time, in 1/4 second increments, for which a cell should flash when its value has changed. B<-flashmode> must be on. Defaults to 2. =item Switch: B<-height> =item Name: B =item Class: B Specifies the desired height for the window, in rows. If zero or less, then the desired height for the window is made just large enough to hold all the rows in the table. The height can be further limited by B<-maxheight >. =item Switch: B<-invertselected> =item Name: B =item Class: B Specifies whether the foreground and background of an item should simply have their values swapped instead of merging the I tag options when the cell is selected. Defaults to 0 (merge I tag). =item Switch: B<-ipadx> =item Name: B =item Class: B A pixel value specifying the internal offset X padding for text in a cell. This value does not grow the size of the cell, it just causes the text to be drawn further from the cell border. It only affects one side (depending on anchor). Defaults to 0. See B<-padx> for an alternate padding style. =item Switch: B<-ipady> =item Name: B =item Class: B A pixel value specifying the internal offset Y padding for text in a cell. This value does not grow the size of the cell, it just causes the text to be drawn further from the cell border. It only affects one side (depending on anchor). Defaults to 0. See B<-pady> for an alternate padding style. =item Switch: B<-justify> =item Name: B =item Class: B How to justify multi-line text in a cell. It must be one of B, B, or B
. Defaults to left. =item Switch: B<-maxheight> =item Name: B =item Class: B The max height in pixels that the window will request. Defaults to 600. =item Switch: B<-maxwidth> =item Name: B =item Class: B The max width in pixels that the window will request. Defaults to 800. =item Switch: B<-multiline> =item Name: B =item Class: B Specifies the default setting for the multiline tag option. Defaults to 1. =item Switch: B<-pady> =item Name: B =item Class: B A pixel value specifying the offset X padding for a cell. This value causes the default size of the cell to increase by two times the value (one for each side), unless a specific pixel size is chosen for the cell with the B command. This will force an empty area on the left and right of each cell edge. This padding affects all types of data in the cell. Defaults to 0. See B<-ipadx> for an alternate padding style. =item Switch: B<-pady> =item Name: B =item Class: B A pixel value specifying the offset Y padding for a cell. This value causes the default size of the cell to increase by two times the value (one for each side), unless a specific pixel size is chosen for the cell with the B command. This will force an empty area on the top and bottom of each cell edge. This padding affects all types of data in the cell. Defaults to 0. See B<-ipadx> for an alternate padding style. =item Switch: B<-resizeborders> =item Name: B =item Class: B Specifies what kind of interactive border resizing to allow, must be one of row, col, both (default) or none. =item Switch: B<-rowheight> =item Name: B =item Class: B Default row height, interpreted as lines in the default font when the number is positive, or pixels if it is negative. Defaults to 1. =item Switch: B<-roworigin> =item Name: B =item Class: B Specifies what row index to interpret as the topmost row in the table. This value is used for user indices in the table. Defaults to 0. =item Switch: B<-rows> =item Name: B =item Class: B Number of rows in the table. Defaults to 10. =item Switch: B<-rowseparator> =item Name: B =item Class: B Specifies a separator character that will be interpreted as the row separator when cutting or pasting data in a table. By default, rows are separated as tcl lists. =item Switch: B<-rowstretchmode> =item Name: B =item Class: B Specifies the stretch modes for rows to fill extra allocated window space. See B<-colstretchmode> for valid options. =item Switch: B<-rowtagcommand> =item Name: B =item Class: B Provides the name of a procedure that can evaluated by the widget to determine the tag to be used for a given row. The procedure must be defined by the user to accept a single argument (the row number), and return a tag name or null string. This operates in a similar manner as B<-coltagcommand>, except that it applies to row tags. The Current row number is passed as an argument to the row command. =item Switch: B<-selectioncommand or -selcmd> =item Name: B =item Class: B Specifies a command (callback) to evaluate when the selection is retrieved from a table via the selection mechanism (ie: evaluating "B"). The return value from this command will become the string passed on by the selection mechanism. The following arguments are passed to this callback: The number of rows in the selection, number of columns in the selection, the selection string, the number of cell in the selection. =item Switch: B<-selectmode> =item Name: B =item Class: B Specifies one of several styles for manipulating the selection. The value of the option may be arbitrary, but the default bindings expect it to be either B, B, B, or B; the default value is B. These styles are like those for the Tk listbox, except expanded for 2 dimensions. =item Switch: B<-selecttitle> =item Name: B =item Class: B Specifies whether title cells should be allowed in the selection. Defaults to 0 (disallowed). =item Switch: B<-selecttype> =item Name: B =item Class: B Specifies one of several types of selection for the table. The value of the option may be one of B, B, B, or B (meaning B); the default value is B. These types define whether an entire row/col is affected when a cell's selection is changed (set or clear). =item Switch: B<-sparsearray> =item Name: B =item Class: B A boolean value that specifies whether an associated Tcl array should be kept as a sparse array (1, the default) or as a full array (0). If true, then cell values that are empty will be deleted from the array (taking less memory). If false, then all values in the array will be maintained. =item Switch: B<-state> =item Name: B =item Class: B Specifies one of two states for the entry: B or B. If the table is disabled then the value may not be changed using widget commands and no insertion cursor will be displayed, even if the input focus is in the widget. Also, all insert or delete methods will be ignored. Defaults to B. =item Switch: B<-titlecols> =item Name: B =item Class: B Number of columns to use as a title area. Defaults to 0. =item Switch: B<-titlerows> =item Name: B =item Class: B Number of rows to use as a title area. Defaults to 0. =item Switch: B<-usecommand> =item Name: B =item Class: B A boolean value which specifies whether to use the B option. This value sets itself to zero if B is used and returns an error. Defaults to 1 (will use B if specified). =item Switch: B<-validate> =item Name: B =item Class: B A boolean specifying whether validation should occur for the active buffer. Defaults to 0. =item Switch: B<-validatecommand or -vcmd> =item Name: B =item Class: B Specifies a command (callback) to execute when the active cell is edited. This command is expected to return a 1 or 0. If it returns 1, then it is assumed the new value is OK, otherwise the new value is rejected (the edition will not take place). Errors in this command are handled in the background. The following arguments are supplied to the callback: row, col, oldContents of cell, potential new contents of cell, Current Index in the cell. =item Switch: B<-variable> =item Name: B =item Class: B Global Tcl array variable to attach to the table's C array. It will be created if it doesn't already exist or is a simple variable. Keys used by the table in the array are of the form I,I for cells and the special key I which contains the value of the active cell buffer. The Tcl array is managed as a sparse array (the table doesn't require all valid indices have values). No stored value for an index is equivalent to the empty string, and clearing a cell will remove that index from the Tcl array, unless the B<-sparsearray> options is set to 0. =item Switch: B<-width> =item Name: B =item Class: B Specifies the desired width for the window, in columns. If zero or less, then the desired width for the window is made just large enough to hold all the columns in the table. The width can be further limited by B<-maxwidth>. =item Switch: B<-wrap> =item Name: B =item Class: B Specifies the default wrap value for tags. Defaults to 0. =back =head1 DESCRIPTION The B command creates a 2-dimensional grid of cells. The table can use a Tcl array variable or Tcl command for data storage and retrieval. The widget has an active cell, the contents of which can be edited (when the state is normal). The widget supports a default style for the cells and also multiple I, which can be used to change the style of a row, column or cell (see TAGS for details). A cell I can be set up so that changed cells will change color for a specified amount of time ("blink"). Cells can have embedded images or windows, as described in L and L respectively. One or more cells may be selected as described below. If a table is exporting its selection (see B<-exportselection> option), then it will observe the standard X11 protocols for handling the selection. See L for details. It is not necessary for all the cells to be displayed in the table window at once; commands described below may be used to change the view in the window. Tables allow scrolling in both directions using the standard B<-xscrollcommand> and B<-yscrollcommand> options. They also support scanning, as described below. In order to obtain good performance, the table widget supports multiple drawing modes, two of which are fully Tk compatible. =head1 Indices Many of the widget commands for tables take one or more indices as arguments. An index specifies a particular cell of the table, in any of the following ways: =over 1 =item I Specifies the cell as a numerical index of row,col which corresponds to the index of the associated Perl Hash, where B<-roworigin,-colorigin> corresponds to the first cell in the table (0,0 by default). The values for row and column will be constrained to actual values in the table, which means a valid cell is always found. =item B Indicates the cell that has the location cursor. It is specified with the B widget command. =item B Indicates the anchor point for the selection, which is set with the B widget command. =item B Indicates the bottom-rightmost cell visible in the table. =item B Indicates the bottom right cell of the table. =item B Indicates the top-leftmost editable cell of the table, not necessarily in the display. This takes into account the user specified origin and title area. =item B Indicates the top-leftmost editable cell visible in the table (this excludes title cells). =item B<@x,y> Indicates the cell that covers the point in the table window specified by I and I (in pixel coordinates). If no cell covers that point, then the closest cell to that point is used. In the widget command descriptions below, arguments named I, I, and I always contain text indices in one of the above forms. =back =head1 Tags A tag is a textual string that is associated with zero or more rows, columns or cells in a table. Tags may contain arbitrary characters, but it is probably best to avoid using names which look like indices to reduce coding confusion. There may be any number of tags in a table, but each row, column or cell can only have one tag associated with it at a time. There are several permanent tags in each table that can be configured by the user and will determine the attributes for special cells: =over 1 =item B This tag is given to the I cell =item B If flash mode is on, this tag is given to any recently edited cells. =item B This tag is given to any selected cells. =item B This tag is given to any cells in the title rows and columns. This tag has B<-state> I<disabled> by default. =back Tags control the way cells are displayed on the screen. Where appropriate, the default for displaying cells is determined by the options for the table widget. However, display options may be associated with individual tags using the L<tagConfigure> method. If a cell, row or column has been tagged, then the display options associated with the tag override the default display style. The following options are currently supported for tags: =over 1 =item B<-anchor> I<anchor> Anchor for item in the cell space. =item B<-background> or B<-bg> I<color> Background color of the cell. =item B<-borderwidth> or B<-bd> I<pixel> Borderwidth of the cell, of the same format for the table, but may also be empty to inherit the default table borderwidth value (the default). =item B<-font> I<fontName> Font for text in the cell. =item B<-foreground> or B<-fg> I<color> Foreground color of the cell. =item B<-justify> I<justify> How to justify multi-line text in a cell. It must be one of B<left>, B<right>, or B<center>. =item B<-image> I<imageName> An image to display in the cell instead of text. =item B<-multiline> I<boolean> Whether to display text with newlines on multiple lines. =item B<-relief> The relief for the cell. May be the empty string to cause this tag to not disturb the value. =item B<-showtext> I<boolean> Whether to show the text over an image. =item B<-state> I<state> The state of the cell, to allow for certain cells to be disabled. This prevents the cell from being edited by the I<insert > or I<delete> methods, but a direct I<set> will not be prevented. =item B<-wrap> I<boolean> Whether characters should wrap in a cell that is not wide enough. =back A priority order is defined among tags based on creation order (first created tag has highest default priority), and this order is used in implementing some of the tag-related functions described below. When a cell is displayed, its properties are determined by the tags which are assigned to it. The priority of a tag can be modified by the I<tagLower> and the I<tagRaise> methods. If a cell has several tags associated with it that define the same display options (eg - a B<title> cell with specific B<row> and B<cell> tags), then the options of the highest priority tag are used. If a particular display option hasn't been specified for a particular tag, or if it is specified as an empty string, then that option will not be used; the next-highest-priority tag's option will be used instead. If no tag specifies a particular display option, then the default style for the widget will be used. Images are used for display purposes only. Editing in that cell will still be enabled and any querying of the cell will show the text value of the cell, regardless of the value of B<-showtext>. Note: There can be only one tag for a given tag type. ( Tag types = B<flash>, B<active>, B<sel>, B<title>, B<celltag> B<rowtag>, B<coltag>.) For example, you can't apply two cell tags to a single cell (or two row tags to a single row, etc) and expect the tag's properties to be merged. The last tag-type applied will be the one that is used. =head1 Embedded Windows There may be any number of embedded windows in a table widget (one per cell), and any widget may be used as an embedded window (subject to the usual rules for geometry management, which require the table window to be the parent of the embedded window or a descendant of its parent). The embedded window's position on the screen will be updated as the table is modified or scrolled, and it will be mapped and unmapped as it moves into and out of the visible area of the table widget. Each embedded window occupies one cell's worth of space in the table widget, and it is referred to by the index of the cell in the table. Windows associated with the table widget are destroyed when the table widget is destroyed. Windows are used for display purposes only. A value still exists for that cell, but will not be shown unless the window is deleted in some way. If the window is destroyed or lost by the table widget to another geometry manager, then any data associated with it is lost (the cell it occupied will no longer appear in B<window names>). When an embedded window is added to a table widget with the window configure widget command, several configuration options may be associated with it. These options may be modified with later calls to the window configure widget command. The following options are currently supported: =over 1 =item B<-create> I<callback> NOT CURRENTLY SUPPORTED. Specifies a Tcl script that may be evaluated to create the window for the annotation. If no -window option has been specified for this cell then this script will be evaluated when the cell is about to be displayed on the screen. Script must create a window for the cell and return the name of that window as its result. If the cell's window should ever be deleted, the script will be evaluated again the next time the cell is displayed. =item B<-background> or B<-bg> I<color> Background color of the cell. If not specified, it uses the table's default background. =item B<-borderwidth> or B<-bd> I<pixelList> Borderwidth of the cell, of the same format for the table, but may also be empty to inherit the default table borderwidth value (the default). =item B<-padx> I<pixels> As defined in the Tk options man page. =item B<-pady> I<pixels> As defined in the Tk options man page. =item B<-relief> I<relief> The relief to use for the cell in which the window lies. If not specified, it uses the table's default relief. =item B<-sticky> I<sticky> Stickiness of the window inside the cell, as defined by the B<grid> command. =item B<-window> I<$widget> Specifies the a window to display in the annotation. It must exist before being specified here. =back =head1 the Selection Table selections are available as type STRING. By default, the value of the selection will be the values of the selected cells in nested Tcl list form where each row is a list and each column is an element of a row list. You can change the way this value is interpreted by setting the B<-rowseparator> and B<-colseparator> options. For example, default Excel format would be to set B<-rowseparator> to "\n" and B<-colseparator> to "\t". Changing these values affects both how the table sends out the selection and reads in pasted data, ensuring that the table should always be able to cut and paste to itself. It is possible to change how pastes are handled by editing the table library procedure B<tk_tablePasteHandler >. This might be necessary if B<-selectioncommand> is set. =head1 Row/Col Spanning Individual cells can span multiple rows and/or columns. This is done via the B<spans> command (see below for exact arguments). Cells in the title area that span are not permitted to span beyond the title area, and will be constrained accordingly. If the title area shrinks during a configure, sanity checking will occur to ensure the above. You may set spans on regular cells that extend beyond the defined row/col area. These spans will not be constrained, so that when the defined row/col area expands, the span will expand with it. When setting a span, checks are made as to whether the span would overlap an already spanning or hidden cell. This is an error and it not allowed. Spans can affect the overall speed of table drawing, although not significantly. If spans are not used, then there is no performance loss. Cells I<hidden> by spanning cells still have valid data. This will be seen during cut and paste operations that involve hidden cells, or through direct access by a command like B<get> or B<set>. The drawing properties of spanning cells apply to only the visual area of the cell. For example, if a cell is center justified over 5 columns, then when viewing any portion of those columns, it will appear centered in the visible area. The non-visible column area will not be considered in the centering calculations. =head1 Command Substitution The various option based commands that the table supports all support the familiar Tk %-substitution model (see L<Tk::bind> for more details). The following %-sequences are recognized and substituted by the table widget: =over 1 =item B<%c> For B<SelectionCommand>, it is the maximum number of columns in any row in the selection. Otherwise it is the column of the triggered cell. =item B<%C> A convenience substitution for I<%r>,I<%c>. =item B<%i> For B<SelectionCommand>, it is the total number of cells in the selection. For B<Command>, it is 0 for a read (get) and 1 for a write (set). Otherwise it is the current cursor position in the cell. =item B<%r> For B<SelectionCommand>, it is the number of rows in the selection. Otherwise it is the row of the triggered cell. =item B<%s> For B<ValidateCommand>, it is the current value of the cell being validated. For B<SelectionCommand>, it is the default value of the selection. For B<BrowseCommand >, it is the index of the last active cell. For B<Command>, it is empty for reads (get) and the current value of the cell for writes (set). =item B<%S> For B<ValidateCommand>, it is the potential new value of the cell being validated. For B<BrowseCommand>, it is the index of the new active cell. =item B<%W> The pathname to the window for which the command was generated. =back =head1 Widget Methods The B<$window->E<gt>B<TableMatrix> method creates a widget object. This object supports the B<configure> and B<cget> methods described in L<Tk::options> which can be used to enquire and modify the options described above. The widget also inherits all the methods provided by the generic L<Tk::Widget|Tk::Widget> class. The following additional methods are available for scale widgets: =over 1 =item I<$table>-E<gt>B<activate>(I<index>) Sets the active cell to the one indicated by I<index>. =item I<$table>-E<gt>B<bbox>(I<first>, ?I<last>?) It returns the bounding box for the specified cell (range) as a 4-tuple of x, y, width and height in pixels. It clips the box to the visible portion, if any, otherwise an empty string is returned. =item I<$table>-E<gt>B<border>(I<option, args>) This command is a voodoo hack to implement border sizing for tables. This is normally called through bindings, with the following as valid options: =back =over 2 =item I<$table>-E<gt>B<borderMark>(I<x, y>, ?I<row|col>?) Records I<x> and I<y> and the row and/or column border under that point in the table window, if any; used in conjunction with later B<border dragto> commands. Typically this command is associated with a mouse button press in the widget. If I<row> or I<col> is not specified, it returns a tuple of both border indices (an empty item means no border). Otherwise, just the specified item is returned. =item I<$table>-E<gt>B<borderDragto>(I<x, y>) This command computes the difference between its I<x> and I<y> arguments and the I<x> and I<y> arguments to the last B<border mark> command for the widget. It then adjusts the previously marked border by the difference. This command is typically associated with mouse motion events in the widget, to produce the effect of interactive border resizing. =back =over 1 =item I<$table>-E<gt>B<cget>(I<option>) Returns the current value of the configuration option given by I<option>. I<Option> may have any of the values accepted by the B<table> command. =item I<$table>-E<gt>B<clear>(I<option>, ?I<first>?, ?I<last>?) This command is a convenience routine to clear certain state information managed by the table. I<first> and I<last> represent valid table indices. If neither are specified, then the command operates on the whole table. The following options are recognized: =back =over 2 =item I<$table>-E<gt>B<clearCache>(?I<first>?, ?I<last>?) Clears the specified section of the cache, if the table has been keeping one. =item I<$table>-E<gt>B<clearSizes>(?I<first>?, ?I<last>?) Clears the specified row and column areas of specific height/width dimensions. When just one index is specified, for example B<2,0>, that is interpreted as row 2 B<and> column 0. =item I<$table>-E<gt>B<clearTags>(?I<first>?, ?I<last>?) Clears the specified area of tags (all row, column and cell tags). =item I<$table>-E<gt>B<clearAll>(?I<first>?, ?I<last>?) Performs all of the above clear functions on the specified area. =back =over 1 =item I<$table>-E<gt>B<colWidth>(?I<col>?, ?I<value, col, value, ...>?) If no I<col> is specified, returns a list describing all cols for which a width has been set. If B<col> is specified with no value, it prints out the width of that col in characters (positive number) or pixels (negative number). If one or more I<col-value> pairs are specified, then it sets each col to be that width in characters (positive number) or pixels (negative number). If I<value> is I<default>, then the col uses the default width, specified by B<-colwidth>. =over 1 =item I<$table>-E<gt>B<configure>(?I<option>?, ?I<value, option, value, ...>?) Query or modify the configuration options of the widget. If no I<option> is specified, returns a list describing all of the available options for I<pathName> (see B<Tk_ConfigureInfo> for information on the format of this list). If I<option> is specified with no I<value>, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no I<option> is specified). If one or more I<option-value> pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. I<Option> may have any of the values accepted by the B<table> command. =item I<$table>-E<gt>B<curselection>(?I<value>?) With no arguments, it returns the sorted indices of the currently selected cells. Otherwise it sets all the selected cells to the given value. The set has no effect if there is no associated Tcl array or the state is disabled. =item I<$table>-E<gt>B<curvalue>(?I<value>?) If no value is given, the value of the cell being edited (indexed by B<active>) is returned, else it is set to the given value. =item I<$table>-E<gt>B<delete>(I<option, arg>, ?I<arg>?) This command is used to delete various things in a table. It has several forms, depending on the I<option>: =back =over 2 =item I<$table>-E<gt>B<deleteActive>(I<index>, ?I<index>?) Deletes text from the active cell. If only one index is given, it deletes the character after that index, otherwise it deletes from the first index to the second. I<index> can be a number, B<insert> or B<end>. =item I<$table>-E<gt>B<deleteCols>(?I<switches>?, I<index>, ?I<count>?) Deletes I<count> cols starting at (and including) col I<index>. The I<index> will be constrained to the limits of the tables. If I<count> is negative, it deletes cols to the left. Otherwise it deletes cols to the right. I<count> defaults to 1 (meaning just the column specified). The selection will be cleared. At the moment, spans are not adjusted with this action. Optional switches are: =back =over 3 =item B<-holddimensions> Causes the table cols to be unaffected by the deletion (empty cols may appear). By default the dimensions are adjusted by B<count>. =item B<-holdtags> Causes the tags specified by the I<tag> method to not move along with the data. Also prevents specific widths set by the I<width> method from being adjusted. By default, these tags are properly adjusted. =item B<-holdwindows> Causes the embedded windows created with the I<window> method to not move along with the data. By default, these windows are properly adjusted. =item B<-keeptitles> Prevents title area cells from being changed. Otherwise they are treated just like regular cells and will move as specified. =back =over 2 =item I<$table>-E<gt>B<deleteRows>(?I<switches>?, I<index>, ?I<count>?) Deletes B<count> rows starting at (and including) row B<index>. If B<count> is negative, it deletes rows going up. Otherwise it deletes rows going down. The selection will be cleared. The switches are the same as those for column deletion. =back =over 1 =item I<$table>-E<gt>B<get>(I<first>, ?I<last>?) Returns the value of the cells specified by the table indices I<first> and (optionally) I<last> in a list. =item I<$table>-E<gt>B<hidden>(?I<index>?, ?I<index, ...>?) When called without args, it returns all the I<hidden> cells (those cells covered by a spanning cell). If one index is specified, it returns the spanning cell covering that index, if any. If multiple indices are specified, it returns 1 if all indices are hidden cells, 0 otherwise. =item I<$table>-E<gt>B<icursor>(?I<arg>?) With no arguments, prints out the location of the insertion cursor in the active cell. With one argument, sets the cursor to that point in the string. 0 is before the first character, you can also use B<insert> or B<end> for the current insertion point or the end of the text. If there is no active cell, or the cell or table is disabled, this will return -1. =item I<$table>-E<gt>B<index>(I<index>, ?I<row|col>?) Returns the integer cell coordinate that corresponds to I<index> in the form row,col. If B<row > or B<col> is specified, then only the row or column index is returned. =item I<$table>-E<gt>B<insert>(I<option, arg, arg>) This command is used to into various things into a table. It has several forms, depending on the I<option>: =back =over 2 =item I<$table>-E<gt>B<insertActive>(I<index, value>) The I<value> is a text string which is inserted at the I<index> postion of the active cell. The cursor is then positioned after the new text. I<index> can be a number, B<insert> or B<end>. =item I<$table>-E<gt>B<insertCols>(?I<switches>?, I<index>, ?I<count>?) Inserts B<count> cols starting at col B<index>. If B<count> is negative, it inserts before the specified col. Otherwise it inserts after the specified col. The selection will be cleared. The switches are the same as those for column deletion. =item I<$table>-E<gt>B<insertRows>(?I<switches>?, I<index>, ?I<count>?) Inserts B<count> rows starting at row B<index>. If B<count> is negative, it inserts before the specified row. Otherwise it inserts after the specified row. The selection will be cleared. The switches are the same as those for column deletion. =back =over 1 =item I<$table>-E<gt>B<reread>() Rereads the old contents of the cell back into the editing buffer. Useful for a key binding when <Escape> is pressed to abort the edit (a default binding). =item I<$table>-E<gt>B<rowHeight>(?I<row>?, ?I<value, row, value, ...>?) If no I<row> is specified, returns a list describing all rows for which a height has been set. If B<row> is specified with no value, it prints out the height of that row in characters (positive number) or pixels (negative number). If one or more I<row-value> pairs are specified, then it sets each row to be that height in lines (positive number) or pixels (negative number). If I<value> is I<default>, then the row uses the default height, specified by B<-rowheight>. =item I<$table>-E<gt>B<scan>(I<option, args>) This command is used to implement scanning on tables. It has two forms, depending on I<option>: =back =over 2 =item I<$table>-E<gt>B<scanMark>(I<x, y>) Records I<x> and I<y> and the current view in the table window; used in conjunction with later B<scan dragto> commands. Typically this command is associated with a mouse button press in the widget. It returns an empty string. =item I<$table>-E<gt>B<scanDragto>(I<x, y>.) This command computes the difference between its I<x> and I<y> arguments and the I<x> and I<y> arguments to the last B<scan mark> command for the widget. It then adjusts the view by 5 times the difference in coordinates. This command is typically associated with mouse motion events in the widget, to produce the effect of dragging the list at high speed through the window. The return value is an empty string. =back =over 1 =item I<$table>-E<gt>B<see>(I<index>) Adjust the view in the table so that the cell given by I<index> is positioned as the cell one off from top left (excluding title rows and columns) if the cell is not currently visible on the screen. The actual cell may be different to keep the screen full. =item I<$table>-E<gt>B<selection>(I<option, arg>) This command is used to adjust the selection within a table. It has several forms, depending on I<option>: =back =over 2 =item I<$table>-E<gt>B<selectionAnchor>(I<index>) Sets the selection anchor to the cell given by I<index>. The selection anchor is the end of the selection that is fixed while dragging out a selection with the mouse. The index B<anchor> may be used to refer to the anchor cell. =item I<$table>-E<gt>B<selectionClear>(I<first>?I<last>?) If any of the cells between I<first> and I<last> (inclusive) are selected, they are deselected. The selection state is not changed for cells outside this range. I<first> may be specified as B<all> to remove the selection from all cells. =item I<$table>-E<gt>B<selectionIncludes>(I<index>) Returns 1 if the cell indicated by I<index> is currently selected, 0 if it isn't. =item I<$table>-E<gt>B<selectionSet>(I<first>, ?I<last>?) Selects all of the cells in the range between I<first> and I<last>, inclusive, without affecting the selection state of cells outside that range. =back perltk note this needs to be perlized =over 1 =item I<$table>-E<gt>B<set>(?I<row|col>?, I<index>, ?I<value>?, ?I<index, value, ...>?) Sets the specified index to the associated value. Table validation will not be triggered via this method. If B<row> or B<col> precedes the list of index/value pairs, then the value is assumed to be a Tcl list whose values will be split and set into the subsequent columns (if B<row> is specified) or rows (for B<col>). For example, B< set row 2,3 {2,3 2,4 2,5}> will set 3 cells, from 2,3 to 2,5. The setting of cells is silently bounded by the known table dimensions. =item I<$table>-E<gt>B<spans>(?I<index>?, ?I<rows,cols, index, rows,cols, ...>?) This command is used to manipulate row/col spans. When called with no arguments, all known spans are returned as a list of tuples of the form {index span}. When called with only the I<index>, the span for that I<index> only is returned, if any. Otherwise an even number of I<index rows,cols> pairs are used to set spans. A span starts at the I<index> and continues for the specified number of rows and cols. Negative spans are not supported. A span of 0,0 unsets any span on that cell. See EXAMPLES for more info. =item I<$table>-E<gt>B<tag>(option, ?I<arg, arg, ...>?) This command is used to manipulate tags. The exact behavior of the command depends on the I<option> argument that follows the B<tag> argument. I<cget>, I<cell>, and I<row|col> complain about unknown tag names. The following forms of the command are currently supported: =back =over 2 =item I<$table>-E<gt>B<tagCell>(I<tagName, ?index, ...?>) With no arguments, prints out the list of cells that use the I<tag>. Otherwise it sets the specified cells to use the named tag, replacing any tag that may have been set using this method before. If I<tagName> is '', the cells are reset to the default I<tag>. Tags added during -*tagcommand evaluation do not register here. If I<tagName> does not exist, it will be created with the default options. =item I<$table>-E<gt>B<tagCget>(I<tagName, option>) This command returns the current value of the option named I<option> associated with the tag given by I<tagName>. I<Option> may have any of the values accepted by the B<tag configure> widget command. =item I<$table>-E<gt>B<tagCol>(I<tagName, ?col, ...?>) With no arguments, prints out the list of cols that use the I<tag>. Otherwise it sets the specified columns to use the named tag, replacing any tag that may have been set using this method before. If <tagName> is '', the cols are reset to the default I<tag>. Tags added during -coltagcommand evaluation do not register here. If I<tagName> does not exist, it will be created with the default options. =item I<$table>-E<gt>B<tagConfigure>(I<tagName>, ?I<option>?, ?I<value>?, ?I<option, value, ...>?) This command is similar to the B<configure> widget command except that it modifies options associated with the tag given by I<tagName> instead of modifying options for the overall table widget. If no I<option> is specified, the command returns a list describing all of the available options for I<tagName> (see B<Tk_ConfigureInfo> for information on the format of this list). If I<option> is specified with no I<value>, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no I<option> is specified). If one or more I<option-value> pairs are specified, then the command modifies the given option(s) to have the given value(s) in I<tagName>; in this case the command returns an empty string. See TAGS above for details on the options available for tags. =item I<$table>-E<gt>B<tagDelete>(I<tagName>) Deletes a tag. No error if the tag does not exist. =item I<$table>-E<gt>B<tagExists>(I<tagName>) Returns 1 if the named tag exists, 0 otherwise. =item I<$table>-E<gt>B<tagIncludes>(I<tagName, index>) Returns 1 if the specified index has the named tag, 0 otherwise. =item I<$table>-E<gt>B<tagLower>(I<tagName, ?belowThis?>) Lower the priority of the named tag. If I<belowThis> is not specified, then the tag's priority is lowered to the bottom, otherwise it is lowered to one below I<belowThis>. =item I<$table>-E<gt>B<tagNames>(?I<pattern>?) If no pattern is specified, shows the names of all defined tags. Otherwise the I<pattern> is used as a glob pattern to show only tags matching that pattern. Tag names are returned in priority order (highest priority tag first). =item I<$table>-E<gt>B<tagRaise>(I<tagName, ?aboveThis?>) Raise the priority of the named tag. If I<aboveThis> is not specified, then the tag's priority is raised to the top, otherwise it is raised to one above I<aboveThis>. =item I<$table>-E<gt>B<tagRow>(I<tagName, ?row, ...?>) With no arguments, prints out the list of rows that use the I<tag>. Otherwise it sets the specified columns to use the named tag, replacing any tag that may have been set using this method before. If I<tagName> is '', the rows are reset to use the default tag. Tags added during -rowtagcommand evaluation do not register here. If I<tagName> does not exist, it will be created with the default options. =back =over 1 =item I<$table>-E<gt>B<validate>(I<index>) Explicitly validates the specified index based on the current B<-validatecommand> and returns 0 or 1 based on whether the cell was validated. =item I<$table>-E<gt>B<window>(option, ?I<arg, arg, ...>?) This command is used to manipulate embedded windows. The exact behavior of the command depends on the I<option> argument that follows the B<window> argument. The following forms of the command are currently supported: =back =over 2 =item I<$table>-E<gt>B<windowCget>(I<index, option>) This command returns the current value of the option named I<option> associated with the window given by I<index>. I<Option> may have any of the values accepted by the B<window configure> widget command. =item I<$table>-E<gt>B<windowConfigure>(I<index>, ?I<option>?, ?I<value>?, ?I<option, value, ...>?) This command is similar to the B<configure> widget command except that it modifies options associated with the embedded window given by I<index> instead of modifying options for the overall table widget. If no I<option> is specified, the command returns a list describing all of the available options for I<index > (see B<Tk_ConfigureInfo> for information on the format of this list). If I<option> is specified with no I<value>, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no I<option> is specified). If one or more I<option-value> pairs are specified, then the command modifies the given option(s) to have the given value(s) in I<index>; in this case the command returns an empty string. See EMBEDDED WINDOWS above for details on the options available for windows. =item I<$table>-E<gt>B<windowDelete>(I<index>, ?I<index, ...>?) Deletes an embedded window from the table. The associated window will also be deleted. =item I<$table>-E<gt>B<windowMove>(I<indexFrom, indexTo>) Moves an embedded window from one cell to another. If a window already exists in the target cell, it will be deleted. =item I<$table>-E<gt>B<windowNames>(?I<pattern>?) If no pattern is specified, shows the cells of all embedded windows. Otherwise the I<pattern> is used as a glob pattern to show only cells matching that pattern. =back =over 1 =item I<$table>-E<gt>B<xview>(I<args>) This command is used to query and change the horizontal position of the information in the widget's window. It can take any of the following forms: =item I<$table>-E<gt>B<xview>() Returns a list containing two elements. Each element is a real fraction between 0 and 1; together they describe the horizontal span that is visible in the window. For example, if the first element is .2 and the second element is .6, 20% of the table's text is off-screen to the left, the middle 40% is visible in the window, and 40% of the text is off-screen to the right. These are the same values passed to scrollbars via the B<-xscrollcommand> option. =item I<$table>-E<gt>B<xview>(I<index>) Adjusts the view in the window so that the column given by I<index> is displayed at the left edge of the window. =item I<$table>-E<gt>B<xviewMoveto>(I<fraction>) Adjusts the view in the window so that I<fraction> of the total width of the table text is off-screen to the left. I<fraction> must be a fraction between 0 and 1. =item I<$table>-E<gt>B<xviewScroll>(I<number, what>) This command shifts the view in the window left or right according to I<number> and I<what>. I<Number> must be an integer. I<What> must be either B<units> or B<pages> or an abbreviation of one of these. If I<what> is B<units>, the view adjusts left or right by I<number> cells on the display; if it is B<pages> then the view adjusts by I<number> screenfuls. If I<number> is negative then cells farther to the left become visible; if it is positive then cells farther to the right become visible. =item I<$table>-E<gt>B<yview>(I<?args>?) This command is used to query and change the vertical position of the text in the widget's window. It can take any of the following forms: =back =over 2 =item I<$table>-E<gt>B<yview>() Returns a list containing two elements, both of which are real fractions between 0 and 1. The first element gives the position of the table element at the top of the window, relative to the table as a whole (0.5 means it is halfway through the table, for example). The second element gives the position of the table element just after the last one in the window, relative to the table as a whole. These are the same values passed to scrollbars via the B<-yscrollcommand> option. =item I<$table>-E<gt>B<yview>(I<index>) Adjusts the view in the window so that the row given by I<index> is displayed at the top of the window. =item I<$table>-E<gt>B<yviewMoveto>(I<fraction>) Adjusts the view in the window so that the element given by I<fraction> appears at the top of the window. I<Fraction> is a fraction between 0 and 1; 0 indicates the first element in the table, 0.33 indicates the element one-third the way through the table, and so on. =item I<$table>-E<gt>B<yviewscroll>(I<number, what>) This command adjusts the view in the window up or down according to I<number> and I<what>. I<Number> must be an integer. I<What> must be either B<units> or B<pages>. If I<what> is B<units>, the view adjusts up or down by I<number> cells; if it is B<pages> then the view adjusts by I<number> screenfuls. If I<number> is negative then earlier elements become visible; if it is positive then later elements become visible. =back =back =head1 Default Bindings The initialization creates class bindings that give the following default behaviour: =over 1 =item [1] Clicking Button-1 in a cell activates that cell. Clicking into an already active cell moves the insertion cursor to the character nearest the mouse. =item [2] Moving the mouse while Button-1 is pressed will stroke out a selection area. Exiting while Button-1 is pressed causing scanning to occur on the table along with selection. =item [3] Moving the mouse while Button-2 is pressed causes scanning to occur without any selection. =item [4] Home moves the table to have the origin in view. =item [5] End moves the table to have the B<end> cell in view. =item [6] Control-Home moves the table to the origin and activates that cell. =item [7] Control-End moves the table to the end and activates that cell. =item [8] Shift-Control-Home extends the selection to the origin. =item [9] Shift-Control-End extends the selection to the end. =item [10] The left, right, up and down arrows move the active cell. =item [11] Shift-<arrow> extends the selection in that direction. =item [12] Control-leftarrow and Control-rightarrow move the insertion cursor within the cell. =item [13] Control-slash selects all the cells. =item [14] Control-backslash clears selection from all the cells. =item [15] Backspace deletes the character before the insertion cursor in the active cell. =item [16] Delete deletes the character after the insertion cursor in the active cell. =item [17] Escape rereads the value of the active cell from the specified data source, discarding any edits that have may been performed on the cell. =item [18] Control-a moves the insertion cursor to the beginning of the active cell. =item [19] Control-e moves the insertion cursor to the end of the active cell. =item [20] Control-minus and Control-equals decrease and increase the width of the column with the active cell in it. =item [21] Moving the mouse while Button-3 (the right button on Windows) is pressed while you are over a border will cause interactive resizing of that row and/or column to occur, based on the value of B<-resizeborders>. Some bindings may have slightly different behavior dependent on the B<-selectionmode> of the widget. If the widget is disabled using the B<-state> option, then its view can still be adjusted and cells can still be selected, but no insertion cursor will be displayed and no cell modifications will take place. The behavior of tables can be changed by defining new bindings for individual widgets or by redefining the class bindings. The default bindings are either compiled in the TableMatrix.pm file =back =head1 Performance Issues The number of rows and columns or a table widget should not significantly affect the speed of redraw. Recalculation and redraw of table parameters and cells is restricted as much as possible. The display cell with the insert cursor is redrawn each time the cursor blinks, which causes a steady stream of graphics traffic. Set the B<-insertofftime> option to 0 avoid this. The use of a B<-command> with the table without a cache can cause significant slow-down, as the command is called once for each request of a cell value. =head1 Examples Set the topleft title area to be one spanning cell. This overestimates both row and column span by one, but the command does all the constraining for us. B<$table span [$table cget -roworigin],[$table cget -colorigin] [$table cget -titlerows],[$table cget -titlecols]> Force a table window refresh (useful for the slight chance that a bug in the table is not causing proper refresh): B<$table configure -padx [$table cget -padx]> =head1 Keywords table, widget, extension ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pod/MYMETA.yml������������������������������������������������������������������0000644�0000000�0000000�00000000754�13746047615�015254� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������--- abstract: unknown author: - unknown build_requires: ExtUtils::MakeMaker: '0' configure_requires: ExtUtils::MakeMaker: '0' dynamic_config: 0 generated_by: 'ExtUtils::MakeMaker version 7.44, CPAN::Meta::Converter version 2.150010' license: unknown meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: Tk-pod no_index: directory: - t - inc version: '' x_serialization_backend: 'CPAN::Meta::YAML version 0.018' ��������������������Tk-TableMatrix-1.26/pod/MYMETA.json�����������������������������������������������������������������0000644�0000000�0000000�00000001461�13746047615�015420� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������{ "abstract" : "unknown", "author" : [ "unknown" ], "dynamic_config" : 0, "generated_by" : "ExtUtils::MakeMaker version 7.44, CPAN::Meta::Converter version 2.150010", "license" : [ "unknown" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : 2 }, "name" : "Tk-pod", "no_index" : { "directory" : [ "t", "inc" ] }, "prereqs" : { "build" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "configure" : { "requires" : { "ExtUtils::MakeMaker" : "0" } } }, "release_status" : "stable", "version" : "", "x_serialization_backend" : "JSON::PP version 4.04" } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pod/Makefile.PL�����������������������������������������������������������������0000644�0000000�0000000�00000000262�13742524721�015473� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������use ExtUtils::MakeMaker; WriteMakefile( NAME => 'Tk::pod', # DIR => [ 'pTk' ], ); sub MY::postamble { ' html :: @echo "Sorry no HTML building yet" ' } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/myConfig������������������������������������������������������������������������0000644�0000000�0000000�00000025245�13745605157�014453� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������require 5.00404; my $path = "$Config{'archlibexp'}/CORE/perl.h"; die "Cannot find '$path' have you installed $^X?\n" unless (-r $path); print "$^X is installed in $Config{'archlibexp'} okay\n"; use Config; use Cwd; use Tk::MMtry; warn "No VERSION" unless (defined $VERSION); my %define = (); $inc = ""; $xlib = ""; $define = ''; $gccopt = ""; @macro = ( macro => {} ); if (defined $Config{'gccversion'}) { $ver = $Config{'gccversion'}; if( $ver ge "2.8" ) { # retain author's favourite warnings if using gcc $gccopt .= " -ggdb -Wall -Wno-implicit-int -Wno-comment -Wno-unused -D__USE_FIXED_PROTOTYPES__"; eval { if ((getpwuid($<))[6] =~ /Nick\s+Ing-Simmons/) { # This is the author - catch as many bugs as possible $gccopt .= " -MMD -Werror"; @macro = ( macro => { INSTALLDIRS => 'perl' }); } }; } # else{ $define .= ' -g ' } } if ($] >= 5.005) { # Add PPM support stuff push(@macro, ABSTRACT => 'Tk::tkTable - a Spreadsheet/Table Widget', AUTHOR => 'jcerney@home.com (John Cerney)' ); my $arch = ($^O eq 'MSWin32') ? $ENV{'PROCESSOR_ARCHITECTURE'} : $Config{'archname'}; push(@ARGV,"BINARY_LOCATION=$arch/Tk$VERSION-PPM.tar.gz"); warn "PPM for perl$]\n"; } else { warn "No PPM for perl$]\n"; } $macro[1]->{WINARCH} = $win_arch; # # Convert perls Config info into -DXXXX for Tk # $define{'USE_PROTOTYPE'} = 1 if ($Config{'prototype'}); $define{'HAVE_UNISTD_H'} = 1 if ($Config{'i_unistd'}); $define{'HAVE_SYS_SELECT_H'} = 1 if ($Config{'i_sysselct'}); $define{'NO_STDLIB_H'} = 1 unless ($Config{'i_stdlib'}); $define{'HAVE_SYS_TIME_H'} = 1 if ($Config{'i_systime'}); $define{'HAVE_LIMITS_H'} = 1 if ($Config{'i_limits'}); $define{'HAS_STDARG'} = 1 if ($Config{'i_stdarg'}); $define{'USE_BCOPY'} = 1 if (!$Config{'d_memmove'} && $Config{'d_bcopy'}); if (defined $Config{'selecttype'}) { my $type = $Config{'selecttype'}; $type =~ s/\s*\*\s*$//; $define{'SELECT_MASK'} = $type; } if (!$Config{'i_unistd'} && defined $Config{'lseektype'}) { my $type = $Config{'lseektype'}; $type =~ s/\s*\*\s*$//; $define{'LSEEK_TYPE'} =$type; } my $voidflags = $Config{'voidflags'}; my $voidused = $Config{'defvoidused'}+0; $define{'NOVOID'} = 1 if (($voidflags & $voidused) != $voidused); $define{'NOCONST'} = 1 unless ($Config{'d_const'}); if (try_compile("config/signedchar.c")) { $define{'ANSI_SIGNED_CHAR'} = 1; } else { if (try_run("config/unsigned.c")) { $define{'CHAR_UNSIGNED'} = 1; } } if (!try_compile("config/Ksprintf.c") && try_compile("-DSPRINTF_RETURN_CHAR config/Ksprintf.c")) { $define{'SPRINTF_RETURN_CHAR'} = 1; } if (!$IsWin32) { if (!try_compile("config/tod.c")) { my $d; my $def; foreach $d (qw(TZ NO_TZ DOTS)) { if (try_compile("-DTIMEOFDAY_$d config/tod.c")) { $def = "TIMEOFDAY_$d"; print STDERR "$d gettimeofday()\n"; last; } } if (defined $def) { $define{$def} = 1; } else { print STDERR "Problem gettimeofday()\n"; } } else { print STDERR "Generic gettimeofday()\n"; } } # # Hunt down X Library - first a function # sub lX11 { my $user = shift; foreach (@_) { # allow any of libX11.a libX11.so.* etc. if (-d $_) { local ($lib); my $pattern = "$_/libX11.*"; $pattern .= " $_/X11$Config::Config{lib_ext}" if $Config::Config{osname} eq 'os2'; foreach $lib (reverse(<$ {pattern}>)) { if (-r $lib) { print "Using -L$_ to find $lib\n"; return "-L$_"; } } } } print "No -lX11 in ",join(' ',@_),"\n" if (@_ && $user); return undef; } sub IX11 { foreach (@_) { if (-d $_ && -d "$_/X11" && -r "$_/X11/Xlib.h") { print "Using -I$_ to find $_/X11/Xlib.h\n"; return "-I$_"; } } return undef; } my @args = (); my $arg; foreach $arg (@ARGV) { if ($arg =~ /^(X11\w*)=(.*)$/) { ${"$1"} = $2; } else { $MakefileName = $1 if ($arg =~ /^MAKEFILE=(.*)$/); push(@args,$arg); } } @ARGV = @args; $win_arch or die '$win_arch not set in myConfig'; if ($win_arch eq 'x') { @xdirs = (); if (defined $X11) { my $dir = $X11; if (-d $dir) { print "Looking for X in $dir\n"; push(@xdirs,$dir); } else { die "X11=$dir is not a directory"; } } else { # Find the X Library through xmkmf! $xmkmf = undef; my @exts = ("", ".cmd", ".bat"); LOOK: foreach $dir (split($Config::Config{path_sep},$ENV{'PATH'})) { foreach $ext (@exts) { if (-x "$dir/xmkmf$ext" && -r "$dir/xmkmf$ext") { $xmkmf = "$dir/xmkmf$ext"; last LOOK; } } } $uiline = undef; if (defined $xmkmf) { open(XMKMF,$xmkmf) || die("Can't open $xmkmf: $!\n"); while(<XMKMF>) { next unless /UseInstalled/o; warn ("Odd, two lines in the $xmkmf file that have UseInstalled on them:\n$uidir$_") if defined $uiline; $uidir = $_; } close(XMKMF); while (defined $uidir) { last unless ($uidir =~ s!^.*-I(\S+)/lib/X11/config!!o); $try = $1; $try =~ s/'x11root'/$ENV{X11ROOT}/; push(@xdirs,$try); } } print "$xmkmf suggests ",join(' ',@xdirs),"\n" if (@xdirs); } undef $xlib; # Make sure if (defined $X11LIB) { $xlib = &lX11(1,$X11LIB) } if (!defined($xlib) && defined($X11)) { $xlib = &lX11(1,"$X11/lib") } $xlib = &lX11(0,map("$_/lib",@xdirs)) unless (defined $xlib); # Special case for sun-machines unless (defined $xlib) { if ($Config{'osname'} eq 'solaris' || $Config{'osname'} eq 'sunos') { $xlib = &lX11(0,'/usr/openwin/lib'); } } sub chooseX11 { # Aim to prefer X11R5 over X11R4 over X11 (reverse(sort(@_))); } # # If no luck there try "common" places # unless (defined $xlib) { $xlib = &lX11(0,chooseX11(</usr/X11*/lib>),chooseX11(</usr/lib/X11*>),</usr/Xfree*/lib>,'/usr/X386/lib') } # # Try places perl looks for libraries # This is now "last resort" as /lib and /usr/local/lib are so often # full of dubious links # unless (defined $xlib) { $xlib = &lX11(0,split(/\s+/,$Config{'libpth'})) } die "Cannot find -lX11 anywhere" unless(defined $xlib); ($base) = $xlib =~ m#-L(.*)(?:/lib)$#x; if (defined $X11INC) { $xinc = &IX11("$X11INC"); } $xinc = &IX11("$base/include") unless (defined $xinc); unless (defined $xinc) { warn "Cannot find X include files via $base/include\n"; $xinc = &IX11(map("$_/include",@xdirs), '/usr/openwin/include', chooseX11(</usr/X11*/include>), chooseX11(</usr/include/X11*>), </usr/Xfree*/include>, '/usr/X386/include', $Config{'usrinc'}); } die "Cannot find X include files anywhere" unless (defined $xinc); if (defined($Config{'gccversion'}) && $Config{'gccversion'} =~ /\S/ && $xinc =~ /^-I(.*openwin.*)$/) { $gccopt .= " -isystem $1"; } $inc = ($xinc eq "-I/usr/include") ? "" : $xinc; } elsif ($win_arch eq 'open32') { unless (defined $toolkit) { my @path = split /;/, $ENV{PATH}; foreach (@path) { next unless m:[\\/]toolkit[\\/]bin:i; my $tlk = "$`/toolkit"; next unless -d "$tlk/H" and -f "$tlk/H/os2win.h"; $toolkit = $tlk; $toolkit =~ s:\\:/:g ; last; } } die "Cannot find OS/2 toolkit" unless $toolkit; $inc = "-I../pTk/mTk/xlib -I../../pTk/mTk/xlib -IpTk/mTk/xlib"; $inc .= " -I$toolkit/H -I../pTk/mTk/open32/h -IpTk/mTk/open32/h -ImTk/os2_rc"; $define .= " -D__WIN32__"; $xlib = "-L$toolkit/LIB -lpmwinx"; } elsif ($win_arch eq 'pm') { $define .= " -D__PM__"; $inc = "-I../pTk/mTk/xlib -I../../pTk/mTk/xlib -IpTk/mTk/xlib -ImTk/os2_rc"; $xlib = ""; # No library is needed } elsif ($IsWin32) { $inc = '-I$(TKDIR)/pTk/mTk/xlib'; } if ($Config{'osname'} eq 'solaris' && $xlib =~ /\bopenwin\b/ ) { $define{'NEED_PRELOAD'} = 1; } sub WriteIfChanged { my ($file,$string) = @_; my ($dir) = $file =~ m#^(.*)/[^/]+$#; if (defined($dir) && !-d $dir) { mkdir($dir,0777) || die "Cannot mkdir $dir:$!"; } my $ok = -f $file; if ($ok = open(IN,"$file")) { my $old = join('',<IN>); close(IN); $ok = $old eq $string; print STDERR "$file has changed\n" unless ($ok); } unless ($ok) { open(OUT,">$file") || die "Cannot open $file:$!"; print STDERR "Writing $file\n"; print OUT $string; close(OUT); } } # Config File Write ( Not Needed when building tkTable ) # if (!defined($MakefileName) || $MakefileName eq 'Makefile') if(0) { my $config = "package Tk::Config;\nrequire Exporter;\nuse base qw(Exporter);\n"; my $sym; my @export = (); foreach $sym (qw(VERSION inc define xlib xinc gccopt win_arch)) { my $val = ${$sym}; $val =~ s/([\\\'])/\\$1/g; $config .= "\$$sym = '$val';\n"; push(@export,"\$$sym"); } $config .= "\@EXPORT = qw(".join(' ',@export).");\n1;\n"; WriteIfChanged("Tk/Config.pm",$config); $config = "#ifndef _TKCONFIG\n#define _TKCONFIG\n"; foreach $sym (sort keys %define) { $config .= "#define $sym $define{$sym}\n"; } $config .= "#endif\n"; WriteIfChanged("pTk/tkConfig.h",$config); } 1; �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/debug���������������������������������������������������������������������������0000644�0000000�0000000�00000000304�13742524721�013745� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh cat <<! > .gdbinit handle SIGWINCH pass nostop noprint break XS_DynaLoader_dl_find_symbol run -Mblib $* shared break Perl_vcroak break Perl_vwarn break Perl_vdie ! gdb perl ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/����������������������������������������������������������������������������0000755�0000000�0000000�00000000000�13746050164�013474� 5����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/tkTable.c�������������������������������������������������������������������0000444�0000000�0000000�00000375361�13746047614�015251� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * tkTable.c -- * * This module implements table widgets for the Tk * toolkit. An table displays a 2D array of strings * and allows the strings to be edited. * * Based on Tk3 table widget written by Roland King * * Updates 1996 by: * Jeffrey Hobbs jeff.hobbs@acm.org * John Ellson ellson@lucent.com * Peter Bruecker peter@bj-ig.de * Tom Moore tmoore@spatial.ca * Sebastian Wangnick wangnick@orthogon.de * * Copyright (c) 1997-2002 Jeffrey Hobbs * * See the file "license.txt" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tkTable.c,v 1.32 2005/01/26 15:27:59 A0182636 Exp $ */ #include "tkTable.h" #include "tkPort.h" #include "tkInt.h" #include "tkVMacro.h" /* perltk debug only for picking up forward referenced definitions */ /* #include "myinc.h" */ /* Perltk: XSETCLIP doesn't Appear to be there for perltk so always define this : */ #define NO_XSETCLIP /* Not Needed??? */ /* static char ** StringifyObjects _ANSI_ARGS_((int objc, Tcl_Obj *CONST objv[])); */ static int TableWidgetObjCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj * CONST objv[])); static int TableConfigure _ANSI_ARGS_((Tcl_Interp *interp, Table *tablePtr, int objc, Tcl_Obj *CONST objv[], int flags, int forceUpdate)); static void TableDestroy _ANSI_ARGS_((ClientData clientdata)); static void TableEventProc _ANSI_ARGS_((ClientData clientData, XEvent *eventPtr)); static void TableCmdDeletedProc _ANSI_ARGS_((ClientData clientData)); static void TableRedrawHighlight _ANSI_ARGS_((Table *tablePtr)); static void TableGetGc _ANSI_ARGS_((Display *display, Drawable d, TableTag *tagPtr, GC *tagGc)); static void TableDisplay _ANSI_ARGS_((ClientData clientdata)); static void TableFlashEvent _ANSI_ARGS_((ClientData clientdata)); static char * TableVarProc _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, Var name, char *index, int flags)); static void TableCursorEvent _ANSI_ARGS_((ClientData clientData)); static int TableFetchSelection _ANSI_ARGS_((ClientData clientData, int offset, char *buffer, int maxBytes)); static Tk_RestrictAction TableRestrictProc _ANSI_ARGS_((ClientData arg, XEvent *eventPtr)); /* * The following tables define the widget commands (and sub- * commands) and map the indexes into the string tables into * enumerated types used to dispatch the widget command. */ static CONST char *selCmdNames[] = { "anchor", "clear", "includes", "present", "set", NULL }; enum selCommand { CMD_SEL_ANCHOR, CMD_SEL_CLEAR, CMD_SEL_INCLUDES, CMD_SEL_PRESENT, CMD_SEL_SET }; static CONST char *commandNames[] = { "activate", "bbox", "border", "cget", "clear", "configure", "curselection", "curvalue", "delete", "get", "rowHeight", "hidden", "icursor", "index", "insert", #ifdef POSTSCRIPT "postscript", #endif "reread", "scan", "see", "selection", "set", "spans", "tag", "validate", "version", "window", "colWidth", "xview", "yview", NULL }; enum command { CMD_ACTIVATE, CMD_BBOX, CMD_BORDER, CMD_CGET, CMD_CLEAR, CMD_CONFIGURE, CMD_CURSEL, CMD_CURVALUE, CMD_DELETE, CMD_GET, CMD_HEIGHT, CMD_HIDDEN, CMD_ICURSOR, CMD_INDEX, CMD_INSERT, #ifdef POSTSCRIPT CMD_POSTSCRIPT, #endif CMD_REREAD, CMD_SCAN, CMD_SEE, CMD_SELECTION, CMD_SET, CMD_SPANS, CMD_TAG, CMD_VALIDATE, CMD_VERSION, CMD_WINDOW, CMD_WIDTH, CMD_XVIEW, CMD_YVIEW }; /* -selecttype selection type options */ static Cmd_Struct sel_vals[]= { {"row", SEL_ROW}, {"col", SEL_COL}, {"both", SEL_BOTH}, {"cell", SEL_CELL}, {"", 0 } }; /* -resizeborders options */ static Cmd_Struct resize_vals[]= { {"row", SEL_ROW}, /* allow rows to be dragged */ {"col", SEL_COL}, /* allow cols to be dragged */ {"both", SEL_ROW|SEL_COL}, /* allow either to be dragged */ {"none", SEL_NONE}, /* allow nothing to be dragged */ {"", 0 } }; /* drawmode values */ /* The display redraws with a pixmap using TK function calls */ #define DRAW_MODE_SLOW (1<<0) /* The redisplay is direct to the screen, but TK function calls are still * used to give correct 3-d border appearance and thus remain compatible * with other TK apps */ #define DRAW_MODE_TK_COMPAT (1<<1) /* the redisplay goes straight to the screen and the 3d borders are rendered * with a single pixel wide line only. It cheats and uses the internal * border structure to do the borders */ #define DRAW_MODE_FAST (1<<2) #define DRAW_MODE_SINGLE (1<<3) static Cmd_Struct drawmode_vals[] = { {"fast", DRAW_MODE_FAST}, {"compatible", DRAW_MODE_TK_COMPAT}, {"slow", DRAW_MODE_SLOW}, {"single", DRAW_MODE_SINGLE}, {"", 0} }; /* stretchmode values */ #define STRETCH_MODE_NONE (1<<0) /* No additional pixels will be added to rows or cols */ #define STRETCH_MODE_UNSET (1<<1) /* All default rows or columns will be stretched to fill the screen */ #define STRETCH_MODE_ALL (1<<2) /* All rows/columns will be padded to fill the window */ #define STRETCH_MODE_LAST (1<<3) /* Stretch last elememt to fill window */ #define STRETCH_MODE_FILL (1<<4) /* More ROWS in Window */ static Cmd_Struct stretch_vals[] = { {"none", STRETCH_MODE_NONE}, {"unset", STRETCH_MODE_UNSET}, {"all", STRETCH_MODE_ALL}, {"last", STRETCH_MODE_LAST}, {"fill", STRETCH_MODE_FILL}, {"", 0} }; static Cmd_Struct state_vals[]= { {"normal", STATE_NORMAL}, {"disabled", STATE_DISABLED}, {"", 0 } }; /* The widget configuration table */ static Tk_CustomOption drawOpt = { Cmd_OptionSet, Cmd_OptionGet, (ClientData)(&drawmode_vals) }; static Tk_CustomOption resizeTypeOpt = { Cmd_OptionSet, Cmd_OptionGet, (ClientData)(&resize_vals) }; static Tk_CustomOption stretchOpt = { Cmd_OptionSet, Cmd_OptionGet, (ClientData)(&stretch_vals) }; static Tk_CustomOption selTypeOpt = { Cmd_OptionSet, Cmd_OptionGet, (ClientData)(&sel_vals) }; static Tk_CustomOption stateTypeOpt = { Cmd_OptionSet, Cmd_OptionGet, (ClientData)(&state_vals) }; static Tk_CustomOption bdOpt = { TableOptionBdSet, TableOptionBdGet, (ClientData) BD_TABLE }; Tk_ConfigSpec tableSpecs[] = { {TK_CONFIG_ANCHOR, "-anchor", "anchor", "Anchor", "center", Tk_Offset(Table, defaultTag.anchor), 0}, {TK_CONFIG_BOOLEAN, "-autoclear", "autoClear", "AutoClear", "0", Tk_Offset(Table, autoClear), 0}, {TK_CONFIG_BORDER, "-background", "background", "Background", NORMAL_BG, Tk_Offset(Table, defaultTag.bg), 0}, {TK_CONFIG_SYNONYM, "-bd", "borderWidth", NULL, NULL, 0, 0}, {TK_CONFIG_SYNONYM, "-bg", "background", NULL, NULL, 0, 0}, {TK_CONFIG_CURSOR, "-bordercursor", "borderCursor", "Cursor", "crosshair", Tk_Offset(Table, bdcursor), TK_CONFIG_NULL_OK }, {TK_CONFIG_CUSTOM, "-borderwidth", "borderWidth", "BorderWidth", "1", Tk_Offset(Table, defaultTag), TK_CONFIG_NULL_OK, &bdOpt }, {TK_CONFIG_CALLBACK, "-browsecommand", "browseCommand", "BrowseCommand", "", Tk_Offset(Table, browseCmd), TK_CONFIG_NULL_OK}, {TK_CONFIG_SYNONYM, "-browsecmd", "browseCommand", NULL, NULL, 0, TK_CONFIG_NULL_OK}, {TK_CONFIG_BOOLEAN, "-cache", "cache", "Cache", "0", Tk_Offset(Table, caching), 0}, {TK_CONFIG_INT, "-colorigin", "colOrigin", "Origin", "0", Tk_Offset(Table, colOffset), 0}, {TK_CONFIG_INT, "-cols", "cols", "Cols", "10", Tk_Offset(Table, cols), 0}, {TK_CONFIG_STRING, "-colseparator", "colSeparator", "Separator", "\t", Tk_Offset(Table, colSep), TK_CONFIG_NULL_OK }, {TK_CONFIG_CUSTOM, "-colstretchmode", "colStretch", "StretchMode", "none", Tk_Offset (Table, colStretch), 0 , &stretchOpt }, {TK_CONFIG_CALLBACK, "-coltagcommand", "colTagCommand", "TagCommand", NULL, Tk_Offset(Table, colTagCmd), TK_CONFIG_NULL_OK }, {TK_CONFIG_INT, "-colwidth", "colWidth", "ColWidth", "10", Tk_Offset(Table, defColWidth), 0}, {TK_CONFIG_CALLBACK, "-command", "command", "Command", "", Tk_Offset(Table, command), TK_CONFIG_NULL_OK}, {TK_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor", "xterm", Tk_Offset(Table, cursor), TK_CONFIG_NULL_OK }, {TK_CONFIG_CUSTOM, "-drawmode", "drawMode", "DrawMode", "compatible", Tk_Offset(Table, drawMode), 0, &drawOpt }, {TK_CONFIG_BOOLEAN, "-exportselection", "exportSelection", "ExportSelection", "1", Tk_Offset(Table, exportSelection), 0}, {TK_CONFIG_SYNONYM, "-fg", "foreground", NULL, NULL, 0, 0}, {TK_CONFIG_BOOLEAN, "-flashmode", "flashMode", "FlashMode", "0", Tk_Offset(Table, flashMode), 0}, {TK_CONFIG_INT, "-flashtime", "flashTime", "FlashTime", "2", Tk_Offset(Table, flashTime), 0}, {TK_CONFIG_FONT, "-font", "font", "Font", DEF_TABLE_FONT, Tk_Offset(Table, defaultTag.tkfont), 0}, {TK_CONFIG_BORDER, "-foreground", "foreground", "Foreground", "black", Tk_Offset(Table, defaultTag.fg), 0}, #ifdef PROCS {TK_CONFIG_BOOLEAN, "-hasprocs", "hasProcs", "hasProcs", "0", Tk_Offset(Table, hasProcs), 0}, #endif {TK_CONFIG_INT, "-height", "height", "Height", "0", Tk_Offset(Table, maxReqRows), 0}, {TK_CONFIG_COLOR, "-highlightbackground", "highlightBackground", "HighlightBackground", NORMAL_BG, Tk_Offset(Table, highlightBgColorPtr), 0}, {TK_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor", HIGHLIGHT, Tk_Offset(Table, highlightColorPtr), 0}, {TK_CONFIG_PIXELS, "-highlightthickness", "highlightThickness", "HighlightThickness", "2", Tk_Offset(Table, highlightWidth), 0}, {TK_CONFIG_BORDER, "-insertbackground", "insertBackground", "Foreground", "Black", Tk_Offset(Table, insertBg), 0}, {TK_CONFIG_PIXELS, "-insertborderwidth", "insertBorderWidth", "BorderWidth", "0", Tk_Offset(Table, insertBorderWidth), TK_CONFIG_COLOR_ONLY}, {TK_CONFIG_PIXELS, "-insertborderwidth", "insertBorderWidth", "BorderWidth", "0", Tk_Offset(Table, insertBorderWidth), TK_CONFIG_MONO_ONLY}, {TK_CONFIG_INT, "-insertofftime", "insertOffTime", "OffTime", "300", Tk_Offset(Table, insertOffTime), 0}, {TK_CONFIG_INT, "-insertontime", "insertOnTime", "OnTime", "600", Tk_Offset(Table, insertOnTime), 0}, {TK_CONFIG_PIXELS, "-insertwidth", "insertWidth", "InsertWidth", "2", Tk_Offset(Table, insertWidth), 0}, {TK_CONFIG_BOOLEAN, "-invertselected", "invertSelected", "InvertSelected", "0", Tk_Offset(Table, invertSelected), 0}, {TK_CONFIG_PIXELS, "-ipadx", "ipadX", "Pad", "0", Tk_Offset(Table, ipadX), 0}, {TK_CONFIG_PIXELS, "-ipady", "ipadY", "Pad", "0", Tk_Offset(Table, ipadY), 0}, {TK_CONFIG_JUSTIFY, "-justify", "justify", "Justify", "left", Tk_Offset(Table, defaultTag.justify), 0 }, {TK_CONFIG_PIXELS, "-maxheight", "maxHeight", "MaxHeight", "600", Tk_Offset(Table, maxReqHeight), 0}, {TK_CONFIG_PIXELS, "-maxwidth", "maxWidth", "MaxWidth", "800", Tk_Offset(Table, maxReqWidth), 0}, {TK_CONFIG_BOOLEAN, "-multiline", "multiline", "Multiline", "1", Tk_Offset(Table, defaultTag.multiline), 0}, {TK_CONFIG_PIXELS, "-padx", "padX", "Pad", "0", Tk_Offset(Table, padX), 0}, {TK_CONFIG_PIXELS, "-pady", "padY", "Pad", "0", Tk_Offset(Table, padY), 0}, {TK_CONFIG_RELIEF, "-relief", "relief", "Relief", "sunken", Tk_Offset(Table, defaultTag.relief), 0}, {TK_CONFIG_CUSTOM, "-resizeborders", "resizeBorders", "ResizeBorders", "both", Tk_Offset(Table, resize), 0, &resizeTypeOpt }, {TK_CONFIG_INT, "-rowheight", "rowHeight", "RowHeight", "1", Tk_Offset(Table, defRowHeight), 0}, {TK_CONFIG_INT, "-roworigin", "rowOrigin", "Origin", "0", Tk_Offset(Table, rowOffset), 0}, {TK_CONFIG_INT, "-rows", "rows", "Rows", "10", Tk_Offset(Table, rows), 0}, {TK_CONFIG_STRING, "-rowseparator", "rowSeparator", "Separator", "\n", Tk_Offset(Table, rowSep), TK_CONFIG_NULL_OK }, {TK_CONFIG_CUSTOM, "-rowstretchmode", "rowStretch", "StretchMode", "none", Tk_Offset(Table, rowStretch), 0 , &stretchOpt }, {TK_CONFIG_CALLBACK, "-rowtagcommand", "rowTagCommand", "TagCommand", NULL, Tk_Offset(Table, rowTagCmd), TK_CONFIG_NULL_OK }, {TK_CONFIG_SYNONYM, "-selcmd", "selectionCommand", NULL, NULL, 0, TK_CONFIG_NULL_OK}, {TK_CONFIG_CALLBACK, "-selectioncommand", "selectionCommand", "SelectionCommand", NULL, Tk_Offset(Table, selCmd), TK_CONFIG_NULL_OK }, {TK_CONFIG_STRING, "-selectmode", "selectMode", "SelectMode", "browse", Tk_Offset(Table, selectMode), TK_CONFIG_NULL_OK }, {TK_CONFIG_BOOLEAN, "-selecttitles", "selectTitles", "SelectTitles", "0", Tk_Offset(Table, selectTitles), 0}, {TK_CONFIG_CUSTOM, "-selecttype", "selectType", "SelectType", "cell", Tk_Offset(Table, selectType), 0, &selTypeOpt }, #ifdef PROCS {TK_CONFIG_BOOLEAN, "-showprocs", "showProcs", "showProcs", "0", Tk_Offset(Table, showProcs), 0}, #endif {TK_CONFIG_BOOLEAN, "-sparsearray", "sparseArray", "SparseArray", "1", Tk_Offset(Table, sparse), 0}, {TK_CONFIG_CUSTOM, "-state", "state", "State", "normal", Tk_Offset(Table, state), 0, &stateTypeOpt}, {TK_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus", NULL, Tk_Offset(Table, takeFocus), TK_CONFIG_NULL_OK }, {TK_CONFIG_INT, "-titlecols", "titleCols", "TitleCols", "0", Tk_Offset(Table, titleCols), TK_CONFIG_NULL_OK }, #ifdef TITLE_CURSOR {TK_CONFIG_CURSOR, "-titlecursor", "titleCursor", "Cursor", "arrow", Tk_Offset(Table, titleCursor), TK_CONFIG_NULL_OK }, #endif {TK_CONFIG_INT, "-titlerows", "titleRows", "TitleRows", "0", Tk_Offset(Table, titleRows), TK_CONFIG_NULL_OK }, {TK_CONFIG_BOOLEAN, "-usecommand", "useCommand", "UseCommand", "1", Tk_Offset(Table, useCmd), 0}, {TK_CONFIG_SCALARVAR, "-variable", "variable", "Variable", NULL, Tk_Offset(Table, arrayVar), TK_CONFIG_NULL_OK }, {TK_CONFIG_BOOLEAN, "-validate", "validate", "Validate", "0", Tk_Offset(Table, validate), 0}, {TK_CONFIG_CALLBACK, "-validatecommand", "validateCommand", "ValidateCommand", "", Tk_Offset(Table, valCmd), TK_CONFIG_NULL_OK}, {TK_CONFIG_SYNONYM, "-vcmd", "validateCommand", NULL, NULL, 0, TK_CONFIG_NULL_OK}, {TK_CONFIG_INT, "-width", "width", "Width", "0", Tk_Offset(Table, maxReqCols), 0}, {TK_CONFIG_BOOLEAN, "-wrap", "wrap", "Wrap", "0", Tk_Offset(Table, defaultTag.wrap), 0}, {TK_CONFIG_CALLBACK, "-xscrollcommand", "xScrollCommand", "ScrollCommand", NULL, Tk_Offset(Table, xScrollCmd), TK_CONFIG_NULL_OK }, {TK_CONFIG_CALLBACK, "-yscrollcommand", "yScrollCommand", "ScrollCommand", NULL, Tk_Offset(Table, yScrollCmd), TK_CONFIG_NULL_OK }, {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} }; /* * This specifies the configure options that will cause an update to * occur, so we should have a quick lookup table for them. * Keep this in sync with the above values. */ static CONST char *updateOpts[] = { "-anchor", "-background", "-bg", "-bd", "-borderwidth", "-cache", "-command", "-colorigin", "-cols", "-colstretchmode", "-coltagcommand", "-drawmode", "-fg", "-font", "-foreground", "-hasprocs", "-height", "-highlightbackground", "-highlightcolor", "-highlightthickness", "-insertbackground", "-insertborderwidth", "-insertwidth", "-invertselected", "-ipadx", "-ipady", "-maxheight", "-maxwidth", "-multiline", "-padx", "-pady", "-relief", "-roworigin", "-rows", "-rowstretchmode", "-rowtagcommand", "-showprocs", "-state", "-titlecols", "-titlerows", "-usecommand", "-variable", "-width", "-wrap", "-xscrollcommand", "-yscrollcommand", NULL }; #ifdef WIN32 /* * Some code from TkWinInt.h that we use to correct and speed up * drawing of cells that need clipping in TableDisplay. */ typedef struct { int type; HWND handle; void *winPtr; } TkWinWindow; typedef struct { int type; HBITMAP handle; Colormap colormap; int depth; } TkWinBitmap; typedef struct { int type; HDC hdc; } TkWinDC; typedef union { int type; TkWinWindow window; TkWinBitmap bitmap; TkWinDC winDC; } TkWinDrawable; #endif /* * END HEADER INFORMATION */ /* *--------------------------------------------------------------------------- * * StringifyObjects -- (from tclCmdAH.c) * * Helper function to bridge the gap between an object-based procedure * and an older string-based procedure. * * Given an array of objects, allocate an array that consists of the * string representations of those objects. * * Results: * The return value is a pointer to the newly allocated array of * strings. Elements 0 to (objc-1) of the string array point to the * string representation of the corresponding element in the source * object array; element objc of the string array is NULL. * * Side effects: * Memory allocated. The caller must eventually free this memory * by calling ckfree() on the return value. * int result; char **argv; argv = StringifyObjects(objc, objv); result = StringBasedCmd(interp, objc, argv); ckfree((char *) argv); return result; * *--------------------------------------------------------------------------- */ /* Don't Need This becuase arrays of Objects equivalent to arrays of Args???? static Arg * StringifyObjects(objc, objv) int objc; /* Number of arguments. Tcl_Obj *CONST objv[]; Argument objects. { int i; Arg *args; /* This needs to not be autoconverted to a Arg, so change the name to argsv args = (Arg *) ckalloc((objc + 1) * sizeof(Arg *)); for (i = 0; i < objc; i++) { args[i] = Tcl_GetString(objv[i]); } args[i] = NULL; return args; } /* * As long as we wait for the Function in general * * This parses the "-class" option for the table. */ static int Tk_ClassOptionObjCmd(Tk_Window tkwin, char *defaultclass, int objc, Tcl_Obj *CONST objv[]) { char *classname = defaultclass; int offset = 0; if ((objc >= 4) && STREQ(Tcl_GetString(objv[2]),"-class")) { classname = Tcl_GetString(objv[3]); offset = 2; } Tk_SetClass(tkwin, classname); return offset; } /* *-------------------------------------------------------------- * * Tk_TableObjCmd -- * This procedure is invoked to process the "table" Tcl * command. See the user documentation for details on what * it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Tk_TableObjCmd(clientData, interp, objc, objv) ClientData clientData; /* Main window associated with interpreter. */ Tcl_Interp *interp; int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument objects. */ { register Table *tablePtr; Tk_Window tkwin, mainWin = (Tk_Window) clientData; int offset; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?"); return TCL_ERROR; } tkwin = Tk_CreateWindowFromPath(interp, mainWin, Tcl_GetString(objv[1]), NULL); if (tkwin == NULL) { return TCL_ERROR; } tablePtr = (Table *) ckalloc(sizeof(Table)); memset((VOID *) tablePtr, 0, sizeof(Table)); /* * Set the structure elments that aren't 0/NULL by default, * and that won't be set by the initial configure call. */ tablePtr->tkwin = tkwin; tablePtr->display = Tk_Display(tkwin); tablePtr->interp = interp; tablePtr->widgetCmd = Lang_CreateWidget(interp, tablePtr->tkwin, TableWidgetObjCmd, (ClientData) tablePtr, (Tcl_CmdDeleteProc *) TableCmdDeletedProc); tablePtr->anchorRow = -1; tablePtr->anchorCol = -1; tablePtr->activeRow = -1; tablePtr->activeCol = -1; tablePtr->oldTopRow = -1; tablePtr->oldLeftCol = -1; tablePtr->oldActRow = -1; tablePtr->oldActCol = -1; tablePtr->seen[0] = -1; tablePtr->dataSource = DATA_NONE; tablePtr->activeBuf = ckalloc(1); *(tablePtr->activeBuf) = '\0'; tablePtr->cursor = None; tablePtr->bdcursor = None; tablePtr->defaultTag.justify = TK_JUSTIFY_LEFT; tablePtr->defaultTag.state = STATE_UNKNOWN; /* misc tables */ tablePtr->tagTable = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(tablePtr->tagTable, TCL_STRING_KEYS); tablePtr->winTable = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(tablePtr->winTable, TCL_STRING_KEYS); /* internal value cache */ tablePtr->cache = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(tablePtr->cache, TCL_STRING_KEYS); /* style hash tables */ tablePtr->colWidths = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(tablePtr->colWidths, TCL_ONE_WORD_KEYS); tablePtr->rowHeights = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(tablePtr->rowHeights, TCL_ONE_WORD_KEYS); /* style hash tables */ tablePtr->rowStyles = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(tablePtr->rowStyles, TCL_ONE_WORD_KEYS); tablePtr->colStyles = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(tablePtr->colStyles, TCL_ONE_WORD_KEYS); tablePtr->cellStyles = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(tablePtr->cellStyles, TCL_STRING_KEYS); /* special style hash tables */ tablePtr->flashCells = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(tablePtr->flashCells, TCL_STRING_KEYS); tablePtr->selCells = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(tablePtr->selCells, TCL_STRING_KEYS); /* * List of tags in priority order. 30 is a good default number to alloc. */ tablePtr->tagPrioMax = 30; tablePtr->tagPrioNames = (char **) ckalloc( sizeof(char *) * tablePtr->tagPrioMax); tablePtr->tagPrios = (TableTag **) ckalloc( sizeof(TableTag *) * tablePtr->tagPrioMax); tablePtr->tagPrioSize = 0; for (offset = 0; offset < tablePtr->tagPrioMax; offset++) { tablePtr->tagPrioNames[offset] = NULL; tablePtr->tagPrios[offset] = (TableTag *) NULL; } #ifdef PROCS tablePtr->inProc = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(tablePtr->inProc, TCL_STRING_KEYS); #endif /* * Handle class name and selection handlers */ offset = 2 + Tk_ClassOptionObjCmd(tkwin, "Table", objc, objv); Tk_CreateEventHandler(tablePtr->tkwin, PointerMotionMask|ExposureMask|StructureNotifyMask|FocusChangeMask|VisibilityChangeMask, TableEventProc, (ClientData) tablePtr); Tk_CreateSelHandler(tablePtr->tkwin, XA_PRIMARY, XA_STRING, TableFetchSelection, (ClientData) tablePtr, XA_STRING); if (TableConfigure(interp, tablePtr, objc - offset, objv + offset, 0, 1 /* force update */) != TCL_OK) { Tk_DestroyWindow(tkwin); return TCL_ERROR; } TableInitTags(tablePtr); /*Tcl_SetStringObj(Tcl_GetObjResult(interp), Tk_PathName(tablePtr->tkwin), -1); */ /* Tk800.022 needs to old-style LangWidgetArg Call newer perltk's should be ok with the default. */ #ifdef USE_LANGWIDGETARG Tcl_SetObjResult(interp, LangWidgetArg(interp,tablePtr->tkwin)); #else Tcl_SetObjResult(interp, LangWidgetObj(interp,tablePtr->tkwin)); #endif return TCL_OK; } /* *-------------------------------------------------------------- * * TableWidgetObjCmd -- * This procedure is invoked to process the Tcl command * that corresponds to a widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ static int TableWidgetObjCmd(clientData, interp, objc, objv) ClientData clientData; Tcl_Interp *interp; int objc; /* Number of arguments. */ Tcl_Obj * CONST objv[]; /* Argument objects. */ { register Table *tablePtr = (Table *) clientData; int row, col, i, cmdIndex, result = TCL_OK; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?"); return TCL_ERROR; } /* parse the first parameter */ result = Tcl_GetIndexFromObj(interp, objv[1], commandNames, "option", 0, &cmdIndex); if (result != TCL_OK) { return result; } Tcl_Preserve((ClientData) tablePtr); switch ((enum command) cmdIndex) { case CMD_ACTIVATE: result = Table_ActivateCmd(clientData, interp, objc, objv); break; case CMD_BBOX: result = Table_BboxCmd(clientData, interp, objc, objv); break; case CMD_BORDER: result = Table_BorderCmd(clientData, interp, objc, objv); break; case CMD_CGET: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "option"); result = TCL_ERROR; } else { result = Tk_ConfigureValue(interp, tablePtr->tkwin, tableSpecs, (char *) tablePtr, Tcl_GetString(objv[2]), 0); } break; case CMD_CLEAR: result = Table_ClearCmd(clientData, interp, objc, objv); break; case CMD_CONFIGURE: if (objc < 4) { result = Tk_ConfigureInfo(interp, tablePtr->tkwin, tableSpecs, (char *) tablePtr, (objc == 3) ? Tcl_GetString(objv[2]) : NULL, 0); } else { result = TableConfigure(interp, tablePtr, objc - 2, objv + 2, TK_CONFIG_ARGV_ONLY, 0); } break; case CMD_CURSEL: result = Table_CurselectionCmd(clientData, interp, objc, objv); break; case CMD_CURVALUE: result = Table_CurvalueCmd(clientData, interp, objc, objv); break; case CMD_DELETE: case CMD_INSERT: result = Table_EditCmd(clientData, interp, objc, objv); break; case CMD_GET: result = Table_GetCmd(clientData, interp, objc, objv); break; case CMD_HEIGHT: result = Table_AdjustCmd(clientData, interp, objc, objv,0); break; case CMD_WIDTH: result = Table_AdjustCmd(clientData, interp, objc, objv,1); break; case CMD_HIDDEN: result = Table_HiddenCmd(clientData, interp, objc, objv); break; case CMD_ICURSOR: if (objc != 2 && objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "?cursorPos?"); result = TCL_ERROR; break; } if (!(tablePtr->flags & HAS_ACTIVE) || (tablePtr->flags & ACTIVE_DISABLED) || tablePtr->state == STATE_DISABLED) { Tcl_SetIntObj(Tcl_GetObjResult(interp), -1); break; } else if (objc == 3) { if (TableGetIcursorObj(tablePtr, objv[2], NULL) != TCL_OK) { result = TCL_ERROR; break; } TableRefresh(tablePtr, tablePtr->activeRow, tablePtr->activeCol, CELL); } Tcl_SetIntObj(Tcl_GetObjResult(interp), tablePtr->icursor); break; case CMD_INDEX: { char *which = NULL; if (objc == 4) { which = Tcl_GetString(objv[3]); } if ((objc < 3 || objc > 4) || ((objc == 4) && (strcmp(which, "row") && strcmp(which, "col")))) { Tcl_WrongNumArgs(interp, 2, objv, "<index> ?row|col?"); result = TCL_ERROR; } else if (TableGetIndexObj(tablePtr, objv[2], &row, &col) != TCL_OK) { result = TCL_ERROR; } else if (objc == 3) { char buf[INDEX_BUFSIZE]; /* recreate the index, just in case it got bounded */ TableMakeArrayIndex(row, col, buf); Tcl_SetStringObj(Tcl_GetObjResult(interp), buf, -1); } else { /* INDEX row|col */ Tcl_SetIntObj(Tcl_GetObjResult(interp), (*which == 'r') ? row : col); } break; } #ifdef POSTSCRIPT case CMD_POSTSCRIPT: result = Table_PostscriptCmd(clientData, interp, objc, objv); break; #endif case CMD_REREAD: if (objc != 2) { Tcl_WrongNumArgs(interp, 2, objv, NULL); result = TCL_ERROR; } else if ((tablePtr->flags & HAS_ACTIVE) && !(tablePtr->flags & ACTIVE_DISABLED) && tablePtr->state != STATE_DISABLED) { TableGetActiveBuf(tablePtr); TableRefresh(tablePtr, tablePtr->activeRow, tablePtr->activeCol, CELL|INV_FORCE); } break; case CMD_SCAN: result = Table_ScanCmd(clientData, interp, objc, objv); break; case CMD_SEE: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "index"); result = TCL_ERROR; } else if (TableGetIndexObj(tablePtr, objv[2], &row, &col) == TCL_ERROR) { result = TCL_ERROR; } else { /* Adjust from user to master coords */ row -= tablePtr->rowOffset; col -= tablePtr->colOffset; if (!TableCellVCoords(tablePtr, row, col, &i, &i, &i, &i, 1)) { tablePtr->topRow = row-1; tablePtr->leftCol = col-1; TableAdjustParams(tablePtr); } } break; case CMD_SELECTION: if (objc < 3) { Tcl_WrongNumArgs(interp, 2, objv, "option ?arg arg ...?"); result = TCL_ERROR; break; } if (Tcl_GetIndexFromObj(interp, objv[2], selCmdNames, "selection option", 0, &cmdIndex) != TCL_OK) { result = TCL_ERROR; break; } switch ((enum selCommand) cmdIndex) { case CMD_SEL_ANCHOR: result = Table_SelAnchorCmd(clientData, interp, objc, objv); break; case CMD_SEL_CLEAR: result = Table_SelClearCmd(clientData, interp, objc, objv); break; case CMD_SEL_INCLUDES: result = Table_SelIncludesCmd(clientData, interp, objc, objv); break; case CMD_SEL_PRESENT: { Tcl_HashSearch search; Tcl_SetBooleanObj(Tcl_GetObjResult(interp), (Tcl_FirstHashEntry(tablePtr->selCells, &search) != NULL)); break; } case CMD_SEL_SET: result = Table_SelSetCmd(clientData, interp, objc, objv); break; } break; case CMD_SET: result = Table_SetCmd(clientData, interp, objc, objv); break; case CMD_SPANS: result = Table_SpanCmd(clientData, interp, objc, objv); break; case CMD_TAG: result = Table_TagCmd(clientData, interp, objc, objv); break; case CMD_VALIDATE: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "index"); result = TCL_ERROR; } else if (TableGetIndexObj(tablePtr, objv[2], &row, &col) == TCL_ERROR) { result = TCL_ERROR; } else { i = tablePtr->validate; tablePtr->validate = 1; result = TableValidateChange(tablePtr, row, col, NULL, NULL, -1); tablePtr->validate = i; Tcl_SetBooleanObj(Tcl_GetObjResult(interp), (result == TCL_OK)); result = TCL_OK; } break; case CMD_VERSION: if (objc != 2) { Tcl_WrongNumArgs(interp, 2, objv, NULL); result = TCL_ERROR; } else { Tcl_SetStringObj(Tcl_GetObjResult(interp), VERSION, -1); } break; case CMD_WINDOW: result = Table_WindowCmd(clientData, interp, objc, objv); break; case CMD_XVIEW: case CMD_YVIEW: result = Table_ViewCmd(clientData, interp, objc, objv); break; } Tcl_Release((ClientData) tablePtr); return result; } /* *---------------------------------------------------------------------- * * TableDestroy -- * This procedure is invoked by Tcl_EventuallyFree * to clean up the internal structure of a table at a safe time * (when no-one is using it anymore). * * Results: * None. * * Side effects: * Everything associated with the table is freed up (hopefully). * *---------------------------------------------------------------------- */ static void TableDestroy(ClientData clientdata) { register Table *tablePtr = (Table *) clientdata; Tcl_HashEntry *entryPtr; Tcl_HashSearch search; /* These may be repetitive from DestroyNotify, but it doesn't hurt */ /* cancel any pending update or timer */ if (tablePtr->flags & REDRAW_PENDING) { Tcl_CancelIdleCall(TableDisplay, (ClientData) tablePtr); tablePtr->flags &= ~REDRAW_PENDING; } Tcl_DeleteTimerHandler(tablePtr->cursorTimer); Tcl_DeleteTimerHandler(tablePtr->flashTimer); /* delete the variable trace */ if (tablePtr->arrayVar != NULL) { Lang_UntraceVar(tablePtr->interp, tablePtr->arrayVar, TCL_TRACE_WRITES | TCL_TRACE_UNSETS | TCL_GLOBAL_ONLY, (Lang_VarTraceProc *)TableVarProc, (ClientData) tablePtr); } /* free the int arrays */ if (tablePtr->colPixels) ckfree((char *) tablePtr->colPixels); if (tablePtr->rowPixels) ckfree((char *) tablePtr->rowPixels); if (tablePtr->colStarts) ckfree((char *) tablePtr->colStarts); if (tablePtr->rowStarts) ckfree((char *) tablePtr->rowStarts); /* delete cached active tag and string */ if (tablePtr->activeTagPtr) ckfree((char *) tablePtr->activeTagPtr); if (tablePtr->activeBuf != NULL) ckfree(tablePtr->activeBuf); /* * Delete the various hash tables, make sure to clear the STRING_KEYS * tables that allocate their strings: * cache, spanTbl (spanAffTbl shares spanTbl info) */ Table_ClearHashTable(tablePtr->cache); ckfree((char *) (tablePtr->cache)); Tcl_DeleteHashTable(tablePtr->rowStyles); ckfree((char *) (tablePtr->rowStyles)); Tcl_DeleteHashTable(tablePtr->colStyles); ckfree((char *) (tablePtr->colStyles)); Tcl_DeleteHashTable(tablePtr->cellStyles); ckfree((char *) (tablePtr->cellStyles)); Tcl_DeleteHashTable(tablePtr->flashCells); ckfree((char *) (tablePtr->flashCells)); Tcl_DeleteHashTable(tablePtr->selCells); ckfree((char *) (tablePtr->selCells)); Tcl_DeleteHashTable(tablePtr->colWidths); ckfree((char *) (tablePtr->colWidths)); Tcl_DeleteHashTable(tablePtr->rowHeights); ckfree((char *) (tablePtr->rowHeights)); #ifdef PROCS Tcl_DeleteHashTable(tablePtr->inProc); ckfree((char *) (tablePtr->inProc)); #endif if (tablePtr->spanTbl) { Table_ClearHashTable(tablePtr->spanTbl); ckfree((char *) (tablePtr->spanTbl)); Tcl_DeleteHashTable(tablePtr->spanAffTbl); ckfree((char *) (tablePtr->spanAffTbl)); } /* Now free up all the tag information */ for (entryPtr = Tcl_FirstHashEntry(tablePtr->tagTable, &search); entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { TableCleanupTag(tablePtr, (TableTag *) Tcl_GetHashValue(entryPtr)); ckfree((char *) Tcl_GetHashValue(entryPtr)); } /* free up the stuff in the default tag */ TableCleanupTag(tablePtr, &(tablePtr->defaultTag)); /* And delete the actual hash table */ Tcl_DeleteHashTable(tablePtr->tagTable); ckfree((char *) (tablePtr->tagTable)); ckfree((char *) (tablePtr->tagPrios)); ckfree((char *) (tablePtr->tagPrioNames)); /* Now free up all the embedded window info */ for (entryPtr = Tcl_FirstHashEntry(tablePtr->winTable, &search); entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { EmbWinDelete(tablePtr, (TableEmbWindow *) Tcl_GetHashValue(entryPtr)); } /* And delete the actual hash table */ Tcl_DeleteHashTable(tablePtr->winTable); ckfree((char *) (tablePtr->winTable)); /* free the configuration options in the widget */ Tk_FreeOptions(tableSpecs, (char *) tablePtr, tablePtr->display, 0); /* and free the widget memory at last! */ ckfree((char *) (tablePtr)); } /* *---------------------------------------------------------------------- * * TableConfigure -- * This procedure is called to process an objc/objv list, plus * the Tk option database, in order to configure (or reconfigure) * a table widget. * * Results: * The return value is a standard Tcl result. If TCL_ERROR is * returned, then interp result contains an error message. * * Side effects: * Configuration information, such as colors, border width, etc. * get set for tablePtr; old resources get freed, if there were any. * Certain values might be constrained. * *---------------------------------------------------------------------- */ static int TableConfigure(interp, tablePtr, objc, objv, flags, forceUpdate) Tcl_Interp *interp; /* Used for error reporting. */ register Table *tablePtr; /* Information about widget; may or may * not already have values for some fields. */ int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument objects. */ int flags; /* Flags to pass to Tk_ConfigureWidget. */ int forceUpdate; /* Whether to force an update - required * for initial configuration */ { Tcl_HashSearch search; int oldUse, oldCaching, oldExport, oldTitleRows, oldTitleCols; int result = TCL_OK; Arg *objArray; Var oldVar = NULL; Tcl_DString error; Tk_FontMetrics fm; char *currentVarString; /* Name of the current array variable */ char *oldVarString = NULL; /* Name of the old array variable */ oldExport = tablePtr->exportSelection; oldCaching = tablePtr->caching; oldUse = tablePtr->useCmd; oldTitleRows = tablePtr->titleRows; oldTitleCols = tablePtr->titleCols; if (tablePtr->arrayVar != NULL) { oldVar = tablePtr->arrayVar; oldVarString = Tcl_GetString(Tcl_ObjGetVar2(interp, oldVar, NULL, TCL_GLOBAL_ONLY)); } /* Do the configuration */ /* objv = StringifyObjects(objc, objv); */ /* Don't Need this because arrays of Args like arrays of Obj?? */ objArray = (Tcl_Obj **) objv; /* Cast gets rid of warnings */ result = Tk_ConfigureWidget(interp, tablePtr->tkwin, tableSpecs, objc, objArray, (char *) tablePtr, flags); /* ckfree((char *) objv); */ if (result != TCL_OK) { return TCL_ERROR; } Tcl_DStringInit(&error); /* Any time we configure, reevaluate what our data source is */ tablePtr->dataSource = DATA_NONE; if (tablePtr->caching) { tablePtr->dataSource |= DATA_CACHE; } if (tablePtr->command && tablePtr->useCmd) { tablePtr->dataSource |= DATA_COMMAND; } else if (tablePtr->arrayVar) { tablePtr->dataSource |= DATA_ARRAY; } /* Check to see if the array variable was changed */ currentVarString = Tcl_GetString(Tcl_ObjGetVar2(interp, tablePtr->arrayVar, NULL, TCL_GLOBAL_ONLY)); if (strcmp((currentVarString?currentVarString:""), (oldVarString?oldVarString:""))) { /* only do the following if arrayVar is our data source */ if (tablePtr->dataSource & DATA_ARRAY) { /* * ensure that the cache will flush later * so it gets the new values */ oldCaching = !(tablePtr->caching); } /* remove the trace on the old array variable if there was one */ if (oldVar != NULL) Lang_UntraceVar(interp, oldVar, TCL_TRACE_WRITES|TCL_TRACE_UNSETS|TCL_GLOBAL_ONLY, (Lang_VarTraceProc *)TableVarProc, (ClientData) tablePtr); /* Check whether variable is an array and trace it if it is */ if (tablePtr->arrayVar != NULL) { /* does the variable exist as an array? */ if (Tcl_ObjSetVar2(interp, tablePtr->arrayVar, Tcl_NewStringObj(TEST_KEY,-1), Tcl_NewStringObj("",-1), TCL_GLOBAL_ONLY) == NULL) { Tcl_DStringAppend(&error, "invalid variable value \"", -1); Tcl_DStringAppend(&error, currentVarString, -1); Tcl_DStringAppend(&error, "\": could not be made an array", -1); ckfree(currentVarString); tablePtr->arrayVar = NULL; tablePtr->dataSource &= ~DATA_ARRAY; result = TCL_ERROR; } else { /* perltk not supported */ /* Tcl_UnsetVar2(interp, currentVarString, TEST_KEY, TCL_GLOBAL_ONLY); */ /* remove the effect of the evaluation */ /* set a trace on the variable */ Lang_TraceVar(interp, tablePtr->arrayVar, TCL_TRACE_WRITES|TCL_TRACE_UNSETS|TCL_GLOBAL_ONLY, (Lang_VarTraceProc *)TableVarProc, (ClientData) tablePtr); /* only do the following if arrayVar is our data source */ if (tablePtr->dataSource & DATA_ARRAY) { /* get the current value of the selection */ TableGetActiveBuf(tablePtr); } } } } /* Free oldVar if it was allocated */ /* if (oldVar != NULL) ckfree(oldVar); */ if ((tablePtr->command && tablePtr->useCmd && !oldUse) || (tablePtr->arrayVar && !(tablePtr->useCmd) && oldUse)) { /* * Our effective data source changed, so flush and * retrieve new active buffer */ Table_ClearHashTable(tablePtr->cache); Tcl_InitHashTable(tablePtr->cache, TCL_STRING_KEYS); TableGetActiveBuf(tablePtr); forceUpdate = 1; } else if (oldCaching != tablePtr->caching) { /* * Caching changed, so just clear the cache for safety */ Table_ClearHashTable(tablePtr->cache); Tcl_InitHashTable(tablePtr->cache, TCL_STRING_KEYS); forceUpdate = 1; } /* * Set up the default column width and row height */ Tk_GetFontMetrics(tablePtr->defaultTag.tkfont, &fm); tablePtr->charWidth = Tk_TextWidth(tablePtr->defaultTag.tkfont, "0", 1); tablePtr->charHeight = fm.linespace + 2; if (tablePtr->insertWidth <= 0) { tablePtr->insertWidth = 2; } if (tablePtr->insertBorderWidth > tablePtr->insertWidth/2) { tablePtr->insertBorderWidth = tablePtr->insertWidth/2; } tablePtr->highlightWidth = MAX(0,tablePtr->highlightWidth); /* * Ensure that certain values are within proper constraints */ tablePtr->rows = MAX(1, tablePtr->rows); tablePtr->cols = MAX(1, tablePtr->cols); tablePtr->padX = MAX(0, tablePtr->padX); tablePtr->padY = MAX(0, tablePtr->padY); tablePtr->ipadX = MAX(0, tablePtr->ipadX); tablePtr->ipadY = MAX(0, tablePtr->ipadY); tablePtr->maxReqCols = MAX(0, tablePtr->maxReqCols); tablePtr->maxReqRows = MAX(0, tablePtr->maxReqRows); CONSTRAIN(tablePtr->titleRows, 0, tablePtr->rows); CONSTRAIN(tablePtr->titleCols, 0, tablePtr->cols); /* * Handle change of default border style * The default borderwidth must be >= 0. */ if (tablePtr->drawMode & (DRAW_MODE_SINGLE|DRAW_MODE_FAST)) { /* * When drawing fast or single, the border must be <= 1. * We have to do this after the normal configuration * to base the borders off the first value given. */ tablePtr->defaultTag.bd[0] = MIN(1, tablePtr->defaultTag.bd[0]); tablePtr->defaultTag.borders = 1; ckfree((char *) tablePtr->defaultTag.borderStr); tablePtr->defaultTag.borderStr = (char *) ckalloc(2); strcpy(tablePtr->defaultTag.borderStr, tablePtr->defaultTag.bd[0] ? "1" : "0"); } /* * Claim the selection if we've suddenly started exporting it and * there is a selection to export. */ if (tablePtr->exportSelection && !oldExport && (Tcl_FirstHashEntry(tablePtr->selCells, &search) != NULL)) { Tk_OwnSelection(tablePtr->tkwin, XA_PRIMARY, TableLostSelection, (ClientData) tablePtr); } if ((tablePtr->titleRows < oldTitleRows) || (tablePtr->titleCols < oldTitleCols)) { /* * Prevent odd movement due to new possible topleft index */ if (tablePtr->titleRows < oldTitleRows) tablePtr->topRow -= oldTitleRows - tablePtr->titleRows; if (tablePtr->titleCols < oldTitleCols) tablePtr->leftCol -= oldTitleCols - tablePtr->titleCols; /* * If our title area shrank, we need to check that the items * within the new title area don't try to span outside it. */ TableSpanSanCheck(tablePtr); } /* * Only do the full reconfigure if absolutely necessary */ if (!forceUpdate) { int i, dummy; for (i = 0; i < objc-1; i += 2) { if (Tcl_GetIndexFromObj(NULL, objv[i], updateOpts, "", 0, &dummy) == TCL_OK) { forceUpdate = 1; break; } } } if (forceUpdate) { /* * Calculate the row and column starts * Adjust the top left corner of the internal display */ TableAdjustParams(tablePtr); /* reset the cursor */ TableConfigCursor(tablePtr); /* set up the background colour in the window */ Tk_SetBackgroundFromBorder(tablePtr->tkwin, tablePtr->defaultTag.bg); /* set the geometry and border */ TableGeometryRequest(tablePtr); Tk_SetInternalBorder(tablePtr->tkwin, tablePtr->highlightWidth); /* invalidate the whole table */ TableInvalidateAll(tablePtr, INV_HIGHLIGHT); } /* * FIX this is goofy because the result could be munged by other * functions. Could be improved. */ Tcl_ResetResult(interp); if (result == TCL_ERROR) { Tcl_AddErrorInfo(interp, "\t(configuring table widget)"); Tcl_DStringResult(interp, &error); } Tcl_DStringFree(&error); return result; } /* *-------------------------------------------------------------- * * TableEventProc -- * This procedure is invoked by the Tk dispatcher for various * events on tables. * * Results: * None. * * Side effects: * When the window gets deleted, internal structures get * cleaned up. When it gets exposed, it is redisplayed. * *-------------------------------------------------------------- */ static void TableEventProc(clientData, eventPtr) ClientData clientData; /* Information about window. */ XEvent *eventPtr; /* Information about event. */ { Table *tablePtr = (Table *) clientData; int row, col; switch (eventPtr->type) { case MotionNotify: if (!(tablePtr->resize & SEL_NONE) && (tablePtr->bdcursor != None) && TableAtBorder(tablePtr, eventPtr->xmotion.x, eventPtr->xmotion.y, &row, &col) && ((row>=0 && (tablePtr->resize & SEL_ROW)) || (col>=0 && (tablePtr->resize & SEL_COL)))) { /* * The bordercursor is defined and we meet the criteria for * being over a border. Set the cursor to border if not * already done. */ if (!(tablePtr->flags & OVER_BORDER)) { tablePtr->flags |= OVER_BORDER; Tk_DefineCursor(tablePtr->tkwin, tablePtr->bdcursor); } } else if (tablePtr->flags & OVER_BORDER) { tablePtr->flags &= ~OVER_BORDER; if (tablePtr->cursor != None) { Tk_DefineCursor(tablePtr->tkwin, tablePtr->cursor); } else { Tk_UndefineCursor(tablePtr->tkwin); } #ifdef TITLE_CURSOR } else if (tablePtr->flags & (OVER_BORDER|OVER_TITLE)) { Tk_Cursor cursor = tablePtr->cursor; //tablePtr->flags &= ~(OVER_BORDER|OVER_TITLE); if (tablePtr->titleCursor != None) { TableWhatCell(tablePtr, eventPtr->xmotion.x, eventPtr->xmotion.y, &row, &col); if ((row < tablePtr->titleRows) || (col < tablePtr->titleCols)) { if (tablePtr->flags & OVER_TITLE) { break; } tablePtr->flags |= OVER_TITLE; cursor = tablePtr->titleCursor; } } if (cursor != None) { Tk_DefineCursor(tablePtr->tkwin, cursor); } else { Tk_UndefineCursor(tablePtr->tkwin); } } else if (tablePtr->titleCursor != None) { Tk_Cursor cursor = tablePtr->cursor; TableWhatCell(tablePtr, eventPtr->xmotion.x, eventPtr->xmotion.y, &row, &col); if ((row < tablePtr->titleRows) || (col < tablePtr->titleCols)) { if (tablePtr->flags & OVER_TITLE) { break; } tablePtr->flags |= OVER_TITLE; cursor = tablePtr->titleCursor; } #endif } break; case Expose: TableInvalidate(tablePtr, eventPtr->xexpose.x, eventPtr->xexpose.y, eventPtr->xexpose.width, eventPtr->xexpose.height, INV_HIGHLIGHT); break; case DestroyNotify: /* remove the command from the interpreter */ if (tablePtr->tkwin != NULL) { tablePtr->tkwin = NULL; Lang_DeleteWidget(tablePtr->interp, tablePtr->widgetCmd); } /* cancel any pending update or timer */ if (tablePtr->flags & REDRAW_PENDING) { Tcl_CancelIdleCall(TableDisplay, (ClientData) tablePtr); tablePtr->flags &= ~REDRAW_PENDING; } Tcl_DeleteTimerHandler(tablePtr->cursorTimer); Tcl_DeleteTimerHandler(tablePtr->flashTimer); Tcl_EventuallyFree((ClientData) tablePtr, (Tcl_FreeProc *) TableDestroy); break; case MapNotify: /* redraw table when remapped if it changed */ if (tablePtr->flags & REDRAW_ON_MAP) { tablePtr->flags &= ~REDRAW_ON_MAP; Tcl_Preserve((ClientData) tablePtr); TableAdjustParams(tablePtr); TableInvalidateAll(tablePtr, INV_HIGHLIGHT); Tcl_Release((ClientData) tablePtr); } break; case ConfigureNotify: Tcl_Preserve((ClientData) tablePtr); TableAdjustParams(tablePtr); TableInvalidateAll(tablePtr, INV_HIGHLIGHT); Tcl_Release((ClientData) tablePtr); break; case FocusIn: case FocusOut: if (eventPtr->xfocus.detail != NotifyInferior) { tablePtr->flags |= REDRAW_BORDER; if (eventPtr->type == FocusOut) { tablePtr->flags &= ~HAS_FOCUS; } else { tablePtr->flags |= HAS_FOCUS; } TableRedrawHighlight(tablePtr); /* cancel the timer */ TableConfigCursor(tablePtr); } break; } } /* *---------------------------------------------------------------------- * * TableCmdDeletedProc -- * * This procedure is invoked when a widget command is deleted. If * the widget isn't already in the process of being destroyed, * this command destroys it. * * Results: * None. * * Side effects: * The widget is destroyed. * *---------------------------------------------------------------------- */ static void TableCmdDeletedProc(ClientData clientData) { Table *tablePtr = (Table *) clientData; Tk_Window tkwin; /* * This procedure could be invoked either because the window was * destroyed and the command was then deleted (in which case tkwin * is NULL) or because the command was deleted, and then this procedure * destroys the widget. */ if (tablePtr->tkwin != NULL) { tkwin = tablePtr->tkwin; tablePtr->tkwin = NULL; Tk_DestroyWindow(tkwin); } } /* *---------------------------------------------------------------------- * * TableRedrawHighlight -- * Redraws just the highlight for the window * * Results: * None. * * Side effects: * None * *---------------------------------------------------------------------- */ static void TableRedrawHighlight(Table *tablePtr) { if ((tablePtr->flags & REDRAW_BORDER) && tablePtr->highlightWidth > 0) { GC gc = Tk_GCForColor((tablePtr->flags & HAS_FOCUS) ? tablePtr->highlightColorPtr : tablePtr->highlightBgColorPtr, Tk_WindowId(tablePtr->tkwin)); Tk_DrawFocusHighlight(tablePtr->tkwin, gc, tablePtr->highlightWidth, Tk_WindowId(tablePtr->tkwin)); } tablePtr->flags &= ~REDRAW_BORDER; } /* *---------------------------------------------------------------------- * * TableRefresh -- * Refreshes an area of the table based on the mode. * row,col in real coords (0-based) * * Results: * Will cause redraw for visible cells * * Side effects: * None. * *---------------------------------------------------------------------- */ void TableRefresh(register Table *tablePtr, int row, int col, int mode) { int x, y, w, h; if ((row < 0) || (col < 0)) { /* * Invalid coords passed in. This can happen when the "active" cell * is refreshed, but doesn't really exist (row==-1 && col==-1). */ return; } if (mode & CELL) { if (TableCellVCoords(tablePtr, row, col, &x, &y, &w, &h, 0)) { TableInvalidate(tablePtr, x, y, w, h, mode); } } else if (mode & ROW) { /* get the position of the leftmost cell in the row */ if ((mode & INV_FILL) && row < tablePtr->topRow) { /* Invalidate whole table */ TableInvalidateAll(tablePtr, mode); } else if (TableCellVCoords(tablePtr, row, tablePtr->leftCol, &x, &y, &w, &h, 0)) { /* Invalidate from this row, maybe to end */ TableInvalidate(tablePtr, 0, y, Tk_Width(tablePtr->tkwin), (mode&INV_FILL)?Tk_Height(tablePtr->tkwin):h, mode); } } else if (mode & COL) { /* get the position of the topmost cell on the column */ if ((mode & INV_FILL) && col < tablePtr->leftCol) { /* Invalidate whole table */ TableInvalidateAll(tablePtr, mode); } else if (TableCellVCoords(tablePtr, tablePtr->topRow, col, &x, &y, &w, &h, 0)) { /* Invalidate from this column, maybe to end */ TableInvalidate(tablePtr, x, 0, (mode&INV_FILL)?Tk_Width(tablePtr->tkwin):w, Tk_Height(tablePtr->tkwin), mode); } } } /* *---------------------------------------------------------------------- * * TableGetGc -- * Gets a GC corresponding to the tag structure passed. * * Results: * Returns usable GC. * * Side effects: * None * *---------------------------------------------------------------------- */ static void TableGetGc(Display *display, Drawable d, TableTag *tagPtr, GC *tagGc) { XGCValues gcValues; gcValues.foreground = Tk_3DBorderColor(tagPtr->fg)->pixel; gcValues.background = Tk_3DBorderColor(tagPtr->bg)->pixel; gcValues.font = Tk_FontId(tagPtr->tkfont); if (*tagGc == NULL) { gcValues.graphics_exposures = False; *tagGc = XCreateGC(display, d, GCForeground|GCBackground|GCFont|GCGraphicsExposures, &gcValues); } else { XChangeGC(display, *tagGc, GCForeground|GCBackground|GCFont, &gcValues); } } #define TableFreeGc XFreeGC /* *-------------------------------------------------------------- * * TableUndisplay -- * This procedure removes the contents of a table window * that have been moved offscreen. * * Results: * Embedded windows can be unmapped. * * Side effects: * Information disappears from the screen. * *-------------------------------------------------------------- */ static void TableUndisplay(register Table *tablePtr) { register int *seen = tablePtr->seen; int row, col; /* We need to find out the true last cell, not considering spans */ tablePtr->flags |= AVOID_SPANS; TableGetLastCell(tablePtr, &row, &col); tablePtr->flags &= ~AVOID_SPANS; if (seen[0] != -1) { if (seen[0] < tablePtr->topRow) { /* Remove now hidden rows */ EmbWinUnmap(tablePtr, seen[0], MIN(seen[2],tablePtr->topRow-1), seen[1], seen[3]); /* Also account for the title area */ EmbWinUnmap(tablePtr, seen[0], MIN(seen[2],tablePtr->topRow-1), 0, tablePtr->titleCols-1); } if (seen[1] < tablePtr->leftCol) { /* Remove now hidden cols */ EmbWinUnmap(tablePtr, seen[0], seen[2], seen[1], MAX(seen[3],tablePtr->leftCol-1)); /* Also account for the title area */ EmbWinUnmap(tablePtr, 0, tablePtr->titleRows-1, seen[1], MAX(seen[3],tablePtr->leftCol-1)); } if (seen[2] > row) { /* Remove now off-screen rows */ EmbWinUnmap(tablePtr, MAX(seen[0],row+1), seen[2], seen[1], seen[3]); /* Also account for the title area */ EmbWinUnmap(tablePtr, MAX(seen[0],row+1), seen[2], 0, tablePtr->titleCols-1); } if (seen[3] > col) { /* Remove now off-screen cols */ EmbWinUnmap(tablePtr, seen[0], seen[2], MAX(seen[1],col+1), seen[3]); /* Also account for the title area */ EmbWinUnmap(tablePtr, 0, tablePtr->titleRows-1, MAX(seen[1],col+1), seen[3]); } } seen[0] = tablePtr->topRow; seen[1] = tablePtr->leftCol; seen[2] = row; seen[3] = col; } #if defined(MAC_TCL) || (defined(WIN32) && defined(TCL_THREADS)) || defined(MAC_OSX_TK) #define NO_XSETCLIP #endif /* *-------------------------------------------------------------- * * TableDisplay -- * This procedure redraws the contents of a table window. * The conditional code in this function is due to these factors: * o Lack of XSetClipRectangles on Macintosh * o Use of alternative routine for Windows * * Results: * None. * * Side effects: * Information appears on the screen. * *-------------------------------------------------------------- */ static void TableDisplay(ClientData clientdata) { register Table *tablePtr = (Table *) clientdata; Tk_Window tkwin = tablePtr->tkwin; Display *display = tablePtr->display; Drawable window; #ifdef NO_XSETCLIP Drawable clipWind; #elif !defined(WIN32) XRectangle clipRect; #endif int rowFrom, rowTo, colFrom, colTo, invalidX, invalidY, invalidWidth, invalidHeight, x, y, width, height, itemX, itemY, itemW, itemH, row, col, urow, ucol, hrow=0, hcol=0, cx, cy, cw, ch, borders, bd[6], numBytes, new, boundW, boundH, maxW, maxH, cellType, originX, originY, activeCell, shouldInvert, ipadx, ipady, padx, pady; GC tagGc = NULL, topGc, bottomGc; char *string = NULL; char buf[INDEX_BUFSIZE]; TableTag *tagPtr = NULL, *titlePtr, *selPtr, *activePtr, *flashPtr, *rowPtr, *colPtr; Tcl_HashEntry *entryPtr; static XPoint rect[3] = { {0, 0}, {0, 0}, {0, 0} }; Tcl_HashTable *colTagsCache = NULL; Tcl_HashTable *drawnCache = NULL; Tk_TextLayout textLayout = NULL; TableEmbWindow *ewPtr; tablePtr->flags &= ~REDRAW_PENDING; if ((tkwin == NULL) || !Tk_IsMapped(tkwin)) { return; } boundW = Tk_Width(tkwin) - tablePtr->highlightWidth; boundH = Tk_Height(tkwin) - tablePtr->highlightWidth; /* Constrain drawable to not include highlight borders */ invalidX = MAX(tablePtr->highlightWidth, tablePtr->invalidX); invalidY = MAX(tablePtr->highlightWidth, tablePtr->invalidY); invalidWidth = MIN(tablePtr->invalidWidth, MAX(1, boundW-invalidX)); invalidHeight = MIN(tablePtr->invalidHeight, MAX(1, boundH-invalidY)); ipadx = tablePtr->ipadX; ipady = tablePtr->ipadY; padx = tablePtr->padX; pady = tablePtr->padY; /* * if we are using the slow drawing mode with a pixmap * create the pixmap and adjust x && y for offset in pixmap */ if (tablePtr->drawMode == DRAW_MODE_SLOW) { window = Tk_GetPixmap(display, Tk_WindowId(tkwin), invalidWidth, invalidHeight, Tk_Depth(tkwin)); } else { window = Tk_WindowId(tkwin); } #ifdef NO_XSETCLIP clipWind = Tk_GetPixmap(display, window, invalidWidth, invalidHeight, Tk_Depth(tkwin)); #endif /* set up the permanent tag styles */ entryPtr = Tcl_FindHashEntry(tablePtr->tagTable, "title"); titlePtr = (TableTag *) Tcl_GetHashValue(entryPtr); entryPtr = Tcl_FindHashEntry(tablePtr->tagTable, "sel"); selPtr = (TableTag *) Tcl_GetHashValue(entryPtr); entryPtr = Tcl_FindHashEntry(tablePtr->tagTable, "active"); activePtr = (TableTag *) Tcl_GetHashValue(entryPtr); entryPtr = Tcl_FindHashEntry(tablePtr->tagTable, "flash"); flashPtr = (TableTag *) Tcl_GetHashValue(entryPtr); /* We need to find out the true cell span, not considering spans */ tablePtr->flags |= AVOID_SPANS; /* find out the cells represented by the invalid region */ TableWhatCell(tablePtr, invalidX, invalidY, &rowFrom, &colFrom); TableWhatCell(tablePtr, invalidX+invalidWidth-1, invalidY+invalidHeight-1, &rowTo, &colTo); tablePtr->flags &= ~AVOID_SPANS; #ifdef DEBUG tcl_dprintf(tablePtr->interp, "%d,%d => %d,%d", rowFrom+tablePtr->rowOffset, colFrom+tablePtr->colOffset, rowTo+tablePtr->rowOffset, colTo+tablePtr->colOffset); #endif /* * Initialize colTagsCache hash table to cache column tag names. */ colTagsCache = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(colTagsCache, TCL_ONE_WORD_KEYS); /* * Initialize drawnCache hash table to cache drawn cells. * This is necessary to prevent spanning cells being drawn multiple times. */ drawnCache = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(drawnCache, TCL_STRING_KEYS); /* * Create the tag here. This will actually create a JoinTag * That will handle the priority management of merging for us. * We only need one allocated, and we'll reset it for each cell. */ tagPtr = TableNewTag(tablePtr); /* Cycle through the cells and display them */ for (row = rowFrom; row <= rowTo; row++) { /* * are we in the 'dead zone' between the * title rows and the first displayed row */ if (row < tablePtr->topRow && row >= tablePtr->titleRows) { row = tablePtr->topRow; } /* Cache the row in user terms */ urow = row+tablePtr->rowOffset; /* Get the row tag once for all iterations of col */ rowPtr = FindRowColTag(tablePtr, urow, ROW); for (col = colFrom; col <= colTo; col++) { activeCell = 0; /* * Adjust to first viewable column if we are in the 'dead zone' * between the title cols and the first displayed column. */ if (col < tablePtr->leftCol && col >= tablePtr->titleCols) { col = tablePtr->leftCol; } /* * Get the coordinates for the cell before possible rearrangement * of row,col due to spanning cells */ cellType = TableCellCoords(tablePtr, row, col, &x, &y, &width, &height); if (cellType == CELL_HIDDEN) { /* * width,height holds the real start row,col of the span. * Put the use cell ref into a buffer for the hash lookups. */ TableMakeArrayIndex(width, height, buf); Tcl_CreateHashEntry(drawnCache, buf, &new); if (!new) { /* Not new in the entry, so it's already drawn */ continue; } hrow = row; hcol = col; row = width-tablePtr->rowOffset; col = height-tablePtr->colOffset; TableCellVCoords(tablePtr, row, col, &x, &y, &width, &height, 0); /* We have to adjust the coords back onto the visual display */ urow = row+tablePtr->rowOffset; rowPtr = FindRowColTag(tablePtr, urow, ROW); } /* Constrain drawn size to the visual boundaries */ if (width > boundW-x) { width = boundW-x; } if (height > boundH-y) { height = boundH-y; } /* Cache the col in user terms */ ucol = col+tablePtr->colOffset; /* put the use cell ref into a buffer for the hash lookups */ TableMakeArrayIndex(urow, ucol, buf); if (cellType != CELL_HIDDEN) { Tcl_CreateHashEntry(drawnCache, buf, &new); } /* * Make sure we start with a clean tag (set to table defaults). */ TableResetTag(tablePtr, tagPtr); /* * Check to see if we have an embedded window in this cell. */ entryPtr = Tcl_FindHashEntry(tablePtr->winTable, buf); if (entryPtr != NULL) { ewPtr = (TableEmbWindow *) Tcl_GetHashValue(entryPtr); if (ewPtr->tkwin != NULL) { /* Display embedded window instead of text */ /* if active, make it disabled to avoid * unnecessary editing */ if ((tablePtr->flags & HAS_ACTIVE) && row == tablePtr->activeRow && col == tablePtr->activeCol) { tablePtr->flags |= ACTIVE_DISABLED; } /* * The EmbWinDisplay function may modify values in * tagPtr, so reference those after this call. */ EmbWinDisplay(tablePtr, window, ewPtr, tagPtr, x, y, width, height); if (tablePtr->drawMode == DRAW_MODE_SLOW) { /* Correctly adjust x && y with the offset */ x -= invalidX; y -= invalidY; } Tk_Fill3DRectangle(tkwin, window, tagPtr->bg, x, y, width, height, 0, TK_RELIEF_FLAT); /* border width for cell should now be properly set */ borders = TableGetTagBorders(tagPtr, &bd[0], &bd[1], &bd[2], &bd[3]); bd[4] = (bd[0] + bd[1])/2; bd[5] = (bd[2] + bd[3])/2; goto DrawBorder; } } if (tablePtr->drawMode == DRAW_MODE_SLOW) { /* Correctly adjust x && y with the offset */ x -= invalidX; y -= invalidY; } shouldInvert = 0; /* * Get the combined tag structure for the cell. * First clear out a new tag structure that we will build in * then add tags as we realize they belong. * * Tags have their own priorities which TableMergeTag will * take into account when merging tags. */ /* * Merge colPtr if it exists * let's see if we have the value cached already * if not, run the findColTag routine and cache the value */ entryPtr = Tcl_CreateHashEntry(colTagsCache, (char *)ucol, &new); if (new) { colPtr = FindRowColTag(tablePtr, ucol, COL); Tcl_SetHashValue(entryPtr, colPtr); } else { colPtr = (TableTag *) Tcl_GetHashValue(entryPtr); } if (colPtr != (TableTag *) NULL) { TableMergeTag(tablePtr, tagPtr, colPtr); } /* Merge rowPtr if it exists */ if (rowPtr != (TableTag *) NULL) { TableMergeTag(tablePtr, tagPtr, rowPtr); } /* Am I in the titles */ if (row < tablePtr->titleRows || col < tablePtr->titleCols) { TableMergeTag(tablePtr, tagPtr, titlePtr); } /* Does this have a cell tag */ entryPtr = Tcl_FindHashEntry(tablePtr->cellStyles, buf); if (entryPtr != NULL) { TableMergeTag(tablePtr, tagPtr, (TableTag *) Tcl_GetHashValue(entryPtr)); } /* is this cell active? */ if ((tablePtr->flags & HAS_ACTIVE) && (tablePtr->state == STATE_NORMAL) && row == tablePtr->activeRow && col == tablePtr->activeCol) { if (tagPtr->state == STATE_DISABLED) { tablePtr->flags |= ACTIVE_DISABLED; } else { TableMergeTag(tablePtr, tagPtr, activePtr); activeCell = 1; tablePtr->flags &= ~ACTIVE_DISABLED; } } /* is this cell selected? */ if (Tcl_FindHashEntry(tablePtr->selCells, buf) != NULL) { if (tablePtr->invertSelected && !activeCell) { shouldInvert = 1; } else { TableMergeTag(tablePtr, tagPtr, selPtr); } } /* if flash mode is on, is this cell flashing? */ if (tablePtr->flashMode && Tcl_FindHashEntry(tablePtr->flashCells, buf) != NULL) { TableMergeTag(tablePtr, tagPtr, flashPtr); } if (shouldInvert) { TableInvertTag(tagPtr); } /* * Borders for cell should now be properly set */ borders = TableGetTagBorders(tagPtr, &bd[0], &bd[1], &bd[2], &bd[3]); bd[4] = (bd[0] + bd[1])/2; bd[5] = (bd[2] + bd[3])/2; /* * First fill in a blank rectangle. */ Tk_Fill3DRectangle(tkwin, window, tagPtr->bg, x, y, width, height, 0, TK_RELIEF_FLAT); /* * Correct the dimensions to enforce padding constraints */ width -= bd[0] + bd[1] + (2 * padx); height -= bd[2] + bd[3] + (2 * pady); /* * If an image is in the tag, draw it */ if (tagPtr->image != NULL) { Tk_SizeOfImage(tagPtr->image, &itemW, &itemH); /* Handle anchoring of image in cell space */ switch (tagPtr->anchor) { case TK_ANCHOR_NW: case TK_ANCHOR_W: case TK_ANCHOR_SW: /* western position */ originX = itemX = 0; break; case TK_ANCHOR_N: case TK_ANCHOR_S: case TK_ANCHOR_CENTER: /* centered position */ itemX = MAX(0, (itemW - width) / 2); originX = MAX(0, (width - itemW) / 2); break; default: /* eastern position */ itemX = MAX(0, itemW - width); originX = MAX(0, width - itemW); } switch (tagPtr->anchor) { case TK_ANCHOR_N: case TK_ANCHOR_NE: case TK_ANCHOR_NW: /* northern position */ originY = itemY = 0; break; case TK_ANCHOR_W: case TK_ANCHOR_E: case TK_ANCHOR_CENTER: /* centered position */ itemY = MAX(0, (itemH - height) / 2); originY = MAX(0, (height - itemH) / 2); break; default: /* southern position */ itemY = MAX(0, itemH - height); originY = MAX(0, height - itemH); } Tk_RedrawImage(tagPtr->image, itemX, itemY, MIN(itemW, width-originX), MIN(itemH, height-originY), window, x + originX + bd[0] + padx, y + originY + bd[2] + pady); /* * If we don't want to display the text as well, then jump. */ if (tagPtr->showtext == 0) { /* * Re-Correct the dimensions before border drawing */ width += bd[0] + bd[1] + (2 * padx); height += bd[2] + bd[3] + (2 * pady); goto DrawBorder; } } /* * Get the GC for this particular blend of tags. * This creates the GC if it never existed, otherwise it * modifies the one we have, so we only need the one */ TableGetGc(display, window, tagPtr, &tagGc); /* if this is the active cell, use the buffer */ if (activeCell) { string = tablePtr->activeBuf; } else { /* Is there a value in the cell? If so, draw it */ string = TableGetCellValue(tablePtr, urow, ucol); } #ifdef TCL_UTF_MAX /* * We have to use strlen here because otherwise it stops * at the first \x00 unicode char it finds (!= '\0'), * although there can be more to the string than that */ numBytes = Tcl_NumUtfChars(string, strlen(string)); #else numBytes = strlen(string); #endif /* If there is a string, show it */ if (activeCell || numBytes) { /* get the dimensions of the string */ textLayout = Tk_ComputeTextLayout(tagPtr->tkfont, string, numBytes, (tagPtr->wrap > 0) ? width : 0, tagPtr->justify, (tagPtr->multiline > 0) ? 0 : TK_IGNORE_NEWLINES, &itemW, &itemH); /* * Set the origin coordinates of the string to draw using * the anchor. origin represents the (x,y) coordinate of * the lower left corner of the text box, relative to the * internal (inside the border) window */ /* set the X origin first */ switch (tagPtr->anchor) { case TK_ANCHOR_NW: case TK_ANCHOR_W: case TK_ANCHOR_SW: /* western position */ originX = ipadx; break; case TK_ANCHOR_N: case TK_ANCHOR_S: case TK_ANCHOR_CENTER: /* centered position */ originX = (width - itemW) / 2; break; default: /* eastern position */ originX = width - itemW - ipadx; } /* then set the Y origin */ switch (tagPtr->anchor) { case TK_ANCHOR_N: case TK_ANCHOR_NE: case TK_ANCHOR_NW: /* northern position */ originY = ipady; break; case TK_ANCHOR_W: case TK_ANCHOR_E: case TK_ANCHOR_CENTER: /* centered position */ originY = (height - itemH) / 2; break; default: /* southern position */ originY = height - itemH - ipady; } /* * If this is the active cell and we are editing, * ensure that the cursor will be displayed */ if (activeCell) { Tk_CharBbox(textLayout, tablePtr->icursor, &cx, &cy, &cw, &ch); /* we have to fudge with maxW because of odd width * determination for newlines at the end of a line */ maxW = width - tablePtr->insertWidth - (cx + MIN(tablePtr->charWidth, cw)); maxH = height - (cy + ch); if (originX < bd[0] - cx) { /* cursor off cell to the left */ /* use western positioning to cet cursor at left * with slight variation to show some text */ originX = bd[0] - cx + MIN(cx, width - tablePtr->insertWidth); } else if (originX > maxW) { /* cursor off cell to the right */ /* use eastern positioning to cet cursor at right */ originX = maxW; } if (originY < bd[2] - cy) { /* cursor before top of cell */ /* use northern positioning to cet cursor at top */ originY = bd[2] - cy; } else if (originY > maxH) { /* cursor beyond bottom of cell */ /* use southern positioning to cet cursor at bottom */ originY = maxH; } tablePtr->activeTagPtr = tagPtr; tablePtr->activeX = originX; tablePtr->activeY = originY; } /* * Use a clip rectangle only if necessary as it means * updating the GC in the server which slows everything down. * We can't fudge the width or height, just in case the user * wanted empty pad space. */ if ((originX < 0) || (originY < 0) || (originX+itemW > width) || (originY+itemH > height)) { /* * The text wants to overflow the boundaries of the * displayed cell, so we must clip in some way */ #ifdef NO_XSETCLIP /* * This code is basically for the Macintosh. * Copy the the current contents of the cell into the * clipped window area. This keeps any fg/bg and image * data intact. */ XCopyArea(display, window, clipWind, tagGc, x, y, width + bd[0] + bd[1] + (2 * padx), height + bd[2] + bd[3] + (2 * pady), 0, 0); /* * Now draw into the cell space on the special window. * Don't use x,y base offset for clipWind. */ Tk_DrawTextLayout(display, clipWind, tagGc, textLayout, 0 + originX + bd[0] + padx, 0 + originY + bd[2] + pady, 0, -1); /* * Now copy back only the area that we want the * text to be drawn on. */ XCopyArea(display, clipWind, window, tagGc, bd[0] + padx, bd[2] + pady, width, height, x + bd[0] + padx, y + bd[2] + pady); #elif defined(WIN32) /* * This is evil, evil evil! but the XCopyArea * doesn't work in all cases - Michael Teske. * The general structure follows the comments below. */ TkWinDrawable *twdPtr = (TkWinDrawable *) window; HDC dc = GetDC(twdPtr->window.handle); HRGN clipR; clipR = CreateRectRgn(x + bd[0] + padx, y + bd[2] + pady, x + bd[0] + padx + width, y + bd[2] + pady + height); SelectClipRgn(dc, clipR); OffsetClipRgn(dc, 0, 0); Tk_DrawTextLayout(display, window, tagGc, textLayout, x + originX + bd[0] + padx, y + originY + bd[2] + pady, 0, -1); SelectClipRgn(dc, NULL); DeleteObject(clipR); #else /* * Use an X clipping rectangle. The clipping is the * rectangle just for the actual text space (to allow * for empty padding space). */ clipRect.x = x + bd[0] + padx; clipRect.y = y + bd[2] + pady; clipRect.width = width; clipRect.height = height; XSetClipRectangles(display, tagGc, 0, 0, &clipRect, 1, Unsorted); Tk_DrawTextLayout(display, window, tagGc, textLayout, x + originX + bd[0] + padx, y + originY + bd[2] + pady, 0, -1); XSetClipMask(display, tagGc, None); #endif } else { Tk_DrawTextLayout(display, window, tagGc, textLayout, x + originX + bd[0] + padx, y + originY + bd[2] + pady, 0, -1); } /* if this is the active cell draw the cursor if it's on. * this ignores clip rectangles. */ if (activeCell && (tablePtr->flags & CURSOR_ON) && (originY + cy + bd[2] + pady < height) && (originX + cx + bd[0] + padx - (tablePtr->insertWidth / 2) >= 0)) { /* make sure it will fit in the box */ maxW = MAX(0, originY + cy + bd[2] + pady); maxH = MIN(ch, height - maxW + bd[2] + pady); Tk_Fill3DRectangle(tkwin, window, tablePtr->insertBg, x + originX + cx + bd[0] + padx - (tablePtr->insertWidth/2), y + maxW, tablePtr->insertWidth, maxH, 0, TK_RELIEF_FLAT); } } /* * Re-Correct the dimensions before border drawing */ width += bd[0] + bd[1] + (2 * padx); height += bd[2] + bd[3] + (2 * pady); DrawBorder: /* Draw the 3d border on the pixmap correctly offset */ if (tablePtr->drawMode == DRAW_MODE_SINGLE) { topGc = Tk_3DBorderGC(tkwin, tagPtr->bg, TK_3D_DARK_GC); /* draw a line with single pixel width */ rect[0].x = x; rect[0].y = y + height - 1; rect[1].y = -height + 1; rect[2].x = width - 1; XDrawLines(display, window, topGc, rect, 3, CoordModePrevious); } else if (tablePtr->drawMode == DRAW_MODE_FAST) { /* * This depicts a full 1 pixel border. * * Choose the GCs to get the best approximation * to the desired drawing style. */ switch(tagPtr->relief) { case TK_RELIEF_FLAT: topGc = bottomGc = Tk_3DBorderGC(tkwin, tagPtr->bg, TK_3D_FLAT_GC); break; case TK_RELIEF_RAISED: case TK_RELIEF_RIDGE: topGc = Tk_3DBorderGC(tkwin, tagPtr->bg, TK_3D_LIGHT_GC); bottomGc = Tk_3DBorderGC(tkwin, tagPtr->bg, TK_3D_DARK_GC); break; default: /* TK_RELIEF_SUNKEN TK_RELIEF_GROOVE */ bottomGc = Tk_3DBorderGC(tkwin, tagPtr->bg, TK_3D_LIGHT_GC); topGc = Tk_3DBorderGC(tkwin, tagPtr->bg, TK_3D_DARK_GC); break; } /* draw a line with single pixel width */ rect[0].x = x + width - 1; rect[0].y = y; rect[1].y = height - 1; rect[2].x = -width + 1; XDrawLines(display, window, bottomGc, rect, 3, CoordModePrevious); rect[0].x = x; rect[0].y = y + height - 1; rect[1].y = -height + 1; rect[2].x = width - 1; XDrawLines(display, window, topGc, rect, 3, CoordModePrevious); } else { if (borders > 1) { if (bd[0]) { Tk_3DVerticalBevel(tkwin, window, tagPtr->bg, x, y, bd[0], height, 1 /* left side */, tagPtr->relief); } if (bd[1]) { Tk_3DVerticalBevel(tkwin, window, tagPtr->bg, x + width - bd[1], y, bd[1], height, 0 /* right side */, tagPtr->relief); } if ((borders == 4) && bd[2]) { Tk_3DHorizontalBevel(tkwin, window, tagPtr->bg, x, y, width, bd[2], 1, 1, 1 /* top */, tagPtr->relief); } if ((borders == 4) && bd[3]) { Tk_3DHorizontalBevel(tkwin, window, tagPtr->bg, x, y + height - bd[3], width, bd[3], 0, 0, 0 /* bottom */, tagPtr->relief); } } else if (borders == 1) { Tk_Draw3DRectangle(tkwin, window, tagPtr->bg, x, y, width, height, bd[0], tagPtr->relief); } } /* clean up the necessaries */ if (tagPtr == tablePtr->activeTagPtr) { /* * This means it was the activeCell with text displayed. * We buffer the active tag for the 'activate' command. */ tablePtr->activeTagPtr = TableNewTag(NULL); memcpy((VOID *) tablePtr->activeTagPtr, (VOID *) tagPtr, sizeof(TableTag)); } if (textLayout) { Tk_FreeTextLayout(textLayout); textLayout = NULL; } if (cellType == CELL_HIDDEN) { /* the last cell was a hidden one, * rework row stuff back to normal */ row = hrow; col = hcol; urow = row+tablePtr->rowOffset; rowPtr = FindRowColTag(tablePtr, urow, ROW); } } } ckfree((char *) tagPtr); #ifdef NO_XSETCLIP Tk_FreePixmap(display, clipWind); #endif /* Take care of removing embedded windows that are no longer in view */ TableUndisplay(tablePtr); /* copy over and delete the pixmap if we are in slow mode */ if (tablePtr->drawMode == DRAW_MODE_SLOW) { /* Get a default valued GC */ TableGetGc(display, window, &(tablePtr->defaultTag), &tagGc); XCopyArea(display, window, Tk_WindowId(tkwin), tagGc, 0, 0, invalidWidth, invalidHeight, invalidX, invalidY); Tk_FreePixmap(display, window); window = Tk_WindowId(tkwin); } /* * If we are at the end of the table, clear the area after the last * row/col. We discount spans here because we just need the coords * for the area that would be the last physical cell. */ tablePtr->flags |= AVOID_SPANS; TableCellCoords(tablePtr, tablePtr->rows-1, tablePtr->cols-1, &x, &y, &width, &height); tablePtr->flags &= ~AVOID_SPANS; /* This should occur before moving pixmap, but this simplifies things * * Could use Tk_Fill3DRectangle instead of XFillRectangle * for best compatibility, and XClearArea could be used on Unix * for best speed, so this is the compromise w/o #ifdef's */ if (x+width < invalidX+invalidWidth) { XFillRectangle(display, window, Tk_3DBorderGC(tkwin, tablePtr->defaultTag.bg, TK_3D_FLAT_GC), x+width, invalidY, invalidX+invalidWidth-x-width, invalidHeight); } if (y+height < invalidY+invalidHeight) { XFillRectangle(display, window, Tk_3DBorderGC(tkwin, tablePtr->defaultTag.bg, TK_3D_FLAT_GC), invalidX, y+height, invalidWidth, invalidY+invalidHeight-y-height); } if (tagGc != NULL) { TableFreeGc(display, tagGc); } TableRedrawHighlight(tablePtr); /* * Free the hash table used to cache evaluations. */ Tcl_DeleteHashTable(colTagsCache); ckfree((char *) (colTagsCache)); Tcl_DeleteHashTable(drawnCache); ckfree((char *) (drawnCache)); } /* *---------------------------------------------------------------------- * * TableInvalidate -- * Invalidates a rectangle and adds it to the total invalid rectangle * waiting to be redrawn. If the INV_FORCE flag bit is set, * it does an update instantly else waits until Tk is idle. * * Results: * Will schedule table (re)display. * * Side effects: * None * *---------------------------------------------------------------------- */ void TableInvalidate(Table * tablePtr, int x, int y, int w, int h, int flags) { Tk_Window tkwin = tablePtr->tkwin; int hl = tablePtr->highlightWidth; int height = Tk_Height(tkwin); int width = Tk_Width(tkwin); /* * Make sure that the window hasn't been destroyed already. * Avoid allocating 0 sized pixmaps which would be fatal, * and check if rectangle is even on the screen. */ if ((tkwin == NULL) || (w <= 0) || (h <= 0) || (x > width) || (y > height)) { return; } /* If not even mapped, wait for the remap to redraw all */ if (!Tk_IsMapped(tkwin)) { tablePtr->flags |= REDRAW_ON_MAP; return; } /* * If no pending updates exist, then replace the rectangle. * Otherwise find the bounding rectangle. */ if ((flags & INV_HIGHLIGHT) && (x < hl || y < hl || x+w >= width-hl || y+h >= height-hl)) { tablePtr->flags |= REDRAW_BORDER; } if (tablePtr->flags & REDRAW_PENDING) { tablePtr->invalidWidth = MAX(x + w, tablePtr->invalidX+tablePtr->invalidWidth); tablePtr->invalidHeight = MAX(y + h, tablePtr->invalidY+tablePtr->invalidHeight); if (tablePtr->invalidX > x) tablePtr->invalidX = x; if (tablePtr->invalidY > y) tablePtr->invalidY = y; tablePtr->invalidWidth -= tablePtr->invalidX; tablePtr->invalidHeight -= tablePtr->invalidY; /* Do we want to force this update out? */ if (flags & INV_FORCE) { Tcl_CancelIdleCall(TableDisplay, (ClientData) tablePtr); TableDisplay((ClientData) tablePtr); } } else { tablePtr->invalidX = x; tablePtr->invalidY = y; tablePtr->invalidWidth = w; tablePtr->invalidHeight = h; if (flags & INV_FORCE) { TableDisplay((ClientData) tablePtr); } else { tablePtr->flags |= REDRAW_PENDING; Tcl_DoWhenIdle(TableDisplay, (ClientData) tablePtr); } } } /* *---------------------------------------------------------------------- * * TableFlashEvent -- * Called when the flash timer goes off. * * Results: * Decrements all the entries in the hash table and invalidates * any cells that expire, deleting them from the table. If the * table is now empty, stops the timer, else reenables it. * * Side effects: * None. * *---------------------------------------------------------------------- */ static void TableFlashEvent(ClientData clientdata) { Table *tablePtr = (Table *) clientdata; Tcl_HashEntry *entryPtr; Tcl_HashSearch search; int entries, count, row, col; entries = 0; for (entryPtr = Tcl_FirstHashEntry(tablePtr->flashCells, &search); entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { count = (int) Tcl_GetHashValue(entryPtr); if (--count <= 0) { /* get the cell address and invalidate that region only */ TableParseArrayIndex(&row, &col, Tcl_GetHashKey(tablePtr->flashCells, entryPtr)); /* delete the entry from the table */ Tcl_DeleteHashEntry(entryPtr); TableRefresh(tablePtr, row-tablePtr->rowOffset, col-tablePtr->colOffset, CELL); } else { Tcl_SetHashValue(entryPtr, (ClientData) count); entries++; } } /* do I need to restart the timer */ if (entries && tablePtr->flashMode) { tablePtr->flashTimer = Tcl_CreateTimerHandler(250, TableFlashEvent, (ClientData) tablePtr); } else { tablePtr->flashTimer = 0; } } /* *---------------------------------------------------------------------- * * TableAddFlash -- * Adds a flash on cell row,col (real coords) with the default timeout * if flashing is enabled and flashtime > 0. * * Results: * Cell will flash. * * Side effects: * Will start flash timer if it didn't exist. * *---------------------------------------------------------------------- */ void TableAddFlash(Table *tablePtr, int row, int col) { char buf[INDEX_BUFSIZE]; int dummy; Tcl_HashEntry *entryPtr; if (!tablePtr->flashMode || tablePtr->flashTime < 1) { return; } /* create the array index in user coords */ TableMakeArrayIndex(row+tablePtr->rowOffset, col+tablePtr->colOffset, buf); /* add the flash to the hash table */ entryPtr = Tcl_CreateHashEntry(tablePtr->flashCells, buf, &dummy); Tcl_SetHashValue(entryPtr, tablePtr->flashTime); /* now set the timer if it's not already going and invalidate the area */ if (tablePtr->flashTimer == NULL) { tablePtr->flashTimer = Tcl_CreateTimerHandler(250, TableFlashEvent, (ClientData) tablePtr); } } /* *---------------------------------------------------------------------- * * TableSetActiveIndex -- * Sets the "active" index of the associated array to the current * value of the active buffer. * * Results: * None. * * Side effects: * Traces on the array can cause side effects. * *---------------------------------------------------------------------- */ void TableSetActiveIndex(register Table *tablePtr) { if (tablePtr->arrayVar) { tablePtr->flags |= SET_ACTIVE; Tcl_ObjSetVar2(tablePtr->interp, tablePtr->arrayVar, Tcl_NewStringObj("active",-1), Tcl_NewStringObj(tablePtr->activeBuf,-1), TCL_GLOBAL_ONLY); tablePtr->flags &= ~SET_ACTIVE; } } /* *---------------------------------------------------------------------- * * TableGetActiveBuf -- * Get the current selection into the buffer and mark it as unedited. * Set the position to the end of the string. * * Results: * None. * * Side effects: * tablePtr->activeBuf will change. * *---------------------------------------------------------------------- */ void TableGetActiveBuf(register Table *tablePtr) { char *data = ""; if (tablePtr->flags & HAS_ACTIVE) { data = TableGetCellValue(tablePtr, tablePtr->activeRow+tablePtr->rowOffset, tablePtr->activeCol+tablePtr->colOffset); } if (STREQ(tablePtr->activeBuf, data)) { /* this forced SetActiveIndex is necessary if we change array vars and * they happen to have these cells equal, we won't properly set the * active index for the new array var unless we do this here */ TableSetActiveIndex(tablePtr); return; } /* is the buffer long enough */ tablePtr->activeBuf = (char *)ckrealloc(tablePtr->activeBuf, strlen(data)+1); strcpy(tablePtr->activeBuf, data); TableGetIcursor(tablePtr, "end", (int *)0); tablePtr->flags &= ~TEXT_CHANGED; TableSetActiveIndex(tablePtr); } /* *---------------------------------------------------------------------- * * TableVarProc -- * This is the trace procedure associated with the Tcl array. No * validation will occur here because this only triggers when the * array value is directly set, and we can't maintain the old value. * * Results: * Invalidates changed cell. * * Side effects: * Creates/Updates entry in the cache if we are caching. * *---------------------------------------------------------------------- */ static char * TableVarProc(clientData, interp, name, index, flags) ClientData clientData; /* Information about table. */ Tcl_Interp *interp; /* Interpreter containing variable. */ Var name; /* Not used. */ char *index; /* Not used. */ int flags; /* Information about what happened. */ { Table *tablePtr = (Table *) clientData; int row, col, update = 1; /* This is redundant, as the name should always == arrayVar */ name = tablePtr->arrayVar; /* is this the whole var being destroyed or just one cell being deleted */ if ((flags & TCL_TRACE_UNSETS) && index == NULL) { /* if this isn't the interpreter being destroyed reinstate the trace */ if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) { Tcl_ObjSetVar2(interp, name, Tcl_NewStringObj(TEST_KEY,-1), Tcl_NewStringObj("",-1), TCL_GLOBAL_ONLY); /* Perltk not supported */ /* Tcl_UnsetVar2(interp, LangString(Tcl_GetVar(interp, name, TCL_GLOBAL_ONLY)), TEST_KEY, TCL_GLOBAL_ONLY); */ Tcl_ResetResult(interp); /* set a trace on the variable */ Lang_TraceVar(interp, name, TCL_TRACE_WRITES | TCL_TRACE_UNSETS | TCL_GLOBAL_ONLY, (Lang_VarTraceProc *)TableVarProc, (ClientData) tablePtr); /* only do the following if arrayVar is our data source */ if (tablePtr->dataSource & DATA_ARRAY) { /* clear the selection buffer */ TableGetActiveBuf(tablePtr); /* flush any cache */ Table_ClearHashTable(tablePtr->cache); Tcl_InitHashTable(tablePtr->cache, TCL_STRING_KEYS); /* and invalidate the table */ TableInvalidateAll(tablePtr, 0); } } return NULL; } /* only continue if arrayVar is our data source */ if (!(tablePtr->dataSource & DATA_ARRAY)) { return NULL; } /* get the cell address and invalidate that region only. * Make sure that it is a valid cell address. */ if (STREQ("active", index)) { if (tablePtr->flags & SET_ACTIVE) { /* If we are already setting the active cell, the update * will occur in other code */ update = 0; } else { /* modified TableGetActiveBuf */ CONST char *data = ""; row = tablePtr->activeRow; col = tablePtr->activeCol; if (tablePtr->flags & HAS_ACTIVE) data = Tcl_GetString(Tcl_ObjGetVar2(interp, name, Tcl_NewStringObj(index,-1), TCL_GLOBAL_ONLY)); if (!data) data = ""; if (STREQ(tablePtr->activeBuf, data)) { return NULL; } tablePtr->activeBuf = (char *)ckrealloc(tablePtr->activeBuf, strlen(data)+1); strcpy(tablePtr->activeBuf, data); /* set cursor to the last char */ TableGetIcursor(tablePtr, "end", (int *)0); tablePtr->flags |= TEXT_CHANGED; } } else if (TableParseArrayIndex(&row, &col, index) == 2) { char buf[INDEX_BUFSIZE]; /* Make sure it won't trigger on array(2,3extrastuff) */ TableMakeArrayIndex(row, col, buf); if (strcmp(buf, index)) { return NULL; } if (tablePtr->caching) { Tcl_HashEntry *entryPtr; int new; char *val, *data; entryPtr = Tcl_CreateHashEntry(tablePtr->cache, buf, &new); if (!new) { data = (char *) Tcl_GetHashValue(entryPtr); if (data) { ckfree(data); } } data = Tcl_GetString(Tcl_ObjGetVar2(interp, name, Tcl_NewStringObj(index,-1), TCL_GLOBAL_ONLY)); if (!data) data = ""; val = (char *)ckalloc(strlen(data)+1); strcpy(val, data); Tcl_SetHashValue(entryPtr, val); } /* convert index to real coords */ row -= tablePtr->rowOffset; col -= tablePtr->colOffset; /* did the active cell just update */ if (row == tablePtr->activeRow && col == tablePtr->activeCol) { TableGetActiveBuf(tablePtr); } /* Flash the cell */ TableAddFlash(tablePtr, row, col); } else { return NULL; } if (update) { TableRefresh(tablePtr, row, col, CELL); } return NULL; } /* *---------------------------------------------------------------------- * * TableGeometryRequest -- * This procedure is invoked to request a new geometry from Tk. * * Results: * None. * * Side effects: * Geometry information is updated and a new requested size is * registered for the widget. Internal border info is also set. * *---------------------------------------------------------------------- */ void TableGeometryRequest(tablePtr) register Table *tablePtr; { int x, y; /* Do the geometry request * If -width #cols was not specified or it is greater than the real * number of cols, use maxWidth as a lower bound, with the other lower * bound being the upper bound of the window's user-set width and the * value of -maxwidth set by the programmer * Vice versa for rows/height */ x = MIN((tablePtr->maxReqCols==0 || tablePtr->maxReqCols > tablePtr->cols)? tablePtr->maxWidth : tablePtr->colStarts[tablePtr->maxReqCols], tablePtr->maxReqWidth) + 2*tablePtr->highlightWidth; y = MIN((tablePtr->maxReqRows==0 || tablePtr->maxReqRows > tablePtr->rows)? tablePtr->maxHeight : tablePtr->rowStarts[tablePtr->maxReqRows], tablePtr->maxReqHeight) + 2*tablePtr->highlightWidth; Tk_GeometryRequest(tablePtr->tkwin, x, y); } /* *---------------------------------------------------------------------- * * TableAdjustActive -- * This procedure is called by AdjustParams and CMD_ACTIVATE to * move the active cell. * * Results: * Old and new active cell indices will be invalidated. * * Side effects: * If the old active cell index was edited, it will be saved. * The active buffer will be updated. * *---------------------------------------------------------------------- */ void TableAdjustActive(tablePtr) register Table *tablePtr; /* Widget record for table */ { if (tablePtr->flags & HAS_ACTIVE) { /* * Make sure the active cell has a reasonable real index */ CONSTRAIN(tablePtr->activeRow, 0, tablePtr->rows-1); CONSTRAIN(tablePtr->activeCol, 0, tablePtr->cols-1); } /* * Check the new value of active cell against the original, * Only invalidate if it changed. */ if (tablePtr->oldActRow == tablePtr->activeRow && tablePtr->oldActCol == tablePtr->activeCol) { return; } if (tablePtr->oldActRow >= 0 && tablePtr->oldActCol >= 0) { /* * Set the value of the old active cell to the active buffer * SetCellValue will check if the value actually changed */ if (tablePtr->flags & TEXT_CHANGED) { /* WARNING an outside trace will be triggered here and if it * calls something that causes TableAdjustParams to be called * again, we are in data consistency trouble */ /* HACK - turn TEXT_CHANGED off now to possibly avoid the * above data inconsistency problem. */ tablePtr->flags &= ~TEXT_CHANGED; TableSetCellValue(tablePtr, tablePtr->oldActRow + tablePtr->rowOffset, tablePtr->oldActCol + tablePtr->colOffset, tablePtr->activeBuf); } /* * Invalidate the old active cell */ TableRefresh(tablePtr, tablePtr->oldActRow, tablePtr->oldActCol, CELL); } /* * Store the new active cell value into the active buffer */ TableGetActiveBuf(tablePtr); /* * Invalidate the new active cell */ TableRefresh(tablePtr, tablePtr->activeRow, tablePtr->activeCol, CELL); /* * Cache the old active row/col for the next time this is called */ tablePtr->oldActRow = tablePtr->activeRow; tablePtr->oldActCol = tablePtr->activeCol; } /* *---------------------------------------------------------------------- * * TableAdjustParams -- * Calculate the row and column starts. Adjusts the topleft corner * variable to keep it within the screen range, out of the titles * and keep the screen full make sure the selected cell is in the * visible area checks to see if the top left cell has changed at * all and invalidates the table if it has. * * Results: * None. * * Side Effects: * Number of rows can change if -rowstretchmode == fill. * topRow && leftCol can change to fit display. * activeRow/Col can change to ensure it is a valid cell. * *---------------------------------------------------------------------- */ void TableAdjustParams(register Table *tablePtr) { int topRow, leftCol, row, col, total, i, value, x, y, width, height, w, h, hl, px, py, recalc, bd[4], diff, unpreset, lastUnpreset, pad, lastPad, numPixels, defColWidth, defRowHeight; Tcl_HashEntry *entryPtr; /* * Cache some values for many upcoming calculations */ hl = tablePtr->highlightWidth; w = Tk_Width(tablePtr->tkwin) - (2 * hl); h = Tk_Height(tablePtr->tkwin) - (2 * hl); TableGetTagBorders(&(tablePtr->defaultTag), &bd[0], &bd[1], &bd[2], &bd[3]); px = bd[0] + bd[1] + (2 * tablePtr->padX); py = bd[2] + bd[3] + (2 * tablePtr->padY); /* * Account for whether default dimensions are in chars (>0) or * pixels (<=0). Border and Pad space is added in here for convenience. * * When a value in pixels is specified, we take that exact amount, * not adding in padding. */ if (tablePtr->defColWidth > 0) { defColWidth = tablePtr->charWidth * tablePtr->defColWidth + px; } else { defColWidth = -(tablePtr->defColWidth); } if (tablePtr->defRowHeight > 0) { defRowHeight = tablePtr->charHeight * tablePtr->defRowHeight + py; } else { defRowHeight = -(tablePtr->defRowHeight); } /* * Set up the arrays to hold the col pixels and starts. * ckrealloc was fixed in 8.2.1 to handle NULLs, so we can't rely on it. */ if (tablePtr->colPixels) ckfree((char *) tablePtr->colPixels); tablePtr->colPixels = (int *) ckalloc(tablePtr->cols * sizeof(int)); if (tablePtr->colStarts) ckfree((char *) tablePtr->colStarts); tablePtr->colStarts = (int *) ckalloc((tablePtr->cols+1) * sizeof(int)); /* * Get all the preset columns and set their widths */ lastUnpreset = 0; numPixels = 0; unpreset = 0; for (i = 0; i < tablePtr->cols; i++) { entryPtr = Tcl_FindHashEntry(tablePtr->colWidths, (char *) i); if (entryPtr == NULL) { tablePtr->colPixels[i] = -1; unpreset++; lastUnpreset = i; } else { value = (int) Tcl_GetHashValue(entryPtr); if (value > 0) { tablePtr->colPixels[i] = value * tablePtr->charWidth + px; } else { /* * When a value in pixels is specified, we take that exact * amount, not adding in pad or border values. */ tablePtr->colPixels[i] = -value; } numPixels += tablePtr->colPixels[i]; } } /* * Work out how much to pad each col depending on the mode. */ diff = w - numPixels - (unpreset * defColWidth); total = 0; /* * Now do the padding and calculate the column starts. * Diff lower than 0 means we can't see the entire set of columns, * thus no special stretching will occur & we optimize the calculation. */ if (diff <= 0) { for (i = 0; i < tablePtr->cols; i++) { if (tablePtr->colPixels[i] == -1) { tablePtr->colPixels[i] = defColWidth; } tablePtr->colStarts[i] = total; total += tablePtr->colPixels[i]; } } else { switch (tablePtr->colStretch) { case STRETCH_MODE_NONE: pad = 0; lastPad = 0; break; case STRETCH_MODE_UNSET: if (unpreset == 0) { pad = 0; lastPad = 0; } else { pad = diff / unpreset; lastPad = diff - pad * (unpreset - 1); } break; case STRETCH_MODE_LAST: pad = 0; lastPad = diff; lastUnpreset = tablePtr->cols - 1; break; default: /* STRETCH_MODE_ALL, but also FILL for cols */ pad = diff / tablePtr->cols; /* force it to be applied to the last column too */ lastUnpreset = tablePtr->cols - 1; lastPad = diff - pad * lastUnpreset; } for (i = 0; i < tablePtr->cols; i++) { if (tablePtr->colPixels[i] == -1) { tablePtr->colPixels[i] = defColWidth + ((i == lastUnpreset) ? lastPad : pad); } else if (tablePtr->colStretch == STRETCH_MODE_ALL) { tablePtr->colPixels[i] += (i == lastUnpreset) ? lastPad : pad; } tablePtr->colStarts[i] = total; total += tablePtr->colPixels[i]; } } tablePtr->colStarts[i] = tablePtr->maxWidth = total; /* * The 'do' loop is only necessary for rows because of FILL mode */ recalc = 0; do { /* Set up the arrays to hold the row pixels and starts */ /* FIX - this can be moved outside 'do' if you check >row size */ if (tablePtr->rowPixels) ckfree((char *) tablePtr->rowPixels); tablePtr->rowPixels = (int *) ckalloc(tablePtr->rows * sizeof(int)); /* get all the preset rows and set their heights */ lastUnpreset = 0; numPixels = 0; unpreset = 0; for (i = 0; i < tablePtr->rows; i++) { entryPtr = Tcl_FindHashEntry(tablePtr->rowHeights, (char *) i); if (entryPtr == NULL) { tablePtr->rowPixels[i] = -1; unpreset++; lastUnpreset = i; } else { value = (int) Tcl_GetHashValue(entryPtr); if (value > 0) { tablePtr->rowPixels[i] = value * tablePtr->charHeight + py; } else { /* * When a value in pixels is specified, we take that exact * amount, not adding in pad or border values. */ tablePtr->rowPixels[i] = -value; } numPixels += tablePtr->rowPixels[i]; } } /* work out how much to pad each row depending on the mode */ diff = h - numPixels - (unpreset * defRowHeight); switch(tablePtr->rowStretch) { case STRETCH_MODE_NONE: pad = 0; lastPad = 0; break; case STRETCH_MODE_UNSET: if (unpreset == 0) { pad = 0; lastPad = 0; } else { pad = MAX(0,diff) / unpreset; lastPad = MAX(0,diff) - pad * (unpreset - 1); } break; case STRETCH_MODE_LAST: pad = 0; lastPad = MAX(0,diff); /* force it to be applied to the last column too */ lastUnpreset = tablePtr->rows - 1; break; case STRETCH_MODE_FILL: pad = 0; lastPad = diff; if (diff && !recalc) { tablePtr->rows += (diff/defRowHeight); if (diff < 0 && tablePtr->rows <= 0) { tablePtr->rows = 1; } lastUnpreset = tablePtr->rows - 1; recalc = 1; continue; } else { lastUnpreset = tablePtr->rows - 1; recalc = 0; } break; default: /* STRETCH_MODE_ALL */ pad = MAX(0,diff) / tablePtr->rows; /* force it to be applied to the last column too */ lastUnpreset = tablePtr->rows - 1; lastPad = MAX(0,diff) - pad * lastUnpreset; } } while (recalc); if (tablePtr->rowStarts) ckfree((char *) tablePtr->rowStarts); tablePtr->rowStarts = (int *) ckalloc((tablePtr->rows+1)*sizeof(int)); /* * Now do the padding and calculate the row starts */ total = 0; for (i = 0; i < tablePtr->rows; i++) { if (tablePtr->rowPixels[i] == -1) { tablePtr->rowPixels[i] = defRowHeight + ((i==lastUnpreset)?lastPad:pad); } else if (tablePtr->rowStretch == STRETCH_MODE_ALL) { tablePtr->rowPixels[i] += (i==lastUnpreset)?lastPad:pad; } /* calculate the start of each row */ tablePtr->rowStarts[i] = total; total += tablePtr->rowPixels[i]; } tablePtr->rowStarts[i] = tablePtr->maxHeight = total; /* * Make sure the top row and col have reasonable real indices */ CONSTRAIN(tablePtr->topRow, tablePtr->titleRows, tablePtr->rows-1); CONSTRAIN(tablePtr->leftCol, tablePtr->titleCols, tablePtr->cols-1); /* * If we don't have the info, don't bother to fix up the other parameters */ if (Tk_WindowId(tablePtr->tkwin) == None) { tablePtr->oldTopRow = tablePtr->oldLeftCol = -1; return; } topRow = tablePtr->topRow; leftCol = tablePtr->leftCol; w += hl; h += hl; /* * If we use this value of topRow, will we fill the window? * if not, decrease it until we will, or until it gets to titleRows * make sure we don't cut off the bottom row */ for (; topRow > tablePtr->titleRows; topRow--) { if ((tablePtr->maxHeight-(tablePtr->rowStarts[topRow-1] - tablePtr->rowStarts[tablePtr->titleRows])) > h) { break; } } /* * If we use this value of topCol, will we fill the window? * if not, decrease it until we will, or until it gets to titleCols * make sure we don't cut off the left column */ for (; leftCol > tablePtr->titleCols; leftCol--) { if ((tablePtr->maxWidth-(tablePtr->colStarts[leftCol-1] - tablePtr->colStarts[tablePtr->titleCols])) > w) { break; } } tablePtr->topRow = topRow; tablePtr->leftCol = leftCol; /* * Now work out where the bottom right is for scrollbar update and to test * for one last stretch. Avoid the confusion that spans could cause for * determining the last cell dimensions. */ tablePtr->flags |= AVOID_SPANS; TableGetLastCell(tablePtr, &row, &col); TableCellVCoords(tablePtr, row, col, &x, &y, &width, &height, 0); tablePtr->flags &= ~AVOID_SPANS; /* * Do we have scrollbars, if so, calculate and call the TCL functions In * order to get the scrollbar to be completely full when the whole screen * is shown and there are titles, we have to arrange for the scrollbar * range to be 0 -> rows-titleRows etc. This leads to the position * setting methods, toprow and leftcol, being relative to the titles, not * absolute row and column numbers. */ if (tablePtr->yScrollCmd != NULL || tablePtr->xScrollCmd != NULL) { Tcl_Interp *interp = tablePtr->interp; char buf[INDEX_BUFSIZE]; double first, last; /* * We must hold onto the interpreter because the data referred to at * tablePtr might be freed as a result of the call to Tcl_VarEval. */ Tcl_Preserve((ClientData) interp); /* Do we have a Y-scrollbar and rows to scroll? */ if (tablePtr->yScrollCmd != NULL) { if (row < tablePtr->titleRows) { first = 0; last = 1; } else { diff = tablePtr->rowStarts[tablePtr->titleRows]; last = (double) (tablePtr->rowStarts[tablePtr->rows]-diff); if (last <= 0.0) { first = 0; last = 1; } else { first = (tablePtr->rowStarts[topRow]-diff) / last; last = (height+tablePtr->rowStarts[row]-diff) / last; } } if ( LangDoCallback(interp,tablePtr->yScrollCmd, 0,2, " %g %g", first, last) != TCL_OK) { Tcl_AddErrorInfo(interp, "\n\t(vertical scrolling command executed by table)"); Tcl_BackgroundError(interp); } } /* Do we have a X-scrollbar and cols to scroll? */ if (tablePtr->xScrollCmd != NULL) { if (col < tablePtr->titleCols) { first = 0; last = 1; } else { diff = tablePtr->colStarts[tablePtr->titleCols]; last = (double) (tablePtr->colStarts[tablePtr->cols]-diff); if (last <= 0.0) { first = 0; last = 1; } else { first = (tablePtr->colStarts[leftCol]-diff) / last; last = (width+tablePtr->colStarts[col]-diff) / last; } } if ( LangDoCallback(interp,tablePtr->xScrollCmd, 0,2, " %g %g", first, last) != TCL_OK) { Tcl_AddErrorInfo(interp, "\n\t(horizontal scrolling command executed by table)"); Tcl_BackgroundError(interp); } } Tcl_Release((ClientData) interp); } /* * Adjust the last row/col to fill empty space if it is visible. * Do this after setting the scrollbars to not upset its calculations. */ if (row == tablePtr->rows-1 && tablePtr->rowStretch != STRETCH_MODE_NONE) { diff = h-(y+height); if (diff > 0) { tablePtr->rowPixels[tablePtr->rows-1] += diff; tablePtr->rowStarts[tablePtr->rows] += diff; } } if (col == tablePtr->cols-1 && tablePtr->colStretch != STRETCH_MODE_NONE) { diff = w-(x+width); if (diff > 0) { tablePtr->colPixels[tablePtr->cols-1] += diff; tablePtr->colStarts[tablePtr->cols] += diff; } } TableAdjustActive(tablePtr); /* * now check the new value of topleft cell against the originals, * If they changed, invalidate the area, else leave it alone */ if (tablePtr->topRow != tablePtr->oldTopRow || tablePtr->leftCol != tablePtr->oldLeftCol) { /* set the old top row/col for the next time this function is called */ tablePtr->oldTopRow = tablePtr->topRow; tablePtr->oldLeftCol = tablePtr->leftCol; /* only the upper corner title cells wouldn't change */ TableInvalidateAll(tablePtr, 0); } } /* *---------------------------------------------------------------------- * * TableCursorEvent -- * Toggle the cursor status. Equivalent to EntryBlinkProc. * * Results: * None. * * Side effects: * The cursor will be switched off/on. * *---------------------------------------------------------------------- */ static void TableCursorEvent(ClientData clientData) { register Table *tablePtr = (Table *) clientData; if (!(tablePtr->flags & HAS_FOCUS) || (tablePtr->insertOffTime == 0) || (tablePtr->flags & ACTIVE_DISABLED) || (tablePtr->state != STATE_NORMAL)) { return; } if (tablePtr->cursorTimer != NULL) { Tcl_DeleteTimerHandler(tablePtr->cursorTimer); } tablePtr->cursorTimer = Tcl_CreateTimerHandler((tablePtr->flags & CURSOR_ON) ? tablePtr->insertOffTime : tablePtr->insertOnTime, TableCursorEvent, (ClientData) tablePtr); /* Toggle the cursor */ tablePtr->flags ^= CURSOR_ON; /* invalidate the cell */ TableRefresh(tablePtr, tablePtr->activeRow, tablePtr->activeCol, CELL); } /* *---------------------------------------------------------------------- * * TableConfigCursor -- * Configures the timer depending on the state of the table. * Equivalent to EntryFocusProc. * * Results: * None. * * Side effects: * The cursor will be switched off/on. * *---------------------------------------------------------------------- */ void TableConfigCursor(register Table *tablePtr) { /* * To have a cursor, we have to have focus and allow edits */ if ((tablePtr->flags & HAS_FOCUS) && (tablePtr->state == STATE_NORMAL) && !(tablePtr->flags & ACTIVE_DISABLED)) { /* * Turn the cursor ON */ if (!(tablePtr->flags & CURSOR_ON)) { tablePtr->flags |= CURSOR_ON; /* * Only refresh when we toggled cursor */ TableRefresh(tablePtr, tablePtr->activeRow, tablePtr->activeCol, CELL); } /* set up the first timer */ if (tablePtr->insertOffTime != 0) { /* make sure nothing existed */ Tcl_DeleteTimerHandler(tablePtr->cursorTimer); tablePtr->cursorTimer = Tcl_CreateTimerHandler(tablePtr->insertOnTime, TableCursorEvent, (ClientData) tablePtr); } } else { /* * Turn the cursor OFF */ if ((tablePtr->flags & CURSOR_ON)) { tablePtr->flags &= ~CURSOR_ON; TableRefresh(tablePtr, tablePtr->activeRow, tablePtr->activeCol, CELL); } /* and disable the timer */ if (tablePtr->cursorTimer != NULL) { Tcl_DeleteTimerHandler(tablePtr->cursorTimer); } tablePtr->cursorTimer = NULL; } } /* *---------------------------------------------------------------------- * * TableFetchSelection -- * This procedure is called back by Tk when the selection is * requested by someone. It returns part or all of the selection * in a buffer provided by the caller. * * Results: * The return value is the number of non-NULL bytes stored * at buffer. Buffer is filled (or partially filled) with a * NULL-terminated string containing part or all of the selection, * as given by offset and maxBytes. * * Side effects: * None. * *---------------------------------------------------------------------- */ static int SelectionFetched = 0; /* Flag = 1 if a selection has been fetched before */ static int TableFetchSelection(clientData, offset, buffer, maxBytes) ClientData clientData; /* Information about table widget. */ int offset; /* Offset within selection of first * character to be returned. */ char *buffer; /* Location in which to place selection. */ int maxBytes; /* Maximum number of bytes to place at buffer, * not including terminating NULL. */ { register Table *tablePtr = (Table *) clientData; Tcl_Interp *interp = tablePtr->interp; char *data, *rowsep = tablePtr->rowSep, *colsep = tablePtr->colSep; /* We keep a static selection around so we don't have to remake the selection if we are getting the selection in chunks (i.e. offset != 0) */ static Tcl_DString selection; Tcl_HashEntry *entryPtr; Tcl_HashSearch search; int length, count, lastrow=0, needcs=0, r, c, listArgc, rslen=0, cslen=0; int numcols, numrows; Arg *listArgv; Arg value; /* if we are not exporting the selection || * we have no data source, return */ if (!tablePtr->exportSelection || (tablePtr->dataSource == DATA_NONE)) { return -1; } if( offset == 0){ /* First Time thru, get the selection, otherwise, just use the selection obtained before */ Tk_Cursor existingCursor; existingCursor = tablePtr->cursor; /* Set Cursor to wait, becuase this can take some time for large selections */ /* tablePtr->cursor = Tk_GetCursor(interp, tablePtr->tkwin, LangStringArg("watch")); */ Tk_DefineCursor(tablePtr->tkwin, Tk_AllocCursorFromObj(interp, tablePtr->tkwin, LangStringArg("watch"))); Tcl_DoOneEvent(TCL_DONT_WAIT); if( SelectionFetched){ /* If we have fetched a selection before, free it */ Tcl_DStringFree(&selection); } SelectionFetched = 1; /* First get a sorted list of the selected elements */ Tcl_DStringInit(&selection); for (entryPtr = Tcl_FirstHashEntry(tablePtr->selCells, &search); entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { Tcl_DStringAppendElement(&selection, Tcl_GetHashKey(tablePtr->selCells, entryPtr)); } value = TableCellSort(tablePtr, Tcl_DStringValue(&selection)); Tcl_DStringFree(&selection); if (value == NULL || Tcl_ListObjGetElements(interp, value, &listArgc, &listArgv) != TCL_OK) { Tk_DefineCursor(tablePtr->tkwin, existingCursor); /* Set Cursor Back */ return -1; } Tcl_DStringInit(&selection); rslen = (rowsep?(strlen(rowsep)):0); cslen = (colsep?(strlen(colsep)):0); numrows = numcols = 0; for (count = 0; count < listArgc; count++) { TableParseArrayIndex(&r, &c, Tcl_GetString(listArgv[count])); if (count) { if (lastrow != r) { lastrow = r; needcs = 0; if (rslen) { Tcl_DStringAppend(&selection, rowsep, rslen); /* perltk: Temporarily?? commented out, don't have a Tcl_DtringStartSublist } else { Tcl_DStringEndSublist(&selection); Tcl_DStringStartSublist(&selection); */ } ++numrows; } else { if (++needcs > numcols) numcols = needcs; } } else { lastrow = r; needcs = 0; /* perltk: Temporarily?? commented out, don't have a Tcl_DtringStartSublist if (!rslen) Tcl_DStringStartSublist(&selection); */ } data = TableGetCellValue(tablePtr, r, c); if (cslen) { if (needcs) { Tcl_DStringAppend(&selection, colsep, cslen); } Tcl_DStringAppend(&selection, data, -1); } else { Tcl_DStringAppendElement(&selection, data); } } /* perltk: Temporarily?? commented out, don't have a Tcl_DtringStartSublist if (!rslen && count) { Tcl_DStringEndSublist(&selection); } */ if (tablePtr->selCmd != NULL) { if ( LangDoCallback(interp, tablePtr->selCmd, 1, 4, "%d %d %s %d", numrows+1, numcols+1, Tcl_DStringValue(&selection), listArgc) == TCL_ERROR) { Tcl_AddErrorInfo(interp, "\n (error in table selection command)"); Tcl_BackgroundError(interp); Tk_DefineCursor(tablePtr->tkwin, existingCursor); /* Set Cursor Back */ Tcl_DStringFree(&selection); return -1; } else { Tcl_DStringFree(&selection); Tcl_DStringInit(&selection); Tcl_DStringAppendElement(&selection, Tcl_GetStringFromObj(Tcl_GetObjResult(interp),NULL)); } } Tk_DefineCursor(tablePtr->tkwin, existingCursor); /* Set Cursor Back */ } length = Tcl_DStringLength(&selection); if (length == 0){ return -1; } /* Copy the requested portion of the selection to the buffer. */ count = length - offset; if (count <= 0) { count = 0; } else { if (count > maxBytes) { count = maxBytes; } memcpy((VOID *) buffer, (VOID *) (Tcl_DStringValue(&selection) + offset), (size_t) count); } buffer[count] = '\0'; return count; } /* *---------------------------------------------------------------------- * * TableLostSelection -- * This procedure is called back by Tk when the selection is * grabbed away from a table widget. * * Results: * None. * * Side effects: * The existing selection is unhighlighted, and the window is * marked as not containing a selection. * *---------------------------------------------------------------------- */ void TableLostSelection(clientData) ClientData clientData; /* Information about table widget. */ { register Table *tablePtr = (Table *) clientData; if (tablePtr->exportSelection) { Tcl_HashEntry *entryPtr; Tcl_HashSearch search; int row, col; /* Same as SEL CLEAR ALL */ for (entryPtr = Tcl_FirstHashEntry(tablePtr->selCells, &search); entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { TableParseArrayIndex(&row, &col, Tcl_GetHashKey(tablePtr->selCells,entryPtr)); Tcl_DeleteHashEntry(entryPtr); TableRefresh(tablePtr, row-tablePtr->rowOffset, col-tablePtr->colOffset, CELL); } } } /* *---------------------------------------------------------------------- * * TableRestrictProc -- * A Tk_RestrictProc used by TableValidateChange to eliminate any * extra key input events in the event queue that * have a serial number no less than a given value. * * Results: * Returns either TK_DISCARD_EVENT or TK_DEFER_EVENT. * * Side effects: * None. * *---------------------------------------------------------------------- */ static Tk_RestrictAction TableRestrictProc(serial, eventPtr) ClientData serial; XEvent *eventPtr; { if ((eventPtr->type == KeyRelease || eventPtr->type == KeyPress) && ((eventPtr->xany.serial-(unsigned int)serial) > 0)) { return TK_DEFER_EVENT; } else { return TK_PROCESS_EVENT; } } /* *-------------------------------------------------------------- * * TableValidateChange -- * This procedure is invoked when any character is added or * removed from the table widget, or a set has triggered validation. * * Results: * TCL_OK if the validatecommand accepts the new string, * TCL_BREAK if the validatecommand rejects the new string, * TCL_ERROR if any problems occured with validatecommand. * * Side effects: * The insertion/deletion may be aborted, and the * validatecommand might turn itself off (if an error * or loop condition arises). * *-------------------------------------------------------------- */ int TableValidateChange(tablePtr, r, c, old, new, index) register Table *tablePtr; /* Table that needs validation. */ int r, c; /* row,col index of cell in user coords */ char *old; /* current value of cell */ char *new; /* potential new value of cell */ int index; /* index of insert/delete, -1 otherwise */ { register Tcl_Interp *interp = tablePtr->interp; int code, booln; /* perltk: Bool to booln to avoid problems with DEFINES*/ Tk_RestrictProc *rstrct; ClientData cdata; if (tablePtr->valCmd == NULL || tablePtr->validate == 0) { return TCL_OK; } /* Magic code to make this bit of code UI synchronous in the face of * possible new key events */ XSync(tablePtr->display, False); rstrct = Tk_RestrictEvents(TableRestrictProc, (ClientData) NextRequest(tablePtr->display), &cdata); /* * If we're already validating, then we're hitting a loop condition * Return and set validate to 0 to disallow further validations * and prevent current validation from finishing */ if (tablePtr->flags & VALIDATING) { tablePtr->validate = 0; return TCL_OK; } tablePtr->flags |= VALIDATING; code = LangDoCallback(tablePtr->interp, tablePtr->valCmd, 1, 5, "%d %d %s %s %d", r, c, old, new, index); if (code != TCL_OK && code != TCL_RETURN) { Tcl_AddErrorInfo(interp, "\n\t(in validation command executed by table)"); Tcl_BackgroundError(interp); code = TCL_ERROR; } else if (Tcl_GetBooleanFromObj(interp, Tcl_GetObjResult(interp), &booln) != TCL_OK) { Tcl_AddErrorInfo(interp, "\n\tboolean not returned by validation command"); Tcl_BackgroundError(interp); code = TCL_ERROR; } else { code = (booln) ? TCL_OK : TCL_BREAK; } Tcl_SetStringObj(Tcl_GetObjResult(interp), NULL, 0); /* * If ->validate has become VALIDATE_NONE during the validation, * it means that a loop condition almost occured. Do not allow * this validation result to finish. */ if (tablePtr->validate == 0) { code = TCL_ERROR; } /* If validate will return ERROR, then disallow further validations */ if (code == TCL_ERROR) { tablePtr->validate = 0; } Tk_RestrictEvents(rstrct, cdata, &cdata); tablePtr->flags &= ~VALIDATING; return code; } /* *-------------------------------------------------------------- * * ExpandPercents -- * Given a command and an event, produce a new command * by replacing % constructs in the original command * with information from the X event. * * Results: * The new expanded command is appended to the dynamic string * given by dsPtr. * * Side effects: * None. * *-------------------------------------------------------------- */ void ExpandPercents(tablePtr, before, r, c, old, new, index, dsPtr, cmdType) Table *tablePtr; /* Table that needs validation. */ char *before; /* Command containing percent * expressions to be replaced. */ int r, c; /* row,col index of cell */ char *old; /* current value of cell */ char *new; /* potential new value of cell */ int index; /* index of insert/delete */ Tcl_DString *dsPtr; /* Dynamic string in which to append * new command. */ int cmdType; /* type of command to make %-subs for */ { int length, spaceNeeded, cvtFlags; #ifdef TCL_UTF_MAX Tcl_UniChar ch; #else char ch; #endif char *string, buf[INDEX_BUFSIZE]; /* This returns the static value of the string as set in the array */ if (old == NULL && cmdType == CMD_VALIDATE) { old = TableGetCellValue(tablePtr, r, c); } while (1) { if (*before == '\0') { break; } /* * Find everything up to the next % character and append it * to the result string. */ string = before; #ifndef _LANG /* No need to convert '%', as it is in ascii range */ string = (char *) Tcl_UtfFindFirst(before, '%'); #else string = strchr(before, '%'); #endif if (string == NULL) { Tcl_DStringAppend(dsPtr, before, -1); break; } else if (string != before) { Tcl_DStringAppend(dsPtr, before, string-before); before = string; } /* * There's a percent sequence here. Process it. */ before++; /* skip over % */ if (*before != '\0') { #ifdef TCL_UTF_MAX before += Tcl_UtfToUniChar(before, &ch); #else ch = before[0]; before++; #endif } else { ch = '%'; } switch (ch) { case 'c': sprintf(buf, "%d", c); string = buf; break; case 'C': /* index of cell */ TableMakeArrayIndex(r, c, buf); string = buf; break; case 'r': sprintf(buf, "%d", r); string = buf; break; case 'i': /* index of cursor OR |number| of cells selected */ sprintf(buf, "%d", index); string = buf; break; case 's': /* Current cell value */ string = old; break; case 'S': /* Potential new value of cell */ string = (new?new:old); break; case 'W': /* widget name */ string = Tk_PathName(tablePtr->tkwin); break; default: #ifdef TCL_UTF_MAX length = Tcl_UniCharToUtf(ch, buf); #else buf[0] = ch; length = 1; #endif buf[length] = '\0'; string = buf; break; } /* perltk not supported */ /* spaceNeeded = Tcl_ScanElement(string, &cvtFlags); */ spaceNeeded = 0; length = Tcl_DStringLength(dsPtr); Tcl_DStringSetLength(dsPtr, length + spaceNeeded); /* perltk not supported */ /* spaceNeeded = Tcl_ConvertElement(string, Tcl_DStringValue(dsPtr) + length, cvtFlags | TCL_DONT_USE_BRACES); */ Tcl_DStringSetLength(dsPtr, length + spaceNeeded); } Tcl_DStringAppend(dsPtr, "", 1); } /* Function to call on loading the Table module */ #ifdef BUILD_Tktable # undef TCL_STORAGE_CLASS # define TCL_STORAGE_CLASS DLLEXPORT #endif #ifdef MAC_TCL #pragma export on #endif #if 0 /* perltk This not needed by perlTk */ EXTERN int Tktable_Init(interp) Tcl_Interp *interp; { /* This defines the static char initScript */ if ( #ifdef USE_TCL_STUBS Tcl_InitStubs(interp, "8.0", 0) #else Tcl_PkgRequire(interp, "Tcl", "8.0", 0) #endif == NULL) { return TCL_ERROR; } if ( #ifdef USE_TK_STUBS Tk_InitStubs(interp, "8.0", 0) #else # if (TK_MAJOR_VERSION == 8) && (TK_MINOR_VERSION == 0) /* We require 8.0 exact because of the Unicode in 8.1+ */ Tcl_PkgRequire(interp, "Tk", "8.0", 1) # else Tcl_PkgRequire(interp, "Tk", "8.0", 0) # endif #endif == NULL) { return TCL_ERROR; } if (Tcl_PkgProvide(interp, "Tktable", VERSION) != TCL_OK) { return TCL_ERROR; } Tcl_CreateObjCommand(interp, TBL_COMMAND, Tk_TableObjCmd, (ClientData) Tk_MainWindow(interp), (Tcl_CmdDeleteProc *) NULL); /* * The init script can't make certain calls in a safe interpreter, * so we always have to use the embedded runtime for it */ return Tcl_Eval(interp, Tcl_IsSafe(interp) ? tkTableSafeInitScript : tkTableInitScript); } EXTERN int Tktable_SafeInit(interp) Tcl_Interp *interp; { return Tktable_Init(interp); } #ifdef MAC_TCL #pragma export reset #endif #endif /* ifdef 0 */ #ifdef WIN32 /* *---------------------------------------------------------------------- * * DllEntryPoint -- * * This wrapper function is used by Windows to invoke the * initialization code for the DLL. If we are compiling * with Visual C++, this routine will be renamed to DllMain. * routine. * * Results: * Returns TRUE; * * Side effects: * None. * *---------------------------------------------------------------------- */ BOOL APIENTRY DllEntryPoint(hInst, reason, reserved) HINSTANCE hInst; /* Library instance handle. */ DWORD reason; /* Reason this function is being called. */ LPVOID reserved; /* Not used. */ { return TRUE; } #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mkXinfo���������������������������������������������������������������������0000644�0000000�0000000�00000002142�13742524721�015032� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/local/bin/perl -w $file = shift; @cargs = @ARGV; @ARGV = grep(!/\.ft\./,<*.c>,<xpm/*.c>); print STDERR "Scanning .c files for X functions\n"; while (<>) { if (/\b(X[A-Za-z0-9]*)\s*\(/) { $XFunc{$1} = $ARGV ; } } open(STDOUT,">$file") || die "Cannot open $file:$!"; $gard = "\U$file"; $gard =~ s/\..*$//; $gard =~ s#/#_#g; print "#ifndef _$gard\n"; print "#define _$gard\n"; print "#ifndef _${gard}_H_\n"; print STDERR "Extracting protos with gcc\n"; die if (system("gcc","-aux-info","/tmp/X-info","-S","-o","/dev/null",@cargs)); open(INFO,"</tmp/X-info") || die "Cannot open /tmp/X-info:$!"; while (<INFO>) { if (m#/X11/X[^/]*\.h:\d+:NC\s*\*/\s*(.*)$#o) { $_ = $1; if (/\b(X[A-Za-z0-9]*)\s*\(/) { if (exists $XFunc{$1}) { chomp; s/^(.*?)\(/$1 _ANSI_ARGS_((/; s/\);\s*$/));\n/; print; } } else { warn "No function:$_"; } } } close(INFO); print "#endif /* _${gard}_H_ */\n"; print "#endif /* _$gard */\n"; ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/tkTable.h�������������������������������������������������������������������0000444�0000000�0000000�00000063105�13746047614�015244� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * tkTable.h -- * * This is the header file for the module that implements * table widgets for the Tk toolkit. * * Copyright (c) 1997-2002 Jeffrey Hobbs * * See the file "license.txt" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tkTable.h,v 1.18 2004/02/08 03:09:45 cerney Exp $ */ #ifndef _TKTABLE_H_ #define _TKTABLE_H_ #include <string.h> #include <stdlib.h> #include "tk.h" #include "tkVMacro.h" #include "tkTableversion.h" #ifdef MAC_TCL # include <Xatom.h> #else # include <X11/Xatom.h> #endif /* MAC_TCL */ #if (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION == 0) /* Tcl8.0 stuff */ #define Tcl_GetString(objPtr) Tcl_GetStringFromObj(objPtr, (int *)NULL) #endif #define Arg Tcl_Obj* /* * Tcl/Tk 8.4 introduced better CONST-ness in the APIs, but we use CONST84 in * some cases for compatibility with earlier Tcl headers to prevent warnings. */ #ifndef CONST84 # define CONST84 #endif /* This EXTERN declaration is needed for Tcl < 8.0.3 */ #ifndef EXTERN # ifdef __cplusplus # define EXTERN extern "C" # else # define EXTERN extern # endif #endif #ifdef TCL_STORAGE_CLASS # undef TCL_STORAGE_CLASS #endif #ifdef BUILD_Tktable # define TCL_STORAGE_CLASS DLLEXPORT #else # define TCL_STORAGE_CLASS DLLIMPORT #endif #ifdef WIN32 # define WIN32_LEAN_AND_MEAN # include <windows.h> # undef WIN32_LEAN_AND_MEAN /* VC++ has an entry point called DllMain instead of DllEntryPoint */ # if defined(_MSC_VER) # define DllEntryPoint DllMain # endif #endif #if defined(WIN32) || defined(MAC_TCL) || defined(MAC_OSX_TK) /* XSync call defined in the internals for some reason */ # ifndef XSync # define XSync(display, bool) {display->request++;} # endif #endif /* defn of XSync */ #ifndef NORMAL_BG # ifdef WIN32 # define NORMAL_BG "SystemButtonFace" # define ACTIVE_BG NORMAL_BG # define SELECT_BG "SystemHighlight" # define SELECT_FG "SystemHighlightText" # define DISABLED "SystemDisabledText" # define HIGHLIGHT "SystemWindowFrame" # define DEF_TABLE_FONT "{MS Sans Serif} 8" # elif defined(MAC_TCL) || defined(MAC_OSX_TK) # define NORMAL_BG "systemWindowBody" # define ACTIVE_BG "#ececec" # define SELECT_BG "systemHighlight" # define SELECT_FG "systemHighlightText" # define DISABLED "#a3a3a3" # define HIGHLIGHT "Black" # define DEF_TABLE_FONT "Helvetica 12" # else # define NORMAL_BG "#d9d9d9" # define ACTIVE_BG "#fcfcfc" # define SELECT_BG "#c3c3c3" # define SELECT_FG "Black" # define DISABLED "#a3a3a3" # define HIGHLIGHT "Black" # define DEF_TABLE_FONT "Helvetica -12" # endif #endif /* NORMAL_BG */ #define MAX(A,B) (((A)>(B))?(A):(B)) #define MIN(A,B) (((A)>(B))?(B):(A)) #define BETWEEN(val,min,max) ( ((val)<(min)) ? (min) : \ ( ((val)>(max)) ? (max) : (val) ) ) #define CONSTRAIN(val,min,max) if ((val) < (min)) { (val) = (min); } \ else if ((val) > (max)) { (val) = (max); } #define STREQ(s1, s2) (strcmp((s1), (s2)) == 0) #define ARSIZE(A) (sizeof(A)/sizeof(*A)) #define INDEX_BUFSIZE 32 /* max size of buffer for indices */ #define TEST_KEY "#TEST KEY#" /* index for testing array existence */ /* * Assigned bits of "flags" fields of Table structures, and what those * bits mean: * * REDRAW_PENDING: Non-zero means a DoWhenIdle handler has * already been queued to redisplay the table. * REDRAW_BORDER: Non-zero means 3-D border must be redrawn * around window during redisplay. Normally * only text portion needs to be redrawn. * CURSOR_ON: Non-zero means insert cursor is displayed at * present. 0 means it isn't displayed. * TEXT_CHANGED: Non-zero means the active cell text is being edited. * HAS_FOCUS: Non-zero means this window has the input focus. * HAS_ACTIVE: Non-zero means the active cell is set. * HAS_ANCHOR: Non-zero means the anchor cell is set. * BROWSE_CMD: Non-zero means we're evaluating the -browsecommand. * VALIDATING: Non-zero means we are in a valCmd * SET_ACTIVE: About to set the active array element internally * ACTIVE_DISABLED: Non-zero means the active cell is -state disabled * OVER_BORDER: Non-zero means we are over a table cell border * REDRAW_ON_MAP: Forces a redraw on the unmap * AVOID_SPANS: prevent cell spans from being used * * FIX - consider adding UPDATE_SCROLLBAR a la entry */ #define REDRAW_PENDING (1L<<0) #define CURSOR_ON (1L<<1) #define HAS_FOCUS (1L<<2) #define TEXT_CHANGED (1L<<3) #define HAS_ACTIVE (1L<<4) #define HAS_ANCHOR (1L<<5) #define BROWSE_CMD (1L<<6) #define REDRAW_BORDER (1L<<7) #define VALIDATING (1L<<8) #define SET_ACTIVE (1L<<9) #define ACTIVE_DISABLED (1L<<10) #define OVER_BORDER (1L<<11) #define REDRAW_ON_MAP (1L<<12) #define AVOID_SPANS (1L<<13) /* Flags for TableInvalidate && TableRedraw */ #define ROW (1L<<0) #define COL (1L<<1) #define CELL (1L<<2) #define CELL_BAD (1<<0) #define CELL_OK (1<<1) #define CELL_SPAN (1<<2) #define CELL_HIDDEN (1<<3) #define CELL_VIEWABLE (CELL_OK|CELL_SPAN) #define INV_FILL (1L<<3) /* use for Redraw when the affected * row/col will affect neighbors */ #define INV_FORCE (1L<<4) #define INV_HIGHLIGHT (1L<<5) #define INV_NO_ERR_MSG (1L<<5) /* Don't leave an error message */ /* These alter how the selection set/clear commands behave */ #define SEL_ROW (1<<0) #define SEL_COL (1<<1) #define SEL_BOTH (1<<2) #define SEL_CELL (1<<3) #define SEL_NONE (1<<4) /* * Definitions for tablePtr->dataSource, by bit */ #define DATA_NONE 0 #define DATA_CACHE (1<<1) #define DATA_ARRAY (1<<2) #define DATA_COMMAND (1<<3) /* * Definitions for configuring -borderwidth */ #define BD_TABLE 0 #define BD_TABLE_TAG (1<<1) #define BD_TABLE_WIN (1<<2) /* * Possible state values for tags */ typedef enum { STATE_UNUSED, STATE_UNKNOWN, STATE_HIDDEN, STATE_NORMAL, STATE_DISABLED, STATE_ACTIVE, STATE_LAST } TableState; /* * Structure for use in parsing table commands/values. * Accessor functions defined in tkTableUtil.c */ typedef struct { char *name; /* name of the command/value */ int value; /* >0 because 0 represents an error or proc */ } Cmd_Struct; /* * The tag structure */ typedef struct { Tk_3DBorder bg; /* background color */ Tk_3DBorder fg; /* foreground color */ char * borderStr; /* border style */ int borders; /* number of borders specified (1, 2 or 4) */ int bd[4]; /* cell border width */ int relief; /* relief type */ Tk_Font tkfont; /* Information about text font, or NULL. */ Tk_Anchor anchor; /* default anchor point */ char * imageStr; /* name of image */ Tk_Image image; /* actual pointer to image, if any */ TableState state; /* state of the cell */ Tk_Justify justify; /* justification of text in the cell */ int multiline; /* wrapping style of multiline text */ int wrap; /* wrapping style of multiline text */ int showtext; /* whether to display text over image */ } TableTag; /* The widget structure for the table Widget */ typedef struct { /* basic information about the window and the interpreter */ Tk_Window tkwin; Display *display; Tcl_Interp *interp; Tcl_Command widgetCmd; /* Token for entry's widget command. */ /* * Configurable Options */ int autoClear; char *selectMode; /* single, browse, multiple, or extended */ int selectType; /* row, col, both, or cell */ int selectTitles; /* whether to do automatic title selection */ int rows, cols; /* number of rows and columns */ int defRowHeight; /* default row height in chars (positive) * or pixels (negative) */ int defColWidth; /* default column width in chars (positive) * or pixels (negative) */ int maxReqCols; /* the requested # cols to display */ int maxReqRows; /* the requested # rows to display */ int maxReqWidth; /* the maximum requested width in pixels */ int maxReqHeight; /* the maximum requested height in pixels */ Var arrayVar; /* name of traced array variable */ char *rowSep; /* separator string to place between * rows when getting selection */ char *colSep; /* separator string to place between * cols when getting selection */ TableTag defaultTag; /* the default tag colors/fonts etc */ LangCallback *yScrollCmd; /* the y-scroll command */ LangCallback *xScrollCmd; /* the x-scroll command */ LangCallback *browseCmd; /* the command that is called when the * active cell changes */ int caching; /* whether to cache values of table */ LangCallback *command; /* A command to eval when get/set occurs * for table values */ int useCmd; /* Signals whether to use command or the * array variable, will be 0 if command errs */ LangCallback *selCmd; /* the command that is called to when a * [selection get] call occurs for a table */ LangCallback *valCmd; /* Command prefix to use when invoking * validate command. NULL means don't * invoke commands. Malloc'ed. */ int validate; /* Non-zero means try to validate */ Tk_3DBorder insertBg; /* the cursor color */ Tk_Cursor cursor; /* the regular mouse pointer */ Tk_Cursor bdcursor; /* the mouse pointer when over borders */ #ifdef TITLE_CURSOR Tk_Cursor titleCursor; /* the mouse pointer when over titles */ #endif int exportSelection; /* Non-zero means tie internal table * to X selection. */ TableState state; /* Normal or disabled. Table is read-only * when disabled. */ int insertWidth; /* Total width of insert cursor. */ int insertBorderWidth; /* Width of 3-D border around insert cursor. */ int insertOnTime; /* Number of milliseconds cursor should spend * in "on" state for each blink. */ int insertOffTime; /* Number of milliseconds cursor should spend * in "off" state for each blink. */ int invertSelected; /* Whether to draw selected cells swapping * foreground and background */ int colStretch; /* The way to stretch columns if the window * is too large */ int rowStretch; /* The way to stretch rows if the window is * too large */ int colOffset; /* X index of leftmost col in the display */ int rowOffset; /* Y index of topmost row in the display */ int drawMode; /* The mode to use when redrawing */ int flashMode; /* Specifies whether flashing is enabled */ int flashTime; /* The number of ms to flash a cell for */ int resize; /* -resizeborders option for interactive * resizing of borders */ int sparse; /* Whether to use "sparse" arrays by * deleting empty array elements (default) */ LangCallback *rowTagCmd, *colTagCmd; /* script to eval for getting row/tag cmd */ int highlightWidth; /* Width in pixels of highlight to draw * around widget when it has the focus. * <= 0 means don't draw a highlight. */ XColor *highlightBgColorPtr;/* Color for drawing traversal highlight * area when highlight is off. */ XColor *highlightColorPtr; /* Color for drawing traversal highlight. */ char *takeFocus; /* Used only in Tcl to check if this * widget will accept focus */ int padX, padY; /* Extra space around text (pixels to leave * on each side). Ignored for bitmaps and * images. */ int ipadX, ipadY; /* Space to leave empty around cell borders. * This differs from pad* in that it is always * present for the cell (except windows). */ /* * Cached Information */ #ifdef TITLE_CURSOR Tk_Cursor *lastCursorPtr; /* pointer to last cursor defined. */ #endif int titleRows, titleCols; /* the number of rows|cols to use as a title */ /* these are kept in real coords */ int topRow, leftCol; /* The topleft cell to display excluding the * fixed title rows. This is just the * config request. The actual cell used may * be different to keep the screen full */ int anchorRow, anchorCol; /* the row,col of the anchor cell */ int activeRow, activeCol; /* the row,col of the active cell */ int oldTopRow, oldLeftCol; /* cached by TableAdjustParams */ int oldActRow, oldActCol; /* cached by TableAdjustParams */ int icursor; /* The index of the insertion cursor in the * active cell */ int flags; /* An or'ed combination of flags concerning * redraw/cursor etc. */ int dataSource; /* where our data comes from: * DATA_{NONE,CACHE,ARRAY,COMMAND} */ int maxWidth, maxHeight; /* max width|height required in pixels */ int charWidth, charHeight; /* size of a character in the default font */ int *colPixels, *rowPixels; /* Array of the pixel widths/heights */ int *colStarts, *rowStarts; /* Array of start pixels for rows|columns */ int scanMarkX, scanMarkY; /* Used by "scan" and "border" to mark */ int scanMarkRow, scanMarkCol;/* necessary information for dragto */ /* values in these are kept in user coords */ Tcl_HashTable *cache; /* value cache */ /* * colWidths and rowHeights are indexed from 0, so always adjust numbers * by the appropriate *Offset factor */ Tcl_HashTable *colWidths; /* hash table of non default column widths */ Tcl_HashTable *rowHeights; /* hash table of non default row heights */ Tcl_HashTable *spanTbl; /* table for spans */ Tcl_HashTable *spanAffTbl; /* table for cells affected by spans */ Tcl_HashTable *tagTable; /* table for style tags */ Tcl_HashTable *winTable; /* table for embedded windows */ Tcl_HashTable *rowStyles; /* table for row styles */ Tcl_HashTable *colStyles; /* table for col styles */ Tcl_HashTable *cellStyles; /* table for cell styles */ Tcl_HashTable *flashCells; /* table of flashing cells */ Tcl_HashTable *selCells; /* table of selected cells */ Tcl_TimerToken cursorTimer; /* timer token for the cursor blinking */ Tcl_TimerToken flashTimer; /* timer token for the cell flashing */ char *activeBuf; /* buffer where the selection is kept * for editing the active cell */ char **tagPrioNames; /* list of tag names in priority order */ TableTag **tagPrios; /* list of tag pointers in priority order */ TableTag *activeTagPtr; /* cache of active composite tag */ int activeX, activeY; /* cache offset of active layout in cell */ int tagPrioSize; /* size of tagPrios list */ int tagPrioMax; /* max allocated size of tagPrios list */ /* The invalid rectangle if there is an update pending */ int invalidX, invalidY, invalidWidth, invalidHeight; int seen[4]; /* see TableUndisplay */ #ifdef POSTSCRIPT /* Pointer to information used for generating Postscript for the canvas. * NULL means no Postscript is currently being generated. */ struct TkPostscriptInfo *psInfoPtr; #endif #ifdef PROCS Tcl_HashTable *inProc; /* cells where proc is being evaled */ int showProcs; /* whether to show embedded proc (1) or * its calculated value (0) */ int hasProcs; /* whether table has embedded procs or not */ #endif } Table; /* * HEADERS FOR EMBEDDED WINDOWS */ /* * A structure of the following type holds information for each window * embedded in a table widget. */ typedef struct TableEmbWindow { Table *tablePtr; /* Information about the overall table * widget. */ Tk_Window tkwin; /* Window for this segment. NULL means that * the window hasn't been created yet. */ Tcl_HashEntry *hPtr; /* entry into winTable */ LangCallback *create; /* Script to create window on-demand. * NULL means no such script. * Malloc-ed. */ Tk_3DBorder bg; /* background color */ char *borderStr; /* border style */ int borders; /* number of borders specified (1, 2 or 4) */ int bd[4]; /* border width for cell around window */ int relief; /* relief type */ int sticky; /* How to align window in space */ int padX, padY; /* Padding to leave around each side * of window, in pixels. */ int displayed; /* Non-zero means that the window has been * displayed on the screen recently. */ } TableEmbWindow; extern Tk_ConfigSpec tableSpecs[]; extern void EmbWinDisplay _ANSI_ARGS_((Table *tablePtr, Drawable window, TableEmbWindow *ewPtr, TableTag *tagPtr, int x, int y, int width, int height)); extern void EmbWinUnmap _ANSI_ARGS_((register Table *tablePtr, int rlo, int rhi, int clo, int chi)); extern void EmbWinDelete _ANSI_ARGS_((register Table *tablePtr, TableEmbWindow *ewPtr)); extern int Table_WinMove _ANSI_ARGS_((register Table *tablePtr, char *CONST srcPtr, char *CONST destPtr, int flags)); extern int Table_WinDelete _ANSI_ARGS_((register Table *tablePtr, char *CONST idxPtr)); extern int Table_WindowCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int TableValidateChange _ANSI_ARGS_((Table *tablePtr, int r, int c, char *oldVal, char *newVal, int idx)); extern void TableLostSelection _ANSI_ARGS_((ClientData clientData)); extern void TableSetActiveIndex _ANSI_ARGS_((register Table *tablePtr)); /* * HEADERS IN tkTableCmds.c */ extern int Table_ActivateCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_AdjustCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], int widthType)); extern int Table_BboxCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_BorderCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_ClearCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_CurselectionCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_CurvalueCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_GetCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_ScanCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_SeeCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_SelAnchorCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_SelClearCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_SelIncludesCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_SelSetCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_ViewCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); /* * HEADERS IN tkTableEdit.c */ extern int Table_EditCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern void TableDeleteChars _ANSI_ARGS_((register Table *tablePtr, int idx, int count)); extern void TableInsertChars _ANSI_ARGS_((register Table *tablePtr, int idx, char *string)); /* * HEADERS IN tkTableTag.c */ extern TableTag *TableNewTag _ANSI_ARGS_((Table *tablePtr)); extern void TableResetTag _ANSI_ARGS_((Table *tablePtr, TableTag *tagPtr)); extern void TableMergeTag _ANSI_ARGS_((Table *tablePtr, TableTag *baseTag, TableTag *addTag)); extern void TableInvertTag _ANSI_ARGS_((TableTag *baseTag)); extern int TableGetTagBorders _ANSI_ARGS_((TableTag *tagPtr, int *left, int *right, int *top, int *bottom)); extern void TableInitTags _ANSI_ARGS_((Table *tablePtr)); extern TableTag *FindRowColTag _ANSI_ARGS_((Table *tablePtr, int cell, int type)); extern void TableCleanupTag _ANSI_ARGS_((Table *tablePtr, TableTag *tagPtr)); extern int Table_TagCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); /* * HEADERS IN tkTableUtil.c */ extern void Table_ClearHashTable _ANSI_ARGS_((Tcl_HashTable *hashTblPtr)); extern int TableOptionBdSet _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, Arg value, char *widgRec, int offset)); extern Arg TableOptionBdGet _ANSI_ARGS_((ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)); extern int TableTagConfigureBd _ANSI_ARGS_((Table *tablePtr, TableTag *tagPtr, Arg oldValue, int nullOK)); extern int Cmd_OptionSet _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, Tk_Window unused, Arg value, char *widgRec, int offset)); extern Arg Cmd_OptionGet _ANSI_ARGS_((ClientData clientData, Tk_Window unused, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)); /* * HEADERS IN tkTableCell.c */ extern int TableTrueCell _ANSI_ARGS_((Table *tablePtr, int row, int col, int *trow, int *tcol)); extern int TableCellCoords _ANSI_ARGS_((Table *tablePtr, int row, int col, int *rx, int *ry, int *rw, int *rh)); extern int TableCellVCoords _ANSI_ARGS_((Table *tablePtr, int row, int col, int *rx, int *ry, int *rw, int *rh, int full)); extern void TableWhatCell _ANSI_ARGS_((register Table *tablePtr, int x, int y, int *row, int *col)); extern int TableAtBorder _ANSI_ARGS_((Table *tablePtr, int x, int y, int *row, int *col)); extern char * TableGetCellValue _ANSI_ARGS_((Table *tablePtr, int r, int c)); extern int TableSetCellValue _ANSI_ARGS_((Table *tablePtr, int r, int c, char *value)); extern int TableMoveCellValue _ANSI_ARGS_((Table *tablePtr, int fromr, int fromc, char *frombuf, int tor, int toc, char *tobuf, int outOfBounds)); extern int TableGetIcursor _ANSI_ARGS_((Table *tablePtr, char *arg, int *posn)); #define TableGetIcursorObj(tablePtr, objPtr, posnPtr) \ TableGetIcursor(tablePtr, Tcl_GetString(objPtr), posnPtr) extern int TableGetIndex _ANSI_ARGS_((register Table *tablePtr, char *str, int *row_p, int *col_p)); #define TableGetIndexObj(tablePtr, objPtr, rowPtr, colPtr) \ TableGetIndex(tablePtr, Tcl_GetString(objPtr), rowPtr, colPtr) extern int Table_SetCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_HiddenCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_SpanCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern void TableSpanSanCheck _ANSI_ARGS_((register Table *tablePtr)); /* * HEADERS IN TKTABLECELLSORT */ /* * We keep the old CellSort true because it is used for grabbing * the selection, so we really want them ordered */ extern Arg TableCellSort _ANSI_ARGS_((Table *tablePtr, char *str)); #ifdef NO_SORT_CELLS # define TableCellSortObj(interp, objPtr) (objPtr) #else extern Tcl_Obj* TableCellSortObj _ANSI_ARGS_((Tcl_Interp *interp, Tcl_Obj *listObjPtr)); #endif /* * HEADERS IN TKTABLEPS */ #ifdef POSTSCRIPT extern int Table_PostscriptCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern void Tcl_DStringAppendAll _ANSI_ARGS_(TCL_VARARGS(Tcl_DString *, arg1)); #endif /* * HEADERS IN TKTABLE */ EXTERN int Tktable_Init _ANSI_ARGS_((Tcl_Interp *interp)); EXTERN int Tktable_SafeInit _ANSI_ARGS_((Tcl_Interp *interp)); extern void TableGetActiveBuf _ANSI_ARGS_((register Table *tablePtr)); extern void ExpandPercents _ANSI_ARGS_((Table *tablePtr, char *before, int r, int c, char *oldVal, char *newVal, int idx, Tcl_DString *dsPtr, int cmdType)); extern void TableInvalidate _ANSI_ARGS_((Table *tablePtr, int x, int y, int width, int height, int force)); extern void TableRefresh _ANSI_ARGS_((register Table *tablePtr, int arg1, int arg2, int mode)); extern void TableGeometryRequest _ANSI_ARGS_((Table *tablePtr)); extern void TableAdjustActive _ANSI_ARGS_((register Table *tablePtr)); extern void TableAdjustParams _ANSI_ARGS_((register Table *tablePtr)); extern void TableConfigCursor _ANSI_ARGS_((register Table *tablePtr)); extern void TableAddFlash _ANSI_ARGS_((Table *tablePtr, int row, int col)); #define TableInvalidateAll(tablePtr, flags) \ TableInvalidate((tablePtr), 0, 0, Tk_Width((tablePtr)->tkwin),\ Tk_Height((tablePtr)->tkwin), (flags)) /* * Turn row/col into an index into the table */ #define TableMakeArrayIndex(r, c, i) sprintf((i), "%d,%d", (r), (c)) /* * Turn array index back into row/col * return the number of args parsed (should be two) */ #define TableParseArrayIndex(r, c, i) sscanf((i), "%d,%d", (r), (c)) /* * Macro for finding the last cell of the table */ #define TableGetLastCell(tablePtr, rowPtr, colPtr) \ TableWhatCell((tablePtr),\ Tk_Width((tablePtr)->tkwin)-(tablePtr)->highlightWidth-1,\ Tk_Height((tablePtr)->tkwin)-(tablePtr)->highlightWidth-1,\ (rowPtr), (colPtr)) EXTERN int Tk_TableObjCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); /* * end of header * reset TCL_STORAGE_CLASS to DLLIMPORT. */ #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT /* perltk tkTables replacement for TCL_unsetVar. deletes an element in a hash */ EXTERN void tkTableUnsetElement _ANSI_ARGS_((Var hashEntry, char * key)); #endif /* _TKTABLE_H_ */ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/findX�����������������������������������������������������������������������0000644�0000000�0000000�00000000563�13742524721�014474� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/local/bin/perl -w BEGIN { require Exporter }; use Tk::Pretty; # %depth = (); require 'process_object'; foreach $obj (<*.o>) { do_nm($obj); } foreach $obj (<*.o>) { do_need($obj,0,"ARGV"); } foreach $name (sort keys %unres) { if ($name =~ /^X[A-Z]/) { print "$name : ",Pretty($unres{$name}),"\n"; } } ���������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/findcore��������������������������������������������������������������������0000644�0000000�0000000�00000000773�13742524721�015220� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/local/bin/perl -w BEGIN { require Exporter }; use Tk::Pretty; %depth = (); require 'process_object'; foreach (<*.o>) { do_nm($_); } @ARGV = <*_f.o> unless(@ARGV); foreach (@ARGV) { do_need($_,0,"ARGV"); } foreach $file (sort keys %need) { my $src = $file; $src =~ s/\.o$/.c/; print "$src ($depth{$file}) : ",Pretty($need{$file}),"\n"; } print "\n"; foreach $name (sort keys %unres) { print "$name : ",Pretty($unres{$name}),"\n"; } �����Tk-TableMatrix-1.26/pTk/tkTableversion.h������������������������������������������������������������0000444�0000000�0000000�00000000317�13746047614�016646� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#if 0 TBL_MAJOR_VERSION = 2 TBL_MINOR_VERSION = 7 TBL_VERSION = $(TBL_MAJOR_VERSION).$(TBL_MINOR_VERSION) #endif #define TBL_MAJOR_VERSION 2 #define TBL_MINOR_VERSION 7 #define TBL_VERSION "2.7" �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/counts����������������������������������������������������������������������0000644�0000000�0000000�00000002345�13745605157�014745� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/local/bin/perl sub count { local($file) = @_; if (open(C,"gcc -E -DHAVE_UNISTD_H $file|")) { my $match = 0; local(%vars); while (<C>) { next if (/^\s*$/); $match = m/$file/ if (/^#/); if ($match) { study; &match; } } close(C); $match = 0; foreach (keys %vars) { $file{$_} .= "$file($vars{$_}),"; $match += $vars{$_}; } printf(STDERR "%5d $file\n",$match); } else { warn "Cannot open pipe to $file"; } } open(NEED,"<need") || die; while (<NEED>) { next if (/^ld:/); next if (/^\s+\./); if (/^([A-Za-z][A-Za-z0-9_]*).*\.o\s*$/) { $need{$1}++; } elsif (/^\s+_([_A-Za-z][A-Za-z0-9_]*)\s*$/) { my $sym = $1; $need{$sym}++ unless($sym =~ /^_/); } else { warn "No match:$_"; } } close(NEED); print STDERR "Building proc\n"; $proc = "sub match {\n"; foreach (keys %need) { $proc .= " \$count{\"$_\"}++,\$vars{\"$_\"}++ if (/\\b$_\\b/);\n" } $proc .= "}\n"; print STDERR "eval...\n"; eval ($proc); foreach (@ARGV) { &count($_); } foreach (sort keys %need) { my $file = $file{$_}; chop($file); printf("%6d %-20s %s\n",$count{$_},$_,$file); } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/fakeld����������������������������������������������������������������������0000644�0000000�0000000�00000003271�13742524721�014651� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/local/bin/perl -w use strict; my %ref; my %def; my %file; my %where; my %need; sub read_object { my $obj = shift; open(NM,"nm -p $obj|") || die "Cannot open nm $obj:$!"; $def{$obj} = {}; $file{$obj} = {}; my @refs = (); while (<NM>) { if (/\b([A-Z])\b\s*_?(.*)$/) { my ($kind,$name) = ($1,$2); $file{$obj}{$name} = $kind; if ($kind ne 'U') { $def{$obj}{$name} = $kind; $where{$name} = [] unless (exists $where{$name}); push(@{$where{$name}},$obj); } else { $ref{$name} = [] unless (exists $ref{$name}); push(@{$ref{$name}},$obj); push(@refs,$name); } } } close(NM); return $need{$obj} = \@refs; } warn "Scanning object files\n"; foreach my $obj (<*.o>,<../*.o>) { # next if $obj =~ /_f\.o$/; read_object($obj); } my %inc; warn "Analysing...\n"; sub process { my $file = shift; $inc{$file} = 1; if (exists $need{$file}) { foreach my $sym (@{$need{$file}}) { if (exists $where{$sym}) { print "$file need $sym ",join(' ',@{$where{$sym}}),"\n"; if (@{$where{$sym}} > 1) { # warn "Multiply defined $sym\n"; } else { my $inc = $where{$sym}->[0]; unless (exists $inc{$inc}) { process($inc); } } } } } } foreach my $file (@ARGV) { process($file); } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/license.html_lib������������������������������������������������������������0000644�0000000�0000000�00000004014�13745605157�016640� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������---------------------------------------------------------------------- COPYRIGHT NOTICE OF THE HTML_LIBRARY SOFTWARE. THE TERM "SOFTWARE" SHALL MEAN THE HTML_LIBRARY SOFTWARE ONLY. THIS NOTICE DOES NOT COVER THE TIX LIBRARY. SEE THE FILE "license.terms" FOR COPYRIGHT NOTICE AND LICENSE TERMS OF THE TIX LIBRARY. ---------------------------------------------------------------------- Sun Microsystems, Inc. The following terms apply to all files associated with the software unless explicitly disclaimed in individual files. The authors hereby grant permission to use, copy, modify, distribute, and license this software and its documentation for any purpose, provided that existing copyright notices are retained in all copies and that this notice is included verbatim in any distributions. No written agreement, license, or royalty fee is required for any of the authorized uses. Modifications to this software may be copyrighted by their authors and need not follow the licensing terms described here, provided that the new terms are clearly indicated on the first page of each file where they apply. IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. RESTRICTED RIGHTS: Use, duplication or disclosure by the government is subject to the restrictions as set forth in subparagraph (c) (1) (ii) of the Rights in Technical Data and Computer Software Clause as DFARS 252.227-7013 and FAR 52.227-19. ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/tkTableCmds.c���������������������������������������������������������������0000444�0000000�0000000�00000115140�13746047614�016043� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * tkTableCmds.c -- * * This module implements general commands of a table widget, * based on the major/minor command structure. * * Copyright (c) 1998-2002 Jeffrey Hobbs * * See the file "license.txt" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * */ #include "tkVMacro.h" #include "tkTable.h" /* *-------------------------------------------------------------- * * Table_ActivateCmd -- * This procedure is invoked to process the activate method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_ActivateCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int result = TCL_OK; int row, col; if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "index"); return TCL_ERROR; } else if (TableGetIndexObj(tablePtr, objv[2], &row, &col) != TCL_OK) { return TCL_ERROR; } else { int x, y, w, dummy; char buf1[INDEX_BUFSIZE], buf2[INDEX_BUFSIZE]; /* convert to valid active index in real coords */ row -= tablePtr->rowOffset; col -= tablePtr->colOffset; /* we do this regardless, to avoid cell commit problems */ if ((tablePtr->flags & HAS_ACTIVE) && (tablePtr->flags & TEXT_CHANGED)) { tablePtr->flags &= ~TEXT_CHANGED; TableSetCellValue(tablePtr, tablePtr->activeRow+tablePtr->rowOffset, tablePtr->activeCol+tablePtr->colOffset, tablePtr->activeBuf); } if (row != tablePtr->activeRow || col != tablePtr->activeCol) { if (tablePtr->flags & HAS_ACTIVE) { TableMakeArrayIndex(tablePtr->activeRow+tablePtr->rowOffset, tablePtr->activeCol+tablePtr->colOffset, buf1); } else { buf1[0] = '\0'; } tablePtr->flags |= HAS_ACTIVE; tablePtr->flags &= ~ACTIVE_DISABLED; tablePtr->activeRow = row; tablePtr->activeCol = col; if (tablePtr->activeTagPtr != NULL) { ckfree((char *) (tablePtr->activeTagPtr)); tablePtr->activeTagPtr = NULL; } TableAdjustActive(tablePtr); TableConfigCursor(tablePtr); if (!(tablePtr->flags & BROWSE_CMD) && tablePtr->browseCmd != NULL) { tablePtr->flags |= BROWSE_CMD; row = tablePtr->activeRow+tablePtr->rowOffset; col = tablePtr->activeCol+tablePtr->colOffset; TableMakeArrayIndex(row, col, buf2); result = LangDoCallback(interp, tablePtr->browseCmd, 1, 2, "%s %s",buf1,buf2); if (result == TCL_OK || result == TCL_RETURN) { Tcl_ResetResult(interp); } tablePtr->flags &= ~BROWSE_CMD; } } else { char *p = Tcl_GetString(objv[2]); if ((tablePtr->activeTagPtr != NULL) && *p == '@' && !(tablePtr->flags & ACTIVE_DISABLED) && TableCellVCoords(tablePtr, row, col, &x, &y, &w, &dummy, 0)) { /* we are clicking into the same cell * If it was activated with @x,y indexing, * find the closest char */ Tk_TextLayout textLayout; TableTag *tagPtr = tablePtr->activeTagPtr; /* no error checking because GetIndex did it for us */ p++; x = strtol(p, &p, 0) - x - tablePtr->activeX; p++; y = strtol(p, &p, 0) - y - tablePtr->activeY; textLayout = Tk_ComputeTextLayout(tagPtr->tkfont, tablePtr->activeBuf, -1, (tagPtr->wrap) ? w : 0, tagPtr->justify, 0, &dummy, &dummy); tablePtr->icursor = Tk_PointToChar(textLayout, x, y); Tk_FreeTextLayout(textLayout); TableRefresh(tablePtr, row, col, CELL|INV_FORCE); } } tablePtr->flags |= HAS_ACTIVE; } return result; } /* *-------------------------------------------------------------- * * Table_AdjustCmd -- * This procedure is invoked to process the width/height method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_AdjustCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], int widthType) { /* widthType is a Flag = 1 if this is a col width change command, otherwise assumed to be a row height change command */ register Table *tablePtr = (Table *) clientData; Tcl_HashEntry *entryPtr; Tcl_HashSearch search; Tcl_HashTable *hashTablePtr; int i, dummy, value, posn, offset; char buf1[INDEX_BUFSIZE]; /* changes the width/height of certain selected columns */ if (objc != 3 && (objc & 1)) { Tcl_WrongNumArgs(interp, 2, objv, widthType ? "?col? ?width col width ...?" : "?row? ?height row height ...?"); return TCL_ERROR; } if (widthType) { hashTablePtr = tablePtr->colWidths; offset = tablePtr->colOffset; } else { hashTablePtr = tablePtr->rowHeights; offset = tablePtr->rowOffset; } if (objc == 2) { /* print out all the preset column widths or row heights */ entryPtr = Tcl_FirstHashEntry(hashTablePtr, &search); while (entryPtr != NULL) { posn = ((int) Tcl_GetHashKey(hashTablePtr, entryPtr)) + offset; value = (int) Tcl_GetHashValue(entryPtr); sprintf(buf1, "%d %d", posn, value); /* OBJECTIFY */ Tcl_AppendElement(interp, buf1); entryPtr = Tcl_NextHashEntry(&search); } } else if (objc == 3) { /* get the width/height of a particular row/col */ if (Tcl_GetIntFromObj(interp, objv[2], &posn) != TCL_OK) { return TCL_ERROR; } /* no range check is done, why bother? */ posn -= offset; entryPtr = Tcl_FindHashEntry(hashTablePtr, (char *) posn); if (entryPtr != NULL) { Tcl_SetIntObj(Tcl_GetObjResult(interp), (int) Tcl_GetHashValue(entryPtr)); } else { Tcl_SetIntObj(Tcl_GetObjResult(interp), widthType ? tablePtr->defColWidth : tablePtr->defRowHeight); } } else { for (i=2; i<objc; i++) { /* set new width|height here */ value = -999999; if (Tcl_GetIntFromObj(interp, objv[i++], &posn) != TCL_OK || (strcmp(Tcl_GetString(objv[i]), "default") && Tcl_GetIntFromObj(interp, objv[i], &value) != TCL_OK)) { return TCL_ERROR; } posn -= offset; if (value == -999999) { /* reset that field */ entryPtr = Tcl_FindHashEntry(hashTablePtr, (char *) posn); if (entryPtr != NULL) { Tcl_DeleteHashEntry(entryPtr); } } else { entryPtr = Tcl_CreateHashEntry(hashTablePtr, (char *) posn, &dummy); Tcl_SetHashValue(entryPtr, (ClientData) value); } } TableAdjustParams(tablePtr); /* rerequest geometry */ TableGeometryRequest(tablePtr); /* * Invalidate the whole window as TableAdjustParams * will only check to see if the top left cell has moved * FIX: should just move from lowest order visible cell * to edge of window */ TableInvalidateAll(tablePtr, 0); } return TCL_OK; } /* *-------------------------------------------------------------- * * Table_BboxCmd -- * This procedure is invoked to process the bbox method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_BboxCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int x, y, w, h, row, col, key; Tcl_Obj *resultPtr; /* Returns bounding box of cell(s) */ if (objc < 3 || objc > 4) { Tcl_WrongNumArgs(interp, 2, objv, "first ?last?"); return TCL_ERROR; } else if (TableGetIndexObj(tablePtr, objv[2], &row, &col) == TCL_ERROR || (objc == 4 && TableGetIndexObj(tablePtr, objv[3], &x, &y) == TCL_ERROR)) { return TCL_ERROR; } resultPtr = Tcl_GetObjResult(interp); if (objc == 3) { row -= tablePtr->rowOffset; col -= tablePtr->colOffset; if (TableCellVCoords(tablePtr, row, col, &x, &y, &w, &h, 0)) { Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewIntObj(x)); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewIntObj(y)); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewIntObj(w)); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewIntObj(h)); } return TCL_OK; } else { int r1, c1, r2, c2, minX = 99999, minY = 99999, maxX = 0, maxY = 0; row -= tablePtr->rowOffset; col -= tablePtr->colOffset; x -= tablePtr->rowOffset; y -= tablePtr->colOffset; r1 = MIN(row,x); r2 = MAX(row,x); c1 = MIN(col,y); c2 = MAX(col,y); key = 0; for (row = r1; row <= r2; row++) { for (col = c1; col <= c2; col++) { if (TableCellVCoords(tablePtr, row, col, &x, &y, &w, &h, 0)) { /* Get max bounding box */ if (x < minX) minX = x; if (y < minY) minY = y; if (x+w > maxX) maxX = x+w; if (y+h > maxY) maxY = y+h; key++; } } } if (key) { Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewIntObj(minX)); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewIntObj(minY)); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewIntObj(maxX-minX)); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewIntObj(maxY-minY)); } } return TCL_OK; } static CONST char *bdCmdNames[] = { "mark", "dragto", NULL }; enum bdCmd { BD_MARK, BD_DRAGTO }; /* *-------------------------------------------------------------- * * Table_BorderCmd -- * This procedure is invoked to process the bbox method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_BorderCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; Tcl_HashEntry *entryPtr; int x, y, w, h, row, col, key, dummy, value, cmdIndex; char *rc = NULL; Tcl_Obj *objPtr, *resultPtr; if (objc < 5 || objc > 6) { Tcl_WrongNumArgs(interp, 2, objv, "mark|dragto x y ?row|col?"); return TCL_ERROR; } if (Tcl_GetIndexFromObj(interp, objv[2], bdCmdNames, "option", 0, &cmdIndex) != TCL_OK || Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK || Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK) { return TCL_ERROR; } if (objc == 6) { rc = Tcl_GetStringFromObj(objv[5], &w); if ((w < 1) || (strncmp(rc, "row", w) && strncmp(rc, "col", w))) { Tcl_WrongNumArgs(interp, 2, objv, "mark|dragto x y ?row|col?"); return TCL_ERROR; } } resultPtr = Tcl_GetObjResult(interp); switch ((enum bdCmd) cmdIndex) { case BD_MARK: /* Use x && y to determine if we are over a border */ value = TableAtBorder(tablePtr, x, y, &row, &col); /* Cache the row && col for use in DRAGTO */ tablePtr->scanMarkRow = row; tablePtr->scanMarkCol = col; if (!value) { return TCL_OK; } TableCellCoords(tablePtr, row, col, &x, &y, &dummy, &dummy); tablePtr->scanMarkX = x; tablePtr->scanMarkY = y; if (objc == 5 || *rc == 'r') { if (row < 0) { objPtr = Tcl_NewStringObj("", 0); } else { objPtr = Tcl_NewIntObj(row+tablePtr->rowOffset); } Tcl_ListObjAppendElement(NULL, resultPtr, objPtr); } if (objc == 5 || *rc == 'c') { if (col < 0) { objPtr = Tcl_NewStringObj("", 0); } else { objPtr = Tcl_NewIntObj(col+tablePtr->colOffset); } Tcl_ListObjAppendElement(NULL, resultPtr, objPtr); } return TCL_OK; /* BORDER MARK */ case BD_DRAGTO: /* check to see if we want to resize any borders */ if (tablePtr->resize == SEL_NONE) { return TCL_OK; } row = tablePtr->scanMarkRow; col = tablePtr->scanMarkCol; TableCellCoords(tablePtr, row, col, &w, &h, &dummy, &dummy); key = 0; if (row >= 0 && (tablePtr->resize & SEL_ROW)) { /* row border was active, move it */ value = y-h; if (value < -1) value = -1; if (value != tablePtr->scanMarkY) { entryPtr = Tcl_CreateHashEntry(tablePtr->rowHeights, (char *) row, &dummy); /* -value means rowHeight will be interp'd as pixels, not lines */ Tcl_SetHashValue(entryPtr, (ClientData) MIN(0,-value)); tablePtr->scanMarkY = value; key++; } } if (col >= 0 && (tablePtr->resize & SEL_COL)) { /* col border was active, move it */ value = x-w; if (value < -1) value = -1; if (value != tablePtr->scanMarkX) { entryPtr = Tcl_CreateHashEntry(tablePtr->colWidths, (char *) col, &dummy); /* -value means colWidth will be interp'd as pixels, not chars */ Tcl_SetHashValue(entryPtr, (ClientData) MIN(0,-value)); tablePtr->scanMarkX = value; key++; } } /* Only if something changed do we want to update */ if (key) { TableAdjustParams(tablePtr); /* Only rerequest geometry if the basis is the #rows &| #cols */ if (tablePtr->maxReqCols || tablePtr->maxReqRows) TableGeometryRequest(tablePtr); TableInvalidateAll(tablePtr, 0); } return TCL_OK; /* BORDER DRAGTO */ } return TCL_OK; } /* clear subcommands */ static CONST char *clearNames[] = { "all", "cache", "sizes", "tags", NULL }; enum clearCommand { CLEAR_ALL, CLEAR_CACHE, CLEAR_SIZES, CLEAR_TAGS }; /* *-------------------------------------------------------------- * * Table_ClearCmd -- * This procedure is invoked to process the clear method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * Cached info can be lost. Returns valid Tcl result. * * Side effects: * Can cause redraw. * See the user documentation. * *-------------------------------------------------------------- */ int Table_ClearCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int cmdIndex, redraw = 0; if (objc < 3 || objc > 5) { Tcl_WrongNumArgs(interp, 2, objv, "option ?first? ?last?"); return TCL_ERROR; } if (Tcl_GetIndexFromObj(interp, objv[2], clearNames, "clear option", 0, &cmdIndex) != TCL_OK) { return TCL_ERROR; } if (objc == 3) { if (cmdIndex == CLEAR_TAGS || cmdIndex == CLEAR_ALL) { Tcl_DeleteHashTable(tablePtr->rowStyles); Tcl_DeleteHashTable(tablePtr->colStyles); Tcl_DeleteHashTable(tablePtr->cellStyles); Tcl_DeleteHashTable(tablePtr->flashCells); Tcl_DeleteHashTable(tablePtr->selCells); /* style hash tables */ Tcl_InitHashTable(tablePtr->rowStyles, TCL_ONE_WORD_KEYS); Tcl_InitHashTable(tablePtr->colStyles, TCL_ONE_WORD_KEYS); Tcl_InitHashTable(tablePtr->cellStyles, TCL_STRING_KEYS); /* special style hash tables */ Tcl_InitHashTable(tablePtr->flashCells, TCL_STRING_KEYS); Tcl_InitHashTable(tablePtr->selCells, TCL_STRING_KEYS); } if (cmdIndex == CLEAR_SIZES || cmdIndex == CLEAR_ALL) { Tcl_DeleteHashTable(tablePtr->colWidths); Tcl_DeleteHashTable(tablePtr->rowHeights); /* style hash tables */ Tcl_InitHashTable(tablePtr->colWidths, TCL_ONE_WORD_KEYS); Tcl_InitHashTable(tablePtr->rowHeights, TCL_ONE_WORD_KEYS); } if (cmdIndex == CLEAR_CACHE || cmdIndex == CLEAR_ALL) { Table_ClearHashTable(tablePtr->cache); Tcl_InitHashTable(tablePtr->cache, TCL_STRING_KEYS); /* If we were caching and we have no other data source, * invalidate all the cells */ if (tablePtr->dataSource == DATA_CACHE) { TableGetActiveBuf(tablePtr); } } redraw = 1; } else { int row, col, r1, r2, c1, c2; Tcl_HashEntry *entryPtr; char buf[INDEX_BUFSIZE], *value; if (TableGetIndexObj(tablePtr, objv[3], &row, &col) != TCL_OK || ((objc == 5) && TableGetIndexObj(tablePtr, objv[4], &r2, &c2) != TCL_OK)) { return TCL_ERROR; } if (objc == 4) { r1 = r2 = row; c1 = c2 = col; } else { r1 = MIN(row,r2); r2 = MAX(row,r2); c1 = MIN(col,c2); c2 = MAX(col,c2); } for (row = r1; row <= r2; row++) { /* Note that *Styles entries are user based (no offset) * while size entries are 0-based (real) */ if ((cmdIndex == CLEAR_TAGS || cmdIndex == CLEAR_ALL) && (entryPtr = Tcl_FindHashEntry(tablePtr->rowStyles, (char *) row))) { Tcl_DeleteHashEntry(entryPtr); redraw = 1; } if ((cmdIndex == CLEAR_SIZES || cmdIndex == CLEAR_ALL) && (entryPtr = Tcl_FindHashEntry(tablePtr->rowHeights, (char *) row-tablePtr->rowOffset))) { Tcl_DeleteHashEntry(entryPtr); redraw = 1; } for (col = c1; col <= c2; col++) { TableMakeArrayIndex(row, col, buf); if (cmdIndex == CLEAR_TAGS || cmdIndex == CLEAR_ALL) { if ((row == r1) && (entryPtr = Tcl_FindHashEntry(tablePtr->colStyles, (char *) col))) { Tcl_DeleteHashEntry(entryPtr); redraw = 1; } if ((entryPtr = Tcl_FindHashEntry(tablePtr->cellStyles, buf))) { Tcl_DeleteHashEntry(entryPtr); redraw = 1; } if ((entryPtr = Tcl_FindHashEntry(tablePtr->flashCells, buf))) { Tcl_DeleteHashEntry(entryPtr); redraw = 1; } if ((entryPtr = Tcl_FindHashEntry(tablePtr->selCells, buf))) { Tcl_DeleteHashEntry(entryPtr); redraw = 1; } } if ((cmdIndex == CLEAR_SIZES || cmdIndex == CLEAR_ALL) && row == r1 && (entryPtr = Tcl_FindHashEntry(tablePtr->colWidths, (char *) col-tablePtr->colOffset))) { Tcl_DeleteHashEntry(entryPtr); redraw = 1; } if ((cmdIndex == CLEAR_CACHE || cmdIndex == CLEAR_ALL) && (entryPtr = Tcl_FindHashEntry(tablePtr->cache, buf))) { value = (char *) Tcl_GetHashValue(entryPtr); if (value) { ckfree(value); } Tcl_DeleteHashEntry(entryPtr); /* if the cache is our data source, * we need to invalidate the cells changed */ if ((tablePtr->dataSource == DATA_CACHE) && (row-tablePtr->rowOffset == tablePtr->activeRow && col-tablePtr->colOffset == tablePtr->activeCol)) TableGetActiveBuf(tablePtr); redraw = 1; } } } } /* This could be more sensitive about what it updates, * but that can actually be a lot more costly in some cases */ if (redraw) { if (cmdIndex == CLEAR_SIZES || cmdIndex == CLEAR_ALL) { TableAdjustParams(tablePtr); /* rerequest geometry */ TableGeometryRequest(tablePtr); } TableInvalidateAll(tablePtr, 0); } return TCL_OK; } /* *-------------------------------------------------------------- * * Table_CurselectionCmd -- * This procedure is invoked to process the bbox method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_CurselectionCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; Tcl_HashEntry *entryPtr; Tcl_HashSearch search; char *value = NULL; int row, col; if (objc > 3) { Tcl_WrongNumArgs(interp, 2, objv, "?value?"); return TCL_ERROR; } if (objc == 3) { /* make sure there is a data source to accept a set value */ if ((tablePtr->state == STATE_DISABLED) || (tablePtr->dataSource == DATA_NONE)) { return TCL_OK; } value = Tcl_GetString(objv[2]); for (entryPtr = Tcl_FirstHashEntry(tablePtr->selCells, &search); entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { TableParseArrayIndex(&row, &col, Tcl_GetHashKey(tablePtr->selCells, entryPtr)); TableSetCellValue(tablePtr, row, col, value); row -= tablePtr->rowOffset; col -= tablePtr->colOffset; if (row == tablePtr->activeRow && col == tablePtr->activeCol) { TableGetActiveBuf(tablePtr); } TableRefresh(tablePtr, row, col, CELL); } } else { Tcl_Obj *objPtr = Tcl_NewObj(); for (entryPtr = Tcl_FirstHashEntry(tablePtr->selCells, &search); entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { value = Tcl_GetHashKey(tablePtr->selCells, entryPtr); Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj(value, -1)); } Tcl_SetObjResult(interp, TableCellSortObj(interp, objPtr)); } return TCL_OK; } /* *-------------------------------------------------------------- * * Table_CurvalueCmd -- * This procedure is invoked to process the curvalue method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_CurvalueCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; if (objc > 3) { Tcl_WrongNumArgs(interp, 2, objv, "?<value>?"); return TCL_ERROR; } else if (!(tablePtr->flags & HAS_ACTIVE)) { return TCL_OK; } if (objc == 3) { char *value; int len; value = Tcl_GetStringFromObj(objv[2], &len); if (STREQ(value, tablePtr->activeBuf)) { Tcl_SetObjResult(interp, objv[2]); return TCL_OK; } /* validate potential new active buffer contents * only accept if validation returns acceptance. */ if (tablePtr->validate && TableValidateChange(tablePtr, tablePtr->activeRow+tablePtr->rowOffset, tablePtr->activeCol+tablePtr->colOffset, tablePtr->activeBuf, value, tablePtr->icursor) != TCL_OK) { return TCL_OK; } tablePtr->activeBuf = (char *)ckrealloc(tablePtr->activeBuf, len+1); strcpy(tablePtr->activeBuf, value); /* mark the text as changed */ tablePtr->flags |= TEXT_CHANGED; TableSetActiveIndex(tablePtr); /* check for possible adjustment of icursor */ TableGetIcursor(tablePtr, "insert", (int *)0); TableRefresh(tablePtr, tablePtr->activeRow, tablePtr->activeCol, CELL); } Tcl_SetStringObj(Tcl_GetObjResult(interp), tablePtr->activeBuf, -1); return TCL_OK; } /* *-------------------------------------------------------------- * * Table_GetCmd -- * This procedure is invoked to process the bbox method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_GetCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int result = TCL_OK; int r1, c1, r2, c2, row, col; if (objc < 3 || objc > 4) { Tcl_WrongNumArgs(interp, 2, objv, "first ?last?"); result = TCL_ERROR; } else if (TableGetIndexObj(tablePtr, objv[2], &row, &col) == TCL_ERROR) { result = TCL_ERROR; } else if (objc == 3) { Tcl_SetObjResult(interp, Tcl_NewStringObj(TableGetCellValue(tablePtr, row, col), -1)); } else if (TableGetIndexObj(tablePtr, objv[3], &r2, &c2) == TCL_ERROR) { result = TCL_ERROR; } else { Tcl_Obj *objPtr = Tcl_NewObj(); r1 = MIN(row,r2); r2 = MAX(row,r2); c1 = MIN(col,c2); c2 = MAX(col,c2); for ( row = r1; row <= r2; row++ ) { for ( col = c1; col <= c2; col++ ) { Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj(TableGetCellValue(tablePtr, row, col), -1)); } } Tcl_SetObjResult(interp, objPtr); } return result; } /* *-------------------------------------------------------------- * * Table_ScanCmd -- * This procedure is invoked to process the scan method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_ScanCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int x, y, row, col, cmdIndex; if (objc != 5) { Tcl_WrongNumArgs(interp, 2, objv, "mark|dragto x y"); return TCL_ERROR; } else if (Tcl_GetIndexFromObj(interp, objv[2], bdCmdNames, "option", 0, &cmdIndex) != TCL_OK || Tcl_GetIntFromObj(interp, objv[3], &x) == TCL_ERROR || Tcl_GetIntFromObj(interp, objv[4], &y) == TCL_ERROR) { return TCL_ERROR; } switch ((enum bdCmd) cmdIndex) { case BD_MARK: TableWhatCell(tablePtr, x, y, &row, &col); tablePtr->scanMarkRow = row-tablePtr->topRow; tablePtr->scanMarkCol = col-tablePtr->leftCol; tablePtr->scanMarkX = x; tablePtr->scanMarkY = y; break; case BD_DRAGTO: { int oldTop = tablePtr->topRow, oldLeft = tablePtr->leftCol; y += (5*(y-tablePtr->scanMarkY)); x += (5*(x-tablePtr->scanMarkX)); TableWhatCell(tablePtr, x, y, &row, &col); /* maintain appropriate real index */ tablePtr->topRow = BETWEEN(row-tablePtr->scanMarkRow, tablePtr->titleRows, tablePtr->rows-1); tablePtr->leftCol = BETWEEN(col-tablePtr->scanMarkCol, tablePtr->titleCols, tablePtr->cols-1); /* Adjust the table if new top left */ if (oldTop != tablePtr->topRow || oldLeft != tablePtr->leftCol) { TableAdjustParams(tablePtr); } break; } } return TCL_OK; } /* *-------------------------------------------------------------- * * Table_SelAnchorCmd -- * This procedure is invoked to process the selection anchor method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_SelAnchorCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int row, col; if (objc != 4) { Tcl_WrongNumArgs(interp, 3, objv, "index"); return TCL_ERROR; } else if (TableGetIndexObj(tablePtr, objv[3], &row, &col) != TCL_OK) { return TCL_ERROR; } tablePtr->flags |= HAS_ANCHOR; /* maintain appropriate real index */ if (tablePtr->selectTitles) { tablePtr->anchorRow = BETWEEN(row-tablePtr->rowOffset, 0, tablePtr->rows-1); tablePtr->anchorCol = BETWEEN(col-tablePtr->colOffset, 0, tablePtr->cols-1); } else { tablePtr->anchorRow = BETWEEN(row-tablePtr->rowOffset, tablePtr->titleRows, tablePtr->rows-1); tablePtr->anchorCol = BETWEEN(col-tablePtr->colOffset, tablePtr->titleCols, tablePtr->cols-1); } return TCL_OK; } /* *-------------------------------------------------------------- * * Table_SelClearCmd -- * This procedure is invoked to process the selection clear method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_SelClearCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int result = TCL_OK; char buf1[INDEX_BUFSIZE]; int row, col, key, clo=0,chi=0,r1,c1,r2,c2; Tcl_HashEntry *entryPtr; if (objc < 4 || objc > 5) { Tcl_WrongNumArgs(interp, 3, objv, "all|<first> ?<last>?"); return TCL_ERROR; } if (STREQ(Tcl_GetString(objv[3]), "all")) { Tcl_HashSearch search; for(entryPtr = Tcl_FirstHashEntry(tablePtr->selCells, &search); entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { TableParseArrayIndex(&row, &col, Tcl_GetHashKey(tablePtr->selCells,entryPtr)); Tcl_DeleteHashEntry(entryPtr); TableRefresh(tablePtr, row-tablePtr->rowOffset, col-tablePtr->colOffset, CELL); } return TCL_OK; } if (TableGetIndexObj(tablePtr, objv[3], &row, &col) == TCL_ERROR || (objc==5 && TableGetIndexObj(tablePtr, objv[4], &r2, &c2) == TCL_ERROR)) { return TCL_ERROR; } key = 0; if (objc == 4) { r1 = r2 = row; c1 = c2 = col; } else { r1 = MIN(row,r2); r2 = MAX(row,r2); c1 = MIN(col,c2); c2 = MAX(col,c2); } switch (tablePtr->selectType) { case SEL_BOTH: clo = c1; chi = c2; c1 = tablePtr->colOffset; c2 = tablePtr->cols-1+c1; key = 1; goto CLEAR_CELLS; CLEAR_BOTH: key = 0; c1 = clo; c2 = chi; case SEL_COL: r1 = tablePtr->rowOffset; r2 = tablePtr->rows-1+r1; break; case SEL_ROW: c1 = tablePtr->colOffset; c2 = tablePtr->cols-1+c1; break; } /* row/col are in user index coords */ CLEAR_CELLS: for ( row = r1; row <= r2; row++ ) { for ( col = c1; col <= c2; col++ ) { TableMakeArrayIndex(row, col, buf1); entryPtr = Tcl_FindHashEntry(tablePtr->selCells, buf1); if (entryPtr != NULL) { Tcl_DeleteHashEntry(entryPtr); TableRefresh(tablePtr, row-tablePtr->rowOffset, col-tablePtr->colOffset, CELL); } } } if (key) goto CLEAR_BOTH; return result; } /* *-------------------------------------------------------------- * * Table_SelIncludesCmd -- * This procedure is invoked to process the selection includes method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_SelIncludesCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int row, col; if (objc != 4) { Tcl_WrongNumArgs(interp, 3, objv, "index"); return TCL_ERROR; } else if (TableGetIndexObj(tablePtr, objv[3], &row, &col) == TCL_ERROR) { return TCL_ERROR; } else { char buf[INDEX_BUFSIZE]; TableMakeArrayIndex(row, col, buf); Tcl_SetBooleanObj(Tcl_GetObjResult(interp), (Tcl_FindHashEntry(tablePtr->selCells, buf)!=NULL)); } return TCL_OK; } /* *-------------------------------------------------------------- * * Table_SelSetCmd -- * This procedure is invoked to process the selection set method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_SelSetCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int row, col, dummy, key; char buf1[INDEX_BUFSIZE]; Tcl_HashSearch search; Tcl_HashEntry *entryPtr; int clo=0, chi=0, r1, c1, r2, c2, firstRow, firstCol, lastRow, lastCol; if (objc < 4 || objc > 5) { Tcl_WrongNumArgs(interp, 3, objv, "first ?last?"); return TCL_ERROR; } if (TableGetIndexObj(tablePtr, objv[3], &row, &col) == TCL_ERROR || (objc==5 && TableGetIndexObj(tablePtr, objv[4], &r2, &c2) == TCL_ERROR)) { return TCL_ERROR; } key = 0; lastRow = tablePtr->rows-1+tablePtr->rowOffset; lastCol = tablePtr->cols-1+tablePtr->colOffset; if (tablePtr->selectTitles) { firstRow = tablePtr->rowOffset; firstCol = tablePtr->colOffset; } else { firstRow = tablePtr->titleRows+tablePtr->rowOffset; firstCol = tablePtr->titleCols+tablePtr->colOffset; } /* maintain appropriate user index */ CONSTRAIN(row, firstRow, lastRow); CONSTRAIN(col, firstCol, lastCol); if (objc == 4) { r1 = r2 = row; c1 = c2 = col; } else { CONSTRAIN(r2, firstRow, lastRow); CONSTRAIN(c2, firstCol, lastCol); r1 = MIN(row,r2); r2 = MAX(row,r2); c1 = MIN(col,c2); c2 = MAX(col,c2); } switch (tablePtr->selectType) { case SEL_BOTH: if (firstCol > lastCol) c2--; /* No selectable columns in table */ if (firstRow > lastRow) r2--; /* No selectable rows in table */ clo = c1; chi = c2; c1 = firstCol; c2 = lastCol; key = 1; goto SET_CELLS; SET_BOTH: key = 0; c1 = clo; c2 = chi; case SEL_COL: r1 = firstRow; r2 = lastRow; if (firstCol > lastCol) c2--; /* No selectable columns in table */ break; case SEL_ROW: c1 = firstCol; c2 = lastCol; if (firstRow>lastRow) r2--; /* No selectable rows in table */ break; } SET_CELLS: entryPtr = Tcl_FirstHashEntry(tablePtr->selCells, &search); for ( row = r1; row <= r2; row++ ) { for ( col = c1; col <= c2; col++ ) { TableMakeArrayIndex(row, col, buf1); if (Tcl_FindHashEntry(tablePtr->selCells, buf1) == NULL) { Tcl_CreateHashEntry(tablePtr->selCells, buf1, &dummy); TableRefresh(tablePtr, row-tablePtr->rowOffset, col-tablePtr->colOffset, CELL); } } } if (key) goto SET_BOTH; /* Adjust the table for top left, selection on screen etc */ TableAdjustParams(tablePtr); /* If the table was previously empty and we want to export the * selection, we should grab it now */ if (entryPtr == NULL && tablePtr->exportSelection) { Tk_OwnSelection(tablePtr->tkwin, XA_PRIMARY, TableLostSelection, (ClientData) tablePtr); } return TCL_OK; } /* *-------------------------------------------------------------- * * Table_ViewCmd -- * This procedure is invoked to process the x|yview method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_ViewCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int row, col, value; char *xy; /* Check xview or yview */ if (objc > 5) { Tcl_WrongNumArgs(interp, 2, objv, "?args?"); return TCL_ERROR; } xy = Tcl_GetString(objv[1]); if (objc == 2) { Tcl_Obj *resultPtr; int diff, x, y, w, h; double first, last; resultPtr = Tcl_GetObjResult(interp); TableGetLastCell(tablePtr, &row, &col); TableCellVCoords(tablePtr, row, col, &x, &y, &w, &h, 0); if (*xy == 'y') { if (row < tablePtr->titleRows) { first = 0; last = 1; } else { diff = tablePtr->rowStarts[tablePtr->titleRows]; last = (double) (tablePtr->rowStarts[tablePtr->rows]-diff); first = (tablePtr->rowStarts[tablePtr->topRow]-diff) / last; last = (h+tablePtr->rowStarts[row]-diff) / last; } } else { if (col < tablePtr->titleCols) { first = 0; last = 1; } else { diff = tablePtr->colStarts[tablePtr->titleCols]; last = (double) (tablePtr->colStarts[tablePtr->cols]-diff); first = (tablePtr->colStarts[tablePtr->leftCol]-diff) / last; last = (w+tablePtr->colStarts[col]-diff) / last; } } Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewDoubleObj(first)); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewDoubleObj(last)); } else { /* cache old topleft to see if it changes */ int oldTop = tablePtr->topRow, oldLeft = tablePtr->leftCol; if (objc == 3) { if (Tcl_GetIntFromObj(interp, objv[2], &value) != TCL_OK) { return TCL_ERROR; } if (*xy == 'y') { tablePtr->topRow = value + tablePtr->titleRows; } else { tablePtr->leftCol = value + tablePtr->titleCols; } } else { int result; double frac; #if (TK_MINOR_VERSION > 0) /* 8.1+ */ result = Tk_GetScrollInfoObj(interp, objc, objv, &frac, &value); #else int i; Arg * args = (Arg *) ckalloc((objc + 1) * sizeof(Arg)); for (i = 0; i < objc; i++) { args[i] = LangStringArg(Tcl_GetString(objv[i])); } args[i] = NULL; result = Tk_GetScrollInfo(interp, objc, args, &frac, &value); ckfree ((char * ) args); #endif switch (result) { case TK_SCROLL_ERROR: return TCL_ERROR; case TK_SCROLL_MOVETO: if (frac < 0) frac = 0; if (*xy == 'y') { tablePtr->topRow = (int)(frac*tablePtr->rows) +tablePtr->titleRows; } else { tablePtr->leftCol = (int)(frac*tablePtr->cols) +tablePtr->titleCols; } break; case TK_SCROLL_PAGES: TableGetLastCell(tablePtr, &row, &col); if (*xy == 'y') { tablePtr->topRow += value * (row-tablePtr->topRow+1); } else { tablePtr->leftCol += value * (col-tablePtr->leftCol+1); } break; case TK_SCROLL_UNITS: if (*xy == 'y') { tablePtr->topRow += value; } else { tablePtr->leftCol += value; } break; } } /* maintain appropriate real index */ CONSTRAIN(tablePtr->topRow, tablePtr->titleRows, tablePtr->rows-1); CONSTRAIN(tablePtr->leftCol, tablePtr->titleCols, tablePtr->cols-1); /* Do the table adjustment if topRow || leftCol changed */ if (oldTop != tablePtr->topRow || oldLeft != tablePtr->leftCol) { TableAdjustParams(tablePtr); } } return TCL_OK; } #if 0 /* *-------------------------------------------------------------- * * Table_Cmd -- * This procedure is invoked to process the CMD method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_Cmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int result = TCL_OK; return result; } #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/chext�����������������������������������������������������������������������0000644�0000000�0000000�00000002012�13742524721�014526� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/local/bin/perl -w open(NEED,"<need") || die; while (<NEED>) { if (/\b([A-Z])\b\s*_?(.*)$/) { if ($1 ne 'U') { $def{$2} = $1; } else { $ref{$2} = 1; } } } close(NEED); @ARGV = <*.h>; while (<>) { if (/(extern|EXTERN|COREXT)\s*(.*)\s(\w+)\s+_ANSI_ARGS_/) { my $kind = $1; if (!exists($def{$3})) { if ($kind ne 'COREXT') { print STDERR "$ARGV:$.: $kind $3 not defined\n"; } print "$ARGV:$.: $3 not defined"; print " - but not referenced" unless (exists($ref{$3})); print "\n"; } } elsif (/(extern|EXTERN|COREXT)\s*(.*)\s(\w+)\s*;/) { my $kind = $1; if (!exists($def{$3})) { if ($kind ne 'COREXT') { print STDERR "$ARGV:$.: $kind $3 not defined\n"; } print "$ARGV:$.: $3 not defined"; print " - but not referenced" unless (exists($ref{$3})); print "\n"; } } $. = 0 if (eof); } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/tkTableCellSort.c�����������������������������������������������������������0000444�0000000�0000000�00000007717�13746047614�016716� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * tkTableCell.c -- * * This module implements cell sort functions for table * widgets. The MergeSort algorithm and other aux sorting * functions were taken from tclCmdIL.c lsort command: * tclCmdIL.c -- * * This file contains the top-level command routines for most of * the Tcl built-in commands whose names begin with the letters * I through L. It contains only commands in the generic core * (i.e. those that don't depend much upon UNIX facilities). * * Copyright (c) 1987-1993 The Regents of the University of California. * Copyright (c) 1993-1997 Lucent Technologies. * Copyright (c) 1994-1997 Sun Microsystems, Inc. * Copyright (c) 1998-1999 by Scriptics Corporation. * * Copyright (c) 1998-2002 Jeffrey Hobbs * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * */ #include "tkTable.h" #ifndef UCHAR #define UCHAR(c) ((unsigned char) (c)) #endif /* *---------------------------------------------------------------------- * * TableSortCompareProc -- * This procedure is invoked by qsort to determine the proper * ordering between two elements. * * Results: * < 0 means first is "smaller" than "second", > 0 means "first" * is larger than "second", and 0 means they should be treated * as equal. * * Side effects: * None, unless a user-defined comparison command does something * weird. * *---------------------------------------------------------------------- */ static int TableSortCompareProc(first, second) CONST VOID *first, *second; /* Elements to be compared. */ { int r1, c1, r2, c2; char *firstString; char *secondString; firstString = Tcl_GetString( *((Arg*) first)); secondString = Tcl_GetString(*((Arg*) second)); /* This doesn't account for badly formed indices */ sscanf(firstString, "%d,%d", &r1, &c1); sscanf(secondString, "%d,%d", &r2, &c2); if (r1 > r2) { return 1; } else if (r1 < r2) { return -1; } else if (c1 > c2) { return 1; } else if (c1 < c2) { return -1; } return 0; } /* *---------------------------------------------------------------------- * * TableCellSort -- * Sort a list of table cell elements (of form row,col) * * Results: * Returns the sorted list of elements. Because Tcl_Merge allocs * the space for result, it must later be Tcl_Free'd by caller. * * Side effects: * Behaviour undefined for ill-formed input list of elements. * *---------------------------------------------------------------------- */ Arg TableCellSort(Table *tablePtr, char *str) { int listArgc; Arg *listArgv; Arg result; Arg argstr; argstr = LangStringArg(str); if (Tcl_ListObjGetElements(tablePtr->interp, argstr, &listArgc, &listArgv) != TCL_OK) { ckfree((char *) argstr); return LangStringArg(str); } qsort((VOID *) listArgv, (size_t) listArgc, sizeof (char *), TableSortCompareProc); result = Tcl_NewListObj(listArgc, listArgv); return result; } /* *---------------------------------------------------------------------- * * TableCellSortObj -- * Sorts a list of table cell elements (of form row,col) in place * * Results: * Sorts list of elements in place. * * Side effects: * Behaviour undefined for ill-formed input list of elements. * *---------------------------------------------------------------------- */ Tcl_Obj * TableCellSortObj(Tcl_Interp *interp, Tcl_Obj *listObjPtr) { int length, i; Tcl_Obj* result; Tcl_Obj *sortedObjPtr, **listObjPtrs; if (Tcl_ListObjGetElements(interp, listObjPtr, &length, &listObjPtrs) != TCL_OK) { return NULL; } if (length <= 0) { return listObjPtr; } qsort((VOID *) listObjPtrs, (size_t) length, sizeof (char *), TableSortCompareProc); result = Tcl_NewListObj(length, listObjPtrs); return result; } �������������������������������������������������Tk-TableMatrix-1.26/pTk/tkTableTag.c����������������������������������������������������������������0000444�0000000�0000000�00000121370�13746047614�015672� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * tkTableTag.c -- * * This module implements tags for table widgets. * * Copyright (c) 1998-2002 Jeffrey Hobbs * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tkTableTag.c,v 1.18 2004/02/08 03:09:46 cerney Exp $ */ #include "tkVMacro.h" #include "tkTable.h" static TableTag *TableTagGetEntry _ANSI_ARGS_((Table *tablePtr, char *name, int objc, Tcl_Obj *CONST *objv)); static unsigned int TableTagGetPriority _ANSI_ARGS_((Table *tablePtr, TableTag *tagPtr)); static void TableImageProc _ANSI_ARGS_((ClientData clientData, int x, int y, int width, int height, int imageWidth, int imageHeight)); static int TableOptionReliefSet _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, Arg value, char *widgRec, int offset)); static Arg TableOptionReliefGet _ANSI_ARGS_((ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)); static CONST char *tagCmdNames[] = { "celltag", "cget", "coltag", "configure", "delete", "exists", "includes", "lower", "names", "raise", "rowtag", NULL }; enum tagCmd { TAG_CELLTAG, TAG_CGET, TAG_COLTAG, TAG_CONFIGURE, TAG_DELETE, TAG_EXISTS, TAG_INCLUDES, TAG_LOWER, TAG_NAMES, TAG_RAISE, TAG_ROWTAG }; static Cmd_Struct tagState_vals[]= { {"unknown", STATE_UNKNOWN}, {"normal", STATE_NORMAL}, {"disabled", STATE_DISABLED}, {"", 0 } }; static Tk_CustomOption tagStateOpt = { Cmd_OptionSet, Cmd_OptionGet, (ClientData) (&tagState_vals) }; static Tk_CustomOption tagBdOpt = { TableOptionBdSet, TableOptionBdGet, (ClientData) BD_TABLE_TAG }; static Tk_CustomOption tagReliefOpt = { TableOptionReliefSet, TableOptionReliefGet, (ClientData) NULL }; /* * The default specification for configuring tags * Done like this to make the command line parsing easy */ static Tk_ConfigSpec tagConfig[] = { {TK_CONFIG_ANCHOR, "-anchor", "anchor", "Anchor", "center", Tk_Offset(TableTag, anchor), TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK }, {TK_CONFIG_BORDER, "-background", "background", "Background", NULL, Tk_Offset(TableTag, bg), TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK }, {TK_CONFIG_SYNONYM, "-bd", "borderWidth", NULL, NULL, 0, 0}, {TK_CONFIG_SYNONYM, "-bg", "background", NULL, NULL, 0, 0}, {TK_CONFIG_CUSTOM, "-borderwidth", "borderWidth", "BorderWidth", "", 0 /* no offset */, TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK, &tagBdOpt }, {TK_CONFIG_BORDER, "-foreground", "foreground", "Foreground", NULL, Tk_Offset(TableTag, fg), TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK }, {TK_CONFIG_SYNONYM, "-fg", "foreground", NULL, NULL, 0, 0}, {TK_CONFIG_FONT, "-font", "font", "Font", NULL, Tk_Offset(TableTag, tkfont), TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK }, {TK_CONFIG_STRING, "-image", "image", "Image", NULL, Tk_Offset(TableTag, imageStr), TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK }, {TK_CONFIG_JUSTIFY, "-justify", "justify", "Justify", "left", Tk_Offset(TableTag, justify), TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK }, {TK_CONFIG_INT, "-multiline", "multiline", "Multiline", "-1", Tk_Offset(TableTag, multiline), TK_CONFIG_DONT_SET_DEFAULT }, {TK_CONFIG_CUSTOM, "-relief", "relief", "Relief", "flat", Tk_Offset(TableTag, relief), TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK, &tagReliefOpt }, {TK_CONFIG_INT, "-showtext", "showText", "ShowText", "-1", Tk_Offset(TableTag, showtext), TK_CONFIG_DONT_SET_DEFAULT }, {TK_CONFIG_CUSTOM, "-state", "state", "State", "unknown", Tk_Offset(TableTag, state), TK_CONFIG_DONT_SET_DEFAULT, &tagStateOpt }, {TK_CONFIG_INT, "-wrap", "wrap", "Wrap", "-1", Tk_Offset(TableTag, wrap), TK_CONFIG_DONT_SET_DEFAULT }, {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} }; /* * The join tag structure is used to create a combined tag, so it * keeps priority info. */ typedef struct { TableTag tag; /* must be first */ unsigned int magic; unsigned int pbg, pfg, pborders, prelief, ptkfont, panchor, pimage; unsigned int pstate, pjustify, pmultiline, pwrap, pshowtext; } TableJoinTag; /* *---------------------------------------------------------------------- * * TableImageProc -- * Called when an image associated with a tag is changed. * * Results: * None. * * Side effects: * Invalidates the whole table. * This should only invalidate affected cells, but that info * is not managed... * *---------------------------------------------------------------------- */ static void TableImageProc(ClientData clientData, int x, int y, int width, int height, int imageWidth, int imageHeight) { TableInvalidateAll((Table *)clientData, 0); } /* *---------------------------------------------------------------------- * * TableNewTag -- * ckallocs space for a new tag structure and inits the structure. * * Results: * Returns a pointer to the new structure. Must be freed later. * * Side effects: * None. * *---------------------------------------------------------------------- */ TableTag * TableNewTag(Table *tablePtr) { TableTag *tagPtr; /* * If tablePtr is NULL, make a regular tag, otherwise make a join tag. */ if (tablePtr == NULL) { tagPtr = (TableTag *) ckalloc(sizeof(TableTag)); memset((VOID *) tagPtr, 0, sizeof(TableTag)); /* * Set the values that aren't 0/NULL by default */ tagPtr->anchor = (Tk_Anchor)-1; tagPtr->justify = (Tk_Justify)-1; tagPtr->multiline = -1; tagPtr->relief = -1; tagPtr->showtext = -1; tagPtr->state = STATE_UNKNOWN; tagPtr->wrap = -1; } else { TableJoinTag *jtagPtr = (TableJoinTag *) ckalloc(sizeof(TableJoinTag)); memset((VOID *) jtagPtr, 0, sizeof(TableJoinTag)); tagPtr = (TableTag *) jtagPtr; tagPtr->anchor = (Tk_Anchor)-1; tagPtr->justify = (Tk_Justify)-1; tagPtr->multiline = -1; tagPtr->relief = -1; tagPtr->showtext = -1; tagPtr->state = STATE_UNKNOWN; tagPtr->wrap = -1; jtagPtr->magic = 0x99ABCDEF; jtagPtr->pbg = -1; jtagPtr->pfg = -1; jtagPtr->pborders = -1; jtagPtr->prelief = -1; jtagPtr->ptkfont = -1; jtagPtr->panchor = -1; jtagPtr->pimage = -1; jtagPtr->pstate = -1; jtagPtr->pjustify = -1; jtagPtr->pmultiline = -1; jtagPtr->pwrap = -1; jtagPtr->pshowtext = -1; } return (TableTag *) tagPtr; } /* *---------------------------------------------------------------------- * * TableResetTag -- * This routine resets a given tag to the table defaults. * * Results: * Tag will have values changed. * * Side effects: * None. * *---------------------------------------------------------------------- */ void TableResetTag(Table *tablePtr, TableTag *tagPtr) { TableJoinTag *jtagPtr = (TableJoinTag *) tagPtr; if (jtagPtr->magic != 0x99ABCDEF) { Tcl_Panic("bad mojo in TableResetTag"); } memset((VOID *) jtagPtr, 0, sizeof(TableJoinTag)); tagPtr->anchor = (Tk_Anchor)-1; tagPtr->justify = (Tk_Justify)-1; tagPtr->multiline = -1; tagPtr->relief = -1; tagPtr->showtext = -1; tagPtr->state = STATE_UNKNOWN; tagPtr->wrap = -1; jtagPtr->magic = 0x99ABCDEF; jtagPtr->pbg = -1; jtagPtr->pfg = -1; jtagPtr->pborders = -1; jtagPtr->prelief = -1; jtagPtr->ptkfont = -1; jtagPtr->panchor = -1; jtagPtr->pimage = -1; jtagPtr->pstate = -1; jtagPtr->pjustify = -1; jtagPtr->pmultiline = -1; jtagPtr->pwrap = -1; jtagPtr->pshowtext = -1; /* * Merge in the default tag. */ memcpy((VOID *) jtagPtr, (VOID *) &(tablePtr->defaultTag), sizeof(TableTag)); } /* *---------------------------------------------------------------------- * * TableMergeTag -- * This routine merges two tags by adding any fields from the addTag * that are set to the baseTag. * * Results: * baseTag will inherit all set characteristics of addTag * (addTag thus has the priority). * * Side effects: * None. * *---------------------------------------------------------------------- */ void TableMergeTag(Table *tablePtr, TableTag *baseTag, TableTag *addTag) { TableJoinTag *jtagPtr = (TableJoinTag *) baseTag; unsigned int prio; if (jtagPtr->magic != 0x99ABCDEF) { Tcl_Panic("bad mojo in TableMergeTag"); } #ifndef NO_TAG_PRIORITIES /* * Find priority for the tag to merge */ prio = TableTagGetPriority(tablePtr, addTag); if ((addTag->anchor != -1) && (prio < jtagPtr->panchor)) { baseTag->anchor = addTag->anchor; jtagPtr->panchor = prio; } if ((addTag->bg != NULL) && (prio < jtagPtr->pbg)) { baseTag->bg = addTag->bg; jtagPtr->pbg = prio; } if ((addTag->fg != NULL) && (prio < jtagPtr->pfg)) { baseTag->fg = addTag->fg; jtagPtr->pfg = prio; } if ((addTag->tkfont != NULL) && (prio < jtagPtr->ptkfont)) { baseTag->tkfont = addTag->tkfont; jtagPtr->ptkfont = prio; } if ((addTag->imageStr != NULL) && (prio < jtagPtr->pimage)) { baseTag->imageStr = addTag->imageStr; baseTag->image = addTag->image; jtagPtr->pimage = prio; } if ((addTag->multiline >= 0) && (prio < jtagPtr->pmultiline)) { baseTag->multiline = addTag->multiline; jtagPtr->pmultiline = prio; } if ((addTag->relief != -1) && (prio < jtagPtr->prelief)) { baseTag->relief = addTag->relief; jtagPtr->prelief = prio; } if ((addTag->showtext >= 0) && (prio < jtagPtr->pshowtext)) { baseTag->showtext = addTag->showtext; jtagPtr->pshowtext = prio; } if ((addTag->state != STATE_UNKNOWN) && (prio < jtagPtr->pstate)) { baseTag->state = addTag->state; jtagPtr->pstate = prio; } if ((addTag->justify != -1) && (prio < jtagPtr->pjustify)) { baseTag->justify = addTag->justify; jtagPtr->pjustify = prio; } if ((addTag->wrap >= 0) && (prio < jtagPtr->pwrap)) { baseTag->wrap = addTag->wrap; jtagPtr->pwrap = prio; } if ((addTag->borders) && (prio < jtagPtr->pborders)) { baseTag->borderStr = addTag->borderStr; baseTag->borders = addTag->borders; baseTag->bd[0] = addTag->bd[0]; baseTag->bd[1] = addTag->bd[1]; baseTag->bd[2] = addTag->bd[2]; baseTag->bd[3] = addTag->bd[3]; jtagPtr->pborders = prio; } #else if (addTag->anchor != -1) baseTag->anchor = addTag->anchor; if (addTag->bg != NULL) baseTag->bg = addTag->bg; if (addTag->fg != NULL) baseTag->fg = addTag->fg; if (addTag->tkfont != NULL) baseTag->tkfont = addTag->tkfont; if (addTag->imageStr != NULL) { baseTag->imageStr = addTag->imageStr; baseTag->image = addTag->image; } if (addTag->multiline >= 0) baseTag->multiline = addTag->multiline; if (addTag->relief != -1) baseTag->relief = addTag->relief; if (addTag->showtext >= 0) baseTag->showtext = addTag->showtext; if (addTag->state != STATE_UNKNOWN) baseTag->state = addTag->state; if (addTag->justify != -1) baseTag->justify = addTag->justify; if (addTag->wrap >= 0) baseTag->wrap = addTag->wrap; if (addTag->borders) { baseTag->borderStr = addTag->borderStr; baseTag->borders = addTag->borders; baseTag->bd[0] = addTag->bd[0]; baseTag->bd[1] = addTag->bd[1]; baseTag->bd[2] = addTag->bd[2]; baseTag->bd[3] = addTag->bd[3]; } #endif } /* *---------------------------------------------------------------------- * * TableInvertTag -- * This routine swaps background and foreground for the selected tag. * * Results: * Inverts fg and bg of tag. * * Side effects: * None. * *---------------------------------------------------------------------- */ void TableInvertTag(TableTag *baseTag) { Tk_3DBorder tmpBg; tmpBg = baseTag->fg; baseTag->fg = baseTag->bg; baseTag->bg = tmpBg; } /* *---------------------------------------------------------------------- * * TableGetTagBorders -- * This routine gets the border values based on a tag. * * Results: * It returns the values in the int*'s (if not NULL), and the * total number of defined borders as a result. * * Side effects: * None. * *---------------------------------------------------------------------- */ int TableGetTagBorders(TableTag *tagPtr, int *left, int *right, int *top, int *bottom) { switch (tagPtr->borders) { case 0: if (left) { *left = 0; } if (right) { *right = 0; } if (top) { *top = 0; } if (bottom) { *bottom = 0; } break; case 1: if (left) { *left = tagPtr->bd[0]; } if (right) { *right = tagPtr->bd[0]; } if (top) { *top = tagPtr->bd[0]; } if (bottom) { *bottom = tagPtr->bd[0]; } break; case 2: if (left) { *left = tagPtr->bd[0]; } if (right) { *right = tagPtr->bd[1]; } if (top) { *top = 0; } if (bottom) { *bottom = 0; } break; case 4: if (left) { *left = tagPtr->bd[0]; } if (right) { *right = tagPtr->bd[1]; } if (top) { *top = tagPtr->bd[2]; } if (bottom) { *bottom = tagPtr->bd[3]; } break; default: Tcl_Panic("invalid border value '%d'\n", tagPtr->borders); break; } return tagPtr->borders; } /* *---------------------------------------------------------------------- * * TableTagGetEntry -- * Takes a name and optional args and creates a tag entry in the * table's tag table. * * Results: * A new tag entry will be created and returned. * * Side effects: * None. * *---------------------------------------------------------------------- */ static TableTag * TableTagGetEntry(Table *tablePtr, char *name, int objc, Tcl_Obj *CONST *objv) { Tcl_HashEntry *entryPtr; TableTag *tagPtr = NULL; int new; entryPtr = Tcl_CreateHashEntry(tablePtr->tagTable, name, &new); if (new) { tagPtr = TableNewTag(NULL); Tcl_SetHashValue(entryPtr, (ClientData) tagPtr); if (tablePtr->tagPrioSize >= tablePtr->tagPrioMax) { int i; /* * Increase the priority list size in blocks of 10 */ tablePtr->tagPrioMax += 10; tablePtr->tagPrioNames = (char **) ckrealloc( (char *) tablePtr->tagPrioNames, sizeof(TableTag *) * tablePtr->tagPrioMax); tablePtr->tagPrios = (TableTag **) ckrealloc( (char *) tablePtr->tagPrios, sizeof(TableTag *) * tablePtr->tagPrioMax); for (i = tablePtr->tagPrioSize; i < tablePtr->tagPrioMax; i++) { tablePtr->tagPrioNames[i] = NULL; tablePtr->tagPrios[i] = (TableTag *) NULL; } } tablePtr->tagPrioNames[tablePtr->tagPrioSize] = (char *) Tcl_GetHashKey(tablePtr->tagTable, entryPtr); tablePtr->tagPrios[tablePtr->tagPrioSize] = tagPtr; tablePtr->tagPrioSize++; } else { tagPtr = (TableTag *) Tcl_GetHashValue(entryPtr); } if (objc) { Tk_ConfigureWidget(tablePtr->interp, tablePtr->tkwin, tagConfig, objc, objv, (char *)tagPtr, TK_CONFIG_ARGV_ONLY); } return tagPtr; } /* *---------------------------------------------------------------------- * * TableTagGetPriority -- * Get the priority value for a tag. * * Results: * returns the priority. * * Side effects: * None. * *---------------------------------------------------------------------- */ static unsigned int TableTagGetPriority(Table *tablePtr, TableTag *tagPtr) { unsigned int prio = 0; while (tagPtr != tablePtr->tagPrios[prio]) { prio++; } return prio; } /* *---------------------------------------------------------------------- * * TableInitTags -- * Creates the static table tags. * * Results: * active, sel, title and flash are created as tags. * * Side effects: * None. * *---------------------------------------------------------------------- */ void TableInitTags(Table *tablePtr) { Arg activeArgs[4]; Arg selArgs[6]; Arg titleArgs[8]; Arg flashArgs[2]; activeArgs[0]= LangStringArg("-bg"); activeArgs[1]= LangStringArg(ACTIVE_BG); activeArgs[2]=LangStringArg("-relief"); activeArgs[3]=LangStringArg("flat"); selArgs[0]= LangStringArg("-bg"); selArgs[1]=LangStringArg(SELECT_BG); selArgs[2]=LangStringArg("-fg"); selArgs[3]=LangStringArg(SELECT_FG); selArgs[4]=LangStringArg("-relief"); selArgs[5]=LangStringArg("sunken"); titleArgs[0]=LangStringArg("-bg"), titleArgs[1]=LangStringArg(DISABLED), titleArgs[2]=LangStringArg("-fg"), titleArgs[3]=LangStringArg("white"), titleArgs[4]=LangStringArg("-relief"), titleArgs[5]=LangStringArg("flat"), titleArgs[6]=LangStringArg("-state"), titleArgs[7]=LangStringArg("disabled"); flashArgs[0]= LangStringArg("-bg"); flashArgs[1]=LangStringArg("red"); /* * The order of creation is important to priority. */ TableTagGetEntry(tablePtr, "flash", ARSIZE(flashArgs), flashArgs); TableTagGetEntry(tablePtr, "active", ARSIZE(activeArgs), activeArgs); TableTagGetEntry(tablePtr, "sel", ARSIZE(selArgs), selArgs); TableTagGetEntry(tablePtr, "title", ARSIZE(titleArgs), titleArgs); } /* *---------------------------------------------------------------------- * * FindRowColTag -- * Finds a row/col tag based on the row/col styles and tagCommand. * * Results: * Returns tag associated with row/col cell, if any. * * Side effects: * Possible side effects from eval of tagCommand. * IMPORTANT: This plays with the interp result object, * so use of resultPtr in prior command may be invalid after * calling this function. * *---------------------------------------------------------------------- */ TableTag * FindRowColTag(Table *tablePtr, int cell, int mode) { Tcl_HashEntry *entryPtr; TableTag *tagPtr = NULL; /* kill(0,2); */ entryPtr = Tcl_FindHashEntry((mode == ROW) ? tablePtr->rowStyles : tablePtr->colStyles, (char *) cell); if (entryPtr == NULL) { LangCallback *cmd = (mode == ROW) ? tablePtr->rowTagCmd : tablePtr->colTagCmd; if (cmd) { register Tcl_Interp *interp = tablePtr->interp; char buf[INDEX_BUFSIZE]; /* * Since no specific row/col tag exists, eval the given command * with row/col appended */ sprintf(buf, " %d", cell); Tcl_Preserve((ClientData) interp); if ( LangDoCallback(interp, cmd, 1, 1, " %d", cell) == TCL_OK) { CONST char *name = Tcl_GetStringFromObj(Tcl_GetObjResult(interp),NULL); if (name && *name) { /* * If a result was returned, check to see if it is * a valid tag. */ entryPtr = Tcl_FindHashEntry(tablePtr->tagTable, name); } } Tcl_Release((ClientData) interp); Tcl_ResetResult(interp); } } if (entryPtr != NULL) { /* * This can be either the one in row|colStyles, * or that returned by eval'ing the row|colTagCmd */ tagPtr = (TableTag *) Tcl_GetHashValue(entryPtr); } return tagPtr; } /* *---------------------------------------------------------------------- * * TableCleanupTag -- * Releases the resources used by a tag before it is freed up. * * Results: * None. * * Side effects: * The tag is no longer valid. * *---------------------------------------------------------------------- */ void TableCleanupTag(Table *tablePtr, TableTag *tagPtr) { /* * Free resources that the optionSpec doesn't specifically know about */ if (tagPtr->image) { Tk_FreeImage(tagPtr->image); } Tk_FreeOptions(tagConfig, (char *) tagPtr, tablePtr->display, 0); } /* *-------------------------------------------------------------- * * Table_TagCmd -- * This procedure is invoked to process the tag method * that corresponds to a widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_TagCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *)clientData; int result = TCL_OK, cmdIndex, i, newEntry, value, len; int row, col, tagPrio, refresh = 0; TableTag *tagPtr, *tag2Ptr; Tcl_HashEntry *entryPtr, *scanPtr; Tcl_HashTable *hashTblPtr; Tcl_HashSearch search; Tk_Image image; Tcl_Obj *objPtr, *resultPtr; char buf[INDEX_BUFSIZE], *keybuf, *tagname; if (objc < 3) { Tcl_WrongNumArgs(interp, 2, objv, "option ?arg arg ...?"); return TCL_ERROR; } result = Tcl_GetIndexFromObj(interp, objv[2], tagCmdNames, "tag option", 0, &cmdIndex); if (result != TCL_OK) { return result; } /* * Before using this object, make sure there aren't any calls that * could have changed the interp result, thus freeing the object. */ resultPtr = Tcl_GetObjResult(interp); switch ((enum tagCmd) cmdIndex) { case TAG_CELLTAG: /* add named tag to a (group of) cell(s) */ if (objc < 4) { Tcl_WrongNumArgs(interp, 3, objv, "tag ?arg arg ...?"); return TCL_ERROR; } tagname = Tcl_GetStringFromObj(objv[3], &len); if (len == 0) { /* * An empty string was specified, so just delete the tag. */ tagPtr = NULL; } else { /* * Get the pointer to the tag structure. If it doesn't * exist, it will be created. */ tagPtr = TableTagGetEntry(tablePtr, tagname, 0, NULL); } if (objc == 4) { /* * The user just wants the cells with this tag returned. * Handle specially tags named: active, flash, sel, title */ if ((tablePtr->flags & HAS_ACTIVE) && STREQ(tagname, "active")) { TableMakeArrayIndex( tablePtr->activeRow+tablePtr->rowOffset, tablePtr->activeCol+tablePtr->colOffset, buf); Tcl_SetStringObj(resultPtr, buf, -1); } else if ((tablePtr->flashMode && STREQ(tagname, "flash")) || STREQ(tagname, "sel")) { hashTblPtr = (*tagname == 's') ? tablePtr->selCells : tablePtr->flashCells; for (scanPtr = Tcl_FirstHashEntry(hashTblPtr, &search); scanPtr != NULL; scanPtr = Tcl_NextHashEntry(&search)) { keybuf = (char *) Tcl_GetHashKey(hashTblPtr, scanPtr); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewStringObj(keybuf, -1)); } } else if (STREQ(tagname, "title") && (tablePtr->titleRows || tablePtr->titleCols)) { for (row = tablePtr->rowOffset; row < tablePtr->rowOffset+tablePtr->rows; row++) { for (col = tablePtr->colOffset; col < tablePtr->colOffset+tablePtr->titleCols; col++) { TableMakeArrayIndex(row, col, buf); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewStringObj(buf, -1)); } } for (row = tablePtr->rowOffset; row < tablePtr->rowOffset+tablePtr->titleRows; row++) { for (col = tablePtr->colOffset+tablePtr->titleCols; col < tablePtr->colOffset+tablePtr->cols; col++) { TableMakeArrayIndex(row, col, buf); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewStringObj(buf, -1)); } } } else { /* * Check this tag pointer amongst all tagged cells */ for (scanPtr = Tcl_FirstHashEntry(tablePtr->cellStyles, &search); scanPtr != NULL; scanPtr = Tcl_NextHashEntry(&search)) { if ((TableTag *) Tcl_GetHashValue(scanPtr) == tagPtr) { keybuf = (char *) Tcl_GetHashKey( tablePtr->cellStyles, scanPtr); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewStringObj(keybuf, -1)); } } } return TCL_OK; } /* * Loop through the arguments and fill in the hash table */ for (i = 4; i < objc; i++) { /* * Try and parse the index */ if (TableGetIndexObj(tablePtr, objv[i], &row, &col) != TCL_OK) { return TCL_ERROR; } /* * Get the hash key ready */ TableMakeArrayIndex(row, col, buf); if (tagPtr == NULL) { /* * This is a deletion */ entryPtr = Tcl_FindHashEntry(tablePtr->cellStyles, buf); if (entryPtr != NULL) { Tcl_DeleteHashEntry(entryPtr); refresh = 1; } } else { /* * Add a key to the hash table and set it to point to the * Tag structure if it wasn't the same as an existing one */ entryPtr = Tcl_CreateHashEntry(tablePtr->cellStyles, buf, &newEntry); if (newEntry || (tagPtr != (TableTag *) Tcl_GetHashValue(entryPtr))) { Tcl_SetHashValue(entryPtr, (ClientData) tagPtr); refresh = 1; } } /* * Now invalidate this cell for redraw */ if (refresh) { TableRefresh(tablePtr, row-tablePtr->rowOffset, col-tablePtr->colOffset, CELL); } } return TCL_OK; case TAG_COLTAG: case TAG_ROWTAG: { /* tag a row or a column */ int forRows = (cmdIndex == TAG_ROWTAG); if (objc < 4) { Tcl_WrongNumArgs(interp, 3, objv, "tag ?arg arg ..?"); return TCL_ERROR; } tagname = Tcl_GetStringFromObj(objv[3], &len); if (len == 0) { /* * Empty string, so we want to delete this element */ tagPtr = NULL; } else { /* * Get the pointer to the tag structure. If it doesn't * exist, it will be created. */ tagPtr = TableTagGetEntry(tablePtr, tagname, 0, NULL); } /* * Choose the correct hash table based on args */ hashTblPtr = forRows ? tablePtr->rowStyles : tablePtr->colStyles; if (objc == 4) { /* the user just wants the tagged cells to be returned */ /* Special handling for tags: active, flash, sel, title */ if ((tablePtr->flags & HAS_ACTIVE) && strcmp(tagname, "active") == 0) { Tcl_SetIntObj(resultPtr, (forRows ? tablePtr->activeRow+tablePtr->rowOffset : tablePtr->activeCol+tablePtr->colOffset)); } else if ((tablePtr->flashMode && STREQ(tagname, "flash")) || STREQ(tagname, "sel")) { Tcl_HashTable *cacheTblPtr; cacheTblPtr = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(cacheTblPtr, TCL_ONE_WORD_KEYS); hashTblPtr = (*tagname == 's') ? tablePtr->selCells : tablePtr->flashCells; for (scanPtr = Tcl_FirstHashEntry(hashTblPtr, &search); scanPtr != NULL; scanPtr = Tcl_NextHashEntry(&search)) { TableParseArrayIndex(&row, &col, Tcl_GetHashKey(hashTblPtr, scanPtr)); value = forRows ? row : col; entryPtr = Tcl_CreateHashEntry(cacheTblPtr, (char *)value, &newEntry); if (newEntry) { Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewIntObj(value)); } } Tcl_DeleteHashTable(cacheTblPtr); ckfree((char *) (cacheTblPtr)); } else if (STREQ(tagname, "title") && (forRows?tablePtr->titleRows:tablePtr->titleCols)) { if (forRows) { for (row = tablePtr->rowOffset; row < tablePtr->rowOffset+tablePtr->titleRows; row++) { Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewIntObj(row)); } } else { for (col = tablePtr->colOffset; col < tablePtr->colOffset+tablePtr->titleCols; col++) { Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewIntObj(col)); } } } else { for (scanPtr = Tcl_FirstHashEntry(hashTblPtr, &search); scanPtr != NULL; scanPtr = Tcl_NextHashEntry(&search)) { /* is this the tag pointer on this row */ if ((TableTag *) Tcl_GetHashValue(scanPtr) == tagPtr) { objPtr = Tcl_NewIntObj( (int) Tcl_GetHashKey(hashTblPtr, scanPtr)); Tcl_ListObjAppendElement(NULL, resultPtr, objPtr); } } } return TCL_OK; } /* * Loop through the arguments and fill in the hash table */ for (i = 4; i < objc; i++) { /* * Try and parse the index */ if (Tcl_GetIntFromObj(interp, objv[i], &value) != TCL_OK) { return TCL_ERROR; } if (tagPtr == NULL) { /* * This is a deletion */ entryPtr = Tcl_FindHashEntry(hashTblPtr, (char *)value); if (entryPtr != NULL) { Tcl_DeleteHashEntry(entryPtr); refresh = 1; } } else { /* * Add a key to the hash table and set it to point to the * Tag structure if it wasn't the same as an existing one */ entryPtr = Tcl_CreateHashEntry(hashTblPtr, (char *) value, &newEntry); if (newEntry || (tagPtr != (TableTag *) Tcl_GetHashValue(entryPtr))) { Tcl_SetHashValue(entryPtr, (ClientData) tagPtr); refresh = 1; } } /* and invalidate the row or column affected */ if (refresh) { if (cmdIndex == TAG_ROWTAG) { TableRefresh(tablePtr, value-tablePtr->rowOffset, 0, ROW); } else { TableRefresh(tablePtr, 0, value-tablePtr->colOffset, COL); } } } return TCL_OK; /* COLTAG && ROWTAG */ } case TAG_CGET: if (objc != 5) { Tcl_WrongNumArgs(interp, 3, objv, "tagName option"); return TCL_ERROR; } tagname = Tcl_GetString(objv[3]); entryPtr = Tcl_FindHashEntry(tablePtr->tagTable, tagname); if (entryPtr == NULL) { goto invalidtag; } else { tagPtr = (TableTag *) Tcl_GetHashValue (entryPtr); result = Tk_ConfigureValue(interp, tablePtr->tkwin, tagConfig, (char *) tagPtr, Tcl_GetString(objv[4]), 0); /* * This is a work-around to fix a bug in Tk_ConfigureValue * that would set Tcl_GetResult(interp) to NULL for -borderwidth * which has no associated tag offset value. This was fixed * in 8.3.5 and 8.4b1. [Bug #522882] */ if (Tcl_GetObjResult(interp) == NULL) { Tcl_SetResult(interp, "",TCL_STATIC); } } return result; /* CGET */ case TAG_CONFIGURE: if (objc < 4) { Tcl_WrongNumArgs(interp, 3, objv, "tagName ?arg arg ...?"); return TCL_ERROR; } /* * Get the pointer to the tag structure. If it doesn't * exist, it will be created. */ tagPtr = TableTagGetEntry(tablePtr, Tcl_GetString(objv[3]), 0, NULL); /* * If there were less than 6 args, we return the configuration * (for all or just one option), even for new tags */ if (objc < 6) { result = Tk_ConfigureInfo(interp, tablePtr->tkwin, tagConfig, (char *) tagPtr, (objc == 5) ? Tcl_GetString(objv[4]) : NULL, 0); } else { Arg *args; /* Stringify */ args = (Arg *) ckalloc((objc + 1) * sizeof(Arg)); for (i = 0; i < objc; i++) args[i] = LangStringArg(Tcl_GetString(objv[i])); args[objc] = NULL; result = Tk_ConfigureWidget(interp, tablePtr->tkwin, tagConfig, objc-4, args+4, (char *) tagPtr, TK_CONFIG_ARGV_ONLY); ckfree((char *) args); if (result == TCL_ERROR) { return TCL_ERROR; } /* * Handle change of image name */ if (tagPtr->imageStr) { image = Tk_GetImage(interp, tablePtr->tkwin, tagPtr->imageStr, TableImageProc, (ClientData)tablePtr); if (image == NULL) { result = TCL_ERROR; } } else { image = NULL; } if (tagPtr->image) { Tk_FreeImage(tagPtr->image); } tagPtr->image = image; /* * We reconfigured, so invalidate the table to redraw */ TableInvalidateAll(tablePtr, 0); } return result; case TAG_DELETE: /* delete a tag */ if (objc < 4) { Tcl_WrongNumArgs(interp, 3, objv, "tagName ?tagName ...?"); return TCL_ERROR; } /* run through the remaining arguments */ for (i = 3; i < objc; i++) { tagname = Tcl_GetString(objv[i]); /* cannot delete the title tag */ if (STREQ(tagname, "title") || STREQ(tagname, "sel") || STREQ(tagname, "flash") || STREQ(tagname, "active")) { Tcl_AppendStringsToObj(resultPtr, "cannot delete ", tagname, " tag", NULL); return TCL_ERROR; } entryPtr = Tcl_FindHashEntry(tablePtr->tagTable, tagname); if (entryPtr != NULL) { /* get the tag pointer */ tagPtr = (TableTag *) Tcl_GetHashValue(entryPtr); /* delete all references to this tag in rows */ scanPtr = Tcl_FirstHashEntry(tablePtr->rowStyles, &search); for (; scanPtr != NULL; scanPtr = Tcl_NextHashEntry(&search)) { if ((TableTag *)Tcl_GetHashValue(scanPtr) == tagPtr) { Tcl_DeleteHashEntry(scanPtr); refresh = 1; } } /* delete all references to this tag in cols */ scanPtr = Tcl_FirstHashEntry(tablePtr->colStyles, &search); for (; scanPtr != NULL; scanPtr = Tcl_NextHashEntry(&search)) { if ((TableTag *)Tcl_GetHashValue(scanPtr) == tagPtr) { Tcl_DeleteHashEntry(scanPtr); refresh = 1; } } /* delete all references to this tag in cells */ scanPtr = Tcl_FirstHashEntry(tablePtr->cellStyles, &search); for (; scanPtr != NULL; scanPtr = Tcl_NextHashEntry(&search)) { if ((TableTag *)Tcl_GetHashValue(scanPtr) == tagPtr) { Tcl_DeleteHashEntry(scanPtr); refresh = 1; } } /* * Remove the tag from the prio list and collapse * the rest of the tags. We could check for shrinking * the prio list as well. */ for (i = 0; i < tablePtr->tagPrioSize; i++) { if (tablePtr->tagPrios[i] == tagPtr) break; } for ( ; i < tablePtr->tagPrioSize; i++) { tablePtr->tagPrioNames[i] = tablePtr->tagPrioNames[i+1]; tablePtr->tagPrios[i] = tablePtr->tagPrios[i+1]; } tablePtr->tagPrioSize--; /* Release the tag structure */ TableCleanupTag(tablePtr, tagPtr); ckfree((char *) tagPtr); /* And free the hash table entry */ Tcl_DeleteHashEntry(entryPtr); } } /* since we deleted a tag, redraw the screen */ if (refresh) { TableInvalidateAll(tablePtr, 0); } return result; case TAG_EXISTS: if (objc != 4) { Tcl_WrongNumArgs(interp, 3, objv, "tagName"); return TCL_ERROR; } Tcl_SetBooleanObj(resultPtr, (Tcl_FindHashEntry(tablePtr->tagTable, Tcl_GetString(objv[3])) != NULL)); return TCL_OK; case TAG_INCLUDES: /* does a tag contain a index ? */ if (objc != 5) { Tcl_WrongNumArgs(interp, 3, objv, "tag index"); return TCL_ERROR; } tagname = Tcl_GetString(objv[3]); /* check to see if the tag actually exists */ entryPtr = Tcl_FindHashEntry(tablePtr->tagTable, tagname); if (entryPtr == NULL) { /* Unknown tag, just return 0 */ Tcl_SetBooleanObj(resultPtr, 0); return TCL_OK; } /* parse index */ if (TableGetIndexObj(tablePtr, objv[4], &row, &col) != TCL_OK) { return TCL_ERROR; } /* create hash key */ TableMakeArrayIndex(row, col, buf); if (STREQ(tagname, "active")) { result = (tablePtr->activeRow+tablePtr->rowOffset==row && tablePtr->activeCol+tablePtr->colOffset==col); } else if (STREQ(tagname, "flash")) { result = (tablePtr->flashMode && (Tcl_FindHashEntry(tablePtr->flashCells, buf) != NULL)); } else if (STREQ(tagname, "sel")) { result = (Tcl_FindHashEntry(tablePtr->selCells, buf) != NULL); } else if (STREQ(tagname, "title")) { result = (row < tablePtr->titleRows+tablePtr->rowOffset || col < tablePtr->titleCols+tablePtr->colOffset); } else { /* get the pointer to the tag structure */ tagPtr = (TableTag *) Tcl_GetHashValue(entryPtr); scanPtr = Tcl_FindHashEntry(tablePtr->cellStyles, buf); /* * Look to see if there is a cell, row, or col tag * for this cell */ result = ((scanPtr && (tagPtr == (TableTag *) Tcl_GetHashValue(scanPtr))) || (tagPtr == FindRowColTag(tablePtr, row, ROW)) || (tagPtr == FindRowColTag(tablePtr, col, COL))); } /* * Because we may call FindRowColTag above, we can't use * the resultPtr, but this is almost equivalent, and is SAFE */ Tcl_SetObjResult(interp, Tcl_NewIntObj(result)); return TCL_OK; case TAG_NAMES: /* * Print out the tag names in priority order */ if (objc < 3 || objc > 4) { Tcl_WrongNumArgs(interp, 3, objv, "?pattern?"); return TCL_ERROR; } tagname = (objc == 4) ? Tcl_GetString(objv[3]) : NULL; for (i = 0; i < tablePtr->tagPrioSize; i++) { keybuf = tablePtr->tagPrioNames[i]; if (objc == 3 || Tcl_StringMatch(keybuf, tagname)) { objPtr = Tcl_NewStringObj(keybuf, -1); Tcl_ListObjAppendElement(NULL, resultPtr, objPtr); } } return TCL_OK; case TAG_LOWER: case TAG_RAISE: /* * Change priority of the named tag */ if (objc != 4 && objc != 5) { Tcl_WrongNumArgs(interp, 3, objv, (cmdIndex == TAG_LOWER) ? "tagName ?belowThis?" : "tagName ?aboveThis?"); return TCL_ERROR; } tagname = Tcl_GetString(objv[3]); /* check to see if the tag actually exists */ entryPtr = Tcl_FindHashEntry(tablePtr->tagTable, tagname); if (entryPtr == NULL) { goto invalidtag; } tagPtr = (TableTag *) Tcl_GetHashValue(entryPtr); tagPrio = TableTagGetPriority(tablePtr, tagPtr); keybuf = tablePtr->tagPrioNames[tagPrio]; /* * In the RAISE case, the priority is one higher (-1) because * we want the named tag to move above the other in priority. */ if (objc == 5) { tagname = Tcl_GetString(objv[4]); entryPtr = Tcl_FindHashEntry(tablePtr->tagTable, tagname); if (entryPtr == NULL) { goto invalidtag; } tag2Ptr = (TableTag *) Tcl_GetHashValue(entryPtr); if (cmdIndex == TAG_LOWER) { value = TableTagGetPriority(tablePtr, tag2Ptr); } else { value = TableTagGetPriority(tablePtr, tag2Ptr) - 1; } } else { if (cmdIndex == TAG_LOWER) { /* * Lower this tag's priority to the bottom. */ value = tablePtr->tagPrioSize - 1; } else { /* * Raise this tag's priority to the top. */ value = -1; } } if (value < tagPrio) { /* * Move tag up in priority. */ for (i = tagPrio; i > value; i--) { tablePtr->tagPrioNames[i] = tablePtr->tagPrioNames[i-1]; tablePtr->tagPrios[i] = tablePtr->tagPrios[i-1]; } i++; tablePtr->tagPrioNames[i] = keybuf; tablePtr->tagPrios[i] = tagPtr; refresh = 1; } else if (value > tagPrio) { /* * Move tag down in priority. */ for (i = tagPrio; i < value; i++) { tablePtr->tagPrioNames[i] = tablePtr->tagPrioNames[i+1]; tablePtr->tagPrios[i] = tablePtr->tagPrios[i+1]; } tablePtr->tagPrioNames[i] = keybuf; tablePtr->tagPrios[i] = tagPtr; refresh = 1; } /* since we deleted a tag, redraw the screen */ if (refresh) { TableInvalidateAll(tablePtr, 0); } return TCL_OK; } return TCL_OK; invalidtag: /* * When jumping here, ensure the invalid 'tagname' is set already. */ Tcl_AppendStringsToObj(resultPtr, "invalid tag name \"", tagname, "\"", NULL); return TCL_ERROR; } /* *---------------------------------------------------------------------- * * TableOptionReliefSet -- * * This routine configures the borderwidth value for a tag. * * Results: * A standard Tcl result. * * Side effects: * It may adjust the tag struct values of relief[0..4] and borders. * *---------------------------------------------------------------------- */ static int TableOptionReliefSet(clientData, interp, tkwin, value, widgRec, offset) ClientData clientData; /* Type of struct being set. */ Tcl_Interp *interp; /* Used for reporting errors. */ Tk_Window tkwin; /* Window containing table widget. */ Arg value; /* Value of option. */ char *widgRec; /* Pointer to record for item. */ int offset; /* Offset into item. */ { TableTag *tagPtr = (TableTag *) widgRec; if (STREQ(Tcl_GetString(value),"")) { tagPtr->relief = -1; } else { return Tk_GetRelief(interp, Tcl_GetString(value), &(tagPtr->relief)); } return TCL_OK; } /* *---------------------------------------------------------------------- * * TableOptionReliefGet -- * * Results: * Value of the tag's -relief option. * * Side effects: * None. * *---------------------------------------------------------------------- */ static Arg TableOptionReliefGet(clientData, tkwin, widgRec, offset, freeProcPtr) ClientData clientData; /* Type of struct being set. */ Tk_Window tkwin; /* Window containing canvas widget. */ char *widgRec; /* Pointer to record for item. */ int offset; /* Offset into item. */ Tcl_FreeProc **freeProcPtr; /* Pointer to variable to fill in with * information about how to reclaim * storage for return string. */ { return LangStringArg( Tk_NameOfRelief(((TableTag *) widgRec)->relief)); } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/from������������������������������������������������������������������������0000644�0000000�0000000�00000001031�13742524721�014356� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/local/bin/perl -w use strict; use File::Find; my %mTk; sub scan { if (/\.[ch]$/) { my $name = $File::Find::name; if (exists $mTk{$_}) { warn "$_ = $mTk{$_} and $name\n"; } $mTk{$_} = $name; } } find(\&scan,"mTk"); opendir(DIR,".") || die; foreach (sort readdir(DIR)) { if (/\.[ch]$/) { if (exists $mTk{$_}) { my $path = $mTk{$_}; print "$path => $_\n"; } else { warn "$_ is orphan\n"; } } } close(DIR); �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/makeenglish�����������������������������������������������������������������0000644�0000000�0000000�00000002217�13742524721�015711� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/local/bin/perl -w # BEGIN { push(@INC, qw(../../../lib ../../lib ../lib lib)) } die "Must be executed from Tk/pTk distribution directory\n" unless -f "Lang.h"; open(STDOUT, ">../Tk/English.pm") || die "open failed: $!"; print <<'EOH'; package Tk::English; require Exporter; use base (Exporter); # This file is generated automatically by pTk/makeenglish from Tk distribution. EOH my %found = (); opendir(DIR,'.') || die "Cannot open '.':$!"; @ARGV = grep(/\.c/,readdir(DIR)); closedir(DIR); while (<>) { if (/strn?cmp\s*\(.*"([a-z][a-z0-9]+)"/) {my $key = $1; my $name = "\U$key"; if (!defined $found{$name}) { $found{$name} = $key; } } } print "\n\@EXPORT = qw(\n"; $line = ""; foreach (sort keys %found) { if (length($line)+length($_)+2 > 76) { print " $line\n"; $line = ""; } else { $line .= ' ' if (length $line); } $line .= "&$_"; } print " $line\n" if (length $line); print ");\n"; foreach $name (sort keys %found) { my $key = $found{$name}; print qq(sub $name () { '$key' }\n); } print "\n1;\n"; ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/license.terms���������������������������������������������������������������0000644�0000000�0000000�00000004310�13745605157�016177� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������This software is copyrighted by the Regents of the University of California, Sun Microsystems, Inc., and other parties. The following terms apply to all files associated with the software unless explicitly disclaimed in individual files. The authors hereby grant permission to use, copy, modify, distribute, and license this software and its documentation for any purpose, provided that existing copyright notices are retained in all copies and that this notice is included verbatim in any distributions. No written agreement, license, or royalty fee is required for any of the authorized uses. Modifications to this software may be copyrighted by their authors and need not follow the licensing terms described here, provided that the new terms are clearly indicated on the first page of each file where they apply. IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. GOVERNMENT USE: If you are acquiring this software on behalf of the U.S. government, the Government shall have only "Restricted Rights" in the software and related documentation as defined in the Federal Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you are acquiring the software on behalf of the Department of Defense, the software shall be classified as "Commercial Computer Software" and the Government shall have only "Restricted Rights" as defined in Clause 252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the authors grant the U.S. Government and others acting in its behalf permission to use and distribute the software in accordance with the terms specified in this license. ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/defs������������������������������������������������������������������������0000644�0000000�0000000�00000000053�13742524721�014337� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh nm -p "$@" | grep ' [A-TV-Z] ' �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/tkTableCell.c���������������������������������������������������������������0000444�0000000�0000000�00000125722�13746047614�016043� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * tkTableCell.c -- * * This module implements cell oriented functions for table * widgets. * * Copyright (c) 1998-2000 Jeffrey Hobbs * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tkTableCell.c,v 1.17 2004/02/08 03:09:46 cerney Exp $ */ #include "tkVMacro.h" #include "tkTable.h" static int TableSortCompareProc _ANSI_ARGS_((CONST VOID *first, CONST VOID *second)); /* *---------------------------------------------------------------------- * * TableTrueCell -- * Takes a row,col pair in user coords and returns the true * cell that it relates to, either dimension bounded, or a * span cell if it was hidden. * * Results: * The true row, col in user coords are placed in the pointers. * If the value changed for some reasons, 0 is returned (it was not * the /true/ cell). * * Side effects: * None. * *---------------------------------------------------------------------- */ int TableTrueCell(Table *tablePtr, int r, int c, int *row, int *col) { *row = r; *col = c; /* * We check spans before constraints, because we don't want to * constrain and then think we ended up in a span */ if (tablePtr->spanAffTbl && !(tablePtr->flags & AVOID_SPANS)) { char buf[INDEX_BUFSIZE]; Tcl_HashEntry *entryPtr; TableMakeArrayIndex(r, c, buf); entryPtr = Tcl_FindHashEntry(tablePtr->spanAffTbl, buf); if ((entryPtr != NULL) && ((char *)Tcl_GetHashValue(entryPtr) != NULL)) { /* * This cell is covered by another spanning cell. * We need to return the coords for that spanning cell. */ TableParseArrayIndex(row, col, (char *)Tcl_GetHashValue(entryPtr)); return 0; } } *row = BETWEEN(r, tablePtr->rowOffset, tablePtr->rows-1+tablePtr->rowOffset); *col = BETWEEN(c, tablePtr->colOffset, tablePtr->cols-1+tablePtr->colOffset); return ((*row == r) && (*col == c)); } /* *---------------------------------------------------------------------- * * TableCellCoords -- * Takes a row,col pair in real coords and finds it position * on the virtual screen. * * Results: * The virtual x, y, width, and height of the cell * are placed in the pointers. * * Side effects: * None. * *---------------------------------------------------------------------- */ int TableCellCoords(Table *tablePtr, int row, int col, int *x, int *y, int *w, int *h) { register int hl = tablePtr->highlightWidth; int result = CELL_OK; if (tablePtr->rows <= 0 || tablePtr->cols <= 0) { *w = *h = *x = *y = 0; return CELL_BAD; } /* * Real coords required, always should be passed acceptable values, * but this is a possible seg fault otherwise */ CONSTRAIN(row, 0, tablePtr->rows-1); CONSTRAIN(col, 0, tablePtr->cols-1); *w = tablePtr->colPixels[col]; *h = tablePtr->rowPixels[row]; /* * Adjust for sizes of spanning cells * and ensure that this cell isn't "hidden" */ if (tablePtr->spanAffTbl && !(tablePtr->flags & AVOID_SPANS)) { char buf[INDEX_BUFSIZE]; Tcl_HashEntry *entryPtr; TableMakeArrayIndex(row+tablePtr->rowOffset, col+tablePtr->colOffset, buf); entryPtr = Tcl_FindHashEntry(tablePtr->spanAffTbl, buf); if (entryPtr != NULL) { int rs, cs; char *cell; cell = (char *) Tcl_GetHashValue(entryPtr); if (cell != NULL) { /* This cell is covered by another spanning cell */ /* We need to return the coords for that cell */ TableParseArrayIndex(&rs, &cs, cell); *w = rs; *h = cs; result = CELL_HIDDEN; goto setxy; } /* Get the actual span values out of spanTbl */ entryPtr = Tcl_FindHashEntry(tablePtr->spanTbl, buf); cell = (char *) Tcl_GetHashValue(entryPtr); TableParseArrayIndex(&rs, &cs, cell); if (rs > 0) { /* * Make sure we don't overflow our space */ if (row < tablePtr->titleRows) { rs = MIN(tablePtr->titleRows-1, row+rs); } else { rs = MIN(tablePtr->rows-1, row+rs); } *h = tablePtr->rowStarts[rs+1]-tablePtr->rowStarts[row]; result = CELL_SPAN; } else if (rs <= 0) { /* currently negative spans are not supported */ } if (cs > 0) { /* * Make sure we don't overflow our space */ if (col < tablePtr->titleCols) { cs = MIN(tablePtr->titleCols-1, col+cs); } else { cs = MIN(tablePtr->cols-1, col+cs); } *w = tablePtr->colStarts[cs+1]-tablePtr->colStarts[col]; result = CELL_SPAN; } else if (cs <= 0) { /* currently negative spans are not supported */ } } } setxy: *x = hl + tablePtr->colStarts[col]; if (col >= tablePtr->titleCols) { *x -= tablePtr->colStarts[tablePtr->leftCol] - tablePtr->colStarts[tablePtr->titleCols]; } *y = hl + tablePtr->rowStarts[row]; if (row >= tablePtr->titleRows) { *y -= tablePtr->rowStarts[tablePtr->topRow] - tablePtr->rowStarts[tablePtr->titleRows]; } return result; } /* *---------------------------------------------------------------------- * * TableCellVCoords -- * Takes a row,col pair in real coords and finds it position * on the actual screen. The full arg specifies whether * only 100% visible cells should be considered visible. * * Results: * The x, y, width, and height of the cell are placed in the pointers, * depending upon visibility of the cell. * Returns 0 for hidden and 1 for visible cells. * * Side effects: * None. * *---------------------------------------------------------------------- */ int TableCellVCoords(Table *tablePtr, int row, int col, int *rx, int *ry, int *rw, int *rh, int full) { int x, y, w, h, w0, h0, cellType, hl = tablePtr->highlightWidth; if (tablePtr->tkwin == NULL) return 0; /* * Necessary to use separate vars in case dummies are passed in */ cellType = TableCellCoords(tablePtr, row, col, &x, &y, &w, &h); *rx = x; *ry = y; *rw = w; *rh = h; if (cellType == CELL_OK) { if ((row < tablePtr->topRow && row >= tablePtr->titleRows) || (col < tablePtr->leftCol && col >= tablePtr->titleCols)) { /* * A non-spanning cell hiding in "dead" space * between title areas and visible cells */ return 0; } } else if (cellType == CELL_SPAN) { /* * we might need to treat full better is CELL_SPAN but primary * cell is visible */ int topX = tablePtr->colStarts[tablePtr->titleCols]+hl; int topY = tablePtr->rowStarts[tablePtr->titleRows]+hl; if ((col < tablePtr->leftCol) && (col >= tablePtr->titleCols)) { if (full || (x+w < topX)) { return 0; } else { w -= topX-x; x = topX; } } if ((row < tablePtr->topRow) && (row >= tablePtr->titleRows)) { if (full || (y+h < topY)) { return 0; } else { h -= topY-y; y = topY; } } /* * re-set these according to changed coords */ *rx = x; *ry = y; *rw = w; *rh = h; } else { /* * If it is a hidden cell, then w,h is the row,col in user coords * of the cell that spans over this one */ return 0; } /* * At this point, we know it is on the screen, * but not if we can see 100% of it (if we care) */ if (full) { w0 = w; h0 = h; } else { /* * if we don't care about seeing the whole thing, then * make sure we at least see a pixel worth */ w0 = h0 = 1; } /* * Is the cell visible? */ if ((x < hl) || (y < hl) || ((x+w0) > (Tk_Width(tablePtr->tkwin)-hl)) || ((y+h0) > (Tk_Height(tablePtr->tkwin)-hl))) { /* definitely off the screen */ return 0; } else { /* if it was full, then w,h are already be properly constrained */ if (!full) { *rw = MIN(w, Tk_Width(tablePtr->tkwin)-hl-x); *rh = MIN(h, Tk_Height(tablePtr->tkwin)-hl-y); } return 1; } } /* *---------------------------------------------------------------------- * * TableWhatCell -- * Takes a x,y screen coordinate and determines what cell contains. * that point. This will return cells that are beyond the right/bottom * edge of the viewable screen. * * Results: * The row,col of the cell are placed in the pointers. * * Side effects: * None. * *---------------------------------------------------------------------- */ void TableWhatCell(register Table *tablePtr, int x, int y, int *row, int *col) { int i; x = MAX(0, x); y = MAX(0, y); /* Adjust for table's global highlightthickness border */ x -= tablePtr->highlightWidth; y -= tablePtr->highlightWidth; /* Adjust the x coord if not in the column titles to change display coords * into internal coords */ x += (x < tablePtr->colStarts[tablePtr->titleCols]) ? 0 : tablePtr->colStarts[tablePtr->leftCol] - tablePtr->colStarts[tablePtr->titleCols]; y += (y < tablePtr->rowStarts[tablePtr->titleRows]) ? 0 : tablePtr->rowStarts[tablePtr->topRow] - tablePtr->rowStarts[tablePtr->titleRows]; x = MIN(x, tablePtr->maxWidth-1); y = MIN(y, tablePtr->maxHeight-1); for (i = 1; x >= tablePtr->colStarts[i]; i++); *col = i - 1; for (i = 1; y >= tablePtr->rowStarts[i]; i++); *row = i - 1; if (tablePtr->spanAffTbl && !(tablePtr->flags & AVOID_SPANS)) { char buf[INDEX_BUFSIZE]; Tcl_HashEntry *entryPtr; /* We now correct the returned cell if this was "hidden" */ TableMakeArrayIndex(*row+tablePtr->rowOffset, *col+tablePtr->colOffset, buf); entryPtr = Tcl_FindHashEntry(tablePtr->spanAffTbl, buf); if ((entryPtr != NULL) && /* We have to make sure this was not already hidden * that's an error */ ((char *)Tcl_GetHashValue(entryPtr) != NULL)) { /* this is a "hidden" cell */ TableParseArrayIndex(row, col, (char *)Tcl_GetHashValue(entryPtr)); *row -= tablePtr->rowOffset; *col -= tablePtr->colOffset; } } } /* *---------------------------------------------------------------------- * * TableAtBorder -- * Takes a x,y screen coordinate and determines if that point is * over a border. * * Results: * The left/top row,col corresponding to that point are placed in * the pointers. The number of borders (+1 for row, +1 for col) * hit is returned. * * Side effects: * None. * *---------------------------------------------------------------------- */ int TableAtBorder(Table * tablePtr, int x, int y, int *row, int *col) { int i, brow, bcol, borders = 2, bd[6]; TableGetTagBorders(&(tablePtr->defaultTag), &bd[0], &bd[1], &bd[2], &bd[3]); bd[4] = (bd[0] + bd[1])/2; bd[5] = (bd[2] + bd[3])/2; /* * Constrain x && y appropriately, and adjust x if it is not in the * column titles to change display coords into internal coords. */ x = MAX(0, x); y = MAX(0, y); x -= tablePtr->highlightWidth; y -= tablePtr->highlightWidth; x += (x < tablePtr->colStarts[tablePtr->titleCols]) ? 0 : tablePtr->colStarts[tablePtr->leftCol] - tablePtr->colStarts[tablePtr->titleCols]; x = MIN(x, tablePtr->maxWidth - 1); for (i = 1; (i <= tablePtr->cols) && (x + (bd[0] + bd[1])) >= tablePtr->colStarts[i]; i++); if (x > tablePtr->colStarts[--i] + bd[4]) { borders--; *col = -1; bcol = (i < tablePtr->leftCol && i >= tablePtr->titleCols) ? tablePtr->titleCols-1 : i-1; } else { bcol = *col = (i < tablePtr->leftCol && i >= tablePtr->titleCols) ? tablePtr->titleCols-1 : i-1; } y += (y < tablePtr->rowStarts[tablePtr->titleRows]) ? 0 : tablePtr->rowStarts[tablePtr->topRow] - tablePtr->rowStarts[tablePtr->titleRows]; y = MIN(y, tablePtr->maxHeight - 1); for (i = 1; i <= tablePtr->rows && (y + (bd[2] + bd[3])) >= tablePtr->rowStarts[i]; i++); if (y > tablePtr->rowStarts[--i]+bd[5]) { borders--; *row = -1; brow = (i < tablePtr->topRow && i >= tablePtr->titleRows) ? tablePtr->titleRows-1 : i-1; } else { brow = *row = (i < tablePtr->topRow && i >= tablePtr->titleRows) ? tablePtr->titleRows-1 : i-1; } /* * We have to account for spanning cells, which may hide cells. * In that case, we have to decrement our border count. */ if (tablePtr->spanAffTbl && !(tablePtr->flags & AVOID_SPANS) && borders) { Tcl_HashEntry *entryPtr1, *entryPtr2 ; char buf1[INDEX_BUFSIZE], buf2[INDEX_BUFSIZE]; char *val; if (*row != -1) { TableMakeArrayIndex(brow+tablePtr->rowOffset, bcol+tablePtr->colOffset+1, buf1); TableMakeArrayIndex(brow+tablePtr->rowOffset+1, bcol+tablePtr->colOffset+1, buf2); entryPtr1 = Tcl_FindHashEntry(tablePtr->spanAffTbl, buf1); entryPtr2 = Tcl_FindHashEntry(tablePtr->spanAffTbl, buf2); if (entryPtr1 != NULL && entryPtr2 != NULL) { if ((val = (char *) Tcl_GetHashValue(entryPtr1)) != NULL) { strcpy(buf1, val); } if ((val = (char *) Tcl_GetHashValue(entryPtr2)) != NULL) { strcpy(buf2, val); } if (strcmp(buf1, buf2) == 0) { borders--; *row = -1; } } } if (*col != -1) { TableMakeArrayIndex(brow+tablePtr->rowOffset+1, bcol+tablePtr->colOffset, buf1); TableMakeArrayIndex(brow+tablePtr->rowOffset+1, bcol+tablePtr->colOffset+1, buf2); entryPtr1 = Tcl_FindHashEntry(tablePtr->spanAffTbl, buf1); entryPtr2 = Tcl_FindHashEntry(tablePtr->spanAffTbl, buf2); if (entryPtr1 != NULL && entryPtr2 != NULL) { if ((val = (char *) Tcl_GetHashValue(entryPtr1)) != NULL) { strcpy(buf1, val); } if ((val = (char *) Tcl_GetHashValue(entryPtr2)) != NULL) { strcpy(buf2, val); } if (strcmp(buf1, buf2) == 0) { borders--; *col = -1; } } } } return borders; } /* *---------------------------------------------------------------------- * * TableGetCellValue -- * Takes a row,col pair in user coords and returns the value for * that cell. This varies depending on what data source the * user has selected. * * Results: * The value of the cell is returned. The return value is VOLATILE * (do not free). * * Side effects: * The value will be cached if caching is turned on. * *---------------------------------------------------------------------- */ char * TableGetCellValue(Table *tablePtr, int r, int c) { register Tcl_Interp *interp = tablePtr->interp; char *result = NULL; char buf[INDEX_BUFSIZE]; Tcl_HashEntry *entryPtr = NULL; int new = 1; TableMakeArrayIndex(r, c, buf); if (tablePtr->caching) { /* * If we are caching, let's see if we have the value cached */ entryPtr = Tcl_CreateHashEntry(tablePtr->cache, buf, &new); if (!new) { result = (char *) Tcl_GetHashValue(entryPtr); if (result == NULL) { result = ""; } goto VALUE; } } if (tablePtr->command && tablePtr->useCmd) { if (LangDoCallback(interp, tablePtr->command, 1, 3, "%d %d %d",0,r,c) == TCL_ERROR) { tablePtr->useCmd = 0; tablePtr->dataSource &= ~DATA_COMMAND; if (tablePtr->arrayVar) tablePtr->dataSource |= DATA_ARRAY; Tcl_AddErrorInfo(interp, "\n\t(in -command evaled by table)"); Tcl_BackgroundError(interp); TableInvalidateAll(tablePtr, 0); } else { result = (char *) Tcl_GetStringFromObj(Tcl_GetObjResult(interp),NULL); } /* Tcl_FreeResult(interp); not support for perl/tk */ } else if (tablePtr->arrayVar) { result = Tcl_GetString(Tcl_ObjGetVar2(interp, tablePtr->arrayVar, Tcl_NewStringObj(buf,-1), TCL_GLOBAL_ONLY)); } if (result == NULL) result = ""; if (tablePtr->caching && entryPtr != NULL) { /* * If we are caching, make sure we cache the returned value * * entryPtr will have been set from above, but check to make sure * someone didn't change caching during -command evaluation. */ char *val; val = (char *)ckalloc(strlen(result)+1); strcpy(val, result); Tcl_SetHashValue(entryPtr, val); } VALUE: #ifdef PROCS if (result != NULL) { /* Do we have procs, are we showing their value, is this a proc? */ if (tablePtr->hasProcs && !tablePtr->showProcs && *result == '=' && !(r-tablePtr->rowOffset == tablePtr->activeRow && c-tablePtr->colOffset == tablePtr->activeCol)) { Tcl_DString script; /* provides a rough mutex on preventing proc loops */ entryPtr = Tcl_CreateHashEntry(tablePtr->inProc, buf, &new); if (!new) { Tcl_SetHashValue(entryPtr, 1); Tcl_AddErrorInfo(interp, "\n\t(loop hit in proc evaled by table)"); return result; } Tcl_SetHashValue(entryPtr, 0); Tcl_DStringInit(&script); ExpandPercents(tablePtr, result+1, r, c, result+1, NULL, 0, &script, 0); if (Tcl_GlobalEval(interp, Tcl_DStringValue(&script)) != TCL_OK || Tcl_GetHashValue(entryPtr) == 1) { Tcl_AddErrorInfo(interp, "\n\tin proc evaled by table:\n"); Tcl_AddErrorInfo(interp, Tcl_DStringValue(&script)); Tcl_BackgroundError(interp); } else { result = Tcl_GetResult(interp); } /* Tcl_FreeResult(interp); Not Supported for perl/tk */ Tcl_DStringFree(&script); Tcl_DeleteHashEntry(entryPtr); } } #endif return (result?result:""); } /* *---------------------------------------------------------------------- * * TableSetCellValue -- * Takes a row,col pair in user coords and saves the given value for * that cell. This varies depending on what data source the * user has selected. * * Results: * Returns TCL_ERROR or TCL_OK, depending on whether an error * occured during set (ie: during evaluation of -command). * * Side effects: * If the value is NULL (empty string), it will be unset from * an array rather than set to the empty string. * *---------------------------------------------------------------------- */ int TableSetCellValue(Table *tablePtr, int r, int c, char *value) { register Tcl_Interp *interp = tablePtr->interp; char buf[INDEX_BUFSIZE]; int code = TCL_OK, flash = 0; TableMakeArrayIndex(r, c, buf); if (tablePtr->state == STATE_DISABLED) { return TCL_OK; } if (tablePtr->command && tablePtr->useCmd) { if (LangDoCallback(interp, tablePtr->command, 1, 4, "%d %d %d %_",1,r,c, LangStringArg(value)) == TCL_ERROR) { /* An error resulted. Prevent further triggering of the command * and set up the error message. */ tablePtr->useCmd = 0; tablePtr->dataSource &= ~DATA_COMMAND; if (tablePtr->arrayVar) tablePtr->dataSource |= DATA_ARRAY; Tcl_AddErrorInfo(interp, "\n\t(in command executed by table)"); Tcl_BackgroundError(interp); code = TCL_ERROR; } else { flash = 1; } Tcl_SetResult(interp, NULL, TCL_STATIC); } else if (tablePtr->arrayVar) { /* Warning: checking for \0 as the first char could invalidate * allowing it as a valid first char */ if ((value == NULL || *value == '\0') && tablePtr->sparse) { /* perltk not supported */ /* Tcl_UnsetVar2(interp, LangString(Tcl_GetVar(interp, tablePtr->arrayVar, TCL_GLOBAL_ONLY)), buf, TCL_GLOBAL_ONLY); */ /* Replaced with This (defined in tkTable.xs) */ tkTableUnsetElement(tablePtr->arrayVar, buf); } else if (Tcl_ObjSetVar2(interp, tablePtr->arrayVar, Tcl_NewStringObj(buf,-1), Tcl_NewStringObj(value,-1), TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) { code = TCL_ERROR; } } if (code == TCL_ERROR) { return TCL_ERROR; } if (tablePtr->caching) { Tcl_HashEntry *entryPtr; int new; char *val; entryPtr = Tcl_CreateHashEntry(tablePtr->cache, buf, &new); if (!new) { val = (char *) Tcl_GetHashValue(entryPtr); if (val) ckfree(val); } val = (char *)ckalloc(strlen(value)+1); strcpy(val, value); Tcl_SetHashValue(entryPtr, val); flash = 1; } /* We do this conditionally because the var array already has * it's own check to flash */ if (flash && tablePtr->flashMode) { r -= tablePtr->rowOffset; c -= tablePtr->colOffset; TableAddFlash(tablePtr, r, c); TableRefresh(tablePtr, r, c, CELL); } return TCL_OK; } /* *---------------------------------------------------------------------- * * TableMoveCellValue -- * To move cells faster on delete/insert line or col when cache is on * and variable, command is off. * To avoid another call to TableMakeArrayIndex(r, c, buf), * we optionally provide the buffers. * outOfBounds means we will just set the cell value to "" * * Results: * Returns TCL_ERROR or TCL_OK, depending on whether an error * occured during set (ie: during evaluation of -command). * * Side effects: * If the value is NULL (empty string), it will be unset from * an array rather than set to the empty string. * *---------------------------------------------------------------------- */ int TableMoveCellValue(Table *tablePtr, int fromr, int fromc, char *frombuf, int tor, int toc, char *tobuf, int outOfBounds) { int new; char *result = NULL; Tcl_Interp *interp = tablePtr->interp; if (outOfBounds) { return TableSetCellValue(tablePtr, tor, toc, ""); } if (tablePtr->caching && (!(tablePtr->command && tablePtr->useCmd))) { Tcl_HashEntry *entryPtr; /* * if we are caching, let's see if we have the value cached */ entryPtr = Tcl_CreateHashEntry(tablePtr->cache, frombuf, &new); if (!new) { char *val; result = (char *) Tcl_GetHashValue(entryPtr); /* * we set tho old value to NULL */ Tcl_SetHashValue(entryPtr, NULL); /* * set the destination to the source pointer without new mallocing! */ entryPtr = Tcl_CreateHashEntry(tablePtr->cache, tobuf, &new); /* * free old value */ if (!new) { val = (char *) Tcl_GetHashValue(entryPtr); if (val) ckfree(val); } Tcl_SetHashValue(entryPtr, result); if (tablePtr->arrayVar) { /* * first, delete from var. */ /* perltk not supported */ /*Tcl_UnsetVar2(interp, tablePtr->arrayVar, frombuf, TCL_GLOBAL_ONLY); */ /* Replaced with This (defined in tkTable.xs) */ tkTableUnsetElement(tablePtr->arrayVar, frombuf); /* * Warning: checking for \0 as the first char could invalidate * allowing it as a valid first char */ if (Tcl_ObjSetVar2(interp, tablePtr->arrayVar, Tcl_NewStringObj(tobuf,-1), Tcl_NewStringObj(result, -1), TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) { return TCL_ERROR; } } return TCL_OK; } } /* * We have to do it the old way */ return TableSetCellValue(tablePtr, tor, toc, TableGetCellValue(tablePtr, fromr, fromc)); } /* *---------------------------------------------------------------------- * * TableGetIcursor -- * Parses the argument as an index into the active cell string. * Recognises 'end', 'insert' or an integer. Constrains it to the * size of the buffer. This acts like a "SetIcursor" when *posn is NULL. * * Results: * If (posn != NULL), then it gets the cursor position. * * Side effects: * Can move cursor position. * *---------------------------------------------------------------------- */ int TableGetIcursor(Table *tablePtr, char *arg, int *posn) { int tmp, len; len = strlen(tablePtr->activeBuf); #ifdef TCL_UTF_MAX /* Need to base it off strlen to account for \x00 (Unicode null) */ len = Tcl_NumUtfChars(tablePtr->activeBuf, len); #endif /* ensure icursor didn't get out of sync */ if (tablePtr->icursor > len) tablePtr->icursor = len; /* is this end */ if (strcmp(arg, "end") == 0) { tmp = len; } else if (strcmp(arg, "insert") == 0) { tmp = tablePtr->icursor; } else { if (Tcl_GetIntFromObj(tablePtr->interp, LangStringArg(arg), &tmp) != TCL_OK) { return TCL_ERROR; } CONSTRAIN(tmp, 0, len); } if (posn) { *posn = tmp; } else { tablePtr->icursor = tmp; } return TCL_OK; } /* *-------------------------------------------------------------- * * TableGetIndex -- * Parse an index into a table and return either its value * or an error. * * Results: * A standard Tcl result. If all went well, then *row,*col is * filled in with the index corresponding to string. If an * error occurs then an error message is left in interp result. * The index returned is in user coords. * * Side effects: * Sets row,col index to an appropriately constrained user index. * *-------------------------------------------------------------- */ int TableGetIndex(tablePtr, str, row_p, col_p) register Table *tablePtr; /* Table for which the index is being * specified. */ char *str; /* Symbolic specification of cell in table. */ int *row_p; /* Where to store converted row. */ int *col_p; /* Where to store converted col. */ { int r, c, len = strlen(str); char dummy; /* * Note that all of these values will be adjusted by row/ColOffset */ if (str[0] == '@') { /* @x,y coordinate */ int x, y; if (sscanf(str+1, "%d,%d%c", &x, &y, &dummy) != 2) { /* Make sure it won't work for "2,3extrastuff" */ goto IndexError; } TableWhatCell(tablePtr, x, y, &r, &c); r += tablePtr->rowOffset; c += tablePtr->colOffset; } else if (*str == '-' || isdigit(str[0])) { if (sscanf(str, "%d,%d%c", &r, &c, &dummy) != 2) { /* Make sure it won't work for "2,3extrastuff" */ goto IndexError; } /* ensure appropriate user index */ CONSTRAIN(r, tablePtr->rowOffset, tablePtr->rows-1+tablePtr->rowOffset); CONSTRAIN(c, tablePtr->colOffset, tablePtr->cols-1+tablePtr->colOffset); } else if (len > 1 && strncmp(str, "active", len) == 0 ) { /* active */ if (tablePtr->flags & HAS_ACTIVE) { r = tablePtr->activeRow+tablePtr->rowOffset; c = tablePtr->activeCol+tablePtr->colOffset; } else { Tcl_SetStringObj(Tcl_GetObjResult(tablePtr->interp), "no \"active\" cell in table", -1); return TCL_ERROR; } } else if (len > 1 && strncmp(str, "anchor", len) == 0) { /* anchor */ if (tablePtr->flags & HAS_ANCHOR) { r = tablePtr->anchorRow+tablePtr->rowOffset; c = tablePtr->anchorCol+tablePtr->colOffset; } else { Tcl_SetStringObj(Tcl_GetObjResult(tablePtr->interp), "no \"anchor\" cell in table", -1); return TCL_ERROR; } } else if (strncmp(str, "end", len) == 0) { /* end */ r = tablePtr->rows-1+tablePtr->rowOffset; c = tablePtr->cols-1+tablePtr->colOffset; } else if (strncmp(str, "origin", len) == 0) { /* origin */ r = tablePtr->titleRows+tablePtr->rowOffset; c = tablePtr->titleCols+tablePtr->colOffset; } else if (strncmp(str, "topleft", len) == 0) { /* topleft */ r = tablePtr->topRow+tablePtr->rowOffset; c = tablePtr->leftCol+tablePtr->colOffset; } else if (strncmp(str, "bottomright", len) == 0) { /* bottomright */ /* * FIX: Should this avoid spans, or consider them in the bottomright? tablePtr->flags |= AVOID_SPANS; tablePtr->flags &= ~AVOID_SPANS; */ TableGetLastCell(tablePtr, &r, &c); r += tablePtr->rowOffset; c += tablePtr->colOffset; } else { IndexError: Tcl_AppendStringsToObj(Tcl_GetObjResult(tablePtr->interp), "bad table index \"", str, "\": must be active, anchor, end, ", "origin, topleft, bottomright, @x,y, or <row>,<col>", NULL); return TCL_ERROR; } /* Note: values are expected to be properly constrained * as a user index by this point */ if (row_p) *row_p = r; if (col_p) *col_p = c; return TCL_OK; } /* *-------------------------------------------------------------- * * Table_SetCmd -- * This procedure is invoked to process the set method * that corresponds to a widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_SetCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *)clientData; int row, col, len, i, j, max; char *str; /* sets any number of tags/indices to a given value */ if (objc < 3) { CMD_SET_USAGE: Tcl_WrongNumArgs(interp, 2, objv, "?row|col? index ?value? ?index value ...?"); return TCL_ERROR; } /* make sure there is a data source to accept set */ if (tablePtr->dataSource == DATA_NONE) { return TCL_OK; } str = Tcl_GetStringFromObj(objv[2], &len); if (strncmp(str, "row", len) == 0 || strncmp(str, "col", len) == 0) { Tcl_Obj *resultPtr = Tcl_GetObjResult(interp); /* set row index list ?index list ...? */ if (objc < 4) { goto CMD_SET_USAGE; } else if (objc == 4) { if (TableGetIndexObj(tablePtr, objv[3], &row, &col) != TCL_OK) { return TCL_ERROR; } if (*str == 'r') { max = tablePtr->cols+tablePtr->colOffset; for (i=col; i<max; i++) { str = TableGetCellValue(tablePtr, row, i); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewStringObj(str, -1)); } } else { max = tablePtr->rows+tablePtr->rowOffset; for (i=row; i<max; i++) { str = TableGetCellValue(tablePtr, i, col); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewStringObj(str, -1)); } } } else if (tablePtr->state == STATE_NORMAL) { int listc; Tcl_Obj **listv; /* make sure there are an even number of index/list pairs */ if (objc & 0) { goto CMD_SET_USAGE; } for (i = 3; i < objc-1; i += 2) { if ((TableGetIndexObj(tablePtr, objv[i], &row, &col) != TCL_OK) || (Tcl_ListObjGetElements(interp, objv[i+1], &listc, &listv) != TCL_OK)) { return TCL_ERROR; } if (*str == 'r') { max = col+MIN(tablePtr->cols+tablePtr->colOffset-col, listc); for (j = col; j < max; j++) { if (TableSetCellValue(tablePtr, row, j, Tcl_GetString(listv[j-col])) != TCL_OK) { return TCL_ERROR; } if (row-tablePtr->rowOffset == tablePtr->activeRow && j-tablePtr->colOffset == tablePtr->activeCol) { TableGetActiveBuf(tablePtr); } TableRefresh(tablePtr, row-tablePtr->rowOffset, j-tablePtr->colOffset, CELL); } } else { max = row+MIN(tablePtr->rows+tablePtr->rowOffset-row, listc); for (j = row; j < max; j++) { if (TableSetCellValue(tablePtr, j, col, Tcl_GetString(listv[j-row])) != TCL_OK) { return TCL_ERROR; } if (j-tablePtr->rowOffset == tablePtr->activeRow && col-tablePtr->colOffset == tablePtr->activeCol) { TableGetActiveBuf(tablePtr); } TableRefresh(tablePtr, j-tablePtr->rowOffset, col-tablePtr->colOffset, CELL); } } } } } else if (objc == 3) { /* set index */ if (TableGetIndexObj(tablePtr, objv[2], &row, &col) != TCL_OK) { return TCL_ERROR; } else { /* * Cannot use Tcl_GetObjResult here because TableGetCellValue * can corrupt the resultPtr. */ Tcl_SetObjResult(interp, Tcl_NewStringObj( TableGetCellValue(tablePtr, row, col),-1)); } } else { /* set index val ?index val ...? */ /* make sure there are an even number of index/value pairs */ if (objc & 1) { goto CMD_SET_USAGE; } for (i = 2; i < objc-1; i += 2) { if ((TableGetIndexObj(tablePtr, objv[i], &row, &col) != TCL_OK) || (TableSetCellValue(tablePtr, row, col, Tcl_GetString(objv[i+1])) != TCL_OK)) { return TCL_ERROR; } row -= tablePtr->rowOffset; col -= tablePtr->colOffset; if (row == tablePtr->activeRow && col == tablePtr->activeCol) { TableGetActiveBuf(tablePtr); } TableRefresh(tablePtr, row, col, CELL); } } return TCL_OK; } /* *-------------------------------------------------------------- * * Table_SpanSet -- * Takes row,col in user coords and sets a span on the * cell if possible * * Results: * A standard Tcl result * * Side effects: * The span can be constrained * *-------------------------------------------------------------- */ static int Table_SpanSet(register Table *tablePtr, int urow, int ucol, int rs, int cs) { Tcl_Interp *interp = tablePtr->interp; int i, j, new, ors, ocs, result = TCL_OK; int row, col; Tcl_HashEntry *entryPtr; Tcl_HashSearch search; char *dbuf, buf[INDEX_BUFSIZE], cell[INDEX_BUFSIZE], span[INDEX_BUFSIZE]; row = urow - tablePtr->rowOffset; col = ucol - tablePtr->colOffset; TableMakeArrayIndex(urow, ucol, cell); if (tablePtr->spanTbl == NULL) { tablePtr->spanTbl = (Tcl_HashTable *)ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(tablePtr->spanTbl, TCL_STRING_KEYS); tablePtr->spanAffTbl = (Tcl_HashTable *)ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(tablePtr->spanAffTbl, TCL_STRING_KEYS); } /* first check in the affected cells table */ if ((entryPtr=Tcl_FindHashEntry(tablePtr->spanAffTbl, cell)) != NULL) { /* We have to make sure this was not already hidden * that's an error */ if ((char *)Tcl_GetHashValue(entryPtr) != NULL) { Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "cannot set spanning on hidden cell ", cell, NULL); return TCL_ERROR; } } /* do constraints on the spans * title cells must not expand beyond the titles * other cells can't expand negatively into title area */ if ((row < tablePtr->titleRows) && (row + rs >= tablePtr->titleRows)) { rs = tablePtr->titleRows - row - 1; } if ((col < tablePtr->titleCols) && (col + cs >= tablePtr->titleCols)) { cs = tablePtr->titleCols - col - 1; } rs = MAX(0, rs); cs = MAX(0, cs); /* then work in the span cells table */ if ((entryPtr = Tcl_FindHashEntry(tablePtr->spanTbl, cell)) != NULL) { /* We have to readjust for what was there first */ TableParseArrayIndex(&ors, &ocs, (char *)Tcl_GetHashValue(entryPtr)); ckfree((char *) Tcl_GetHashValue(entryPtr)); Tcl_DeleteHashEntry(entryPtr); for (i = urow; i <= urow+ors; i++) { for (j = ucol; j <= ucol+ocs; j++) { TableMakeArrayIndex(i, j, buf); entryPtr = Tcl_FindHashEntry(tablePtr->spanAffTbl, buf); if (entryPtr != NULL) { Tcl_DeleteHashEntry(entryPtr); } TableRefresh(tablePtr, i-tablePtr->rowOffset, j-tablePtr->colOffset, CELL); } } } else { ors = ocs = 0; } /* calc to make sure that span is OK */ for (i = urow; i <= urow+rs; i++) { for (j = ucol; j <= ucol+cs; j++) { TableMakeArrayIndex(i, j, buf); entryPtr = Tcl_FindHashEntry(tablePtr->spanAffTbl, buf); if (entryPtr != NULL) { /* Something already spans here */ Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "cannot overlap already spanned cell ", buf, NULL); result = TCL_ERROR; rs = ors; cs = ocs; break; } } if (result == TCL_ERROR) break; } /* 0,0 span means set to unspanned again */ if (rs == 0 && cs == 0) { entryPtr = Tcl_FindHashEntry(tablePtr->spanTbl, cell); if (entryPtr != NULL) { ckfree((char *) Tcl_GetHashValue(entryPtr)); Tcl_DeleteHashEntry(entryPtr); } entryPtr = Tcl_FindHashEntry(tablePtr->spanAffTbl, cell); if (entryPtr != NULL) { Tcl_DeleteHashEntry(entryPtr); } if (Tcl_FirstHashEntry(tablePtr->spanTbl, &search) == NULL) { /* There are no more spans, so delete tables to improve * performance of TableCellCoords */ Tcl_DeleteHashTable(tablePtr->spanTbl); ckfree((char *) (tablePtr->spanTbl)); Tcl_DeleteHashTable(tablePtr->spanAffTbl); ckfree((char *) (tablePtr->spanAffTbl)); tablePtr->spanTbl = NULL; tablePtr->spanAffTbl = NULL; } return result; } /* Make sure there is no extra stuff */ TableMakeArrayIndex(rs, cs, span); /* Set affected cell table to a NULL value */ entryPtr = Tcl_CreateHashEntry(tablePtr->spanAffTbl, cell, &new); Tcl_SetHashValue(entryPtr, NULL); /* set the spanning cells table with span value */ entryPtr = Tcl_CreateHashEntry(tablePtr->spanTbl, cell, &new); dbuf = (char *)ckalloc(strlen(span)+1); strcpy(dbuf, span); Tcl_SetHashValue(entryPtr, dbuf); dbuf = Tcl_GetHashKey(tablePtr->spanTbl, entryPtr); /* Set other affected cells */ EmbWinUnmap(tablePtr, row, row + rs, col, col + cs); for (i = urow; i <= urow+rs; i++) { for (j = ucol; j <= ucol+cs; j++) { TableMakeArrayIndex(i, j, buf); entryPtr = Tcl_CreateHashEntry(tablePtr->spanAffTbl, buf, &new); if (!(i == urow && j == ucol)) { Tcl_SetHashValue(entryPtr, (char *) dbuf); } } } TableRefresh(tablePtr, row, col, CELL); return result; } /* *-------------------------------------------------------------- * * Table_SpanCmd -- * This procedure is invoked to process the span method * that corresponds to a widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_SpanCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int rs, cs, row, col, i; Tcl_HashEntry *entryPtr; Tcl_Obj *objPtr, *resultPtr; if (objc < 2 || (objc > 4 && (objc&1))) { Tcl_WrongNumArgs(interp, 2, objv, "?index? ?rows,cols index rows,cols ...?"); return TCL_ERROR; } resultPtr = Tcl_GetObjResult(interp); if (objc == 2) { if (tablePtr->spanTbl) { Tcl_HashSearch search; for (entryPtr = Tcl_FirstHashEntry(tablePtr->spanTbl, &search); entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { objPtr = Tcl_NewStringObj(Tcl_GetHashKey(tablePtr->spanTbl, entryPtr), -1); Tcl_ListObjAppendElement(NULL, resultPtr, objPtr); objPtr = Tcl_NewStringObj((char *) Tcl_GetHashValue(entryPtr), -1); Tcl_ListObjAppendElement(NULL, resultPtr, objPtr); } } return TCL_OK; } else if (objc == 3) { if (TableGetIndexObj(tablePtr, objv[2], &row, &col) == TCL_ERROR) { return TCL_ERROR; } /* Just return the spanning values of the one cell */ if (tablePtr->spanTbl && (entryPtr = Tcl_FindHashEntry(tablePtr->spanTbl, Tcl_GetString(objv[2]))) != NULL) { Tcl_SetStringObj(resultPtr, (char *)Tcl_GetHashValue(entryPtr), -1); } return TCL_OK; } else { for (i = 2; i < objc-1; i += 2) { if (TableGetIndexObj(tablePtr, objv[i], &row, &col) == TCL_ERROR || (TableParseArrayIndex(&rs, &cs, Tcl_GetString(objv[i+1])) != 2) || Table_SpanSet(tablePtr, row, col, rs, cs) == TCL_ERROR) { return TCL_ERROR; } } } return TCL_OK; } /* *-------------------------------------------------------------- * * Table_HiddenCmd -- * This procedure is invoked to process the hidden method * that corresponds to a widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_HiddenCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int i, row, col; Tcl_HashEntry *entryPtr; char *span; if (objc < 2) { Tcl_WrongNumArgs(interp, 2, objv, "?index? ?index ...?"); return TCL_ERROR; } if (tablePtr->spanTbl == NULL) { /* Avoid the whole thing if we have no spans */ if (objc > 3) { Tcl_SetBooleanObj(Tcl_GetObjResult(interp), 0); } return TCL_OK; } if (objc == 2) { /* return all "hidden" cells */ Tcl_DString cells; Tcl_HashSearch search; Tcl_DStringInit(&cells); for (entryPtr = Tcl_FirstHashEntry(tablePtr->spanAffTbl, &search); entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { if ((span = (char *) Tcl_GetHashValue(entryPtr)) == NULL) { /* this is actually a spanning cell */ continue; } Tcl_DStringAppendElement(&cells, Tcl_GetHashKey(tablePtr->spanAffTbl, entryPtr)); } span = Tcl_GetString(TableCellSort(tablePtr, Tcl_DStringValue(&cells))); if (span != NULL) { Tcl_SetResult(interp, span, TCL_DYNAMIC); } Tcl_DStringFree(&cells); return TCL_OK; } if (objc == 3) { if (TableGetIndexObj(tablePtr, objv[2], &row, &col) != TCL_OK) { return TCL_ERROR; } /* Just return the spanning values of the one cell */ entryPtr = Tcl_FindHashEntry(tablePtr->spanAffTbl, Tcl_GetString(objv[2])); if (entryPtr != NULL && (span = (char *)Tcl_GetHashValue(entryPtr)) != NULL) { /* this is a hidden cell */ Tcl_SetStringObj(Tcl_GetObjResult(interp), span, -1); } return TCL_OK; } for (i = 2; i < objc; i++) { if (TableGetIndexObj(tablePtr, objv[i], &row, &col) == TCL_ERROR) { return TCL_ERROR; } entryPtr = Tcl_FindHashEntry(tablePtr->spanAffTbl, Tcl_GetString(objv[i])); if (entryPtr != NULL && (char *)Tcl_GetHashValue(entryPtr) != NULL) { /* this is a hidden cell */ continue; } /* We only reach here if it doesn't satisfy "hidden" criteria */ Tcl_SetBooleanObj(Tcl_GetObjResult(interp), 0); return TCL_OK; } Tcl_SetBooleanObj(Tcl_GetObjResult(interp), 1); return TCL_OK; } /* *-------------------------------------------------------------- * * TableSpanSanCheck -- * This procedure is invoked by TableConfigure to make sure * that spans are kept sane according to the docs. * See the user documentation for details on what it does. * * Results: * void. * * Side effects: * Spans in title areas can be reconstrained. * *-------------------------------------------------------------- */ void TableSpanSanCheck(register Table *tablePtr) { int rs, cs, row, col, reset; Tcl_HashEntry *entryPtr; Tcl_HashSearch search; if (tablePtr->spanTbl == NULL) { return; } for (entryPtr = Tcl_FirstHashEntry(tablePtr->spanTbl, &search); entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { reset = 0; TableParseArrayIndex(&row, &col, Tcl_GetHashKey(tablePtr->spanTbl, entryPtr)); TableParseArrayIndex(&rs, &cs, (char *) Tcl_GetHashValue(entryPtr)); if ((row-tablePtr->rowOffset < tablePtr->titleRows) && (row-tablePtr->rowOffset+rs >= tablePtr->titleRows)) { rs = tablePtr->titleRows-(row-tablePtr->rowOffset)-1; reset = 1; } if ((col-tablePtr->colOffset < tablePtr->titleCols) && (col-tablePtr->colOffset+cs >= tablePtr->titleCols)) { cs = tablePtr->titleCols-(col-tablePtr->colOffset)-1; reset = 1; } if (reset) { Table_SpanSet(tablePtr, row, col, rs, cs); } } } ����������������������������������������������Tk-TableMatrix-1.26/pTk/mkmethods�������������������������������������������������������������������0000644�0000000�0000000�00000005600�13745605157�015422� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/local/bin/perl -w $dst = shift; while (<>) { if (defined $Widget) { undef $Widget if (/^}/); if (/strn?cmp\s*\(\s*LangString\(args\[1\]\)\s*,\s*("[^"]*")\s*/) { if ($1 ne '"configure"' and $1 ne '"cget"') { push(@{$table{WIDGET}{$Widget}},$1); } } } elsif (defined $Image) { undef $Image if (/^}/); if (/strn?cmp\s*\(\s*LangString\(args\[1\]\)\s*,\s*("[^"]*")\s*/) { if ($1 ne '"configure"' and $1 ne '"cget"') { push(@{$table{IMAGE}{$Image}},$1); } } } elsif (defined $Command) { undef $Command if (/^}/); if (/strn?cmp\s*\(\s*LangString\(args\[1\]\)\s*,\s*("[^"]*")\s*/) {my $string = $1; push(@{$table{COMMAND}{$Command}},$string) unless ($string =~ /^"-/); } } elsif (defined $Tag) { undef $Tag if (/^}/); if (/strn?cmp\s*\(\s*LangString\(args\[2\]\)\s*,\s*("[^"]*")\s*/) { push(@{$tags{$Tag}},$1); print "$Tag : $1\n"; } } else { if (/^(\w+)WidgetCmd\s*\(/) { $Widget = "\L$1"; $Widget = "\u$Widget"; printf STDERR "Widget : $Widget\n"; $table{WIDGET}{$Widget} = []; } elsif (/^Img(\w+)Cmd\s*\(/) { $Image = "\L$1"; $Image = "\u$Image"; printf STDERR "Image : $Image\n"; $table{IMAGE}{$Image} = []; } elsif (/^(Tk)?([A-Z][a-z]+[A-Z][a-z]+)Cmd\s*\(/) { $Tag = $2; printf STDERR "Tag : $Tag\n"; $tags{$Tag} = []; } elsif (/^Tk_([A-Z][a-z]+)Cmd2?\s*\(/) { $Command = "\L$1"; printf STDERR "Command : $Command\n"; $table{COMMAND}{$Command} = []; } } } if (%{$table{WIDGET}} || %{$table{COMMAND}} || %{$table{IMAGE}}) { if (open(SRC,"<$dst")) { while (<SRC>) { my ($kind,$Widget,$list) = m/^(WIDGET|COMMAND|IMAGE)\(\("(\w+)",(("[^"]*",)*)NULL\)\)$/; if (defined $Widget) { if (!defined ${$table{$kind}}{$Widget}) { chop($list); print STDERR "Keep $kind $Widget : $list\n"; my @list = split(/,/,$list); @list = grep(!/^(configure|cget)$/,@list); ${$table{$kind}}{$Widget} = \@list; } } else { chomp($_); die "Mismatch : $_" unless (/^\s*$/); } } close(SRC); } open(SRC,">$dst") || die "Cannot open $dst:$!"; foreach $kind (sort keys %table) { foreach $Widget (sort keys %{$table{$kind}}) { if (@{$table{$kind}{$Widget}}) { print SRC "$kind((\"$Widget\","; foreach (sort @{$table{$kind}{$Widget}}) { print SRC "$_,"; } print SRC "NULL))\n"; } } } close(SRC); } ��������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mm.h������������������������������������������������������������������������0000444�0000000�0000000�00000007331�13746047614�014266� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * mm.h -- * * This is the header file for the module that implements * command structure lookups. * * Copyright (c) 1997,1998 Jeffrey Hobbs * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * */ #ifndef _MM_H_ #define _MM_H_ #include <string.h> #include <stdlib.h> #include "tk.h" /* Make sure this syncs with Makefile.in */ #define MM_MAJOR_VERSION 1 #define MM_MINOR_VERSION 0 #define MM_RELEASE_SERIAL 0 #define MM_VERSION "1.0" #define MM_PATCH_LEVEL "1.0.0" /* Now we start defining package specific stuff */ #define MM_ERROR 0 #define MM_VALUE (1<<0) #define MM_PROC (1<<1) #define MM_OBJPROC (1<<2) #define MM_SUBPROC (1<<3) #define MM_LAST ( NULL) #define MM_OVERWRITE (1<<0) #define MM_MERGE (1<<1) /* structure for use in parsing general major/minor commands */ typedef struct { char *name; /* name of the command/value */ Tcl_CmdProc *proc; /* >0 because 0 represents an error or proc */ int type; /* whether it is proc or just value */ ClientData data; /* optional clientData arg */ } MajorMinor_Cmd; extern int MM_GetProcExact _ANSI_ARGS_((const MajorMinor_Cmd *cmds, const char *name, Tcl_CmdProc **proc)); extern void MM_GetError _ANSI_ARGS_((Tcl_Interp *interp, const MajorMinor_Cmd *cmds, const char *arg)); extern int MM_GetProc _ANSI_ARGS_((Tcl_Interp *interp, MajorMinor_Cmd *cmds, const char *arg, MajorMinor_Cmd **cmd)); extern int MM_HandleArgs _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, MajorMinor_Cmd *cmds, int argc, Tcl_Obj *CONST *objv)); extern int MM_HandleCmds _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *CONST *objv)); extern MajorMinor_Cmd *MM_InitCmds _ANSI_ARGS_((Tcl_Interp *interp, char *name, MajorMinor_Cmd *cmds, ClientData clientData, int flags)); extern int MM_InsertCmd _ANSI_ARGS_((Tcl_Interp *interp, MajorMinor_Cmd *cmds, const char *name, Tcl_CmdProc **proc, int type)); extern int MM_RemoveCmd _ANSI_ARGS_((Tcl_Interp *interp, MajorMinor_Cmd *cmds, const char *name)); EXTERN int Majmin_Init _ANSI_ARGS_((Tcl_Interp *interp)); EXTERN int Majmin_SafeInit _ANSI_ARGS_((Tcl_Interp *interp)); EXTERN int Tcl_MajminCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *CONST *objv)); /* structure for use in parsing table commands/values */ typedef struct { char *name; /* name of the command/value */ int value; /* >0 because 0 represents an error or proc */ } Cmd_Struct; extern char * Cmd_GetName _ANSI_ARGS_((const Cmd_Struct *cmds, int val)); extern int Cmd_GetValue _ANSI_ARGS_((const Cmd_Struct *cmds, Arg arg)); extern void Cmd_GetError _ANSI_ARGS_((Tcl_Interp *interp, const Cmd_Struct *cmds, Arg arg)); extern int Cmd_Parse _ANSI_ARGS_((Tcl_Interp *interp, Cmd_Struct *cmds, const char *arg)); extern int Cmd_OptionSet _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, Tk_Window unused, Arg value, char *widgRec, int offset)); extern Arg Cmd_OptionGet _ANSI_ARGS_((ClientData clientData, Tk_Window unused, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)); extern int Cmd_BitSet _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, Tk_Window unused, Arg value, char *widgRec, int offset)); extern char * Cmd_BitGet _ANSI_ARGS_((ClientData clientData, Tk_Window unused, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)); #endif /* _MM_H_ */ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/refs������������������������������������������������������������������������0000644�0000000�0000000�00000000045�13742524721�014356� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh nm -Ap "$@" | grep ' U ' �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/Tcl-pTk���������������������������������������������������������������������0000644�0000000�0000000�00000013445�13742524721�014705� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/local/bin/perl -w use Carp; my $verbose = 0; $SIG{'__WARN__'} = sub { print STDERR $_; Carp::confess(shift) }; $src = shift; $dst = shift; die "Usage: $0 <src> <dst> \n" unless (defined $src and defined $dst); chmod(0666, $dst); unlink($dst); open(DST,">$dst") || die "Cannot open $dst;$!"; select(DST); my $copyright; @ARGV = ($src); undef $undone; sub getline { local $_; if (defined $undone) { $_ = $undone; undef $undone; } else { $_ = <>; } return $_; } sub int_results {my $fmt = shift; my $type = shift; my @fmt = split(/\s+/,$fmt); my $cnt = @fmt; # print STDERR "'$fmt' => $cnt\n"; return "Tcl_${type}Results(interp,$cnt,0"; } sub result {my ($interp,$value,$tail) = @_; my $line = &getline; my $kind = "TCL_STATIC"; if (defined $line) { if ($line =~ /^\s*$interp\s*->\s*freeProc\s*=\s*(.*)\s*;\s*$/) { $kind = $1; } else { $undone = $line if (defined $line); } } return "Tcl_SetResult($interp,$value,$kind)$tail"; } sub complete { my $tail = ""; until (/;/) { my $line = &getline; last unless defined($line); s/\s*$//; $line =~ s/^\s*//; $_ .= " " . $line; $tail .= "\n"; } $_ .= $tail; } PROCESS: while ($_ = &getline) { s/^\s*#\s*include\s*[<"]tcl\.h[">]\s*$/#include "Lang.h"\n/; s/^\s*#\s*include\s*<((tk|tkInt|tkPort|tix|tixInt)\.h)>\s*$/#include "$1"\n/; next if (/^\s*extern.*\bpanic\s*\(/); s/\(char\s*\*\)\s*NULL\b/ NULL/g; if (/if\s*\(\(c == '.'\)\s*$/) { my $line = &getline; if (defined($line)) { s/\s*$//; $line =~ s/^\s*//; $_ .= " " . $line . "\n"; } } if (/Tcl_DeleteCommandFromToken/) { if (/Tcl_DeleteCommandFromToken[^;{]*$/) { &complete; redo PROCESS; } s/Tcl_DeleteCommandFromToken(.*imageCmd)/Lang_DeleteObject$1/; s/Tcl_DeleteCommandFromToken(.*widgetCmd)/Lang_DeleteWidget$1/; } if (/Tcl_(Create|Delete)Command/) { if (/Tcl_(Create|Delete)Command[^;{]*$/) { &complete; redo PROCESS; } s/Tcl_CreateCommand\s*\(\s*((\w+->)*interp)\s*,\s*Tk_PathName\s*\(([^\)]+)\)/Lang_CreateWidget($1,$3/; s/Tcl_DeleteCommand\s*\(\s*((\w+->)*(\w+\.)?interp)\s*,\s*Tcl_GetCommandName\s*\([^,]+,\s*([^\)]+->(\w+\.style|image)Cmd)\)/Lang_DeleteObject($1,$4/; s/Tcl_DeleteCommand\s*\(\s*((\w+->)*(\w+\.)?interp)\s*,\s*Tcl_GetCommandName\s*\([^,]+,\s*([^\)]+->widgetCmd)\)/Lang_DeleteWidget($1,$4/; } if (/\bargv\w*\b/) { if (/\bargv\w*\s*\[([^[]*)\]\s*=[^=][^;{]*$/) { &complete; redo PROCESS; } if (/\bchar\b.*\bargv\w*\b/) { # convert char *argv[] to char **argv s/char\s*\*\s*\bargv\s*\[\s*\]/char **argv/; # convert char **argv to Arg *args s/char\s*\*\*\s*\bargv\b/Arg *args/; # convert char *argv[n] to Arg *args = LangAllocVec(n) s/char\s*\*\s*\bargv\s*\[\s*([^[]+)\]/Arg *args = LangAllocVec($1)/; } else { s/([^*])\*(argv\w*(\[[^[]*\])?)/${1}${2}[0]/g; } s/\bargv\s*\[([^[]*)\]\s*=([^=].*);\s*$/LangSetString(args+$1,$2);\n/; s/\bargv\s*\[([^[]*)\]\+\+/args[$1] = LangStringArg(LangString(args[$1])+1)/; s/\bargv\s*\[([^[]*)\]\+([0-9])/LangStringArg(LangString(args[$1])+$2)/; # unless (/\b(str\w+|Tk[A-Za-z0-9_]+)\s*\(/) # { # # skip things that look like parm list # s/([(,])\s*argv(\w*|\[[^[]*\])\s*([,)])/$1args$2$3/; # } if (/Tcl_Get(Boolean|Int|Double)/ || /Tk_Get(Cursor)/) { s/\bargv(\w*)\b/args$1/g; } s/\bargv\s*(\[[^[]*\])/LangString(args$1)/g; # s/((\w+->)+)\bargv(\w+)\b/LangString(${1}args$3)/g; # s/\bargv(\w+)\b/LangString(args$1)/g; if (/\bargv\b/) { warn "Leak: $_" if ($verbose && !/\bargv\s*\)/); s/\bargv\b/args/; } } if (/->\s*result\b/) { s/\s*->\s*result\b/->result/g; s/\bsprintf\s*\(\s*interp->result\s*,\s*"((\s*%d)+)"/&int_results($1,"Int")/e; s/\bsprintf\s*\(\s*interp->result\s*,\s*"((\s*%g)+)"/&int_results($1,"Double")/e; s/\bsprintf\s*\(\s*interp->result\b/Tcl_SprintfResult(interp/; if (/\binterp->result\s*=[^;]*$/) { &complete; redo PROCESS; } s/\b((\w+\s*->\s*)*interp)->result\s*=([^;]*);/&result($1,$3,";")/e; s/\b((\w+\s*->\s*)*interp)->result\s*=(.*);\s*$/&result($1,$3,";\n")/e; s/\b((\w+\s*->\s*)*interp)->result/Tcl_GetResult($1)/; } if (/\bTcl_SetResult\s*\(/) { if (/Tcl_SetResult\s*\([^;{]*$/) { &complete; redo PROCESS; } s/Tcl_SetResult\s*\(\s*((\w+->)*interp),\s*"(\d+)",\s*TCL_STATIC\s*\)/Tcl_SetObjResult($1, Tcl_NewIntObj($3))/; s/Tcl_SetResult\s*\(\s*((\w+->)*interp),\s*Tk_PathName\(([^)]+)\),\s*TCL_STATIC\s*\)/Tcl_ArgResult($1,LangWidgetArg($1,$3))/; s/Tcl_SetResult\s*\(\s*((\w+->)*interp),\s*((\w+->)*\w+)->pathName\s*,\s*TCL_STATIC\s*\)/Tcl_ArgResult($1,LangWidgetArg($1,(Tk_Window)($3)))/; die $_ if /(Tk_PathName|->pathName)/; } # 1 2 3 4 5 6 s/\(c == '(.)'\)\s*&&\s*(\(?)\(strncmp\(([^,]+),\s*("-\1[^"]*"),\s*(\w+|strlen\(\3\))\s*\)\s*==\s*0\)(\)?)/(c == '$1') && $2 LangCmpOpt($4,$3,$5) == 0 $6/g; s/\(c == '(.)'\)\s*&&\s*\(strcmp\(([^,]+),\s*("-\1[^"]*")\s*\)\s*==\s*0\)/(c == '$1') && LangCmpOpt($3,$2,0) == 0/g; if (defined($copyright) && !/^\s\*\s*Copyright/) { print $copyright; undef $copyright; } print; if (0 && /^((\s\*)\s*)Copyright/) { $copyright = "$2\n$1Modifications Copyright (c) 1994-1998 Nick Ing-Simmons\n"; } } select(STDOUT); close(DST); chmod(0444,$dst); exit 0; ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mkneed����������������������������������������������������������������������0000644�0000000�0000000�00000000247�13742524721�014666� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh files=`ls *.o | grep -v '_f\.o$'` ld -r -o /tmp/junk $files ../*Glue.o -lX11 -lm -lc nm -p /tmp/junk | grep ' U ' | grep -v 'Perl_' > rneed ned rneed ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/tdiff�����������������������������������������������������������������������0000644�0000000�0000000�00000001277�13742524721�014523� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/local/bin/perl -w sub fail { warn shift(@_)."\n"; return undef; } sub tdiff { my $file = shift; my ($src) = grep(-r $_,map("mTk/$_/$file",qw(unix win generic tclGeneric))); return fail("Cannot find $file in mTk") unless $src; my ($tcl) = grep(-r $_,map("../../../tcltk/$_/$file",qw(unix win generic))); ($tcl) = grep(-r $_,map("../../../tcl/$_/$file",qw(unix win generic))) unless $tcl; return fail("Cannot find $file in tcltk") unless $tcl; print "$tcl\n$src\n"; system("diff -u $tcl $src > /tmp/$file"); return "/tmp/$file"; } if (@ARGV) { foreach (@ARGV) { my $file = tdiff($_); system("ned",$file) if $file; } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/tkTableWin.c����������������������������������������������������������������0000444�0000000�0000000�00000070634�13746047614�015722� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * tkTableWin.c -- * * This module implements embedded windows for table widgets. * Much of this code is adapted from tkGrid.c and tkTextWind.c. * * Copyright (c) 1998-2002 Jeffrey Hobbs * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tkTableWin.c,v 1.10 2004/02/08 03:09:47 cerney Exp $ */ #include "tkVMacro.h" #include "tkTable.h" static int StickyParseProc _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, Arg value, char *widgRec, int offset)); Arg StickyPrintProc _ANSI_ARGS_((ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)); static void EmbWinLostSlaveProc _ANSI_ARGS_((ClientData clientData, Tk_Window tkwin)); static void EmbWinRequestProc _ANSI_ARGS_((ClientData clientData, Tk_Window tkwin)); static void EmbWinCleanup _ANSI_ARGS_((Table *tablePtr, TableEmbWindow *ewPtr)); static int EmbWinConfigure _ANSI_ARGS_((Table *tablePtr, TableEmbWindow *ewPtr, int objc, Tcl_Obj *CONST objv[])); static void EmbWinStructureProc _ANSI_ARGS_((ClientData clientData, XEvent *eventPtr)); static void EmbWinUnmapNow _ANSI_ARGS_((Tk_Window ewTkwin, Tk_Window tkwin)); static Tk_GeomMgr tableGeomType = { "table", /* name */ EmbWinRequestProc, /* requestProc */ EmbWinLostSlaveProc, /* lostSlaveProc */ }; /* windows subcommands */ static CONST char *winCmdNames[] = { "cget", "configure", "delete", "move", "names", NULL }; enum winCommand { WIN_CGET, WIN_CONFIGURE, WIN_DELETE, WIN_MOVE, WIN_NAMES }; /* Flag values for "sticky"ness The 16 combinations subsume the packer's * notion of anchor and fill. * * STICK_NORTH This window sticks to the top of its cavity. * STICK_EAST This window sticks to the right edge of its cavity. * STICK_SOUTH This window sticks to the bottom of its cavity. * STICK_WEST This window sticks to the left edge of its cavity. */ #define STICK_NORTH (1<<0) #define STICK_EAST (1<<1) #define STICK_SOUTH (1<<2) #define STICK_WEST (1<<3) /* * The default specification for configuring embedded windows * Done like this to make the command line parsing easy */ static Tk_CustomOption stickyOption = { StickyParseProc, StickyPrintProc, (ClientData) NULL }; static Tk_CustomOption tagBdOpt = { TableOptionBdSet, TableOptionBdGet, (ClientData) BD_TABLE_WIN }; static Tk_ConfigSpec winConfigSpecs[] = { {TK_CONFIG_BORDER, "-background", "background", "Background", NULL, Tk_Offset(TableEmbWindow, bg), TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK }, {TK_CONFIG_SYNONYM, "-bd", "borderWidth", NULL, NULL, 0, 0}, {TK_CONFIG_SYNONYM, "-bg", "background", NULL, NULL, 0, 0}, {TK_CONFIG_CUSTOM, "-borderwidth", "borderWidth", "BorderWidth", "", 0 /* no offset */, TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK, &tagBdOpt }, {TK_CONFIG_STRING, "-create", NULL, NULL, NULL, Tk_Offset(TableEmbWindow, create), TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK }, {TK_CONFIG_PIXELS, "-padx", NULL, NULL, NULL, Tk_Offset(TableEmbWindow, padX), TK_CONFIG_DONT_SET_DEFAULT }, {TK_CONFIG_PIXELS, "-pady", NULL, NULL, NULL, Tk_Offset(TableEmbWindow, padY), TK_CONFIG_DONT_SET_DEFAULT }, {TK_CONFIG_CUSTOM, "-sticky", NULL, NULL, NULL, Tk_Offset(TableEmbWindow, sticky), TK_CONFIG_DONT_SET_DEFAULT, &stickyOption}, {TK_CONFIG_RELIEF, "-relief", "relief", "Relief", NULL, Tk_Offset(TableEmbWindow, relief), 0 }, {TK_CONFIG_WINDOW, "-window", NULL, NULL, NULL, Tk_Offset(TableEmbWindow, tkwin), TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK }, {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0 } }; /* *---------------------------------------------------------------------- * * StickyPrintProc -- * Converts the internal boolean combination of "sticky" bits onto * a TCL string element containing zero or more of n, s, e, or w. * * Results: * A string is placed into the "result" pointer. * * Side effects: * none. * *---------------------------------------------------------------------- */ Arg StickyPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr) ClientData clientData; /* Ignored. */ Tk_Window tkwin; /* Window for text widget. */ char *widgRec; /* Pointer to TkTextEmbWindow * structure. */ int offset; /* Ignored. */ Tcl_FreeProc **freeProcPtr; /* Pointer to variable to fill in with * information about how to reclaim * storage for return string. */ { int flags = ((TableEmbWindow *) widgRec)->sticky; int count = 0; char *result = (char *) ckalloc(5*sizeof(char)); if (flags&STICK_NORTH) result[count++] = 'n'; if (flags&STICK_EAST) result[count++] = 'e'; if (flags&STICK_SOUTH) result[count++] = 's'; if (flags&STICK_WEST) result[count++] = 'w'; *freeProcPtr = TCL_DYNAMIC; result[count] = '\0'; return LangStringArg(result); } /* *---------------------------------------------------------------------- * * StringParseProc -- * Converts an ascii string representing a widgets stickyness * into the boolean result. * * Results: * The boolean combination of the "sticky" bits is retuned. If an * error occurs, such as an invalid character, -1 is returned instead. * * Side effects: * none * *---------------------------------------------------------------------- */ static int StickyParseProc(clientData, interp, tkwin, value, widgRec, offset) ClientData clientData; /* Not used.*/ Tcl_Interp *interp; /* Used for reporting errors. */ Tk_Window tkwin; /* Window for text widget. */ Arg value; /* Value of option. */ char *widgRec; /* Pointer to TkTextEmbWindow * structure. */ int offset; /* Offset into item (ignored). */ { register TableEmbWindow *ewPtr = (TableEmbWindow *) widgRec; int sticky = 0; char c; char * valuestring = Tcl_GetString(value); while ((c = *valuestring++) != '\0') { switch (c) { case 'n': case 'N': sticky |= STICK_NORTH; break; case 'e': case 'E': sticky |= STICK_EAST; break; case 's': case 'S': sticky |= STICK_SOUTH; break; case 'w': case 'W': sticky |= STICK_WEST; break; case ' ': case ',': case '\t': case '\r': case '\n': break; default: Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "bad sticky value \"", --valuestring, "\": must contain n, s, e or w", NULL); return TCL_ERROR; } } ewPtr->sticky = sticky; return TCL_OK; } /* * ckallocs space for a new embedded window structure and clears the structure * returns the pointer to the new structure */ static TableEmbWindow * TableNewEmbWindow(Table *tablePtr) { TableEmbWindow *ewPtr = (TableEmbWindow *) ckalloc(sizeof(TableEmbWindow)); memset((VOID *) ewPtr, 0, sizeof(TableEmbWindow)); /* * Set the values that aren't 0/NULL by default */ ewPtr->tablePtr = tablePtr; ewPtr->relief = -1; ewPtr->padX = -1; ewPtr->padY = -1; return ewPtr; } /* *---------------------------------------------------------------------- * * EmbWinCleanup -- * Releases resources used by an embedded window before it is freed up. * * Results: * Window will no longer be valid. * * Side effects: * None. * *---------------------------------------------------------------------- */ static void EmbWinCleanup(Table *tablePtr, TableEmbWindow *ewPtr) { Tk_FreeOptions(winConfigSpecs, (char *) ewPtr, tablePtr->display, 0); } /* *-------------------------------------------------------------- * * EmbWinDisplay -- * * This procedure is invoked by TableDisplay for * mapping windows into cells. * * Results: * Displays or moves window on table screen. * * Side effects: * None. * *-------------------------------------------------------------- */ void EmbWinDisplay(Table *tablePtr, Drawable window, TableEmbWindow *ewPtr, TableTag *tagPtr, int x, int y, int width, int height) { Tk_Window tkwin = tablePtr->tkwin; Tk_Window ewTkwin = ewPtr->tkwin; int diffx=0; /* Cavity width - slave width. */ int diffy=0; /* Cavity hight - slave height. */ int sticky = ewPtr->sticky; int padx, pady; if (ewPtr->bg) tagPtr->bg = ewPtr->bg; if (ewPtr->relief != -1) tagPtr->relief = ewPtr->relief; if (ewPtr->borders) { tagPtr->borderStr = ewPtr->borderStr; tagPtr->borders = ewPtr->borders; tagPtr->bd[0] = ewPtr->bd[0]; tagPtr->bd[1] = ewPtr->bd[1]; tagPtr->bd[2] = ewPtr->bd[2]; tagPtr->bd[3] = ewPtr->bd[3]; } padx = (ewPtr->padX < 0) ? tablePtr->padX : ewPtr->padX; pady = (ewPtr->padY < 0) ? tablePtr->padY : ewPtr->padY; x += padx; width -= padx*2; y += pady; height -= pady*2; if (width > Tk_ReqWidth(ewPtr->tkwin)) { diffx = width - Tk_ReqWidth(ewPtr->tkwin); width = Tk_ReqWidth(ewPtr->tkwin); } if (height > Tk_ReqHeight(ewPtr->tkwin)) { diffy = height - Tk_ReqHeight(ewPtr->tkwin); height = Tk_ReqHeight(ewPtr->tkwin); } if (sticky&STICK_EAST && sticky&STICK_WEST) { width += diffx; } if (sticky&STICK_NORTH && sticky&STICK_SOUTH) { height += diffy; } if (!(sticky&STICK_WEST)) { x += (sticky&STICK_EAST) ? diffx : diffx/2; } if (!(sticky&STICK_NORTH)) { y += (sticky&STICK_SOUTH) ? diffy : diffy/2; } /* * If we fall below a specific minimum width/height requirement, * we just unmap the window */ if (width < 4 || height < 4) { if (ewPtr->displayed) { EmbWinUnmapNow(ewTkwin, tkwin); } return; } if (tkwin == Tk_Parent(ewTkwin)) { if ((x != Tk_X(ewTkwin)) || (y != Tk_Y(ewTkwin)) || (width != Tk_Width(ewTkwin)) || (height != Tk_Height(ewTkwin))) { Tk_MoveResizeWindow(ewTkwin, x, y, width, height); } Tk_MapWindow(ewTkwin); } else { Tk_MaintainGeometry(ewTkwin, tkwin, x, y, width, height); } ewPtr->displayed = 1; } /* *-------------------------------------------------------------- * * EmbWinUnmapNow -- * Handles unmapping the window depending on parent. * tkwin should be tablePtr->tkwin. * ewTkwin should be ewPtr->tkwin. * * Results: * Removes the window. * * Side effects: * None. * *-------------------------------------------------------------- */ static void EmbWinUnmapNow(Tk_Window ewTkwin, Tk_Window tkwin) { if (tkwin != Tk_Parent(ewTkwin)) { Tk_UnmaintainGeometry(ewTkwin, tkwin); } Tk_UnmapWindow(ewTkwin); } /* *-------------------------------------------------------------- * * EmbWinUnmap -- * This procedure is invoked by TableAdjustParams for * unmapping windows managed moved offscreen. * rlo, ... should be in real coords. * * Results: * None. * * Side effects: * Unmaps embedded windows. * *-------------------------------------------------------------- */ void EmbWinUnmap(Table *tablePtr, int rlo, int rhi, int clo, int chi) { register TableEmbWindow *ewPtr; Tcl_HashEntry *entryPtr; int row, col, trow, tcol; char buf[INDEX_BUFSIZE]; /* * Transform numbers from real to user user coords */ rlo += tablePtr->rowOffset; rhi += tablePtr->rowOffset; clo += tablePtr->colOffset; chi += tablePtr->colOffset; for (row = rlo; row <= rhi; row++) { for (col = clo; col <= chi; col++) { TableTrueCell(tablePtr, row, col, &trow, &tcol); TableMakeArrayIndex(trow, tcol, buf); entryPtr = Tcl_FindHashEntry(tablePtr->winTable, buf); if (entryPtr != NULL) { ewPtr = (TableEmbWindow *) Tcl_GetHashValue(entryPtr); if (ewPtr->displayed) { ewPtr->displayed = 0; if (ewPtr->tkwin != NULL && tablePtr->tkwin != NULL) { EmbWinUnmapNow(ewPtr->tkwin, tablePtr->tkwin); } } } } } } /* *-------------------------------------------------------------- * * EmbWinRequestProc -- * This procedure is invoked by Tk_GeometryRequest for * windows managed by the Table. * * Results: * None. * * Side effects: * Arranges for tkwin, and all its managed siblings, to * be re-arranged at the next idle point. * *-------------------------------------------------------------- */ static void EmbWinRequestProc(clientData, tkwin) ClientData clientData; /* Table's information about * window that got new preferred * geometry. */ Tk_Window tkwin; /* Other Tk-related information * about the window. */ { register TableEmbWindow *ewPtr = (TableEmbWindow *) clientData; /* * Resize depends on the sticky */ if (ewPtr->displayed && ewPtr->hPtr != NULL) { Table *tablePtr = ewPtr->tablePtr; int row, col, x, y, width, height; TableParseArrayIndex(&row, &col, Tcl_GetHashKey(tablePtr->winTable, ewPtr->hPtr)); if (TableCellVCoords(tablePtr, row-tablePtr->rowOffset, col-tablePtr->colOffset, &x, &y, &width, &height, 0)) { TableInvalidate(tablePtr, x, y, width, height, 0); } } } static void EmbWinRemove(TableEmbWindow *ewPtr) { Table *tablePtr = ewPtr->tablePtr; if (ewPtr->tkwin != NULL) { Tk_DeleteEventHandler(ewPtr->tkwin, StructureNotifyMask, EmbWinStructureProc, (ClientData) ewPtr); ewPtr->tkwin = NULL; } ewPtr->displayed = 0; if (tablePtr->tkwin != NULL) { int row, col, x, y, width, height; TableParseArrayIndex(&row, &col, Tcl_GetHashKey(tablePtr->winTable, ewPtr->hPtr)); /* this will cause windows removed from the table to actually * cause the associated embdedded window hash data to be removed */ Tcl_DeleteHashEntry(ewPtr->hPtr); if (TableCellVCoords(tablePtr, row-tablePtr->rowOffset, col-tablePtr->colOffset, &x, &y, &width, &height, 0)) TableInvalidate(tablePtr, x, y, width, height, 1); } /* this will cause windows removed from the table to actually * cause the associated embdedded window hash data to be removed */ EmbWinCleanup(tablePtr, ewPtr); ckfree((char *) ewPtr); } /* *-------------------------------------------------------------- * * EmbWinLostSlaveProc -- * This procedure is invoked by Tk whenever some other geometry * claims control over a slave that used to be managed by us. * * Results: * None. * * Side effects: * Forgets all table-related information about the slave. * *-------------------------------------------------------------- */ static void EmbWinLostSlaveProc(clientData, tkwin) ClientData clientData; /* Table structure for slave window that * was stolen away. */ Tk_Window tkwin; /* Tk's handle for the slave window. */ { register TableEmbWindow *ewPtr = (TableEmbWindow *) clientData; #if 0 Tcl_CancelIdleCall(EmbWinDelayedUnmap, (ClientData) ewPtr); #endif EmbWinUnmapNow(tkwin, ewPtr->tablePtr->tkwin); EmbWinRemove(ewPtr); } /* *-------------------------------------------------------------- * * EmbWinStructureProc -- * This procedure is invoked by the Tk event loop whenever * StructureNotify events occur for a window that's embedded * in a table widget. This procedure's only purpose is to * clean up when windows are deleted. * * Results: * None. * * Side effects: * The window is disassociated from the window segment, and * the portion of the table is redisplayed. * *-------------------------------------------------------------- */ static void EmbWinStructureProc(clientData, eventPtr) ClientData clientData; /* Pointer to record describing window item. */ XEvent *eventPtr; /* Describes what just happened. */ { register TableEmbWindow *ewPtr = (TableEmbWindow *) clientData; if (eventPtr->type != DestroyNotify) { return; } EmbWinRemove(ewPtr); } /* *-------------------------------------------------------------- * * EmbWinDelete -- * This procedure is invoked by ... whenever * an embedded window is being deleted. * * Results: * None. * * Side effects: * The embedded window is deleted, if it exists, and any resources * associated with it are released. * *-------------------------------------------------------------- */ void EmbWinDelete(register Table *tablePtr, TableEmbWindow *ewPtr) { Tcl_HashEntry *entryPtr = ewPtr->hPtr; if (ewPtr->tkwin != NULL) { Tk_Window tkwin = ewPtr->tkwin; /* * Delete the event handler for the window before destroying * the window, so that EmbWinStructureProc doesn't get called * (we'll already do everything that it would have done, and * it will just get confused). */ ewPtr->tkwin = NULL; Tk_DeleteEventHandler(tkwin, StructureNotifyMask, EmbWinStructureProc, (ClientData) ewPtr); Tk_DestroyWindow(tkwin); } if (tablePtr->tkwin != NULL && entryPtr != NULL) { int row, col, x, y, width, height; TableParseArrayIndex(&row, &col, Tcl_GetHashKey(tablePtr->winTable, entryPtr)); Tcl_DeleteHashEntry(entryPtr); if (TableCellVCoords(tablePtr, row-tablePtr->rowOffset, col-tablePtr->colOffset, &x, &y, &width, &height, 0)) TableInvalidate(tablePtr, x, y, width, height, 0); } #if 0 Tcl_CancelIdleCall(EmbWinDelayedUnmap, (ClientData) ewPtr); #endif EmbWinCleanup(tablePtr, ewPtr); ckfree((char *) ewPtr); } /* *-------------------------------------------------------------- * * EmbWinConfigure -- * This procedure is called to handle configuration options * for an embedded window. * * Results: * The return value is a standard Tcl result. If TCL_ERROR is * returned, then the interp's result contains an error message.. * * Side effects: * Configuration information for the embedded window changes, * such as alignment, stretching, or name of the embedded * window. * *-------------------------------------------------------------- */ static int EmbWinConfigure(tablePtr, ewPtr, objc, objv) Table *tablePtr; /* Information about table widget that * contains embedded window. */ TableEmbWindow *ewPtr; /* Embedded window to be configured. */ int objc; /* Number of objs in objv. */ Tcl_Obj *CONST objv[]; /* Obj type options. */ { Tcl_Interp *interp = tablePtr->interp; Tk_Window oldWindow; int i, result; Arg *args; oldWindow = ewPtr->tkwin; /* Stringify */ args = (Arg *) ckalloc((objc + 1) * sizeof(Arg)); for (i = 0; i < objc; i++) args[i] = LangStringArg(Tcl_GetString(objv[i])); args[i] = NULL; result = Tk_ConfigureWidget(interp, tablePtr->tkwin, winConfigSpecs, objc, args, (char *) ewPtr, TK_CONFIG_ARGV_ONLY); ckfree((char *) args); if (result != TCL_OK) { return TCL_ERROR; } if (oldWindow != ewPtr->tkwin) { ewPtr->displayed = 0; if (oldWindow != NULL) { Tk_DeleteEventHandler(oldWindow, StructureNotifyMask, EmbWinStructureProc, (ClientData) ewPtr); Tk_ManageGeometry(oldWindow, (Tk_GeomMgr *) NULL, (ClientData) NULL); EmbWinUnmapNow(oldWindow, tablePtr->tkwin); } if (ewPtr->tkwin != NULL) { Tk_Window ancestor, parent; /* * Make sure that the table is either the parent of the * embedded window or a descendant of that parent. Also, * don't allow a top-level window to be managed inside * a table. */ parent = Tk_Parent(ewPtr->tkwin); for (ancestor = tablePtr->tkwin; ; ancestor = Tk_Parent(ancestor)) { if (ancestor == parent) { break; } if (Tk_IsTopLevel(ancestor)) { badMaster: Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "can't embed ", Tk_PathName(ewPtr->tkwin), " in ", Tk_PathName(tablePtr->tkwin), NULL); ewPtr->tkwin = NULL; return TCL_ERROR; } } if (Tk_IsTopLevel(ewPtr->tkwin) || (ewPtr->tkwin == tablePtr->tkwin)) { goto badMaster; } /* * Take over geometry management for the window, plus create * an event handler to find out when it is deleted. */ Tk_ManageGeometry(ewPtr->tkwin, &tableGeomType, (ClientData)ewPtr); Tk_CreateEventHandler(ewPtr->tkwin, StructureNotifyMask, EmbWinStructureProc, (ClientData) ewPtr); } } return TCL_OK; } /* *-------------------------------------------------------------- * * Table_WinMove -- * This procedure is invoked by ... whenever * an embedded window is being moved. * * Results: * A standard Tcl result. * * Side effects: * If an embedded window is in the dest cell, it is deleted. * *-------------------------------------------------------------- */ int Table_WinMove(register Table *tablePtr, char *CONST srcPtr, char *CONST destPtr, int flags) { int srow, scol, row, col, new; Tcl_HashEntry *entryPtr; TableEmbWindow *ewPtr; if (TableGetIndex(tablePtr, srcPtr, &srow, &scol) != TCL_OK || TableGetIndex(tablePtr, destPtr, &row, &col) != TCL_OK) { return TCL_ERROR; } entryPtr = Tcl_FindHashEntry(tablePtr->winTable, srcPtr); if (entryPtr == NULL) { if (flags & INV_NO_ERR_MSG) { return TCL_OK; } else { Tcl_AppendStringsToObj(Tcl_GetObjResult(tablePtr->interp), "no window at index \"", srcPtr, "\"", NULL); return TCL_ERROR; } } /* avoid moving it to the same location */ if (srow == row && scol == col) { return TCL_OK; } /* get the window pointer */ ewPtr = (TableEmbWindow *) Tcl_GetHashValue(entryPtr); /* and free the old hash table entry */ Tcl_DeleteHashEntry(entryPtr); entryPtr = Tcl_CreateHashEntry(tablePtr->winTable, destPtr, &new); if (!new) { /* window already there - just delete it */ TableEmbWindow *ewPtrDel; ewPtrDel = (TableEmbWindow *) Tcl_GetHashValue(entryPtr); /* This prevents the deletion of it's own entry, since we need it */ ewPtrDel->hPtr = NULL; EmbWinDelete(tablePtr, ewPtrDel); } /* set the new entry's value */ Tcl_SetHashValue(entryPtr, (ClientData) ewPtr); ewPtr->hPtr = entryPtr; if (flags & INV_FORCE) { int x, y, w, h; /* Invalidate old cell */ if (TableCellVCoords(tablePtr, srow-tablePtr->rowOffset, scol-tablePtr->colOffset, &x, &y, &w, &h, 0)) { TableInvalidate(tablePtr, x, y, w, h, 0); } /* Invalidate new cell */ if (TableCellVCoords(tablePtr, row-tablePtr->rowOffset, col-tablePtr->colOffset, &x, &y, &w, &h, 0)) { TableInvalidate(tablePtr, x, y, w, h, 0); } } return TCL_OK; } /* *-------------------------------------------------------------- * * Table_WinDelete -- * This procedure is invoked by ... whenever * an embedded window is being delete. * * Results: * A standard Tcl result. * * Side effects: * Window info will be deleted. * *-------------------------------------------------------------- */ int Table_WinDelete(register Table *tablePtr, char *CONST idxPtr) { Tcl_HashEntry *entryPtr; entryPtr = Tcl_FindHashEntry(tablePtr->winTable, idxPtr); if (entryPtr != NULL) { /* get the window pointer & clean up data associated with it */ EmbWinDelete(tablePtr, (TableEmbWindow *) Tcl_GetHashValue(entryPtr)); } return TCL_OK; } /* *-------------------------------------------------------------- * * Table_WindowCmd -- * This procedure is invoked to process the window method * that corresponds to a widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_WindowCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *)clientData; int result = TCL_OK, cmdIndex, row, col, x, y, width, height, i, new; TableEmbWindow *ewPtr; Tcl_HashEntry *entryPtr; Tcl_HashSearch search; char buf[INDEX_BUFSIZE], *keybuf, *winname; if (objc < 3) { Tcl_WrongNumArgs(interp, 2, objv, "option ?arg arg ...?"); return TCL_ERROR; } /* parse the next argument */ if (Tcl_GetIndexFromObj(interp, objv[2], winCmdNames, "option", 0, &cmdIndex) != TCL_OK) { return TCL_ERROR; } switch ((enum winCommand) cmdIndex) { case WIN_CGET: if (objc != 5) { Tcl_WrongNumArgs(interp, 3, objv, "index option"); return TCL_ERROR; } entryPtr = Tcl_FindHashEntry(tablePtr->winTable, Tcl_GetString(objv[3])); if (entryPtr == NULL) { Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "no window at index \"", Tcl_GetString(objv[3]), "\"", NULL); return TCL_ERROR; } else { ewPtr = (TableEmbWindow *) Tcl_GetHashValue(entryPtr); result = Tk_ConfigureValue(interp, tablePtr->tkwin, winConfigSpecs, (char *) ewPtr, Tcl_GetString(objv[4]), 0); } return result; /* CGET */ case WIN_CONFIGURE: if (objc < 4) { Tcl_WrongNumArgs(interp, 3, objv, "index ?arg arg ...?"); return TCL_ERROR; } if (TableGetIndexObj(tablePtr, objv[3], &row, &col) == TCL_ERROR) { return TCL_ERROR; } TableMakeArrayIndex(row, col, buf); entryPtr = Tcl_CreateHashEntry(tablePtr->winTable, buf, &new); if (new) { /* create the structure */ ewPtr = TableNewEmbWindow(tablePtr); /* insert it into the table */ Tcl_SetHashValue(entryPtr, (ClientData) ewPtr); ewPtr->hPtr = entryPtr; /* configure the window structure */ result = EmbWinConfigure(tablePtr, ewPtr, objc-4, objv+4); if (result == TCL_ERROR) { /* release the structure */ EmbWinCleanup(tablePtr, ewPtr); ckfree((char *) ewPtr); /* and free the hash table entry */ Tcl_DeleteHashEntry(entryPtr); } } else { /* window exists, do a reconfig if we have enough args */ /* get the window pointer from the table */ ewPtr = (TableEmbWindow *) Tcl_GetHashValue(entryPtr); /* 5 args means that there are values to replace */ if (objc > 5) { /* and do a reconfigure */ result = EmbWinConfigure(tablePtr, ewPtr, objc-4, objv+4); } } if (result == TCL_ERROR) { return TCL_ERROR; } /* * If there were less than 6 args, we need * to do a printout of the config, even for new windows */ if (objc < 6) { result = Tk_ConfigureInfo(interp, tablePtr->tkwin, winConfigSpecs, (char *) ewPtr, (objc == 5)? Tcl_GetString(objv[4]) : NULL, 0); } else { /* Otherwise we reconfigured so invalidate * the table for a redraw */ if (TableCellVCoords(tablePtr, row-tablePtr->rowOffset, col-tablePtr->colOffset, &x, &y, &width, &height, 0)) { TableInvalidate(tablePtr, x, y, width, height, 1); } } return result; /* CONFIGURE */ case WIN_DELETE: if (objc < 4) { Tcl_WrongNumArgs(interp, 3, objv, "index ?index ...?"); return TCL_ERROR; } for (i = 3; i < objc; i++) { Table_WinDelete(tablePtr, Tcl_GetString(objv[i])); } break; case WIN_MOVE: if (objc != 5) { Tcl_WrongNumArgs(interp, 3, objv, "srcIndex destIndex"); return TCL_ERROR; } result = Table_WinMove(tablePtr, Tcl_GetString(objv[3]), Tcl_GetString(objv[4]), INV_FORCE); break; case WIN_NAMES: { Tcl_Obj *objPtr = Tcl_NewObj(); /* just print out the window names */ if (objc < 3 || objc > 4) { Tcl_WrongNumArgs(interp, 3, objv, "?pattern?"); return TCL_ERROR; } winname = (objc == 4) ? Tcl_GetString(objv[3]) : NULL; entryPtr = Tcl_FirstHashEntry(tablePtr->winTable, &search); while (entryPtr != NULL) { keybuf = Tcl_GetHashKey(tablePtr->winTable, entryPtr); if (objc == 3 || Tcl_StringMatch(keybuf, winname) ) { Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj(keybuf, -1)); } entryPtr = Tcl_NextHashEntry(&search); } Tcl_SetResult(interp, Tcl_GetString(TableCellSort(tablePtr, Tcl_GetStringFromObj(Tcl_GetObjResult(interp),NULL))), TCL_DYNAMIC); break; } } return TCL_OK; } ����������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/process_object��������������������������������������������������������������0000644�0000000�0000000�00000002612�13745605157�016433� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������use Data::Dumper; sub do_nm { my $obj = shift; open(NM,"nm -p $obj|") || die "Cannot open nm $obj:$!"; $file{$obj} = {}; while (<NM>) { if (/\b([A-Z])\b\s*_?(.*)$/) { my ($kind,$name) = ($1,$2); $file{$obj}{$name} = $kind; if ($kind ne 'U') { if (exists $def{$name}) { warn "$name " . Dumper($def{$name}) . " and [$kind,$obj]\n"; } $def{$name} = [$kind,$obj]; } else { $ref{$name} = [] unless (exists $ref{$name}); push(@{$ref{$name}},$obj); } } } close(NM); } sub do_need { my ($obj,$depth,$why) = @_; die "No object" unless (defined $obj); my $hash = $file{$obj}; die "No hash for $obj" unless (defined $hash); if (exists $need{$obj}) { push(@{$need{$obj}},[$name,$why]); $depth{$obj} = $depth if ($depth < $depth{$obj}); } else { $depth{$obj} = $depth; $need{$obj} = []; push(@{$need{$obj}},[$name,$why]); foreach $name (sort keys %$hash) { my $kind = $hash->{$name}; if ($kind eq 'U') { if (exists $def{$name}) { my ($kind,$file) = @{$def{$name}}; do_need($file,$depth+1,$obj); } else { $unres{$name} = [] unless (exists $unres{$name}); push(@{$unres{$name}},$obj); } } } } } 1; ����������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/p4e�������������������������������������������������������������������������0000644�0000000�0000000�00000001307�13742524721�014111� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/local/bin/perl -w use File::Find; use Cwd; my $path = getcwd; foreach (@ARGV) { s/\./\\./; } my $re = '^(?:'.join('|',@ARGV).')$'; $re = qr/$re/; find(\&wanted,"$path/mTk"); sub wanted { if ($_ =~ $re) { my $file = "$File::Find::name"; unless (-w $file) { system('p4','edit',$file); } my $cmd = $ENV{'EDITOR'}.' '.$file; invoke($cmd); print "$cmd\n"; } } sub invoke { if ($^O eq 'MSWin32') { system(1,@_); } else { if ($pid = fork) { return $pid; } else { exec(@_); } } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/MYMETA.yml������������������������������������������������������������������0000644�0000000�0000000�00000000760�13746047615�015225� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������--- abstract: unknown author: - unknown build_requires: ExtUtils::MakeMaker: '0' configure_requires: ExtUtils::MakeMaker: '0' dynamic_config: 0 generated_by: 'ExtUtils::MakeMaker version 7.44, CPAN::Meta::Converter version 2.150010' license: unknown meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: Tk-pTk no_index: directory: - t - inc version: '1.26' x_serialization_backend: 'CPAN::Meta::YAML version 0.018' ����������������Tk-TableMatrix-1.26/pTk/genexc����������������������������������������������������������������������0000644�0000000�0000000�00000001461�13742524721�014673� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/local/bin/perl -w my %mTk; my $dir; my @list; if ($^O eq 'MSWin32') { @list = qw(win xlib generic tix tclWin tclGeneric); } else { @list = qw(unix generic tix tclUnix tclGeneric ); } foreach $dir (@list) { my %exc; my $src = catdir("mTk",$dir); next unless -d $src; opendir(DIR,$src) || die "Cannot open $src:$!"; open(EXC,">".catfile($src,"pTk.exc")); my $file; while (defined($file = readdir(DIR))) { next if $exc{$_}; if ($file =~ /\.[ch]$/) { my $o = $file; $o =~ s/\.c$/.o/; unless (-f $o) { print EXC "$file\n"; unlink($file) if (-f $file); } } } closedir(DIR); close(EXC); } sub catfile { return join('/',@_); } sub catdir { return join('/',@_); } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/tkTableEdit.c���������������������������������������������������������������0000444�0000000�0000000�00000052102�13746047614�016040� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * tkTableEdit.c -- * * This module implements editing functions of a table widget. * * Copyright (c) 1998-2000 Jeffrey Hobbs * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tkTableEdit.c,v 1.6 2004/02/08 03:09:46 cerney Exp $ */ #include "tkVMacro.h" #include "tkTable.h" static void TableModifyRC _ANSI_ARGS_((register Table *tablePtr, int doRows, int movetag, Tcl_HashTable *tagTblPtr, Tcl_HashTable *dimTblPtr, int offset, int from, int to, int lo, int hi, int outOfBounds)); /* insert/delete subcommands */ static CONST char *modCmdNames[] = { "active", "cols", "rows", NULL }; enum modCmd { MOD_ACTIVE, MOD_COLS, MOD_ROWS }; /* insert/delete row/col switches */ static CONST char *rcCmdNames[] = { "-keeptitles", "-holddimensions", "-holdselection", "-holdtags", "-holdwindows", "--", NULL }; enum rcCmd { OPT_TITLES, OPT_DIMS, OPT_SEL, OPT_TAGS, OPT_WINS, OPT_LAST }; #define HOLD_TITLES 1<<0 #define HOLD_DIMS 1<<1 #define HOLD_TAGS 1<<2 #define HOLD_WINS 1<<3 #define HOLD_SEL 1<<4 /* *-------------------------------------------------------------- * * Table_EditCmd -- * This procedure is invoked to process the insert/delete method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_EditCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int doInsert, cmdIndex, first, last; if (objc < 4) { Tcl_WrongNumArgs(interp, 2, objv, "option ?switches? arg ?arg?"); return TCL_ERROR; } if (Tcl_GetIndexFromObj(interp, objv[2], modCmdNames, "option", 0, &cmdIndex) != TCL_OK) { return TCL_ERROR; } doInsert = (*(Tcl_GetString(objv[1])) == 'i'); switch ((enum modCmd) cmdIndex) { case MOD_ACTIVE: if (doInsert) { /* INSERT */ if (objc != 5) { Tcl_WrongNumArgs(interp, 3, objv, "index string"); return TCL_ERROR; } if (TableGetIcursorObj(tablePtr, objv[3], &first) != TCL_OK) { return TCL_ERROR; } else if ((tablePtr->flags & HAS_ACTIVE) && !(tablePtr->flags & ACTIVE_DISABLED) && tablePtr->state == STATE_NORMAL) { TableInsertChars(tablePtr, first, Tcl_GetString(objv[4])); } } else { /* DELETE */ if (objc > 5) { Tcl_WrongNumArgs(interp, 3, objv, "first ?last?"); return TCL_ERROR; } if (TableGetIcursorObj(tablePtr, objv[3], &first) != TCL_OK) { return TCL_ERROR; } if (objc == 4) { last = first+1; } else if (TableGetIcursorObj(tablePtr, objv[4], &last) != TCL_OK) { return TCL_ERROR; } if ((last >= first) && (tablePtr->flags & HAS_ACTIVE) && !(tablePtr->flags & ACTIVE_DISABLED) && tablePtr->state == STATE_NORMAL) { TableDeleteChars(tablePtr, first, last-first); } } break; /* EDIT ACTIVE */ case MOD_COLS: case MOD_ROWS: { /* * ROW/COL INSERTION/DELETION * FIX: This doesn't handle spans */ int i, lo, hi, argsLeft, offset, minkeyoff, doRows; int maxrow, maxcol, maxkey, minkey, flags, count, *dimPtr; Tcl_HashTable *tagTblPtr, *dimTblPtr; Tcl_HashSearch search; doRows = (cmdIndex == MOD_ROWS); flags = 0; for (i = 3; i < objc; i++) { if (*(Tcl_GetString(objv[i])) != '-') { break; } if (Tcl_GetIndexFromObj(interp, objv[i], rcCmdNames, "switch", 0, &cmdIndex) != TCL_OK) { return TCL_ERROR; } if (cmdIndex == OPT_LAST) { i++; break; } switch (cmdIndex) { case OPT_TITLES: flags |= HOLD_TITLES; break; case OPT_DIMS: flags |= HOLD_DIMS; break; case OPT_SEL: flags |= HOLD_SEL; break; case OPT_TAGS: flags |= HOLD_TAGS; break; case OPT_WINS: flags |= HOLD_WINS; break; } } argsLeft = objc - i; if (argsLeft < 1 || argsLeft > 2) { Tcl_WrongNumArgs(interp, 3, objv, "?switches? index ?count?"); return TCL_ERROR; } count = 1; maxcol = tablePtr->cols-1+tablePtr->colOffset; maxrow = tablePtr->rows-1+tablePtr->rowOffset; if (strcmp(Tcl_GetString(objv[i]), "end") == 0) { /* allow "end" to be specified as an index */ first = (doRows) ? maxrow : maxcol; } else if (Tcl_GetIntFromObj(interp, objv[i], &first) != TCL_OK) { return TCL_ERROR; } if (argsLeft == 2 && Tcl_GetIntFromObj(interp, objv[++i], &count) != TCL_OK) { return TCL_ERROR; } if (count == 0 || (tablePtr->state == STATE_DISABLED)) { return TCL_OK; } if (doRows) { maxkey = maxrow; minkey = tablePtr->rowOffset; minkeyoff = tablePtr->rowOffset+tablePtr->titleRows; offset = tablePtr->rowOffset; tagTblPtr = tablePtr->rowStyles; dimTblPtr = tablePtr->rowHeights; dimPtr = &(tablePtr->rows); lo = tablePtr->colOffset + ((flags & HOLD_TITLES) ? tablePtr->titleCols : 0); hi = maxcol; } else { maxkey = maxcol; minkey = tablePtr->colOffset; minkeyoff = tablePtr->colOffset+tablePtr->titleCols; offset = tablePtr->colOffset; tagTblPtr = tablePtr->colStyles; dimTblPtr = tablePtr->colWidths; dimPtr = &(tablePtr->cols); lo = tablePtr->rowOffset + ((flags & HOLD_TITLES) ? tablePtr->titleRows : 0); hi = maxrow; } /* constrain the starting index */ if (first > maxkey) { first = maxkey; } else if (first < minkey) { first = minkey; } if (doInsert) { /* +count means insert after index, * -count means insert before index */ if (count < 0) { count = -count; } else { first++; } if ((flags & HOLD_TITLES) && (first < minkeyoff)) { count -= minkeyoff-first; if (count <= 0) { return TCL_OK; } first = minkeyoff; } if (!(flags & HOLD_DIMS)) { maxkey += count; *dimPtr += count; } /* * We need to call TableAdjustParams before TableModifyRC to * ensure that side effect code like var traces that might get * called will access the correct new dimensions. */ if (*dimPtr < 1) { *dimPtr = 1; } TableAdjustParams(tablePtr); for (i = maxkey; i >= first; i--) { /* move row/col style && width/height here */ TableModifyRC(tablePtr, doRows, flags, tagTblPtr, dimTblPtr, offset, i, i-count, lo, hi, ((i-count) < first)); } if (!(flags & HOLD_WINS)) { /* * This may be a little severe, but it does unmap the * windows that need to be unmapped, and those that should * stay do remap correctly. [Bug #551325] */ if (doRows) { EmbWinUnmap(tablePtr, first - tablePtr->rowOffset, maxkey - tablePtr->rowOffset, lo - tablePtr->colOffset, hi - tablePtr->colOffset); } else { EmbWinUnmap(tablePtr, lo - tablePtr->rowOffset, hi - tablePtr->rowOffset, first - tablePtr->colOffset, maxkey - tablePtr->colOffset); } } } else { /* (index = i && count = 1) == (index = i && count = -1) */ if (count < 0) { /* if the count is negative, make sure that the col count will * delete no greater than the original index */ if (first+count < minkey) { if (first-minkey < abs(count)) { /* * In this case, the user is asking to delete more rows * than exist before the minkey, so we have to shrink * the count down to the existing rows up to index. */ count = first-minkey; } else { count += first-minkey; } first = minkey; } else { first += count; count = -count; } } if ((flags & HOLD_TITLES) && (first <= minkeyoff)) { count -= minkeyoff-first; if (count <= 0) { return TCL_OK; } first = minkeyoff; } if (count > maxkey-first+1) { count = maxkey-first+1; } if (!(flags & HOLD_DIMS)) { *dimPtr -= count; } /* * We need to call TableAdjustParams before TableModifyRC to * ensure that side effect code like var traces that might get * called will access the correct new dimensions. */ if (*dimPtr < 1) { *dimPtr = 1; } TableAdjustParams(tablePtr); for (i = first; i <= maxkey; i++) { TableModifyRC(tablePtr, doRows, flags, tagTblPtr, dimTblPtr, offset, i, i+count, lo, hi, ((i+count) > maxkey)); } } if (!(flags & HOLD_SEL) && Tcl_FirstHashEntry(tablePtr->selCells, &search) != NULL) { /* clear selection - forceful, but effective */ Tcl_DeleteHashTable(tablePtr->selCells); Tcl_InitHashTable(tablePtr->selCells, TCL_STRING_KEYS); } /* * Make sure that the modified dimension is actually legal * after removing all that stuff. */ if (*dimPtr < 1) { *dimPtr = 1; TableAdjustParams(tablePtr); } /* change the geometry */ TableGeometryRequest(tablePtr); /* FIX: * This has to handle when the previous rows/cols resize because * of the *stretchmode. InvalidateAll does that, but could be * more efficient. */ TableInvalidateAll(tablePtr, 0); break; } } return TCL_OK; } /* *---------------------------------------------------------------------- * * TableDeleteChars -- * Remove one or more characters from an table widget. * * Results: * None. * * Side effects: * Memory gets freed, the table gets modified and (eventually) * redisplayed. * *---------------------------------------------------------------------- */ void TableDeleteChars(tablePtr, index, count) register Table *tablePtr; /* Table widget to modify. */ int index; /* Index of first character to delete. */ int count; /* How many characters to delete. */ { #ifdef TCL_UTF_MAX int byteIndex, byteCount, newByteCount, numBytes, numChars; char *new, *string; string = tablePtr->activeBuf; numBytes = strlen(string); numChars = Tcl_NumUtfChars(string, numBytes); if ((index + count) > numChars) { count = numChars - index; } if (count <= 0) { return; } byteIndex = Tcl_UtfAtIndex(string, index) - string; byteCount = Tcl_UtfAtIndex(string + byteIndex, count) - (string + byteIndex); newByteCount = numBytes + 1 - byteCount; new = (char *) ckalloc((unsigned) newByteCount); memcpy(new, string, (size_t) byteIndex); strcpy(new + byteIndex, string + byteIndex + byteCount); #else int oldlen; char *new; /* this gets the length of the string, as well as ensuring that * the cursor isn't beyond the end char */ TableGetIcursor(tablePtr, "end", &oldlen); if ((index+count) > oldlen) count = oldlen-index; if (count <= 0) return; new = (char *) ckalloc((unsigned)(oldlen-count+1)); strncpy(new, tablePtr->activeBuf, (size_t) index); strcpy(new+index, tablePtr->activeBuf+index+count); /* make sure this string is null terminated */ new[oldlen-count] = '\0'; #endif /* This prevents deletes on BREAK or validation error. */ if (tablePtr->validate && TableValidateChange(tablePtr, tablePtr->activeRow+tablePtr->rowOffset, tablePtr->activeCol+tablePtr->colOffset, tablePtr->activeBuf, new, index) != TCL_OK) { ckfree(new); return; } ckfree(tablePtr->activeBuf); tablePtr->activeBuf = new; /* mark the text as changed */ tablePtr->flags |= TEXT_CHANGED; if (tablePtr->icursor >= index) { if (tablePtr->icursor >= (index+count)) { tablePtr->icursor -= count; } else { tablePtr->icursor = index; } } TableSetActiveIndex(tablePtr); TableRefresh(tablePtr, tablePtr->activeRow, tablePtr->activeCol, CELL); } /* *---------------------------------------------------------------------- * * TableInsertChars -- * Add new characters to the active cell of a table widget. * * Results: * None. * * Side effects: * New information gets added to tablePtr; it will be redisplayed * soon, but not necessarily immediately. * *---------------------------------------------------------------------- */ void TableInsertChars(tablePtr, index, value) register Table *tablePtr; /* Table that is to get the new elements. */ int index; /* Add the new elements before this element. */ char *value; /* New characters to add (NULL-terminated * string). */ { #ifdef TCL_UTF_MAX int oldlen, byteIndex, byteCount; char *new, *string; byteCount = strlen(value); if (byteCount == 0) { return; } /* Is this an autoclear and this is the first update */ /* Note that this clears without validating */ if (tablePtr->autoClear && !(tablePtr->flags & TEXT_CHANGED)) { /* set the buffer to be empty */ tablePtr->activeBuf = (char *)ckrealloc(tablePtr->activeBuf, 1); tablePtr->activeBuf[0] = '\0'; /* the insert position now has to be 0 */ index = 0; tablePtr->icursor = 0; } string = tablePtr->activeBuf; byteIndex = Tcl_UtfAtIndex(string, index) - string; oldlen = strlen(string); new = (char *) ckalloc((unsigned)(oldlen + byteCount + 1)); memcpy(new, string, (size_t) byteIndex); strcpy(new + byteIndex, value); strcpy(new + byteIndex + byteCount, string + byteIndex); /* validate potential new active buffer */ /* This prevents inserts on either BREAK or validation error. */ if (tablePtr->validate && TableValidateChange(tablePtr, tablePtr->activeRow+tablePtr->rowOffset, tablePtr->activeCol+tablePtr->colOffset, tablePtr->activeBuf, new, byteIndex) != TCL_OK) { ckfree(new); return; } /* * The following construction is used because inserting improperly * formed UTF-8 sequences between other improperly formed UTF-8 * sequences could result in actually forming valid UTF-8 sequences; * the number of characters added may not be Tcl_NumUtfChars(string, -1), * because of context. The actual number of characters added is how * many characters were are in the string now minus the number that * used to be there. */ if (tablePtr->icursor >= index) { tablePtr->icursor += Tcl_NumUtfChars(new, oldlen+byteCount) - Tcl_NumUtfChars(tablePtr->activeBuf, oldlen); } ckfree(string); tablePtr->activeBuf = new; #else int oldlen, newlen; char *new; newlen = strlen(value); if (newlen == 0) return; /* Is this an autoclear and this is the first update */ /* Note that this clears without validating */ if (tablePtr->autoClear && !(tablePtr->flags & TEXT_CHANGED)) { /* set the buffer to be empty */ tablePtr->activeBuf = (char *)ckrealloc(tablePtr->activeBuf, 1); tablePtr->activeBuf[0] = '\0'; /* the insert position now has to be 0 */ index = 0; } oldlen = strlen(tablePtr->activeBuf); /* get the buffer to at least the right length */ new = (char *) ckalloc((unsigned)(oldlen+newlen+1)); strncpy(new, tablePtr->activeBuf, (size_t) index); strcpy(new+index, value); strcpy(new+index+newlen, (tablePtr->activeBuf)+index); /* make sure this string is null terminated */ new[oldlen+newlen] = '\0'; /* validate potential new active buffer */ /* This prevents inserts on either BREAK or validation error. */ if (tablePtr->validate && TableValidateChange(tablePtr, tablePtr->activeRow+tablePtr->rowOffset, tablePtr->activeCol+tablePtr->colOffset, tablePtr->activeBuf, new, index) != TCL_OK) { ckfree(new); return; } ckfree(tablePtr->activeBuf); tablePtr->activeBuf = new; if (tablePtr->icursor >= index) { tablePtr->icursor += newlen; } #endif /* mark the text as changed */ tablePtr->flags |= TEXT_CHANGED; TableSetActiveIndex(tablePtr); TableRefresh(tablePtr, tablePtr->activeRow, tablePtr->activeCol, CELL); } /* *---------------------------------------------------------------------- * * TableModifyRC -- * Helper function that does the core work of moving rows/cols * and associated tags. * * Results: * None. * * Side effects: * Moves cell data and possibly tag data * *---------------------------------------------------------------------- */ static void TableModifyRC(tablePtr, doRows, flags, tagTblPtr, dimTblPtr, offset, from, to, lo, hi, outOfBounds) Table *tablePtr; /* Information about text widget. */ int doRows; /* rows (1) or cols (0) */ int flags; /* flags indicating what to move */ Tcl_HashTable *tagTblPtr, *dimTblPtr; /* Pointers to the row/col tags * and width/height tags */ int offset; /* appropriate offset */ int from, to; /* the from and to row/col */ int lo, hi; /* the lo and hi col/row */ int outOfBounds; /* the boundary check for shifting items */ { int j, new; char buf[INDEX_BUFSIZE], buf1[INDEX_BUFSIZE]; Tcl_HashEntry *entryPtr, *newPtr; TableEmbWindow *ewPtr; /* * move row/col style && width/height here * If -holdtags is specified, we don't move the user-set widths/heights * of the absolute rows/columns, otherwise we enter here to move the * dimensions appropriately */ if (!(flags & HOLD_TAGS)) { entryPtr = Tcl_FindHashEntry(tagTblPtr, (char *)from); if (entryPtr != NULL) { Tcl_DeleteHashEntry(entryPtr); } entryPtr = Tcl_FindHashEntry(dimTblPtr, (char *)from-offset); if (entryPtr != NULL) { Tcl_DeleteHashEntry(entryPtr); } if (!outOfBounds) { entryPtr = Tcl_FindHashEntry(tagTblPtr, (char *)to); if (entryPtr != NULL) { newPtr = Tcl_CreateHashEntry(tagTblPtr, (char *)from, &new); Tcl_SetHashValue(newPtr, Tcl_GetHashValue(entryPtr)); Tcl_DeleteHashEntry(entryPtr); } entryPtr = Tcl_FindHashEntry(dimTblPtr, (char *)to-offset); if (entryPtr != NULL) { newPtr = Tcl_CreateHashEntry(dimTblPtr, (char *)from-offset, &new); Tcl_SetHashValue(newPtr, Tcl_GetHashValue(entryPtr)); Tcl_DeleteHashEntry(entryPtr); } } } for (j = lo; j <= hi; j++) { if (doRows /* rows */) { TableMakeArrayIndex(from, j, buf); TableMakeArrayIndex(to, j, buf1); TableMoveCellValue(tablePtr, to, j, buf1, from, j, buf, outOfBounds); } else { TableMakeArrayIndex(j, from, buf); TableMakeArrayIndex(j, to, buf1); TableMoveCellValue(tablePtr, j, to, buf1, j, from, buf, outOfBounds); } /* * If -holdselection is specified, we leave the selected cells in the * absolute cell values, otherwise we enter here to move the * selection appropriately */ if (!(flags & HOLD_SEL)) { entryPtr = Tcl_FindHashEntry(tablePtr->selCells, buf); if (entryPtr != NULL) { Tcl_DeleteHashEntry(entryPtr); } if (!outOfBounds) { entryPtr = Tcl_FindHashEntry(tablePtr->selCells, buf1); if (entryPtr != NULL) { Tcl_CreateHashEntry(tablePtr->selCells, buf, &new); Tcl_DeleteHashEntry(entryPtr); } } } /* * If -holdtags is specified, we leave the tags in the * absolute cell values, otherwise we enter here to move the * tags appropriately */ if (!(flags & HOLD_TAGS)) { entryPtr = Tcl_FindHashEntry(tablePtr->cellStyles, buf); if (entryPtr != NULL) { Tcl_DeleteHashEntry(entryPtr); } if (!outOfBounds) { entryPtr = Tcl_FindHashEntry(tablePtr->cellStyles, buf1); if (entryPtr != NULL) { newPtr = Tcl_CreateHashEntry(tablePtr->cellStyles, buf, &new); Tcl_SetHashValue(newPtr, Tcl_GetHashValue(entryPtr)); Tcl_DeleteHashEntry(entryPtr); } } } /* * If -holdwindows is specified, we leave the windows in the * absolute cell values, otherwise we enter here to move the * windows appropriately */ if (!(flags & HOLD_WINS)) { /* * Delete whatever window might be in our destination */ Table_WinDelete(tablePtr, buf); if (!outOfBounds) { /* * buf1 is where the window is * buf is where we want it to be * * This is an adaptation of Table_WinMove, which we can't * use because we are intermediately fiddling with boundaries */ entryPtr = Tcl_FindHashEntry(tablePtr->winTable, buf1); if (entryPtr != NULL) { /* * If there was a window in our source, * get the window pointer to move it */ ewPtr = (TableEmbWindow *) Tcl_GetHashValue(entryPtr); /* and free the old hash table entry */ Tcl_DeleteHashEntry(entryPtr); entryPtr = Tcl_CreateHashEntry(tablePtr->winTable, buf, &new); /* * We needn't check if a window was in buf, since the * Table_WinDelete above should guarantee that no window * is there. Just set the new entry's value. */ Tcl_SetHashValue(entryPtr, (ClientData) ewPtr); ewPtr->hPtr = entryPtr; } } } } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/version.h�������������������������������������������������������������������0000444�0000000�0000000�00000000307�13746047614�015336� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#if 0 TBL_MAJOR_VERSION = 2 TBL_MINOR_VERSION = 8 VERSION = $(TBL_MAJOR_VERSION).$(TBL_MINOR_VERSION) #endif #define TBL_MAJOR_VERSION 2 #define TBL_MINOR_VERSION 8 #define VERSION "2.8" �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/why�������������������������������������������������������������������������0000644�0000000�0000000�00000005316�13742524721�014234� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/local/bin/perl -w use strict; my %ref; my %def; my %file; sub read_object { my $obj = shift; open(NM,"nm -p $obj|") || die "Cannot open nm $obj:$!"; $def{$obj} = {}; $file{$obj} = {}; my @refs = (); while (<NM>) { if (/\b([A-Z])\b\s*_?(.*)$/) { my ($kind,$name) = ($1,$2); $file{$obj}{$name} = $kind; if ($kind ne 'U') { $def{$obj}{$name} = $kind; } else { $ref{$name} = [] unless (exists $ref{$name}); push(@{$ref{$name}},$obj); push(@refs,$name); } } } close(NM); return @refs; } warn "Scanning object files\n"; foreach my $obj (<*.o>,<../*.o>) { # next if $obj =~ /_f\.o$/; read_object($obj); } warn "Analysing...\n"; if (@ARGV) { FILE: foreach my $file (@ARGV) { if (exists $file{$file}) { foreach my $sym (keys %{$def{$file}}) { if (exists $ref{$sym}) { my @files = grep(!/_f\.o$/,@{$ref{$sym}}); if (@files) { print "$file defines $sym for ",join(',',@files),"\n"; next FILE; } } } warn "No good reason for $file!\n"; } else { my %exc; my @sym = read_object($file); foreach my $sym (sort @sym) { next unless $sym =~ /^[TL]/; if (exists $ref{$sym}) { my @files = grep($_ ne $file,grep(!/_f\.o$/,@{$ref{$sym}})); if (@files) { print "$sym needed by ",join(',',@files),"\n"; } else { @files = grep(/_f\.o$/,@{$ref{$sym}}); if (@files) { warn "$sym only used in ",join(',',@files),"\n"; if (@files == 1) { my $exc = $files[0]; die "Strange $exc" unless $exc =~ s/_f\.o$/.nexc/; $exc{$exc} = [] unless exists $exc{$exc}; push(@{$exc{$exc}},$sym); } } } } } foreach my $exc (keys %exc) { open(EXC,">$exc") || die "Cannot open $exc:$!"; print EXC join("\n",@{$exc{$exc}},''); close(EXC); } } } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/findstrings�����������������������������������������������������������������0000644�0000000�0000000�00000002560�13742524721�015755� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/local/bin/perl -w %table = (); %where = (); sub notice { my ($index,$str) = @_; ${$cur}[$index] = [] unless defined ${$cur}[$index]; my $array = ${$cur}[$index]; push(@$array,$str); $where{$str} = [] unless defined $where{$str}; push (@{$where{$str}},$Func,$index); } while (<>) { if (defined $Func) { if (/^}/) { undef $Func; undef $cur; } if (/strn?cmp\s*\(\s*LangString\(args\[(\d+)\]\)\s*,\s*("[^"]*")\s*/) { notice($1,$2); } elsif (/strn?cmp\s*\(\s*("[^"]*")\s*,LangString\(args\[(\d+)\]\)/) { notice($2,$1); } } else { if (/^([A-Za-z][A-Za-z0-9_]*)\s*\(/) { $Func = "$ARGV:$1"; $table{$Func} = [] if (!defined $table{$Func}); $cur = $table{$Func}; } } } foreach $Func (sort keys %table) { $cur = $table{$Func}; if (@{$cur}) { print "$Func:\n"; my $i = 0; for ($i = 0; $i < @{$cur}; $i++) { if (defined ${$cur}[$i]) { my $array = ${$cur}[$i]; print " $i ",join(' ',@$array),"\n"; } } print "\n"; } } foreach $str (sort keys %where) { my $array = $where{$str}; my $i = 0; print "$str:"; for ($i=0; $i < @{$array}; $i += 2) { print " ${$array}[$i](${$array}[$i+1])"; } print "\n"; } ������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/������������������������������������������������������������������������0000755�0000000�0000000�00000000000�13746050164�014227� 5����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/license.terms�����������������������������������������������������������0000644�0000000�0000000�00000003346�13745605157�016742� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������This software is copyrighted by the Regents of the University of California, Sun Microsystems, Inc., and other parties. The following terms apply to all files associated with the software unless explicitly disclaimed in individual files. The authors hereby grant permission to use, copy, modify, distribute, and license this software and its documentation for any purpose, provided that existing copyright notices are retained in all copies and that this notice is included verbatim in any distributions. No written agreement, license, or royalty fee is required for any of the authorized uses. Modifications to this software may be copyrighted by their authors and need not follow the licensing terms described here, provided that the new terms are clearly indicated on the first page of each file where they apply. IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. RESTRICTED RIGHTS: Use, duplication or disclosure by the government is subject to the restrictions as set forth in subparagraph (c) (1) (ii) of the Rights in Technical Data and Computer Software Clause as DFARS 252.227-7013 and FAR 52.227-19. ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable800/�������������������������������������������������������������0000755�0000000�0000000�00000000000�13746047627�016057� 5����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable800/tkTable.c����������������������������������������������������0000644�0000000�0000000�00000375035�13745605157�017623� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * tkTable.c -- * * This module implements table widgets for the Tk * toolkit. An table displays a 2D array of strings * and allows the strings to be edited. * * Based on Tk3 table widget written by Roland King * * Updates 1996 by: * Jeffrey Hobbs jeff.hobbs@acm.org * John Ellson ellson@lucent.com * Peter Bruecker peter@bj-ig.de * Tom Moore tmoore@spatial.ca * Sebastian Wangnick wangnick@orthogon.de * * Copyright (c) 1997-2002 Jeffrey Hobbs * * See the file "license.txt" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tkTable.c,v 1.3 2005/01/26 15:27:59 A0182636 Exp $ */ #include "tkTable.h" #include "tkPort.h" #include "tkInt.h" #include "tkVMacro.h" /* perltk debug only for picking up forward referenced definitions */ /* #include "myinc.h" */ /* Perltk: XSETCLIP doesn't Appear to be there for perltk so always define this : */ #define NO_XSETCLIP /* Not Needed??? */ /* static char ** StringifyObjects _ANSI_ARGS_((int objc, Tcl_Obj *CONST objv[])); */ static int TableWidgetObjCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj * objv[])); static int TableConfigure _ANSI_ARGS_((Tcl_Interp *interp, Table *tablePtr, int objc, Tcl_Obj *CONST objv[], int flags, int forceUpdate)); static void TableDestroy _ANSI_ARGS_((ClientData clientdata)); static void TableEventProc _ANSI_ARGS_((ClientData clientData, XEvent *eventPtr)); static void TableCmdDeletedProc _ANSI_ARGS_((ClientData clientData)); static void TableRedrawHighlight _ANSI_ARGS_((Table *tablePtr)); static void TableGetGc _ANSI_ARGS_((Display *display, Drawable d, TableTag *tagPtr, GC *tagGc)); static void TableDisplay _ANSI_ARGS_((ClientData clientdata)); static void TableFlashEvent _ANSI_ARGS_((ClientData clientdata)); static char * TableVarProc _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, Var name, char *index, int flags)); static void TableCursorEvent _ANSI_ARGS_((ClientData clientData)); static int TableFetchSelection _ANSI_ARGS_((ClientData clientData, int offset, char *buffer, int maxBytes)); static Tk_RestrictAction TableRestrictProc _ANSI_ARGS_((ClientData arg, XEvent *eventPtr)); /* * The following tables define the widget commands (and sub- * commands) and map the indexes into the string tables into * enumerated types used to dispatch the widget command. */ static CONST84 char *selCmdNames[] = { "anchor", "clear", "includes", "present", "set", (char *)NULL }; enum selCommand { CMD_SEL_ANCHOR, CMD_SEL_CLEAR, CMD_SEL_INCLUDES, CMD_SEL_PRESENT, CMD_SEL_SET }; static CONST84 char *commandNames[] = { "activate", "bbox", "border", "cget", "clear", "configure", "curselection", "curvalue", "delete", "get", "rowHeight", "hidden", "icursor", "index", "insert", #ifdef POSTSCRIPT "postscript", #endif "reread", "scan", "see", "selection", "set", "spans", "tag", "validate", "version", "window", "colWidth", "xview", "yview", (char *)NULL }; enum command { CMD_ACTIVATE, CMD_BBOX, CMD_BORDER, CMD_CGET, CMD_CLEAR, CMD_CONFIGURE, CMD_CURSEL, CMD_CURVALUE, CMD_DELETE, CMD_GET, CMD_HEIGHT, CMD_HIDDEN, CMD_ICURSOR, CMD_INDEX, CMD_INSERT, #ifdef POSTSCRIPT CMD_POSTSCRIPT, #endif CMD_REREAD, CMD_SCAN, CMD_SEE, CMD_SELECTION, CMD_SET, CMD_SPANS, CMD_TAG, CMD_VALIDATE, CMD_VERSION, CMD_WINDOW, CMD_WIDTH, CMD_XVIEW, CMD_YVIEW }; /* -selecttype selection type options */ static Cmd_Struct sel_vals[]= { {"row", SEL_ROW}, {"col", SEL_COL}, {"both", SEL_BOTH}, {"cell", SEL_CELL}, {"", 0 } }; /* -resizeborders options */ static Cmd_Struct resize_vals[]= { {"row", SEL_ROW}, /* allow rows to be dragged */ {"col", SEL_COL}, /* allow cols to be dragged */ {"both", SEL_ROW|SEL_COL}, /* allow either to be dragged */ {"none", SEL_NONE}, /* allow nothing to be dragged */ {"", 0 } }; /* drawmode values */ /* The display redraws with a pixmap using TK function calls */ #define DRAW_MODE_SLOW (1<<0) /* The redisplay is direct to the screen, but TK function calls are still * used to give correct 3-d border appearance and thus remain compatible * with other TK apps */ #define DRAW_MODE_TK_COMPAT (1<<1) /* the redisplay goes straight to the screen and the 3d borders are rendered * with a single pixel wide line only. It cheats and uses the internal * border structure to do the borders */ #define DRAW_MODE_FAST (1<<2) #define DRAW_MODE_SINGLE (1<<3) static Cmd_Struct drawmode_vals[] = { {"fast", DRAW_MODE_FAST}, {"compatible", DRAW_MODE_TK_COMPAT}, {"slow", DRAW_MODE_SLOW}, {"single", DRAW_MODE_SINGLE}, {"", 0} }; /* stretchmode values */ #define STRETCH_MODE_NONE (1<<0) /* No additional pixels will be added to rows or cols */ #define STRETCH_MODE_UNSET (1<<1) /* All default rows or columns will be stretched to fill the screen */ #define STRETCH_MODE_ALL (1<<2) /* All rows/columns will be padded to fill the window */ #define STRETCH_MODE_LAST (1<<3) /* Stretch last elememt to fill window */ #define STRETCH_MODE_FILL (1<<4) /* More ROWS in Window */ static Cmd_Struct stretch_vals[] = { {"none", STRETCH_MODE_NONE}, {"unset", STRETCH_MODE_UNSET}, {"all", STRETCH_MODE_ALL}, {"last", STRETCH_MODE_LAST}, {"fill", STRETCH_MODE_FILL}, {"", 0} }; static Cmd_Struct state_vals[]= { {"normal", STATE_NORMAL}, {"disabled", STATE_DISABLED}, {"", 0 } }; /* The widget configuration table */ static Tk_CustomOption drawOpt = { Cmd_OptionSet, Cmd_OptionGet, (ClientData)(&drawmode_vals) }; static Tk_CustomOption resizeTypeOpt = { Cmd_OptionSet, Cmd_OptionGet, (ClientData)(&resize_vals) }; static Tk_CustomOption stretchOpt = { Cmd_OptionSet, Cmd_OptionGet, (ClientData)(&stretch_vals) }; static Tk_CustomOption selTypeOpt = { Cmd_OptionSet, Cmd_OptionGet, (ClientData)(&sel_vals) }; static Tk_CustomOption stateTypeOpt = { Cmd_OptionSet, Cmd_OptionGet, (ClientData)(&state_vals) }; static Tk_CustomOption bdOpt = { TableOptionBdSet, TableOptionBdGet, (ClientData) BD_TABLE }; Tk_ConfigSpec tableSpecs[] = { {TK_CONFIG_ANCHOR, "-anchor", "anchor", "Anchor", "center", Tk_Offset(Table, defaultTag.anchor), 0}, {TK_CONFIG_BOOLEAN, "-autoclear", "autoClear", "AutoClear", "0", Tk_Offset(Table, autoClear), 0}, {TK_CONFIG_BORDER, "-background", "background", "Background", NORMAL_BG, Tk_Offset(Table, defaultTag.bg), 0}, {TK_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL, 0, 0}, {TK_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0}, {TK_CONFIG_CURSOR, "-bordercursor", "borderCursor", "Cursor", "crosshair", Tk_Offset(Table, bdcursor), TK_CONFIG_NULL_OK }, {TK_CONFIG_CUSTOM, "-borderwidth", "borderWidth", "BorderWidth", "1", Tk_Offset(Table, defaultTag), TK_CONFIG_NULL_OK, &bdOpt }, {TK_CONFIG_CALLBACK, "-browsecommand", "browseCommand", "BrowseCommand", "", Tk_Offset(Table, browseCmd), TK_CONFIG_NULL_OK}, {TK_CONFIG_SYNONYM, "-browsecmd", "browseCommand", (char *)NULL, (char *)NULL, 0, TK_CONFIG_NULL_OK}, {TK_CONFIG_BOOLEAN, "-cache", "cache", "Cache", "0", Tk_Offset(Table, caching), 0}, {TK_CONFIG_INT, "-colorigin", "colOrigin", "Origin", "0", Tk_Offset(Table, colOffset), 0}, {TK_CONFIG_INT, "-cols", "cols", "Cols", "10", Tk_Offset(Table, cols), 0}, {TK_CONFIG_STRING, "-colseparator", "colSeparator", "Separator", "\t", Tk_Offset(Table, colSep), TK_CONFIG_NULL_OK }, {TK_CONFIG_CUSTOM, "-colstretchmode", "colStretch", "StretchMode", "none", Tk_Offset (Table, colStretch), 0 , &stretchOpt }, {TK_CONFIG_CALLBACK, "-coltagcommand", "colTagCommand", "TagCommand", NULL, Tk_Offset(Table, colTagCmd), TK_CONFIG_NULL_OK }, {TK_CONFIG_INT, "-colwidth", "colWidth", "ColWidth", "10", Tk_Offset(Table, defColWidth), 0}, {TK_CONFIG_CALLBACK, "-command", "command", "Command", "", Tk_Offset(Table, command), TK_CONFIG_NULL_OK}, {TK_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor", "xterm", Tk_Offset(Table, cursor), TK_CONFIG_NULL_OK }, {TK_CONFIG_CUSTOM, "-drawmode", "drawMode", "DrawMode", "compatible", Tk_Offset(Table, drawMode), 0, &drawOpt }, {TK_CONFIG_BOOLEAN, "-exportselection", "exportSelection", "ExportSelection", "1", Tk_Offset(Table, exportSelection), 0}, {TK_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL, (char *)NULL, 0, 0}, {TK_CONFIG_BOOLEAN, "-flashmode", "flashMode", "FlashMode", "0", Tk_Offset(Table, flashMode), 0}, {TK_CONFIG_INT, "-flashtime", "flashTime", "FlashTime", "2", Tk_Offset(Table, flashTime), 0}, {TK_CONFIG_FONT, "-font", "font", "Font", DEF_TABLE_FONT, Tk_Offset(Table, defaultTag.tkfont), 0}, {TK_CONFIG_BORDER, "-foreground", "foreground", "Foreground", "black", Tk_Offset(Table, defaultTag.fg), 0}, #ifdef PROCS {TK_CONFIG_BOOLEAN, "-hasprocs", "hasProcs", "hasProcs", "0", Tk_Offset(Table, hasProcs), 0}, #endif {TK_CONFIG_INT, "-height", "height", "Height", "0", Tk_Offset(Table, maxReqRows), 0}, {TK_CONFIG_COLOR, "-highlightbackground", "highlightBackground", "HighlightBackground", NORMAL_BG, Tk_Offset(Table, highlightBgColorPtr), 0}, {TK_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor", HIGHLIGHT, Tk_Offset(Table, highlightColorPtr), 0}, {TK_CONFIG_PIXELS, "-highlightthickness", "highlightThickness", "HighlightThickness", "2", Tk_Offset(Table, highlightWidth), 0}, {TK_CONFIG_BORDER, "-insertbackground", "insertBackground", "Foreground", "Black", Tk_Offset(Table, insertBg), 0}, {TK_CONFIG_PIXELS, "-insertborderwidth", "insertBorderWidth", "BorderWidth", "0", Tk_Offset(Table, insertBorderWidth), TK_CONFIG_COLOR_ONLY}, {TK_CONFIG_PIXELS, "-insertborderwidth", "insertBorderWidth", "BorderWidth", "0", Tk_Offset(Table, insertBorderWidth), TK_CONFIG_MONO_ONLY}, {TK_CONFIG_INT, "-insertofftime", "insertOffTime", "OffTime", "300", Tk_Offset(Table, insertOffTime), 0}, {TK_CONFIG_INT, "-insertontime", "insertOnTime", "OnTime", "600", Tk_Offset(Table, insertOnTime), 0}, {TK_CONFIG_PIXELS, "-insertwidth", "insertWidth", "InsertWidth", "2", Tk_Offset(Table, insertWidth), 0}, {TK_CONFIG_BOOLEAN, "-invertselected", "invertSelected", "InvertSelected", "0", Tk_Offset(Table, invertSelected), 0}, {TK_CONFIG_PIXELS, "-ipadx", "ipadX", "Pad", "0", Tk_Offset(Table, ipadX), 0}, {TK_CONFIG_PIXELS, "-ipady", "ipadY", "Pad", "0", Tk_Offset(Table, ipadY), 0}, {TK_CONFIG_JUSTIFY, "-justify", "justify", "Justify", "left", Tk_Offset(Table, defaultTag.justify), 0 }, {TK_CONFIG_PIXELS, "-maxheight", "maxHeight", "MaxHeight", "600", Tk_Offset(Table, maxReqHeight), 0}, {TK_CONFIG_PIXELS, "-maxwidth", "maxWidth", "MaxWidth", "800", Tk_Offset(Table, maxReqWidth), 0}, {TK_CONFIG_BOOLEAN, "-multiline", "multiline", "Multiline", "1", Tk_Offset(Table, defaultTag.multiline), 0}, {TK_CONFIG_PIXELS, "-padx", "padX", "Pad", "0", Tk_Offset(Table, padX), 0}, {TK_CONFIG_PIXELS, "-pady", "padY", "Pad", "0", Tk_Offset(Table, padY), 0}, {TK_CONFIG_RELIEF, "-relief", "relief", "Relief", "sunken", Tk_Offset(Table, defaultTag.relief), 0}, {TK_CONFIG_CUSTOM, "-resizeborders", "resizeBorders", "ResizeBorders", "both", Tk_Offset(Table, resize), 0, &resizeTypeOpt }, {TK_CONFIG_INT, "-rowheight", "rowHeight", "RowHeight", "1", Tk_Offset(Table, defRowHeight), 0}, {TK_CONFIG_INT, "-roworigin", "rowOrigin", "Origin", "0", Tk_Offset(Table, rowOffset), 0}, {TK_CONFIG_INT, "-rows", "rows", "Rows", "10", Tk_Offset(Table, rows), 0}, {TK_CONFIG_STRING, "-rowseparator", "rowSeparator", "Separator", "\n", Tk_Offset(Table, rowSep), TK_CONFIG_NULL_OK }, {TK_CONFIG_CUSTOM, "-rowstretchmode", "rowStretch", "StretchMode", "none", Tk_Offset(Table, rowStretch), 0 , &stretchOpt }, {TK_CONFIG_CALLBACK, "-rowtagcommand", "rowTagCommand", "TagCommand", NULL, Tk_Offset(Table, rowTagCmd), TK_CONFIG_NULL_OK }, {TK_CONFIG_SYNONYM, "-selcmd", "selectionCommand", (char *)NULL, (char *)NULL, 0, TK_CONFIG_NULL_OK}, {TK_CONFIG_CALLBACK, "-selectioncommand", "selectionCommand", "SelectionCommand", NULL, Tk_Offset(Table, selCmd), TK_CONFIG_NULL_OK }, {TK_CONFIG_STRING, "-selectmode", "selectMode", "SelectMode", "browse", Tk_Offset(Table, selectMode), TK_CONFIG_NULL_OK }, {TK_CONFIG_BOOLEAN, "-selecttitles", "selectTitles", "SelectTitles", "0", Tk_Offset(Table, selectTitles), 0}, {TK_CONFIG_CUSTOM, "-selecttype", "selectType", "SelectType", "cell", Tk_Offset(Table, selectType), 0, &selTypeOpt }, #ifdef PROCS {TK_CONFIG_BOOLEAN, "-showprocs", "showProcs", "showProcs", "0", Tk_Offset(Table, showProcs), 0}, #endif {TK_CONFIG_BOOLEAN, "-sparsearray", "sparseArray", "SparseArray", "1", Tk_Offset(Table, sparse), 0}, {TK_CONFIG_CUSTOM, "-state", "state", "State", "normal", Tk_Offset(Table, state), 0, &stateTypeOpt}, {TK_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus", (char *)NULL, Tk_Offset(Table, takeFocus), TK_CONFIG_NULL_OK }, {TK_CONFIG_INT, "-titlecols", "titleCols", "TitleCols", "0", Tk_Offset(Table, titleCols), TK_CONFIG_NULL_OK }, #ifdef TITLE_CURSOR {TK_CONFIG_CURSOR, "-titlecursor", "titleCursor", "Cursor", "arrow", Tk_Offset(Table, titleCursor), TK_CONFIG_NULL_OK }, #endif {TK_CONFIG_INT, "-titlerows", "titleRows", "TitleRows", "0", Tk_Offset(Table, titleRows), TK_CONFIG_NULL_OK }, {TK_CONFIG_BOOLEAN, "-usecommand", "useCommand", "UseCommand", "1", Tk_Offset(Table, useCmd), 0}, {TK_CONFIG_SCALARVAR, "-variable", "variable", "Variable", (char *)NULL, Tk_Offset(Table, arrayVar), TK_CONFIG_NULL_OK }, {TK_CONFIG_BOOLEAN, "-validate", "validate", "Validate", "0", Tk_Offset(Table, validate), 0}, {TK_CONFIG_CALLBACK, "-validatecommand", "validateCommand", "ValidateCommand", "", Tk_Offset(Table, valCmd), TK_CONFIG_NULL_OK}, {TK_CONFIG_SYNONYM, "-vcmd", "validateCommand", (char *)NULL, (char *)NULL, 0, TK_CONFIG_NULL_OK}, {TK_CONFIG_INT, "-width", "width", "Width", "0", Tk_Offset(Table, maxReqCols), 0}, {TK_CONFIG_BOOLEAN, "-wrap", "wrap", "Wrap", "0", Tk_Offset(Table, defaultTag.wrap), 0}, {TK_CONFIG_CALLBACK, "-xscrollcommand", "xScrollCommand", "ScrollCommand", NULL, Tk_Offset(Table, xScrollCmd), TK_CONFIG_NULL_OK }, {TK_CONFIG_CALLBACK, "-yscrollcommand", "yScrollCommand", "ScrollCommand", NULL, Tk_Offset(Table, yScrollCmd), TK_CONFIG_NULL_OK }, {TK_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; /* * This specifies the configure options that will cause an update to * occur, so we should have a quick lookup table for them. * Keep this in sync with the above values. */ static CONST84 char *updateOpts[] = { "-anchor", "-background", "-bg", "-bd", "-borderwidth", "-cache", "-command", "-colorigin", "-cols", "-colstretchmode", "-coltagcommand", "-drawmode", "-fg", "-font", "-foreground", "-hasprocs", "-height", "-highlightbackground", "-highlightcolor", "-highlightthickness", "-insertbackground", "-insertborderwidth", "-insertwidth", "-invertselected", "-ipadx", "-ipady", "-maxheight", "-maxwidth", "-multiline", "-padx", "-pady", "-relief", "-roworigin", "-rows", "-rowstretchmode", "-rowtagcommand", "-showprocs", "-state", "-titlecols", "-titlerows", "-usecommand", "-variable", "-width", "-wrap", "-xscrollcommand", "-yscrollcommand", (char *) NULL }; #ifdef WIN32 /* * Some code from TkWinInt.h that we use to correct and speed up * drawing of cells that need clipping in TableDisplay. */ typedef struct { int type; HWND handle; void *winPtr; } TkWinWindow; typedef struct { int type; HBITMAP handle; Colormap colormap; int depth; } TkWinBitmap; typedef struct { int type; HDC hdc; } TkWinDC; typedef union { int type; TkWinWindow window; TkWinBitmap bitmap; TkWinDC winDC; } TkWinDrawable; #endif /* * END HEADER INFORMATION */ /* *--------------------------------------------------------------------------- * * StringifyObjects -- (from tclCmdAH.c) * * Helper function to bridge the gap between an object-based procedure * and an older string-based procedure. * * Given an array of objects, allocate an array that consists of the * string representations of those objects. * * Results: * The return value is a pointer to the newly allocated array of * strings. Elements 0 to (objc-1) of the string array point to the * string representation of the corresponding element in the source * object array; element objc of the string array is NULL. * * Side effects: * Memory allocated. The caller must eventually free this memory * by calling ckfree() on the return value. * int result; char **argv; argv = StringifyObjects(objc, objv); result = StringBasedCmd(interp, objc, argv); ckfree((char *) argv); return result; * *--------------------------------------------------------------------------- */ /* Don't Need This becuase arrays of Objects equivalent to arrays of Args???? static Arg * StringifyObjects(objc, objv) int objc; /* Number of arguments. Tcl_Obj *CONST objv[]; Argument objects. { int i; Arg *args; /* This needs to not be autoconverted to a Arg, so change the name to argsv args = (Arg *) ckalloc((objc + 1) * sizeof(Arg *)); for (i = 0; i < objc; i++) { args[i] = Tcl_GetString(objv[i]); } args[i] = NULL; return args; } /* * As long as we wait for the Function in general * * This parses the "-class" option for the table. */ static int Tk_ClassOptionObjCmd(Tk_Window tkwin, char *defaultclass, int objc, Tcl_Obj *CONST objv[]) { char *classname = defaultclass; int offset = 0; if ((objc >= 4) && STREQ(Tcl_GetString(objv[2]),"-class")) { classname = Tcl_GetString(objv[3]); offset = 2; } Tk_SetClass(tkwin, classname); return offset; } /* *-------------------------------------------------------------- * * Tk_TableObjCmd -- * This procedure is invoked to process the "table" Tcl * command. See the user documentation for details on what * it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Tk_TableObjCmd(clientData, interp, objc, objv) ClientData clientData; /* Main window associated with interpreter. */ Tcl_Interp *interp; int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument objects. */ { register Table *tablePtr; Tk_Window tkwin, mainWin = (Tk_Window) clientData; int offset; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?"); return TCL_ERROR; } tkwin = Tk_CreateWindowFromPath(interp, mainWin, Tcl_GetString(objv[1]), (char *)NULL); if (tkwin == NULL) { return TCL_ERROR; } tablePtr = (Table *) ckalloc(sizeof(Table)); memset((VOID *) tablePtr, 0, sizeof(Table)); /* * Set the structure elments that aren't 0/NULL by default, * and that won't be set by the initial configure call. */ tablePtr->tkwin = tkwin; tablePtr->display = Tk_Display(tkwin); tablePtr->interp = interp; tablePtr->widgetCmd = Lang_CreateWidget(interp, tablePtr->tkwin, TableWidgetObjCmd, (ClientData) tablePtr, (Tcl_CmdDeleteProc *) TableCmdDeletedProc); tablePtr->anchorRow = -1; tablePtr->anchorCol = -1; tablePtr->activeRow = -1; tablePtr->activeCol = -1; tablePtr->oldTopRow = -1; tablePtr->oldLeftCol = -1; tablePtr->oldActRow = -1; tablePtr->oldActCol = -1; tablePtr->seen[0] = -1; tablePtr->dataSource = DATA_NONE; tablePtr->activeBuf = ckalloc(1); *(tablePtr->activeBuf) = '\0'; tablePtr->cursor = None; tablePtr->bdcursor = None; tablePtr->defaultTag.justify = TK_JUSTIFY_LEFT; tablePtr->defaultTag.state = STATE_UNKNOWN; /* misc tables */ tablePtr->tagTable = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(tablePtr->tagTable, TCL_STRING_KEYS); tablePtr->winTable = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(tablePtr->winTable, TCL_STRING_KEYS); /* internal value cache */ tablePtr->cache = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(tablePtr->cache, TCL_STRING_KEYS); /* style hash tables */ tablePtr->colWidths = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(tablePtr->colWidths, TCL_ONE_WORD_KEYS); tablePtr->rowHeights = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(tablePtr->rowHeights, TCL_ONE_WORD_KEYS); /* style hash tables */ tablePtr->rowStyles = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(tablePtr->rowStyles, TCL_ONE_WORD_KEYS); tablePtr->colStyles = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(tablePtr->colStyles, TCL_ONE_WORD_KEYS); tablePtr->cellStyles = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(tablePtr->cellStyles, TCL_STRING_KEYS); /* special style hash tables */ tablePtr->flashCells = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(tablePtr->flashCells, TCL_STRING_KEYS); tablePtr->selCells = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(tablePtr->selCells, TCL_STRING_KEYS); /* * List of tags in priority order. 30 is a good default number to alloc. */ tablePtr->tagPrioMax = 30; tablePtr->tagPrioNames = (char **) ckalloc( sizeof(char *) * tablePtr->tagPrioMax); tablePtr->tagPrios = (TableTag **) ckalloc( sizeof(TableTag *) * tablePtr->tagPrioMax); tablePtr->tagPrioSize = 0; for (offset = 0; offset < tablePtr->tagPrioMax; offset++) { tablePtr->tagPrioNames[offset] = (char *) NULL; tablePtr->tagPrios[offset] = (TableTag *) NULL; } #ifdef PROCS tablePtr->inProc = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(tablePtr->inProc, TCL_STRING_KEYS); #endif /* * Handle class name and selection handlers */ offset = 2 + Tk_ClassOptionObjCmd(tkwin, "Table", objc, objv); Tk_CreateEventHandler(tablePtr->tkwin, PointerMotionMask|ExposureMask|StructureNotifyMask|FocusChangeMask|VisibilityChangeMask, TableEventProc, (ClientData) tablePtr); Tk_CreateSelHandler(tablePtr->tkwin, XA_PRIMARY, XA_STRING, TableFetchSelection, (ClientData) tablePtr, XA_STRING); if (TableConfigure(interp, tablePtr, objc - offset, objv + offset, 0, 1 /* force update */) != TCL_OK) { Tk_DestroyWindow(tkwin); return TCL_ERROR; } TableInitTags(tablePtr); /*Tcl_SetStringObj(Tcl_GetObjResult(interp), Tk_PathName(tablePtr->tkwin), -1); */ /* Tk800.022 needs to old-style LangWidgetArg Call newer perltk's should be ok with the default. */ #ifdef USE_LANGWIDGETARG Tcl_SetObjResult(interp, LangWidgetArg(interp,tablePtr->tkwin)); #else Tcl_SetObjResult(interp, LangWidgetObj(interp,tablePtr->tkwin)); #endif return TCL_OK; } /* *-------------------------------------------------------------- * * TableWidgetObjCmd -- * This procedure is invoked to process the Tcl command * that corresponds to a widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ static int TableWidgetObjCmd(clientData, interp, objc, objv) ClientData clientData; Tcl_Interp *interp; int objc; /* Number of arguments. */ Tcl_Obj * objv[]; /* Argument objects. */ { register Table *tablePtr = (Table *) clientData; int row, col, i, cmdIndex, result = TCL_OK; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?"); return TCL_ERROR; } /* parse the first parameter */ result = Tcl_GetIndexFromObj(interp, objv[1], commandNames, "option", 0, &cmdIndex); if (result != TCL_OK) { return result; } Tcl_Preserve((ClientData) tablePtr); switch ((enum command) cmdIndex) { case CMD_ACTIVATE: result = Table_ActivateCmd(clientData, interp, objc, objv); break; case CMD_BBOX: result = Table_BboxCmd(clientData, interp, objc, objv); break; case CMD_BORDER: result = Table_BorderCmd(clientData, interp, objc, objv); break; case CMD_CGET: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "option"); result = TCL_ERROR; } else { result = Tk_ConfigureValue(interp, tablePtr->tkwin, tableSpecs, (char *) tablePtr, Tcl_GetString(objv[2]), 0); } break; case CMD_CLEAR: result = Table_ClearCmd(clientData, interp, objc, objv); break; case CMD_CONFIGURE: if (objc < 4) { result = Tk_ConfigureInfo(interp, tablePtr->tkwin, tableSpecs, (char *) tablePtr, (objc == 3) ? Tcl_GetString(objv[2]) : (char *) NULL, 0); } else { result = TableConfigure(interp, tablePtr, objc - 2, objv + 2, TK_CONFIG_ARGV_ONLY, 0); } break; case CMD_CURSEL: result = Table_CurselectionCmd(clientData, interp, objc, objv); break; case CMD_CURVALUE: result = Table_CurvalueCmd(clientData, interp, objc, objv); break; case CMD_DELETE: case CMD_INSERT: result = Table_EditCmd(clientData, interp, objc, objv); break; case CMD_GET: result = Table_GetCmd(clientData, interp, objc, objv); break; case CMD_HEIGHT: result = Table_AdjustCmd(clientData, interp, objc, objv,0); break; case CMD_WIDTH: result = Table_AdjustCmd(clientData, interp, objc, objv,1); break; case CMD_HIDDEN: result = Table_HiddenCmd(clientData, interp, objc, objv); break; case CMD_ICURSOR: if (objc != 2 && objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "?cursorPos?"); result = TCL_ERROR; break; } if (!(tablePtr->flags & HAS_ACTIVE) || (tablePtr->flags & ACTIVE_DISABLED) || tablePtr->state == STATE_DISABLED) { Tcl_SetIntObj(Tcl_GetObjResult(interp), -1); break; } else if (objc == 3) { if (TableGetIcursorObj(tablePtr, objv[2], NULL) != TCL_OK) { result = TCL_ERROR; break; } TableRefresh(tablePtr, tablePtr->activeRow, tablePtr->activeCol, CELL); } Tcl_SetIntObj(Tcl_GetObjResult(interp), tablePtr->icursor); break; case CMD_INDEX: { char *which = NULL; if (objc == 4) { which = Tcl_GetString(objv[3]); } if ((objc < 3 || objc > 4) || ((objc == 4) && (strcmp(which, "row") && strcmp(which, "col")))) { Tcl_WrongNumArgs(interp, 2, objv, "<index> ?row|col?"); result = TCL_ERROR; } else if (TableGetIndexObj(tablePtr, objv[2], &row, &col) != TCL_OK) { result = TCL_ERROR; } else if (objc == 3) { char buf[INDEX_BUFSIZE]; /* recreate the index, just in case it got bounded */ TableMakeArrayIndex(row, col, buf); Tcl_SetStringObj(Tcl_GetObjResult(interp), buf, -1); } else { /* INDEX row|col */ Tcl_SetIntObj(Tcl_GetObjResult(interp), (*which == 'r') ? row : col); } break; } #ifdef POSTSCRIPT case CMD_POSTSCRIPT: result = Table_PostscriptCmd(clientData, interp, objc, objv); break; #endif case CMD_REREAD: if (objc != 2) { Tcl_WrongNumArgs(interp, 2, objv, NULL); result = TCL_ERROR; } else if ((tablePtr->flags & HAS_ACTIVE) && !(tablePtr->flags & ACTIVE_DISABLED) && tablePtr->state != STATE_DISABLED) { TableGetActiveBuf(tablePtr); TableRefresh(tablePtr, tablePtr->activeRow, tablePtr->activeCol, CELL|INV_FORCE); } break; case CMD_SCAN: result = Table_ScanCmd(clientData, interp, objc, objv); break; case CMD_SEE: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "index"); result = TCL_ERROR; } else if (TableGetIndexObj(tablePtr, objv[2], &row, &col) == TCL_ERROR) { result = TCL_ERROR; } else { /* Adjust from user to master coords */ row -= tablePtr->rowOffset; col -= tablePtr->colOffset; if (!TableCellVCoords(tablePtr, row, col, &i, &i, &i, &i, 1)) { tablePtr->topRow = row-1; tablePtr->leftCol = col-1; TableAdjustParams(tablePtr); } } break; case CMD_SELECTION: if (objc < 3) { Tcl_WrongNumArgs(interp, 2, objv, "option ?arg arg ...?"); result = TCL_ERROR; break; } if (Tcl_GetIndexFromObj(interp, objv[2], selCmdNames, "selection option", 0, &cmdIndex) != TCL_OK) { result = TCL_ERROR; break; } switch ((enum selCommand) cmdIndex) { case CMD_SEL_ANCHOR: result = Table_SelAnchorCmd(clientData, interp, objc, objv); break; case CMD_SEL_CLEAR: result = Table_SelClearCmd(clientData, interp, objc, objv); break; case CMD_SEL_INCLUDES: result = Table_SelIncludesCmd(clientData, interp, objc, objv); break; case CMD_SEL_PRESENT: { Tcl_HashSearch search; Tcl_SetBooleanObj(Tcl_GetObjResult(interp), (Tcl_FirstHashEntry(tablePtr->selCells, &search) != NULL)); break; } case CMD_SEL_SET: result = Table_SelSetCmd(clientData, interp, objc, objv); break; } break; case CMD_SET: result = Table_SetCmd(clientData, interp, objc, objv); break; case CMD_SPANS: result = Table_SpanCmd(clientData, interp, objc, objv); break; case CMD_TAG: result = Table_TagCmd(clientData, interp, objc, objv); break; case CMD_VALIDATE: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "index"); result = TCL_ERROR; } else if (TableGetIndexObj(tablePtr, objv[2], &row, &col) == TCL_ERROR) { result = TCL_ERROR; } else { i = tablePtr->validate; tablePtr->validate = 1; result = TableValidateChange(tablePtr, row, col, (char *) NULL, (char *) NULL, -1); tablePtr->validate = i; Tcl_SetBooleanObj(Tcl_GetObjResult(interp), (result == TCL_OK)); result = TCL_OK; } break; case CMD_VERSION: if (objc != 2) { Tcl_WrongNumArgs(interp, 2, objv, NULL); result = TCL_ERROR; } else { Tcl_SetStringObj(Tcl_GetObjResult(interp), VERSION, -1); } break; case CMD_WINDOW: result = Table_WindowCmd(clientData, interp, objc, objv); break; case CMD_XVIEW: case CMD_YVIEW: result = Table_ViewCmd(clientData, interp, objc, objv); break; } Tcl_Release((ClientData) tablePtr); return result; } /* *---------------------------------------------------------------------- * * TableDestroy -- * This procedure is invoked by Tcl_EventuallyFree * to clean up the internal structure of a table at a safe time * (when no-one is using it anymore). * * Results: * None. * * Side effects: * Everything associated with the table is freed up (hopefully). * *---------------------------------------------------------------------- */ static void TableDestroy(ClientData clientdata) { register Table *tablePtr = (Table *) clientdata; Tcl_HashEntry *entryPtr; Tcl_HashSearch search; /* These may be repetitive from DestroyNotify, but it doesn't hurt */ /* cancel any pending update or timer */ if (tablePtr->flags & REDRAW_PENDING) { Tcl_CancelIdleCall(TableDisplay, (ClientData) tablePtr); tablePtr->flags &= ~REDRAW_PENDING; } Tcl_DeleteTimerHandler(tablePtr->cursorTimer); Tcl_DeleteTimerHandler(tablePtr->flashTimer); /* delete the variable trace */ if (tablePtr->arrayVar != NULL) { Tcl_UntraceVar(tablePtr->interp, tablePtr->arrayVar, TCL_TRACE_WRITES | TCL_TRACE_UNSETS | TCL_GLOBAL_ONLY, (Tcl_VarTraceProc *)TableVarProc, (ClientData) tablePtr); } /* free the int arrays */ if (tablePtr->colPixels) ckfree((char *) tablePtr->colPixels); if (tablePtr->rowPixels) ckfree((char *) tablePtr->rowPixels); if (tablePtr->colStarts) ckfree((char *) tablePtr->colStarts); if (tablePtr->rowStarts) ckfree((char *) tablePtr->rowStarts); /* delete cached active tag and string */ if (tablePtr->activeTagPtr) ckfree((char *) tablePtr->activeTagPtr); if (tablePtr->activeBuf != NULL) ckfree(tablePtr->activeBuf); /* * Delete the various hash tables, make sure to clear the STRING_KEYS * tables that allocate their strings: * cache, spanTbl (spanAffTbl shares spanTbl info) */ Table_ClearHashTable(tablePtr->cache); ckfree((char *) (tablePtr->cache)); Tcl_DeleteHashTable(tablePtr->rowStyles); ckfree((char *) (tablePtr->rowStyles)); Tcl_DeleteHashTable(tablePtr->colStyles); ckfree((char *) (tablePtr->colStyles)); Tcl_DeleteHashTable(tablePtr->cellStyles); ckfree((char *) (tablePtr->cellStyles)); Tcl_DeleteHashTable(tablePtr->flashCells); ckfree((char *) (tablePtr->flashCells)); Tcl_DeleteHashTable(tablePtr->selCells); ckfree((char *) (tablePtr->selCells)); Tcl_DeleteHashTable(tablePtr->colWidths); ckfree((char *) (tablePtr->colWidths)); Tcl_DeleteHashTable(tablePtr->rowHeights); ckfree((char *) (tablePtr->rowHeights)); #ifdef PROCS Tcl_DeleteHashTable(tablePtr->inProc); ckfree((char *) (tablePtr->inProc)); #endif if (tablePtr->spanTbl) { Table_ClearHashTable(tablePtr->spanTbl); ckfree((char *) (tablePtr->spanTbl)); Tcl_DeleteHashTable(tablePtr->spanAffTbl); ckfree((char *) (tablePtr->spanAffTbl)); } /* Now free up all the tag information */ for (entryPtr = Tcl_FirstHashEntry(tablePtr->tagTable, &search); entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { TableCleanupTag(tablePtr, (TableTag *) Tcl_GetHashValue(entryPtr)); ckfree((char *) Tcl_GetHashValue(entryPtr)); } /* free up the stuff in the default tag */ TableCleanupTag(tablePtr, &(tablePtr->defaultTag)); /* And delete the actual hash table */ Tcl_DeleteHashTable(tablePtr->tagTable); ckfree((char *) (tablePtr->tagTable)); ckfree((char *) (tablePtr->tagPrios)); ckfree((char *) (tablePtr->tagPrioNames)); /* Now free up all the embedded window info */ for (entryPtr = Tcl_FirstHashEntry(tablePtr->winTable, &search); entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { EmbWinDelete(tablePtr, (TableEmbWindow *) Tcl_GetHashValue(entryPtr)); } /* And delete the actual hash table */ Tcl_DeleteHashTable(tablePtr->winTable); ckfree((char *) (tablePtr->winTable)); /* free the configuration options in the widget */ Tk_FreeOptions(tableSpecs, (char *) tablePtr, tablePtr->display, 0); /* and free the widget memory at last! */ ckfree((char *) (tablePtr)); } /* *---------------------------------------------------------------------- * * TableConfigure -- * This procedure is called to process an objc/objv list, plus * the Tk option database, in order to configure (or reconfigure) * a table widget. * * Results: * The return value is a standard Tcl result. If TCL_ERROR is * returned, then interp result contains an error message. * * Side effects: * Configuration information, such as colors, border width, etc. * get set for tablePtr; old resources get freed, if there were any. * Certain values might be constrained. * *---------------------------------------------------------------------- */ static int TableConfigure(interp, tablePtr, objc, objv, flags, forceUpdate) Tcl_Interp *interp; /* Used for error reporting. */ register Table *tablePtr; /* Information about widget; may or may * not already have values for some fields. */ int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument objects. */ int flags; /* Flags to pass to Tk_ConfigureWidget. */ int forceUpdate; /* Whether to force an update - required * for initial configuration */ { Tcl_HashSearch search; int oldUse, oldCaching, oldExport, oldTitleRows, oldTitleCols; int result = TCL_OK; Arg *objArray; Var oldVar = NULL; Tcl_DString error; Tk_FontMetrics fm; char *currentVarString; /* Name of the current array variable */ char *oldVarString = NULL; /* Name of the old array variable */ oldExport = tablePtr->exportSelection; oldCaching = tablePtr->caching; oldUse = tablePtr->useCmd; oldTitleRows = tablePtr->titleRows; oldTitleCols = tablePtr->titleCols; if (tablePtr->arrayVar != NULL) { oldVar = tablePtr->arrayVar; oldVarString = LangString(Tcl_GetVar(interp, oldVar, TCL_GLOBAL_ONLY)); } /* Do the configuration */ /* argv = StringifyObjects(objc, objv); */ /* Don't Need this because arrays of Args like arrays of Obj?? */ objArray = (Tcl_Obj **) objv; /* Cast gets rid of warnings */ result = Tk_ConfigureWidget(interp, tablePtr->tkwin, tableSpecs, objc, objArray, (char *) tablePtr, flags); /* ckfree((char *) argv); */ if (result != TCL_OK) { return TCL_ERROR; } Tcl_DStringInit(&error); /* Any time we configure, reevaluate what our data source is */ tablePtr->dataSource = DATA_NONE; if (tablePtr->caching) { tablePtr->dataSource |= DATA_CACHE; } if (tablePtr->command && tablePtr->useCmd) { tablePtr->dataSource |= DATA_COMMAND; } else if (tablePtr->arrayVar) { tablePtr->dataSource |= DATA_ARRAY; } /* Check to see if the array variable was changed */ currentVarString = LangString(Tcl_GetVar(interp, tablePtr->arrayVar, TCL_GLOBAL_ONLY)); if (strcmp((currentVarString?currentVarString:""), (oldVarString?oldVarString:""))) { /* only do the following if arrayVar is our data source */ if (tablePtr->dataSource & DATA_ARRAY) { /* * ensure that the cache will flush later * so it gets the new values */ oldCaching = !(tablePtr->caching); } /* remove the trace on the old array variable if there was one */ if (oldVar != NULL) Tcl_UntraceVar(interp, oldVar, TCL_TRACE_WRITES|TCL_TRACE_UNSETS|TCL_GLOBAL_ONLY, (Tcl_VarTraceProc *)TableVarProc, (ClientData) tablePtr); /* Check whether variable is an array and trace it if it is */ if (tablePtr->arrayVar != NULL) { /* does the variable exist as an array? */ if (Tcl_SetVar2(interp, tablePtr->arrayVar, TEST_KEY, "", TCL_GLOBAL_ONLY) == NULL) { Tcl_DStringAppend(&error, "invalid variable value \"", -1); Tcl_DStringAppend(&error, currentVarString, -1); Tcl_DStringAppend(&error, "\": could not be made an array", -1); ckfree(currentVarString); tablePtr->arrayVar = NULL; tablePtr->dataSource &= ~DATA_ARRAY; result = TCL_ERROR; } else { /* perltk not supported */ /* Tcl_UnsetVar2(interp, currentVarString, TEST_KEY, TCL_GLOBAL_ONLY); */ /* remove the effect of the evaluation */ /* set a trace on the variable */ Tcl_TraceVar(interp, tablePtr->arrayVar, TCL_TRACE_WRITES|TCL_TRACE_UNSETS|TCL_GLOBAL_ONLY, (Tcl_VarTraceProc *)TableVarProc, (ClientData) tablePtr); /* only do the following if arrayVar is our data source */ if (tablePtr->dataSource & DATA_ARRAY) { /* get the current value of the selection */ TableGetActiveBuf(tablePtr); } } } } /* Free oldVar if it was allocated */ /* if (oldVar != NULL) ckfree(oldVar); */ if ((tablePtr->command && tablePtr->useCmd && !oldUse) || (tablePtr->arrayVar && !(tablePtr->useCmd) && oldUse)) { /* * Our effective data source changed, so flush and * retrieve new active buffer */ Table_ClearHashTable(tablePtr->cache); Tcl_InitHashTable(tablePtr->cache, TCL_STRING_KEYS); TableGetActiveBuf(tablePtr); forceUpdate = 1; } else if (oldCaching != tablePtr->caching) { /* * Caching changed, so just clear the cache for safety */ Table_ClearHashTable(tablePtr->cache); Tcl_InitHashTable(tablePtr->cache, TCL_STRING_KEYS); forceUpdate = 1; } /* * Set up the default column width and row height */ Tk_GetFontMetrics(tablePtr->defaultTag.tkfont, &fm); tablePtr->charWidth = Tk_TextWidth(tablePtr->defaultTag.tkfont, "0", 1); tablePtr->charHeight = fm.linespace + 2; if (tablePtr->insertWidth <= 0) { tablePtr->insertWidth = 2; } if (tablePtr->insertBorderWidth > tablePtr->insertWidth/2) { tablePtr->insertBorderWidth = tablePtr->insertWidth/2; } tablePtr->highlightWidth = MAX(0,tablePtr->highlightWidth); /* * Ensure that certain values are within proper constraints */ tablePtr->rows = MAX(1, tablePtr->rows); tablePtr->cols = MAX(1, tablePtr->cols); tablePtr->padX = MAX(0, tablePtr->padX); tablePtr->padY = MAX(0, tablePtr->padY); tablePtr->ipadX = MAX(0, tablePtr->ipadX); tablePtr->ipadY = MAX(0, tablePtr->ipadY); tablePtr->maxReqCols = MAX(0, tablePtr->maxReqCols); tablePtr->maxReqRows = MAX(0, tablePtr->maxReqRows); CONSTRAIN(tablePtr->titleRows, 0, tablePtr->rows); CONSTRAIN(tablePtr->titleCols, 0, tablePtr->cols); /* * Handle change of default border style * The default borderwidth must be >= 0. */ if (tablePtr->drawMode & (DRAW_MODE_SINGLE|DRAW_MODE_FAST)) { /* * When drawing fast or single, the border must be <= 1. * We have to do this after the normal configuration * to base the borders off the first value given. */ tablePtr->defaultTag.bd[0] = MIN(1, tablePtr->defaultTag.bd[0]); tablePtr->defaultTag.borders = 1; ckfree((char *) tablePtr->defaultTag.borderStr); tablePtr->defaultTag.borderStr = (char *) ckalloc(2); strcpy(tablePtr->defaultTag.borderStr, tablePtr->defaultTag.bd[0] ? "1" : "0"); } /* * Claim the selection if we've suddenly started exporting it and * there is a selection to export. */ if (tablePtr->exportSelection && !oldExport && (Tcl_FirstHashEntry(tablePtr->selCells, &search) != NULL)) { Tk_OwnSelection(tablePtr->tkwin, XA_PRIMARY, TableLostSelection, (ClientData) tablePtr); } if ((tablePtr->titleRows < oldTitleRows) || (tablePtr->titleCols < oldTitleCols)) { /* * Prevent odd movement due to new possible topleft index */ if (tablePtr->titleRows < oldTitleRows) tablePtr->topRow -= oldTitleRows - tablePtr->titleRows; if (tablePtr->titleCols < oldTitleCols) tablePtr->leftCol -= oldTitleCols - tablePtr->titleCols; /* * If our title area shrank, we need to check that the items * within the new title area don't try to span outside it. */ TableSpanSanCheck(tablePtr); } /* * Only do the full reconfigure if absolutely necessary */ if (!forceUpdate) { int i, dummy; for (i = 0; i < objc-1; i += 2) { if (Tcl_GetIndexFromObj(NULL, objv[i], updateOpts, "", 0, &dummy) == TCL_OK) { forceUpdate = 1; break; } } } if (forceUpdate) { /* * Calculate the row and column starts * Adjust the top left corner of the internal display */ TableAdjustParams(tablePtr); /* reset the cursor */ TableConfigCursor(tablePtr); /* set up the background colour in the window */ Tk_SetBackgroundFromBorder(tablePtr->tkwin, tablePtr->defaultTag.bg); /* set the geometry and border */ TableGeometryRequest(tablePtr); Tk_SetInternalBorder(tablePtr->tkwin, tablePtr->highlightWidth); /* invalidate the whole table */ TableInvalidateAll(tablePtr, INV_HIGHLIGHT); } /* * FIX this is goofy because the result could be munged by other * functions. Could be improved. */ Tcl_ResetResult(interp); if (result == TCL_ERROR) { Tcl_AddErrorInfo(interp, "\t(configuring table widget)"); Tcl_DStringResult(interp, &error); } Tcl_DStringFree(&error); return result; } /* *-------------------------------------------------------------- * * TableEventProc -- * This procedure is invoked by the Tk dispatcher for various * events on tables. * * Results: * None. * * Side effects: * When the window gets deleted, internal structures get * cleaned up. When it gets exposed, it is redisplayed. * *-------------------------------------------------------------- */ static void TableEventProc(clientData, eventPtr) ClientData clientData; /* Information about window. */ XEvent *eventPtr; /* Information about event. */ { Table *tablePtr = (Table *) clientData; int row, col; switch (eventPtr->type) { case MotionNotify: if (!(tablePtr->resize & SEL_NONE) && (tablePtr->bdcursor != None) && TableAtBorder(tablePtr, eventPtr->xmotion.x, eventPtr->xmotion.y, &row, &col) && ((row>=0 && (tablePtr->resize & SEL_ROW)) || (col>=0 && (tablePtr->resize & SEL_COL)))) { /* * The bordercursor is defined and we meet the criteria for * being over a border. Set the cursor to border if not * already done. */ if (!(tablePtr->flags & OVER_BORDER)) { tablePtr->flags |= OVER_BORDER; Tk_DefineCursor(tablePtr->tkwin, tablePtr->bdcursor); } } else if (tablePtr->flags & OVER_BORDER) { tablePtr->flags &= ~OVER_BORDER; if (tablePtr->cursor != None) { Tk_DefineCursor(tablePtr->tkwin, tablePtr->cursor); } else { Tk_UndefineCursor(tablePtr->tkwin); } #ifdef TITLE_CURSOR } else if (tablePtr->flags & (OVER_BORDER|OVER_TITLE)) { Tk_Cursor cursor = tablePtr->cursor; //tablePtr->flags &= ~(OVER_BORDER|OVER_TITLE); if (tablePtr->titleCursor != None) { TableWhatCell(tablePtr, eventPtr->xmotion.x, eventPtr->xmotion.y, &row, &col); if ((row < tablePtr->titleRows) || (col < tablePtr->titleCols)) { if (tablePtr->flags & OVER_TITLE) { break; } tablePtr->flags |= OVER_TITLE; cursor = tablePtr->titleCursor; } } if (cursor != None) { Tk_DefineCursor(tablePtr->tkwin, cursor); } else { Tk_UndefineCursor(tablePtr->tkwin); } } else if (tablePtr->titleCursor != None) { Tk_Cursor cursor = tablePtr->cursor; TableWhatCell(tablePtr, eventPtr->xmotion.x, eventPtr->xmotion.y, &row, &col); if ((row < tablePtr->titleRows) || (col < tablePtr->titleCols)) { if (tablePtr->flags & OVER_TITLE) { break; } tablePtr->flags |= OVER_TITLE; cursor = tablePtr->titleCursor; } #endif } break; case Expose: TableInvalidate(tablePtr, eventPtr->xexpose.x, eventPtr->xexpose.y, eventPtr->xexpose.width, eventPtr->xexpose.height, INV_HIGHLIGHT); break; case DestroyNotify: /* remove the command from the interpreter */ if (tablePtr->tkwin != NULL) { tablePtr->tkwin = NULL; Tcl_DeleteCommandFromToken(tablePtr->interp, tablePtr->widgetCmd); } /* cancel any pending update or timer */ if (tablePtr->flags & REDRAW_PENDING) { Tcl_CancelIdleCall(TableDisplay, (ClientData) tablePtr); tablePtr->flags &= ~REDRAW_PENDING; } Tcl_DeleteTimerHandler(tablePtr->cursorTimer); Tcl_DeleteTimerHandler(tablePtr->flashTimer); Tcl_EventuallyFree((ClientData) tablePtr, (Tcl_FreeProc *) TableDestroy); break; case MapNotify: /* redraw table when remapped if it changed */ if (tablePtr->flags & REDRAW_ON_MAP) { tablePtr->flags &= ~REDRAW_ON_MAP; Tcl_Preserve((ClientData) tablePtr); TableAdjustParams(tablePtr); TableInvalidateAll(tablePtr, INV_HIGHLIGHT); Tcl_Release((ClientData) tablePtr); } break; case ConfigureNotify: Tcl_Preserve((ClientData) tablePtr); TableAdjustParams(tablePtr); TableInvalidateAll(tablePtr, INV_HIGHLIGHT); Tcl_Release((ClientData) tablePtr); break; case FocusIn: case FocusOut: if (eventPtr->xfocus.detail != NotifyInferior) { tablePtr->flags |= REDRAW_BORDER; if (eventPtr->type == FocusOut) { tablePtr->flags &= ~HAS_FOCUS; } else { tablePtr->flags |= HAS_FOCUS; } TableRedrawHighlight(tablePtr); /* cancel the timer */ TableConfigCursor(tablePtr); } break; } } /* *---------------------------------------------------------------------- * * TableCmdDeletedProc -- * * This procedure is invoked when a widget command is deleted. If * the widget isn't already in the process of being destroyed, * this command destroys it. * * Results: * None. * * Side effects: * The widget is destroyed. * *---------------------------------------------------------------------- */ static void TableCmdDeletedProc(ClientData clientData) { Table *tablePtr = (Table *) clientData; Tk_Window tkwin; /* * This procedure could be invoked either because the window was * destroyed and the command was then deleted (in which case tkwin * is NULL) or because the command was deleted, and then this procedure * destroys the widget. */ if (tablePtr->tkwin != NULL) { tkwin = tablePtr->tkwin; tablePtr->tkwin = NULL; Tk_DestroyWindow(tkwin); } } /* *---------------------------------------------------------------------- * * TableRedrawHighlight -- * Redraws just the highlight for the window * * Results: * None. * * Side effects: * None * *---------------------------------------------------------------------- */ static void TableRedrawHighlight(Table *tablePtr) { if ((tablePtr->flags & REDRAW_BORDER) && tablePtr->highlightWidth > 0) { GC gc = Tk_GCForColor((tablePtr->flags & HAS_FOCUS) ? tablePtr->highlightColorPtr : tablePtr->highlightBgColorPtr, Tk_WindowId(tablePtr->tkwin)); Tk_DrawFocusHighlight(tablePtr->tkwin, gc, tablePtr->highlightWidth, Tk_WindowId(tablePtr->tkwin)); } tablePtr->flags &= ~REDRAW_BORDER; } /* *---------------------------------------------------------------------- * * TableRefresh -- * Refreshes an area of the table based on the mode. * row,col in real coords (0-based) * * Results: * Will cause redraw for visible cells * * Side effects: * None. * *---------------------------------------------------------------------- */ void TableRefresh(register Table *tablePtr, int row, int col, int mode) { int x, y, w, h; if ((row < 0) || (col < 0)) { /* * Invalid coords passed in. This can happen when the "active" cell * is refreshed, but doesn't really exist (row==-1 && col==-1). */ return; } if (mode & CELL) { if (TableCellVCoords(tablePtr, row, col, &x, &y, &w, &h, 0)) { TableInvalidate(tablePtr, x, y, w, h, mode); } } else if (mode & ROW) { /* get the position of the leftmost cell in the row */ if ((mode & INV_FILL) && row < tablePtr->topRow) { /* Invalidate whole table */ TableInvalidateAll(tablePtr, mode); } else if (TableCellVCoords(tablePtr, row, tablePtr->leftCol, &x, &y, &w, &h, 0)) { /* Invalidate from this row, maybe to end */ TableInvalidate(tablePtr, 0, y, Tk_Width(tablePtr->tkwin), (mode&INV_FILL)?Tk_Height(tablePtr->tkwin):h, mode); } } else if (mode & COL) { /* get the position of the topmost cell on the column */ if ((mode & INV_FILL) && col < tablePtr->leftCol) { /* Invalidate whole table */ TableInvalidateAll(tablePtr, mode); } else if (TableCellVCoords(tablePtr, tablePtr->topRow, col, &x, &y, &w, &h, 0)) { /* Invalidate from this column, maybe to end */ TableInvalidate(tablePtr, x, 0, (mode&INV_FILL)?Tk_Width(tablePtr->tkwin):w, Tk_Height(tablePtr->tkwin), mode); } } } /* *---------------------------------------------------------------------- * * TableGetGc -- * Gets a GC corresponding to the tag structure passed. * * Results: * Returns usable GC. * * Side effects: * None * *---------------------------------------------------------------------- */ static void TableGetGc(Display *display, Drawable d, TableTag *tagPtr, GC *tagGc) { XGCValues gcValues; gcValues.foreground = Tk_3DBorderColor(tagPtr->fg)->pixel; gcValues.background = Tk_3DBorderColor(tagPtr->bg)->pixel; gcValues.font = Tk_FontId(tagPtr->tkfont); if (*tagGc == NULL) { gcValues.graphics_exposures = False; *tagGc = XCreateGC(display, d, GCForeground|GCBackground|GCFont|GCGraphicsExposures, &gcValues); } else { XChangeGC(display, *tagGc, GCForeground|GCBackground|GCFont, &gcValues); } } #define TableFreeGc XFreeGC /* *-------------------------------------------------------------- * * TableUndisplay -- * This procedure removes the contents of a table window * that have been moved offscreen. * * Results: * Embedded windows can be unmapped. * * Side effects: * Information disappears from the screen. * *-------------------------------------------------------------- */ static void TableUndisplay(register Table *tablePtr) { register int *seen = tablePtr->seen; int row, col; /* We need to find out the true last cell, not considering spans */ tablePtr->flags |= AVOID_SPANS; TableGetLastCell(tablePtr, &row, &col); tablePtr->flags &= ~AVOID_SPANS; if (seen[0] != -1) { if (seen[0] < tablePtr->topRow) { /* Remove now hidden rows */ EmbWinUnmap(tablePtr, seen[0], MIN(seen[2],tablePtr->topRow-1), seen[1], seen[3]); /* Also account for the title area */ EmbWinUnmap(tablePtr, seen[0], MIN(seen[2],tablePtr->topRow-1), 0, tablePtr->titleCols-1); } if (seen[1] < tablePtr->leftCol) { /* Remove now hidden cols */ EmbWinUnmap(tablePtr, seen[0], seen[2], seen[1], MAX(seen[3],tablePtr->leftCol-1)); /* Also account for the title area */ EmbWinUnmap(tablePtr, 0, tablePtr->titleRows-1, seen[1], MAX(seen[3],tablePtr->leftCol-1)); } if (seen[2] > row) { /* Remove now off-screen rows */ EmbWinUnmap(tablePtr, MAX(seen[0],row+1), seen[2], seen[1], seen[3]); /* Also account for the title area */ EmbWinUnmap(tablePtr, MAX(seen[0],row+1), seen[2], 0, tablePtr->titleCols-1); } if (seen[3] > col) { /* Remove now off-screen cols */ EmbWinUnmap(tablePtr, seen[0], seen[2], MAX(seen[1],col+1), seen[3]); /* Also account for the title area */ EmbWinUnmap(tablePtr, 0, tablePtr->titleRows-1, MAX(seen[1],col+1), seen[3]); } } seen[0] = tablePtr->topRow; seen[1] = tablePtr->leftCol; seen[2] = row; seen[3] = col; } #if defined(MAC_TCL) || (defined(WIN32) && defined(TCL_THREADS)) || defined(MAC_OSX_TK) #define NO_XSETCLIP #endif /* *-------------------------------------------------------------- * * TableDisplay -- * This procedure redraws the contents of a table window. * The conditional code in this function is due to these factors: * o Lack of XSetClipRectangles on Macintosh * o Use of alternative routine for Windows * * Results: * None. * * Side effects: * Information appears on the screen. * *-------------------------------------------------------------- */ static void TableDisplay(ClientData clientdata) { register Table *tablePtr = (Table *) clientdata; Tk_Window tkwin = tablePtr->tkwin; Display *display = tablePtr->display; Drawable window; #ifdef NO_XSETCLIP Drawable clipWind; #elif !defined(WIN32) XRectangle clipRect; #endif int rowFrom, rowTo, colFrom, colTo, invalidX, invalidY, invalidWidth, invalidHeight, x, y, width, height, itemX, itemY, itemW, itemH, row, col, urow, ucol, hrow=0, hcol=0, cx, cy, cw, ch, borders, bd[6], numBytes, new, boundW, boundH, maxW, maxH, cellType, originX, originY, activeCell, shouldInvert, ipadx, ipady, padx, pady; GC tagGc = NULL, topGc, bottomGc; char *string = NULL; char buf[INDEX_BUFSIZE]; TableTag *tagPtr = NULL, *titlePtr, *selPtr, *activePtr, *flashPtr, *rowPtr, *colPtr; Tcl_HashEntry *entryPtr; static XPoint rect[3] = { {0, 0}, {0, 0}, {0, 0} }; Tcl_HashTable *colTagsCache = NULL; Tcl_HashTable *drawnCache = NULL; Tk_TextLayout textLayout = NULL; TableEmbWindow *ewPtr; tablePtr->flags &= ~REDRAW_PENDING; if ((tkwin == NULL) || !Tk_IsMapped(tkwin)) { return; } boundW = Tk_Width(tkwin) - tablePtr->highlightWidth; boundH = Tk_Height(tkwin) - tablePtr->highlightWidth; /* Constrain drawable to not include highlight borders */ invalidX = MAX(tablePtr->highlightWidth, tablePtr->invalidX); invalidY = MAX(tablePtr->highlightWidth, tablePtr->invalidY); invalidWidth = MIN(tablePtr->invalidWidth, MAX(1, boundW-invalidX)); invalidHeight = MIN(tablePtr->invalidHeight, MAX(1, boundH-invalidY)); ipadx = tablePtr->ipadX; ipady = tablePtr->ipadY; padx = tablePtr->padX; pady = tablePtr->padY; /* * if we are using the slow drawing mode with a pixmap * create the pixmap and adjust x && y for offset in pixmap */ if (tablePtr->drawMode == DRAW_MODE_SLOW) { window = Tk_GetPixmap(display, Tk_WindowId(tkwin), invalidWidth, invalidHeight, Tk_Depth(tkwin)); } else { window = Tk_WindowId(tkwin); } #ifdef NO_XSETCLIP clipWind = Tk_GetPixmap(display, window, invalidWidth, invalidHeight, Tk_Depth(tkwin)); #endif /* set up the permanent tag styles */ entryPtr = Tcl_FindHashEntry(tablePtr->tagTable, "title"); titlePtr = (TableTag *) Tcl_GetHashValue(entryPtr); entryPtr = Tcl_FindHashEntry(tablePtr->tagTable, "sel"); selPtr = (TableTag *) Tcl_GetHashValue(entryPtr); entryPtr = Tcl_FindHashEntry(tablePtr->tagTable, "active"); activePtr = (TableTag *) Tcl_GetHashValue(entryPtr); entryPtr = Tcl_FindHashEntry(tablePtr->tagTable, "flash"); flashPtr = (TableTag *) Tcl_GetHashValue(entryPtr); /* We need to find out the true cell span, not considering spans */ tablePtr->flags |= AVOID_SPANS; /* find out the cells represented by the invalid region */ TableWhatCell(tablePtr, invalidX, invalidY, &rowFrom, &colFrom); TableWhatCell(tablePtr, invalidX+invalidWidth-1, invalidY+invalidHeight-1, &rowTo, &colTo); tablePtr->flags &= ~AVOID_SPANS; #ifdef DEBUG tcl_dprintf(tablePtr->interp, "%d,%d => %d,%d", rowFrom+tablePtr->rowOffset, colFrom+tablePtr->colOffset, rowTo+tablePtr->rowOffset, colTo+tablePtr->colOffset); #endif /* * Initialize colTagsCache hash table to cache column tag names. */ colTagsCache = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(colTagsCache, TCL_ONE_WORD_KEYS); /* * Initialize drawnCache hash table to cache drawn cells. * This is necessary to prevent spanning cells being drawn multiple times. */ drawnCache = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(drawnCache, TCL_STRING_KEYS); /* * Create the tag here. This will actually create a JoinTag * That will handle the priority management of merging for us. * We only need one allocated, and we'll reset it for each cell. */ tagPtr = TableNewTag(tablePtr); /* Cycle through the cells and display them */ for (row = rowFrom; row <= rowTo; row++) { /* * are we in the 'dead zone' between the * title rows and the first displayed row */ if (row < tablePtr->topRow && row >= tablePtr->titleRows) { row = tablePtr->topRow; } /* Cache the row in user terms */ urow = row+tablePtr->rowOffset; /* Get the row tag once for all iterations of col */ rowPtr = FindRowColTag(tablePtr, urow, ROW); for (col = colFrom; col <= colTo; col++) { activeCell = 0; /* * Adjust to first viewable column if we are in the 'dead zone' * between the title cols and the first displayed column. */ if (col < tablePtr->leftCol && col >= tablePtr->titleCols) { col = tablePtr->leftCol; } /* * Get the coordinates for the cell before possible rearrangement * of row,col due to spanning cells */ cellType = TableCellCoords(tablePtr, row, col, &x, &y, &width, &height); if (cellType == CELL_HIDDEN) { /* * width,height holds the real start row,col of the span. * Put the use cell ref into a buffer for the hash lookups. */ TableMakeArrayIndex(width, height, buf); Tcl_CreateHashEntry(drawnCache, buf, &new); if (!new) { /* Not new in the entry, so it's already drawn */ continue; } hrow = row; hcol = col; row = width-tablePtr->rowOffset; col = height-tablePtr->colOffset; TableCellVCoords(tablePtr, row, col, &x, &y, &width, &height, 0); /* We have to adjust the coords back onto the visual display */ urow = row+tablePtr->rowOffset; rowPtr = FindRowColTag(tablePtr, urow, ROW); } /* Constrain drawn size to the visual boundaries */ if (width > boundW-x) { width = boundW-x; } if (height > boundH-y) { height = boundH-y; } /* Cache the col in user terms */ ucol = col+tablePtr->colOffset; /* put the use cell ref into a buffer for the hash lookups */ TableMakeArrayIndex(urow, ucol, buf); if (cellType != CELL_HIDDEN) { Tcl_CreateHashEntry(drawnCache, buf, &new); } /* * Make sure we start with a clean tag (set to table defaults). */ TableResetTag(tablePtr, tagPtr); /* * Check to see if we have an embedded window in this cell. */ entryPtr = Tcl_FindHashEntry(tablePtr->winTable, buf); if (entryPtr != NULL) { ewPtr = (TableEmbWindow *) Tcl_GetHashValue(entryPtr); if (ewPtr->tkwin != NULL) { /* Display embedded window instead of text */ /* if active, make it disabled to avoid * unnecessary editing */ if ((tablePtr->flags & HAS_ACTIVE) && row == tablePtr->activeRow && col == tablePtr->activeCol) { tablePtr->flags |= ACTIVE_DISABLED; } /* * The EmbWinDisplay function may modify values in * tagPtr, so reference those after this call. */ EmbWinDisplay(tablePtr, window, ewPtr, tagPtr, x, y, width, height); if (tablePtr->drawMode == DRAW_MODE_SLOW) { /* Correctly adjust x && y with the offset */ x -= invalidX; y -= invalidY; } Tk_Fill3DRectangle(tkwin, window, tagPtr->bg, x, y, width, height, 0, TK_RELIEF_FLAT); /* border width for cell should now be properly set */ borders = TableGetTagBorders(tagPtr, &bd[0], &bd[1], &bd[2], &bd[3]); bd[4] = (bd[0] + bd[1])/2; bd[5] = (bd[2] + bd[3])/2; goto DrawBorder; } } if (tablePtr->drawMode == DRAW_MODE_SLOW) { /* Correctly adjust x && y with the offset */ x -= invalidX; y -= invalidY; } shouldInvert = 0; /* * Get the combined tag structure for the cell. * First clear out a new tag structure that we will build in * then add tags as we realize they belong. * * Tags have their own priorities which TableMergeTag will * take into account when merging tags. */ /* * Merge colPtr if it exists * let's see if we have the value cached already * if not, run the findColTag routine and cache the value */ entryPtr = Tcl_CreateHashEntry(colTagsCache, (char *)ucol, &new); if (new) { colPtr = FindRowColTag(tablePtr, ucol, COL); Tcl_SetHashValue(entryPtr, colPtr); } else { colPtr = (TableTag *) Tcl_GetHashValue(entryPtr); } if (colPtr != (TableTag *) NULL) { TableMergeTag(tablePtr, tagPtr, colPtr); } /* Merge rowPtr if it exists */ if (rowPtr != (TableTag *) NULL) { TableMergeTag(tablePtr, tagPtr, rowPtr); } /* Am I in the titles */ if (row < tablePtr->titleRows || col < tablePtr->titleCols) { TableMergeTag(tablePtr, tagPtr, titlePtr); } /* Does this have a cell tag */ entryPtr = Tcl_FindHashEntry(tablePtr->cellStyles, buf); if (entryPtr != NULL) { TableMergeTag(tablePtr, tagPtr, (TableTag *) Tcl_GetHashValue(entryPtr)); } /* is this cell active? */ if ((tablePtr->flags & HAS_ACTIVE) && (tablePtr->state == STATE_NORMAL) && row == tablePtr->activeRow && col == tablePtr->activeCol) { if (tagPtr->state == STATE_DISABLED) { tablePtr->flags |= ACTIVE_DISABLED; } else { TableMergeTag(tablePtr, tagPtr, activePtr); activeCell = 1; tablePtr->flags &= ~ACTIVE_DISABLED; } } /* is this cell selected? */ if (Tcl_FindHashEntry(tablePtr->selCells, buf) != NULL) { if (tablePtr->invertSelected && !activeCell) { shouldInvert = 1; } else { TableMergeTag(tablePtr, tagPtr, selPtr); } } /* if flash mode is on, is this cell flashing? */ if (tablePtr->flashMode && Tcl_FindHashEntry(tablePtr->flashCells, buf) != NULL) { TableMergeTag(tablePtr, tagPtr, flashPtr); } if (shouldInvert) { TableInvertTag(tagPtr); } /* * Borders for cell should now be properly set */ borders = TableGetTagBorders(tagPtr, &bd[0], &bd[1], &bd[2], &bd[3]); bd[4] = (bd[0] + bd[1])/2; bd[5] = (bd[2] + bd[3])/2; /* * First fill in a blank rectangle. */ Tk_Fill3DRectangle(tkwin, window, tagPtr->bg, x, y, width, height, 0, TK_RELIEF_FLAT); /* * Correct the dimensions to enforce padding constraints */ width -= bd[0] + bd[1] + (2 * padx); height -= bd[2] + bd[3] + (2 * pady); /* * If an image is in the tag, draw it */ if (tagPtr->image != NULL) { Tk_SizeOfImage(tagPtr->image, &itemW, &itemH); /* Handle anchoring of image in cell space */ switch (tagPtr->anchor) { case TK_ANCHOR_NW: case TK_ANCHOR_W: case TK_ANCHOR_SW: /* western position */ originX = itemX = 0; break; case TK_ANCHOR_N: case TK_ANCHOR_S: case TK_ANCHOR_CENTER: /* centered position */ itemX = MAX(0, (itemW - width) / 2); originX = MAX(0, (width - itemW) / 2); break; default: /* eastern position */ itemX = MAX(0, itemW - width); originX = MAX(0, width - itemW); } switch (tagPtr->anchor) { case TK_ANCHOR_N: case TK_ANCHOR_NE: case TK_ANCHOR_NW: /* northern position */ originY = itemY = 0; break; case TK_ANCHOR_W: case TK_ANCHOR_E: case TK_ANCHOR_CENTER: /* centered position */ itemY = MAX(0, (itemH - height) / 2); originY = MAX(0, (height - itemH) / 2); break; default: /* southern position */ itemY = MAX(0, itemH - height); originY = MAX(0, height - itemH); } Tk_RedrawImage(tagPtr->image, itemX, itemY, MIN(itemW, width-originX), MIN(itemH, height-originY), window, x + originX + bd[0] + padx, y + originY + bd[2] + pady); /* * If we don't want to display the text as well, then jump. */ if (tagPtr->showtext == 0) { /* * Re-Correct the dimensions before border drawing */ width += bd[0] + bd[1] + (2 * padx); height += bd[2] + bd[3] + (2 * pady); goto DrawBorder; } } /* * Get the GC for this particular blend of tags. * This creates the GC if it never existed, otherwise it * modifies the one we have, so we only need the one */ TableGetGc(display, window, tagPtr, &tagGc); /* if this is the active cell, use the buffer */ if (activeCell) { string = tablePtr->activeBuf; } else { /* Is there a value in the cell? If so, draw it */ string = TableGetCellValue(tablePtr, urow, ucol); } #ifdef TCL_UTF_MAX /* * We have to use strlen here because otherwise it stops * at the first \x00 unicode char it finds (!= '\0'), * although there can be more to the string than that */ numBytes = Tcl_NumUtfChars(string, strlen(string)); #else numBytes = strlen(string); #endif /* If there is a string, show it */ if (activeCell || numBytes) { /* get the dimensions of the string */ textLayout = Tk_ComputeTextLayout(tagPtr->tkfont, string, numBytes, (tagPtr->wrap > 0) ? width : 0, tagPtr->justify, (tagPtr->multiline > 0) ? 0 : TK_IGNORE_NEWLINES, &itemW, &itemH); /* * Set the origin coordinates of the string to draw using * the anchor. origin represents the (x,y) coordinate of * the lower left corner of the text box, relative to the * internal (inside the border) window */ /* set the X origin first */ switch (tagPtr->anchor) { case TK_ANCHOR_NW: case TK_ANCHOR_W: case TK_ANCHOR_SW: /* western position */ originX = ipadx; break; case TK_ANCHOR_N: case TK_ANCHOR_S: case TK_ANCHOR_CENTER: /* centered position */ originX = (width - itemW) / 2; break; default: /* eastern position */ originX = width - itemW - ipadx; } /* then set the Y origin */ switch (tagPtr->anchor) { case TK_ANCHOR_N: case TK_ANCHOR_NE: case TK_ANCHOR_NW: /* northern position */ originY = ipady; break; case TK_ANCHOR_W: case TK_ANCHOR_E: case TK_ANCHOR_CENTER: /* centered position */ originY = (height - itemH) / 2; break; default: /* southern position */ originY = height - itemH - ipady; } /* * If this is the active cell and we are editing, * ensure that the cursor will be displayed */ if (activeCell) { Tk_CharBbox(textLayout, tablePtr->icursor, &cx, &cy, &cw, &ch); /* we have to fudge with maxW because of odd width * determination for newlines at the end of a line */ maxW = width - tablePtr->insertWidth - (cx + MIN(tablePtr->charWidth, cw)); maxH = height - (cy + ch); if (originX < bd[0] - cx) { /* cursor off cell to the left */ /* use western positioning to cet cursor at left * with slight variation to show some text */ originX = bd[0] - cx + MIN(cx, width - tablePtr->insertWidth); } else if (originX > maxW) { /* cursor off cell to the right */ /* use eastern positioning to cet cursor at right */ originX = maxW; } if (originY < bd[2] - cy) { /* cursor before top of cell */ /* use northern positioning to cet cursor at top */ originY = bd[2] - cy; } else if (originY > maxH) { /* cursor beyond bottom of cell */ /* use southern positioning to cet cursor at bottom */ originY = maxH; } tablePtr->activeTagPtr = tagPtr; tablePtr->activeX = originX; tablePtr->activeY = originY; } /* * Use a clip rectangle only if necessary as it means * updating the GC in the server which slows everything down. * We can't fudge the width or height, just in case the user * wanted empty pad space. */ if ((originX < 0) || (originY < 0) || (originX+itemW > width) || (originY+itemH > height)) { /* * The text wants to overflow the boundaries of the * displayed cell, so we must clip in some way */ #ifdef NO_XSETCLIP /* * This code is basically for the Macintosh. * Copy the the current contents of the cell into the * clipped window area. This keeps any fg/bg and image * data intact. */ XCopyArea(display, window, clipWind, tagGc, x, y, width + bd[0] + bd[1] + (2 * padx), height + bd[2] + bd[3] + (2 * pady), 0, 0); /* * Now draw into the cell space on the special window. * Don't use x,y base offset for clipWind. */ Tk_DrawTextLayout(display, clipWind, tagGc, textLayout, 0 + originX + bd[0] + padx, 0 + originY + bd[2] + pady, 0, -1); /* * Now copy back only the area that we want the * text to be drawn on. */ XCopyArea(display, clipWind, window, tagGc, bd[0] + padx, bd[2] + pady, width, height, x + bd[0] + padx, y + bd[2] + pady); #elif defined(WIN32) /* * This is evil, evil evil! but the XCopyArea * doesn't work in all cases - Michael Teske. * The general structure follows the comments below. */ TkWinDrawable *twdPtr = (TkWinDrawable *) window; HDC dc = GetDC(twdPtr->window.handle); HRGN clipR; clipR = CreateRectRgn(x + bd[0] + padx, y + bd[2] + pady, x + bd[0] + padx + width, y + bd[2] + pady + height); SelectClipRgn(dc, clipR); OffsetClipRgn(dc, 0, 0); Tk_DrawTextLayout(display, window, tagGc, textLayout, x + originX + bd[0] + padx, y + originY + bd[2] + pady, 0, -1); SelectClipRgn(dc, NULL); DeleteObject(clipR); #else /* * Use an X clipping rectangle. The clipping is the * rectangle just for the actual text space (to allow * for empty padding space). */ clipRect.x = x + bd[0] + padx; clipRect.y = y + bd[2] + pady; clipRect.width = width; clipRect.height = height; XSetClipRectangles(display, tagGc, 0, 0, &clipRect, 1, Unsorted); Tk_DrawTextLayout(display, window, tagGc, textLayout, x + originX + bd[0] + padx, y + originY + bd[2] + pady, 0, -1); XSetClipMask(display, tagGc, None); #endif } else { Tk_DrawTextLayout(display, window, tagGc, textLayout, x + originX + bd[0] + padx, y + originY + bd[2] + pady, 0, -1); } /* if this is the active cell draw the cursor if it's on. * this ignores clip rectangles. */ if (activeCell && (tablePtr->flags & CURSOR_ON) && (originY + cy + bd[2] + pady < height) && (originX + cx + bd[0] + padx - (tablePtr->insertWidth / 2) >= 0)) { /* make sure it will fit in the box */ maxW = MAX(0, originY + cy + bd[2] + pady); maxH = MIN(ch, height - maxW + bd[2] + pady); Tk_Fill3DRectangle(tkwin, window, tablePtr->insertBg, x + originX + cx + bd[0] + padx - (tablePtr->insertWidth/2), y + maxW, tablePtr->insertWidth, maxH, 0, TK_RELIEF_FLAT); } } /* * Re-Correct the dimensions before border drawing */ width += bd[0] + bd[1] + (2 * padx); height += bd[2] + bd[3] + (2 * pady); DrawBorder: /* Draw the 3d border on the pixmap correctly offset */ if (tablePtr->drawMode == DRAW_MODE_SINGLE) { topGc = Tk_3DBorderGC(tkwin, tagPtr->bg, TK_3D_DARK_GC); /* draw a line with single pixel width */ rect[0].x = x; rect[0].y = y + height - 1; rect[1].y = -height + 1; rect[2].x = width - 1; XDrawLines(display, window, topGc, rect, 3, CoordModePrevious); } else if (tablePtr->drawMode == DRAW_MODE_FAST) { /* * This depicts a full 1 pixel border. * * Choose the GCs to get the best approximation * to the desired drawing style. */ switch(tagPtr->relief) { case TK_RELIEF_FLAT: topGc = bottomGc = Tk_3DBorderGC(tkwin, tagPtr->bg, TK_3D_FLAT_GC); break; case TK_RELIEF_RAISED: case TK_RELIEF_RIDGE: topGc = Tk_3DBorderGC(tkwin, tagPtr->bg, TK_3D_LIGHT_GC); bottomGc = Tk_3DBorderGC(tkwin, tagPtr->bg, TK_3D_DARK_GC); break; default: /* TK_RELIEF_SUNKEN TK_RELIEF_GROOVE */ bottomGc = Tk_3DBorderGC(tkwin, tagPtr->bg, TK_3D_LIGHT_GC); topGc = Tk_3DBorderGC(tkwin, tagPtr->bg, TK_3D_DARK_GC); break; } /* draw a line with single pixel width */ rect[0].x = x + width - 1; rect[0].y = y; rect[1].y = height - 1; rect[2].x = -width + 1; XDrawLines(display, window, bottomGc, rect, 3, CoordModePrevious); rect[0].x = x; rect[0].y = y + height - 1; rect[1].y = -height + 1; rect[2].x = width - 1; XDrawLines(display, window, topGc, rect, 3, CoordModePrevious); } else { if (borders > 1) { if (bd[0]) { Tk_3DVerticalBevel(tkwin, window, tagPtr->bg, x, y, bd[0], height, 1 /* left side */, tagPtr->relief); } if (bd[1]) { Tk_3DVerticalBevel(tkwin, window, tagPtr->bg, x + width - bd[1], y, bd[1], height, 0 /* right side */, tagPtr->relief); } if ((borders == 4) && bd[2]) { Tk_3DHorizontalBevel(tkwin, window, tagPtr->bg, x, y, width, bd[2], 1, 1, 1 /* top */, tagPtr->relief); } if ((borders == 4) && bd[3]) { Tk_3DHorizontalBevel(tkwin, window, tagPtr->bg, x, y + height - bd[3], width, bd[3], 0, 0, 0 /* bottom */, tagPtr->relief); } } else if (borders == 1) { Tk_Draw3DRectangle(tkwin, window, tagPtr->bg, x, y, width, height, bd[0], tagPtr->relief); } } /* clean up the necessaries */ if (tagPtr == tablePtr->activeTagPtr) { /* * This means it was the activeCell with text displayed. * We buffer the active tag for the 'activate' command. */ tablePtr->activeTagPtr = TableNewTag(NULL); memcpy((VOID *) tablePtr->activeTagPtr, (VOID *) tagPtr, sizeof(TableTag)); } if (textLayout) { Tk_FreeTextLayout(textLayout); textLayout = NULL; } if (cellType == CELL_HIDDEN) { /* the last cell was a hidden one, * rework row stuff back to normal */ row = hrow; col = hcol; urow = row+tablePtr->rowOffset; rowPtr = FindRowColTag(tablePtr, urow, ROW); } } } ckfree((char *) tagPtr); #ifdef NO_XSETCLIP Tk_FreePixmap(display, clipWind); #endif /* Take care of removing embedded windows that are no longer in view */ TableUndisplay(tablePtr); /* copy over and delete the pixmap if we are in slow mode */ if (tablePtr->drawMode == DRAW_MODE_SLOW) { /* Get a default valued GC */ TableGetGc(display, window, &(tablePtr->defaultTag), &tagGc); XCopyArea(display, window, Tk_WindowId(tkwin), tagGc, 0, 0, invalidWidth, invalidHeight, invalidX, invalidY); Tk_FreePixmap(display, window); window = Tk_WindowId(tkwin); } /* * If we are at the end of the table, clear the area after the last * row/col. We discount spans here because we just need the coords * for the area that would be the last physical cell. */ tablePtr->flags |= AVOID_SPANS; TableCellCoords(tablePtr, tablePtr->rows-1, tablePtr->cols-1, &x, &y, &width, &height); tablePtr->flags &= ~AVOID_SPANS; /* This should occur before moving pixmap, but this simplifies things * * Could use Tk_Fill3DRectangle instead of XFillRectangle * for best compatibility, and XClearArea could be used on Unix * for best speed, so this is the compromise w/o #ifdef's */ if (x+width < invalidX+invalidWidth) { XFillRectangle(display, window, Tk_3DBorderGC(tkwin, tablePtr->defaultTag.bg, TK_3D_FLAT_GC), x+width, invalidY, invalidX+invalidWidth-x-width, invalidHeight); } if (y+height < invalidY+invalidHeight) { XFillRectangle(display, window, Tk_3DBorderGC(tkwin, tablePtr->defaultTag.bg, TK_3D_FLAT_GC), invalidX, y+height, invalidWidth, invalidY+invalidHeight-y-height); } if (tagGc != NULL) { TableFreeGc(display, tagGc); } TableRedrawHighlight(tablePtr); /* * Free the hash table used to cache evaluations. */ Tcl_DeleteHashTable(colTagsCache); ckfree((char *) (colTagsCache)); Tcl_DeleteHashTable(drawnCache); ckfree((char *) (drawnCache)); } /* *---------------------------------------------------------------------- * * TableInvalidate -- * Invalidates a rectangle and adds it to the total invalid rectangle * waiting to be redrawn. If the INV_FORCE flag bit is set, * it does an update instantly else waits until Tk is idle. * * Results: * Will schedule table (re)display. * * Side effects: * None * *---------------------------------------------------------------------- */ void TableInvalidate(Table * tablePtr, int x, int y, int w, int h, int flags) { Tk_Window tkwin = tablePtr->tkwin; int hl = tablePtr->highlightWidth; int height = Tk_Height(tkwin); int width = Tk_Width(tkwin); /* * Make sure that the window hasn't been destroyed already. * Avoid allocating 0 sized pixmaps which would be fatal, * and check if rectangle is even on the screen. */ if ((tkwin == NULL) || (w <= 0) || (h <= 0) || (x > width) || (y > height)) { return; } /* If not even mapped, wait for the remap to redraw all */ if (!Tk_IsMapped(tkwin)) { tablePtr->flags |= REDRAW_ON_MAP; return; } /* * If no pending updates exist, then replace the rectangle. * Otherwise find the bounding rectangle. */ if ((flags & INV_HIGHLIGHT) && (x < hl || y < hl || x+w >= width-hl || y+h >= height-hl)) { tablePtr->flags |= REDRAW_BORDER; } if (tablePtr->flags & REDRAW_PENDING) { tablePtr->invalidWidth = MAX(x + w, tablePtr->invalidX+tablePtr->invalidWidth); tablePtr->invalidHeight = MAX(y + h, tablePtr->invalidY+tablePtr->invalidHeight); if (tablePtr->invalidX > x) tablePtr->invalidX = x; if (tablePtr->invalidY > y) tablePtr->invalidY = y; tablePtr->invalidWidth -= tablePtr->invalidX; tablePtr->invalidHeight -= tablePtr->invalidY; /* Do we want to force this update out? */ if (flags & INV_FORCE) { Tcl_CancelIdleCall(TableDisplay, (ClientData) tablePtr); TableDisplay((ClientData) tablePtr); } } else { tablePtr->invalidX = x; tablePtr->invalidY = y; tablePtr->invalidWidth = w; tablePtr->invalidHeight = h; if (flags & INV_FORCE) { TableDisplay((ClientData) tablePtr); } else { tablePtr->flags |= REDRAW_PENDING; Tcl_DoWhenIdle(TableDisplay, (ClientData) tablePtr); } } } /* *---------------------------------------------------------------------- * * TableFlashEvent -- * Called when the flash timer goes off. * * Results: * Decrements all the entries in the hash table and invalidates * any cells that expire, deleting them from the table. If the * table is now empty, stops the timer, else reenables it. * * Side effects: * None. * *---------------------------------------------------------------------- */ static void TableFlashEvent(ClientData clientdata) { Table *tablePtr = (Table *) clientdata; Tcl_HashEntry *entryPtr; Tcl_HashSearch search; int entries, count, row, col; entries = 0; for (entryPtr = Tcl_FirstHashEntry(tablePtr->flashCells, &search); entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { count = (int) Tcl_GetHashValue(entryPtr); if (--count <= 0) { /* get the cell address and invalidate that region only */ TableParseArrayIndex(&row, &col, Tcl_GetHashKey(tablePtr->flashCells, entryPtr)); /* delete the entry from the table */ Tcl_DeleteHashEntry(entryPtr); TableRefresh(tablePtr, row-tablePtr->rowOffset, col-tablePtr->colOffset, CELL); } else { Tcl_SetHashValue(entryPtr, (ClientData) count); entries++; } } /* do I need to restart the timer */ if (entries && tablePtr->flashMode) { tablePtr->flashTimer = Tcl_CreateTimerHandler(250, TableFlashEvent, (ClientData) tablePtr); } else { tablePtr->flashTimer = 0; } } /* *---------------------------------------------------------------------- * * TableAddFlash -- * Adds a flash on cell row,col (real coords) with the default timeout * if flashing is enabled and flashtime > 0. * * Results: * Cell will flash. * * Side effects: * Will start flash timer if it didn't exist. * *---------------------------------------------------------------------- */ void TableAddFlash(Table *tablePtr, int row, int col) { char buf[INDEX_BUFSIZE]; int dummy; Tcl_HashEntry *entryPtr; if (!tablePtr->flashMode || tablePtr->flashTime < 1) { return; } /* create the array index in user coords */ TableMakeArrayIndex(row+tablePtr->rowOffset, col+tablePtr->colOffset, buf); /* add the flash to the hash table */ entryPtr = Tcl_CreateHashEntry(tablePtr->flashCells, buf, &dummy); Tcl_SetHashValue(entryPtr, tablePtr->flashTime); /* now set the timer if it's not already going and invalidate the area */ if (tablePtr->flashTimer == NULL) { tablePtr->flashTimer = Tcl_CreateTimerHandler(250, TableFlashEvent, (ClientData) tablePtr); } } /* *---------------------------------------------------------------------- * * TableSetActiveIndex -- * Sets the "active" index of the associated array to the current * value of the active buffer. * * Results: * None. * * Side effects: * Traces on the array can cause side effects. * *---------------------------------------------------------------------- */ void TableSetActiveIndex(register Table *tablePtr) { if (tablePtr->arrayVar) { tablePtr->flags |= SET_ACTIVE; Tcl_SetVar2(tablePtr->interp, tablePtr->arrayVar, "active", tablePtr->activeBuf, TCL_GLOBAL_ONLY); tablePtr->flags &= ~SET_ACTIVE; } } /* *---------------------------------------------------------------------- * * TableGetActiveBuf -- * Get the current selection into the buffer and mark it as unedited. * Set the position to the end of the string. * * Results: * None. * * Side effects: * tablePtr->activeBuf will change. * *---------------------------------------------------------------------- */ void TableGetActiveBuf(register Table *tablePtr) { char *data = ""; if (tablePtr->flags & HAS_ACTIVE) { data = TableGetCellValue(tablePtr, tablePtr->activeRow+tablePtr->rowOffset, tablePtr->activeCol+tablePtr->colOffset); } if (STREQ(tablePtr->activeBuf, data)) { /* this forced SetActiveIndex is necessary if we change array vars and * they happen to have these cells equal, we won't properly set the * active index for the new array var unless we do this here */ TableSetActiveIndex(tablePtr); return; } /* is the buffer long enough */ tablePtr->activeBuf = (char *)ckrealloc(tablePtr->activeBuf, strlen(data)+1); strcpy(tablePtr->activeBuf, data); TableGetIcursor(tablePtr, "end", (int *)0); tablePtr->flags &= ~TEXT_CHANGED; TableSetActiveIndex(tablePtr); } /* *---------------------------------------------------------------------- * * TableVarProc -- * This is the trace procedure associated with the Tcl array. No * validation will occur here because this only triggers when the * array value is directly set, and we can't maintain the old value. * * Results: * Invalidates changed cell. * * Side effects: * Creates/Updates entry in the cache if we are caching. * *---------------------------------------------------------------------- */ static char * TableVarProc(clientData, interp, name, index, flags) ClientData clientData; /* Information about table. */ Tcl_Interp *interp; /* Interpreter containing variable. */ Var name; /* Not used. */ char *index; /* Not used. */ int flags; /* Information about what happened. */ { Table *tablePtr = (Table *) clientData; int row, col, update = 1; /* This is redundant, as the name should always == arrayVar */ name = tablePtr->arrayVar; /* is this the whole var being destroyed or just one cell being deleted */ if ((flags & TCL_TRACE_UNSETS) && index == NULL) { /* if this isn't the interpreter being destroyed reinstate the trace */ if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) { Tcl_SetVar2(interp, name, TEST_KEY, "", TCL_GLOBAL_ONLY); /* Perltk not supported */ /* Tcl_UnsetVar2(interp, LangString(Tcl_GetVar(interp, name, TCL_GLOBAL_ONLY)), TEST_KEY, TCL_GLOBAL_ONLY); */ Tcl_ResetResult(interp); /* set a trace on the variable */ Tcl_TraceVar(interp, name, TCL_TRACE_WRITES | TCL_TRACE_UNSETS | TCL_GLOBAL_ONLY, (Tcl_VarTraceProc *)TableVarProc, (ClientData) tablePtr); /* only do the following if arrayVar is our data source */ if (tablePtr->dataSource & DATA_ARRAY) { /* clear the selection buffer */ TableGetActiveBuf(tablePtr); /* flush any cache */ Table_ClearHashTable(tablePtr->cache); Tcl_InitHashTable(tablePtr->cache, TCL_STRING_KEYS); /* and invalidate the table */ TableInvalidateAll(tablePtr, 0); } } return (char *)NULL; } /* only continue if arrayVar is our data source */ if (!(tablePtr->dataSource & DATA_ARRAY)) { return (char *)NULL; } /* get the cell address and invalidate that region only. * Make sure that it is a valid cell address. */ if (STREQ("active", index)) { if (tablePtr->flags & SET_ACTIVE) { /* If we are already setting the active cell, the update * will occur in other code */ update = 0; } else { /* modified TableGetActiveBuf */ CONST char *data = ""; row = tablePtr->activeRow; col = tablePtr->activeCol; if (tablePtr->flags & HAS_ACTIVE) data = LangString(Tcl_GetVar2(interp, name, index, TCL_GLOBAL_ONLY)); if (!data) data = ""; if (STREQ(tablePtr->activeBuf, data)) { return (char *)NULL; } tablePtr->activeBuf = (char *)ckrealloc(tablePtr->activeBuf, strlen(data)+1); strcpy(tablePtr->activeBuf, data); /* set cursor to the last char */ TableGetIcursor(tablePtr, "end", (int *)0); tablePtr->flags |= TEXT_CHANGED; } } else if (TableParseArrayIndex(&row, &col, index) == 2) { char buf[INDEX_BUFSIZE]; /* Make sure it won't trigger on array(2,3extrastuff) */ TableMakeArrayIndex(row, col, buf); if (strcmp(buf, index)) { return (char *)NULL; } if (tablePtr->caching) { Tcl_HashEntry *entryPtr; int new; char *val, *data; entryPtr = Tcl_CreateHashEntry(tablePtr->cache, buf, &new); if (!new) { data = (char *) Tcl_GetHashValue(entryPtr); if (data) { ckfree(data); } } data = LangString(Tcl_GetVar2(interp, name, index, TCL_GLOBAL_ONLY)); if (!data) data = ""; val = (char *)ckalloc(strlen(data)+1); strcpy(val, data); Tcl_SetHashValue(entryPtr, val); } /* convert index to real coords */ row -= tablePtr->rowOffset; col -= tablePtr->colOffset; /* did the active cell just update */ if (row == tablePtr->activeRow && col == tablePtr->activeCol) { TableGetActiveBuf(tablePtr); } /* Flash the cell */ TableAddFlash(tablePtr, row, col); } else { return (char *)NULL; } if (update) { TableRefresh(tablePtr, row, col, CELL); } return (char *)NULL; } /* *---------------------------------------------------------------------- * * TableGeometryRequest -- * This procedure is invoked to request a new geometry from Tk. * * Results: * None. * * Side effects: * Geometry information is updated and a new requested size is * registered for the widget. Internal border info is also set. * *---------------------------------------------------------------------- */ void TableGeometryRequest(tablePtr) register Table *tablePtr; { int x, y; /* Do the geometry request * If -width #cols was not specified or it is greater than the real * number of cols, use maxWidth as a lower bound, with the other lower * bound being the upper bound of the window's user-set width and the * value of -maxwidth set by the programmer * Vice versa for rows/height */ x = MIN((tablePtr->maxReqCols==0 || tablePtr->maxReqCols > tablePtr->cols)? tablePtr->maxWidth : tablePtr->colStarts[tablePtr->maxReqCols], tablePtr->maxReqWidth) + 2*tablePtr->highlightWidth; y = MIN((tablePtr->maxReqRows==0 || tablePtr->maxReqRows > tablePtr->rows)? tablePtr->maxHeight : tablePtr->rowStarts[tablePtr->maxReqRows], tablePtr->maxReqHeight) + 2*tablePtr->highlightWidth; Tk_GeometryRequest(tablePtr->tkwin, x, y); } /* *---------------------------------------------------------------------- * * TableAdjustActive -- * This procedure is called by AdjustParams and CMD_ACTIVATE to * move the active cell. * * Results: * Old and new active cell indices will be invalidated. * * Side effects: * If the old active cell index was edited, it will be saved. * The active buffer will be updated. * *---------------------------------------------------------------------- */ void TableAdjustActive(tablePtr) register Table *tablePtr; /* Widget record for table */ { if (tablePtr->flags & HAS_ACTIVE) { /* * Make sure the active cell has a reasonable real index */ CONSTRAIN(tablePtr->activeRow, 0, tablePtr->rows-1); CONSTRAIN(tablePtr->activeCol, 0, tablePtr->cols-1); } /* * Check the new value of active cell against the original, * Only invalidate if it changed. */ if (tablePtr->oldActRow == tablePtr->activeRow && tablePtr->oldActCol == tablePtr->activeCol) { return; } if (tablePtr->oldActRow >= 0 && tablePtr->oldActCol >= 0) { /* * Set the value of the old active cell to the active buffer * SetCellValue will check if the value actually changed */ if (tablePtr->flags & TEXT_CHANGED) { /* WARNING an outside trace will be triggered here and if it * calls something that causes TableAdjustParams to be called * again, we are in data consistency trouble */ /* HACK - turn TEXT_CHANGED off now to possibly avoid the * above data inconsistency problem. */ tablePtr->flags &= ~TEXT_CHANGED; TableSetCellValue(tablePtr, tablePtr->oldActRow + tablePtr->rowOffset, tablePtr->oldActCol + tablePtr->colOffset, tablePtr->activeBuf); } /* * Invalidate the old active cell */ TableRefresh(tablePtr, tablePtr->oldActRow, tablePtr->oldActCol, CELL); } /* * Store the new active cell value into the active buffer */ TableGetActiveBuf(tablePtr); /* * Invalidate the new active cell */ TableRefresh(tablePtr, tablePtr->activeRow, tablePtr->activeCol, CELL); /* * Cache the old active row/col for the next time this is called */ tablePtr->oldActRow = tablePtr->activeRow; tablePtr->oldActCol = tablePtr->activeCol; } /* *---------------------------------------------------------------------- * * TableAdjustParams -- * Calculate the row and column starts. Adjusts the topleft corner * variable to keep it within the screen range, out of the titles * and keep the screen full make sure the selected cell is in the * visible area checks to see if the top left cell has changed at * all and invalidates the table if it has. * * Results: * None. * * Side Effects: * Number of rows can change if -rowstretchmode == fill. * topRow && leftCol can change to fit display. * activeRow/Col can change to ensure it is a valid cell. * *---------------------------------------------------------------------- */ void TableAdjustParams(register Table *tablePtr) { int topRow, leftCol, row, col, total, i, value, x, y, width, height, w, h, hl, px, py, recalc, bd[4], diff, unpreset, lastUnpreset, pad, lastPad, numPixels, defColWidth, defRowHeight; Tcl_HashEntry *entryPtr; /* * Cache some values for many upcoming calculations */ hl = tablePtr->highlightWidth; w = Tk_Width(tablePtr->tkwin) - (2 * hl); h = Tk_Height(tablePtr->tkwin) - (2 * hl); TableGetTagBorders(&(tablePtr->defaultTag), &bd[0], &bd[1], &bd[2], &bd[3]); px = bd[0] + bd[1] + (2 * tablePtr->padX); py = bd[2] + bd[3] + (2 * tablePtr->padY); /* * Account for whether default dimensions are in chars (>0) or * pixels (<=0). Border and Pad space is added in here for convenience. * * When a value in pixels is specified, we take that exact amount, * not adding in padding. */ if (tablePtr->defColWidth > 0) { defColWidth = tablePtr->charWidth * tablePtr->defColWidth + px; } else { defColWidth = -(tablePtr->defColWidth); } if (tablePtr->defRowHeight > 0) { defRowHeight = tablePtr->charHeight * tablePtr->defRowHeight + py; } else { defRowHeight = -(tablePtr->defRowHeight); } /* * Set up the arrays to hold the col pixels and starts. * ckrealloc was fixed in 8.2.1 to handle NULLs, so we can't rely on it. */ if (tablePtr->colPixels) ckfree((char *) tablePtr->colPixels); tablePtr->colPixels = (int *) ckalloc(tablePtr->cols * sizeof(int)); if (tablePtr->colStarts) ckfree((char *) tablePtr->colStarts); tablePtr->colStarts = (int *) ckalloc((tablePtr->cols+1) * sizeof(int)); /* * Get all the preset columns and set their widths */ lastUnpreset = 0; numPixels = 0; unpreset = 0; for (i = 0; i < tablePtr->cols; i++) { entryPtr = Tcl_FindHashEntry(tablePtr->colWidths, (char *) i); if (entryPtr == NULL) { tablePtr->colPixels[i] = -1; unpreset++; lastUnpreset = i; } else { value = (int) Tcl_GetHashValue(entryPtr); if (value > 0) { tablePtr->colPixels[i] = value * tablePtr->charWidth + px; } else { /* * When a value in pixels is specified, we take that exact * amount, not adding in pad or border values. */ tablePtr->colPixels[i] = -value; } numPixels += tablePtr->colPixels[i]; } } /* * Work out how much to pad each col depending on the mode. */ diff = w - numPixels - (unpreset * defColWidth); total = 0; /* * Now do the padding and calculate the column starts. * Diff lower than 0 means we can't see the entire set of columns, * thus no special stretching will occur & we optimize the calculation. */ if (diff <= 0) { for (i = 0; i < tablePtr->cols; i++) { if (tablePtr->colPixels[i] == -1) { tablePtr->colPixels[i] = defColWidth; } tablePtr->colStarts[i] = total; total += tablePtr->colPixels[i]; } } else { switch (tablePtr->colStretch) { case STRETCH_MODE_NONE: pad = 0; lastPad = 0; break; case STRETCH_MODE_UNSET: if (unpreset == 0) { pad = 0; lastPad = 0; } else { pad = diff / unpreset; lastPad = diff - pad * (unpreset - 1); } break; case STRETCH_MODE_LAST: pad = 0; lastPad = diff; lastUnpreset = tablePtr->cols - 1; break; default: /* STRETCH_MODE_ALL, but also FILL for cols */ pad = diff / tablePtr->cols; /* force it to be applied to the last column too */ lastUnpreset = tablePtr->cols - 1; lastPad = diff - pad * lastUnpreset; } for (i = 0; i < tablePtr->cols; i++) { if (tablePtr->colPixels[i] == -1) { tablePtr->colPixels[i] = defColWidth + ((i == lastUnpreset) ? lastPad : pad); } else if (tablePtr->colStretch == STRETCH_MODE_ALL) { tablePtr->colPixels[i] += (i == lastUnpreset) ? lastPad : pad; } tablePtr->colStarts[i] = total; total += tablePtr->colPixels[i]; } } tablePtr->colStarts[i] = tablePtr->maxWidth = total; /* * The 'do' loop is only necessary for rows because of FILL mode */ recalc = 0; do { /* Set up the arrays to hold the row pixels and starts */ /* FIX - this can be moved outside 'do' if you check >row size */ if (tablePtr->rowPixels) ckfree((char *) tablePtr->rowPixels); tablePtr->rowPixels = (int *) ckalloc(tablePtr->rows * sizeof(int)); /* get all the preset rows and set their heights */ lastUnpreset = 0; numPixels = 0; unpreset = 0; for (i = 0; i < tablePtr->rows; i++) { entryPtr = Tcl_FindHashEntry(tablePtr->rowHeights, (char *) i); if (entryPtr == NULL) { tablePtr->rowPixels[i] = -1; unpreset++; lastUnpreset = i; } else { value = (int) Tcl_GetHashValue(entryPtr); if (value > 0) { tablePtr->rowPixels[i] = value * tablePtr->charHeight + py; } else { /* * When a value in pixels is specified, we take that exact * amount, not adding in pad or border values. */ tablePtr->rowPixels[i] = -value; } numPixels += tablePtr->rowPixels[i]; } } /* work out how much to pad each row depending on the mode */ diff = h - numPixels - (unpreset * defRowHeight); switch(tablePtr->rowStretch) { case STRETCH_MODE_NONE: pad = 0; lastPad = 0; break; case STRETCH_MODE_UNSET: if (unpreset == 0) { pad = 0; lastPad = 0; } else { pad = MAX(0,diff) / unpreset; lastPad = MAX(0,diff) - pad * (unpreset - 1); } break; case STRETCH_MODE_LAST: pad = 0; lastPad = MAX(0,diff); /* force it to be applied to the last column too */ lastUnpreset = tablePtr->rows - 1; break; case STRETCH_MODE_FILL: pad = 0; lastPad = diff; if (diff && !recalc) { tablePtr->rows += (diff/defRowHeight); if (diff < 0 && tablePtr->rows <= 0) { tablePtr->rows = 1; } lastUnpreset = tablePtr->rows - 1; recalc = 1; continue; } else { lastUnpreset = tablePtr->rows - 1; recalc = 0; } break; default: /* STRETCH_MODE_ALL */ pad = MAX(0,diff) / tablePtr->rows; /* force it to be applied to the last column too */ lastUnpreset = tablePtr->rows - 1; lastPad = MAX(0,diff) - pad * lastUnpreset; } } while (recalc); if (tablePtr->rowStarts) ckfree((char *) tablePtr->rowStarts); tablePtr->rowStarts = (int *) ckalloc((tablePtr->rows+1)*sizeof(int)); /* * Now do the padding and calculate the row starts */ total = 0; for (i = 0; i < tablePtr->rows; i++) { if (tablePtr->rowPixels[i] == -1) { tablePtr->rowPixels[i] = defRowHeight + ((i==lastUnpreset)?lastPad:pad); } else if (tablePtr->rowStretch == STRETCH_MODE_ALL) { tablePtr->rowPixels[i] += (i==lastUnpreset)?lastPad:pad; } /* calculate the start of each row */ tablePtr->rowStarts[i] = total; total += tablePtr->rowPixels[i]; } tablePtr->rowStarts[i] = tablePtr->maxHeight = total; /* * Make sure the top row and col have reasonable real indices */ CONSTRAIN(tablePtr->topRow, tablePtr->titleRows, tablePtr->rows-1); CONSTRAIN(tablePtr->leftCol, tablePtr->titleCols, tablePtr->cols-1); /* * If we don't have the info, don't bother to fix up the other parameters */ if (Tk_WindowId(tablePtr->tkwin) == None) { tablePtr->oldTopRow = tablePtr->oldLeftCol = -1; return; } topRow = tablePtr->topRow; leftCol = tablePtr->leftCol; w += hl; h += hl; /* * If we use this value of topRow, will we fill the window? * if not, decrease it until we will, or until it gets to titleRows * make sure we don't cut off the bottom row */ for (; topRow > tablePtr->titleRows; topRow--) { if ((tablePtr->maxHeight-(tablePtr->rowStarts[topRow-1] - tablePtr->rowStarts[tablePtr->titleRows])) > h) { break; } } /* * If we use this value of topCol, will we fill the window? * if not, decrease it until we will, or until it gets to titleCols * make sure we don't cut off the left column */ for (; leftCol > tablePtr->titleCols; leftCol--) { if ((tablePtr->maxWidth-(tablePtr->colStarts[leftCol-1] - tablePtr->colStarts[tablePtr->titleCols])) > w) { break; } } tablePtr->topRow = topRow; tablePtr->leftCol = leftCol; /* * Now work out where the bottom right is for scrollbar update and to test * for one last stretch. Avoid the confusion that spans could cause for * determining the last cell dimensions. */ tablePtr->flags |= AVOID_SPANS; TableGetLastCell(tablePtr, &row, &col); TableCellVCoords(tablePtr, row, col, &x, &y, &width, &height, 0); tablePtr->flags &= ~AVOID_SPANS; /* * Do we have scrollbars, if so, calculate and call the TCL functions In * order to get the scrollbar to be completely full when the whole screen * is shown and there are titles, we have to arrange for the scrollbar * range to be 0 -> rows-titleRows etc. This leads to the position * setting methods, toprow and leftcol, being relative to the titles, not * absolute row and column numbers. */ if (tablePtr->yScrollCmd != NULL || tablePtr->xScrollCmd != NULL) { Tcl_Interp *interp = tablePtr->interp; char buf[INDEX_BUFSIZE]; double first, last; /* * We must hold onto the interpreter because the data referred to at * tablePtr might be freed as a result of the call to Tcl_VarEval. */ Tcl_Preserve((ClientData) interp); /* Do we have a Y-scrollbar and rows to scroll? */ if (tablePtr->yScrollCmd != NULL) { if (row < tablePtr->titleRows) { first = 0; last = 1; } else { diff = tablePtr->rowStarts[tablePtr->titleRows]; last = (double) (tablePtr->rowStarts[tablePtr->rows]-diff); if (last <= 0.0) { first = 0; last = 1; } else { first = (tablePtr->rowStarts[topRow]-diff) / last; last = (height+tablePtr->rowStarts[row]-diff) / last; } } if ( LangDoCallback(interp,tablePtr->yScrollCmd, 0,2, " %g %g", first, last) != TCL_OK) { Tcl_AddErrorInfo(interp, "\n\t(vertical scrolling command executed by table)"); Tcl_BackgroundError(interp); } } /* Do we have a X-scrollbar and cols to scroll? */ if (tablePtr->xScrollCmd != NULL) { if (col < tablePtr->titleCols) { first = 0; last = 1; } else { diff = tablePtr->colStarts[tablePtr->titleCols]; last = (double) (tablePtr->colStarts[tablePtr->cols]-diff); if (last <= 0.0) { first = 0; last = 1; } else { first = (tablePtr->colStarts[leftCol]-diff) / last; last = (width+tablePtr->colStarts[col]-diff) / last; } } if ( LangDoCallback(interp,tablePtr->xScrollCmd, 0,2, " %g %g", first, last) != TCL_OK) { Tcl_AddErrorInfo(interp, "\n\t(horizontal scrolling command executed by table)"); Tcl_BackgroundError(interp); } } Tcl_Release((ClientData) interp); } /* * Adjust the last row/col to fill empty space if it is visible. * Do this after setting the scrollbars to not upset its calculations. */ if (row == tablePtr->rows-1 && tablePtr->rowStretch != STRETCH_MODE_NONE) { diff = h-(y+height); if (diff > 0) { tablePtr->rowPixels[tablePtr->rows-1] += diff; tablePtr->rowStarts[tablePtr->rows] += diff; } } if (col == tablePtr->cols-1 && tablePtr->colStretch != STRETCH_MODE_NONE) { diff = w-(x+width); if (diff > 0) { tablePtr->colPixels[tablePtr->cols-1] += diff; tablePtr->colStarts[tablePtr->cols] += diff; } } TableAdjustActive(tablePtr); /* * now check the new value of topleft cell against the originals, * If they changed, invalidate the area, else leave it alone */ if (tablePtr->topRow != tablePtr->oldTopRow || tablePtr->leftCol != tablePtr->oldLeftCol) { /* set the old top row/col for the next time this function is called */ tablePtr->oldTopRow = tablePtr->topRow; tablePtr->oldLeftCol = tablePtr->leftCol; /* only the upper corner title cells wouldn't change */ TableInvalidateAll(tablePtr, 0); } } /* *---------------------------------------------------------------------- * * TableCursorEvent -- * Toggle the cursor status. Equivalent to EntryBlinkProc. * * Results: * None. * * Side effects: * The cursor will be switched off/on. * *---------------------------------------------------------------------- */ static void TableCursorEvent(ClientData clientData) { register Table *tablePtr = (Table *) clientData; if (!(tablePtr->flags & HAS_FOCUS) || (tablePtr->insertOffTime == 0) || (tablePtr->flags & ACTIVE_DISABLED) || (tablePtr->state != STATE_NORMAL)) { return; } if (tablePtr->cursorTimer != NULL) { Tcl_DeleteTimerHandler(tablePtr->cursorTimer); } tablePtr->cursorTimer = Tcl_CreateTimerHandler((tablePtr->flags & CURSOR_ON) ? tablePtr->insertOffTime : tablePtr->insertOnTime, TableCursorEvent, (ClientData) tablePtr); /* Toggle the cursor */ tablePtr->flags ^= CURSOR_ON; /* invalidate the cell */ TableRefresh(tablePtr, tablePtr->activeRow, tablePtr->activeCol, CELL); } /* *---------------------------------------------------------------------- * * TableConfigCursor -- * Configures the timer depending on the state of the table. * Equivalent to EntryFocusProc. * * Results: * None. * * Side effects: * The cursor will be switched off/on. * *---------------------------------------------------------------------- */ void TableConfigCursor(register Table *tablePtr) { /* * To have a cursor, we have to have focus and allow edits */ if ((tablePtr->flags & HAS_FOCUS) && (tablePtr->state == STATE_NORMAL) && !(tablePtr->flags & ACTIVE_DISABLED)) { /* * Turn the cursor ON */ if (!(tablePtr->flags & CURSOR_ON)) { tablePtr->flags |= CURSOR_ON; /* * Only refresh when we toggled cursor */ TableRefresh(tablePtr, tablePtr->activeRow, tablePtr->activeCol, CELL); } /* set up the first timer */ if (tablePtr->insertOffTime != 0) { /* make sure nothing existed */ Tcl_DeleteTimerHandler(tablePtr->cursorTimer); tablePtr->cursorTimer = Tcl_CreateTimerHandler(tablePtr->insertOnTime, TableCursorEvent, (ClientData) tablePtr); } } else { /* * Turn the cursor OFF */ if ((tablePtr->flags & CURSOR_ON)) { tablePtr->flags &= ~CURSOR_ON; TableRefresh(tablePtr, tablePtr->activeRow, tablePtr->activeCol, CELL); } /* and disable the timer */ if (tablePtr->cursorTimer != NULL) { Tcl_DeleteTimerHandler(tablePtr->cursorTimer); } tablePtr->cursorTimer = NULL; } } /* *---------------------------------------------------------------------- * * TableFetchSelection -- * This procedure is called back by Tk when the selection is * requested by someone. It returns part or all of the selection * in a buffer provided by the caller. * * Results: * The return value is the number of non-NULL bytes stored * at buffer. Buffer is filled (or partially filled) with a * NULL-terminated string containing part or all of the selection, * as given by offset and maxBytes. * * Side effects: * None. * *---------------------------------------------------------------------- */ static int SelectionFetched = 0; /* Flag = 1 if a selection has been fetched before */ static int TableFetchSelection(clientData, offset, buffer, maxBytes) ClientData clientData; /* Information about table widget. */ int offset; /* Offset within selection of first * character to be returned. */ char *buffer; /* Location in which to place selection. */ int maxBytes; /* Maximum number of bytes to place at buffer, * not including terminating NULL. */ { register Table *tablePtr = (Table *) clientData; Tcl_Interp *interp = tablePtr->interp; char *data, *rowsep = tablePtr->rowSep, *colsep = tablePtr->colSep; /* We keep a static selection around so we don't have to remake the selection if we are getting the selection in chunks (i.e. offset != 0) */ static Tcl_DString selection; Tcl_HashEntry *entryPtr; Tcl_HashSearch search; int length, count, lastrow=0, needcs=0, r, c, listArgc, rslen=0, cslen=0; int numcols, numrows; Arg *listArgv; Arg value; /* if we are not exporting the selection || * we have no data source, return */ if (!tablePtr->exportSelection || (tablePtr->dataSource == DATA_NONE)) { return -1; } if( offset == 0){ /* First Time thru, get the selection, otherwise, just use the selection obtained before */ Tk_Cursor existingCursor; existingCursor = tablePtr->cursor; /* Set Cursor to wait, becuase this can take some time for large selections */ /* tablePtr->cursor = Tk_GetCursor(interp, tablePtr->tkwin, LangStringArg("watch")); */ Tk_DefineCursor(tablePtr->tkwin, Tk_GetCursor(interp, tablePtr->tkwin, LangStringArg("watch"))); Tcl_DoOneEvent(TCL_DONT_WAIT); if( SelectionFetched){ /* If we have fetched a selection before, free it */ Tcl_DStringFree(&selection); } SelectionFetched = 1; /* First get a sorted list of the selected elements */ Tcl_DStringInit(&selection); for (entryPtr = Tcl_FirstHashEntry(tablePtr->selCells, &search); entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { Tcl_DStringAppendElement(&selection, Tcl_GetHashKey(tablePtr->selCells, entryPtr)); } value = TableCellSort(tablePtr, Tcl_DStringValue(&selection)); Tcl_DStringFree(&selection); if (value == NULL || Tcl_ListObjGetElements(interp, value, &listArgc, &listArgv) != TCL_OK) { Tk_DefineCursor(tablePtr->tkwin, existingCursor); /* Set Cursor Back */ return -1; } Tcl_DStringInit(&selection); rslen = (rowsep?(strlen(rowsep)):0); cslen = (colsep?(strlen(colsep)):0); numrows = numcols = 0; for (count = 0; count < listArgc; count++) { TableParseArrayIndex(&r, &c, LangString(listArgv[count])); if (count) { if (lastrow != r) { lastrow = r; needcs = 0; if (rslen) { Tcl_DStringAppend(&selection, rowsep, rslen); /* perltk: Temporarily?? commented out, don't have a Tcl_DtringStartSublist } else { Tcl_DStringEndSublist(&selection); Tcl_DStringStartSublist(&selection); */ } ++numrows; } else { if (++needcs > numcols) numcols = needcs; } } else { lastrow = r; needcs = 0; /* perltk: Temporarily?? commented out, don't have a Tcl_DtringStartSublist if (!rslen) Tcl_DStringStartSublist(&selection); */ } data = TableGetCellValue(tablePtr, r, c); if (cslen) { if (needcs) { Tcl_DStringAppend(&selection, colsep, cslen); } Tcl_DStringAppend(&selection, data, -1); } else { Tcl_DStringAppendElement(&selection, data); } } /* perltk: Temporarily?? commented out, don't have a Tcl_DtringStartSublist if (!rslen && count) { Tcl_DStringEndSublist(&selection); } */ if (tablePtr->selCmd != NULL) { if ( LangDoCallback(interp, tablePtr->selCmd, 1, 4, "%d %d %s %d", numrows+1, numcols+1, Tcl_DStringValue(&selection), listArgc) == TCL_ERROR) { Tcl_AddErrorInfo(interp, "\n (error in table selection command)"); Tcl_BackgroundError(interp); Tk_DefineCursor(tablePtr->tkwin, existingCursor); /* Set Cursor Back */ Tcl_DStringFree(&selection); return -1; } else { Tcl_DStringFree(&selection); Tcl_DStringInit(&selection); Tcl_DStringAppendElement(&selection, Tcl_GetResult(interp)); } } Tk_DefineCursor(tablePtr->tkwin, existingCursor); /* Set Cursor Back */ } length = Tcl_DStringLength(&selection); if (length == 0){ return -1; } /* Copy the requested portion of the selection to the buffer. */ count = length - offset; if (count <= 0) { count = 0; } else { if (count > maxBytes) { count = maxBytes; } memcpy((VOID *) buffer, (VOID *) (Tcl_DStringValue(&selection) + offset), (size_t) count); } buffer[count] = '\0'; return count; } /* *---------------------------------------------------------------------- * * TableLostSelection -- * This procedure is called back by Tk when the selection is * grabbed away from a table widget. * * Results: * None. * * Side effects: * The existing selection is unhighlighted, and the window is * marked as not containing a selection. * *---------------------------------------------------------------------- */ void TableLostSelection(clientData) ClientData clientData; /* Information about table widget. */ { register Table *tablePtr = (Table *) clientData; if (tablePtr->exportSelection) { Tcl_HashEntry *entryPtr; Tcl_HashSearch search; int row, col; /* Same as SEL CLEAR ALL */ for (entryPtr = Tcl_FirstHashEntry(tablePtr->selCells, &search); entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { TableParseArrayIndex(&row, &col, Tcl_GetHashKey(tablePtr->selCells,entryPtr)); Tcl_DeleteHashEntry(entryPtr); TableRefresh(tablePtr, row-tablePtr->rowOffset, col-tablePtr->colOffset, CELL); } } } /* *---------------------------------------------------------------------- * * TableRestrictProc -- * A Tk_RestrictProc used by TableValidateChange to eliminate any * extra key input events in the event queue that * have a serial number no less than a given value. * * Results: * Returns either TK_DISCARD_EVENT or TK_DEFER_EVENT. * * Side effects: * None. * *---------------------------------------------------------------------- */ static Tk_RestrictAction TableRestrictProc(serial, eventPtr) ClientData serial; XEvent *eventPtr; { if ((eventPtr->type == KeyRelease || eventPtr->type == KeyPress) && ((eventPtr->xany.serial-(unsigned int)serial) > 0)) { return TK_DEFER_EVENT; } else { return TK_PROCESS_EVENT; } } /* *-------------------------------------------------------------- * * TableValidateChange -- * This procedure is invoked when any character is added or * removed from the table widget, or a set has triggered validation. * * Results: * TCL_OK if the validatecommand accepts the new string, * TCL_BREAK if the validatecommand rejects the new string, * TCL_ERROR if any problems occured with validatecommand. * * Side effects: * The insertion/deletion may be aborted, and the * validatecommand might turn itself off (if an error * or loop condition arises). * *-------------------------------------------------------------- */ int TableValidateChange(tablePtr, r, c, old, new, index) register Table *tablePtr; /* Table that needs validation. */ int r, c; /* row,col index of cell in user coords */ char *old; /* current value of cell */ char *new; /* potential new value of cell */ int index; /* index of insert/delete, -1 otherwise */ { register Tcl_Interp *interp = tablePtr->interp; int code, booln; /* perltk: Bool to booln to avoid problems with DEFINES*/ Tk_RestrictProc *rstrct; ClientData cdata; if (tablePtr->valCmd == NULL || tablePtr->validate == 0) { return TCL_OK; } /* Magic code to make this bit of code UI synchronous in the face of * possible new key events */ XSync(tablePtr->display, False); rstrct = Tk_RestrictEvents(TableRestrictProc, (ClientData) NextRequest(tablePtr->display), &cdata); /* * If we're already validating, then we're hitting a loop condition * Return and set validate to 0 to disallow further validations * and prevent current validation from finishing */ if (tablePtr->flags & VALIDATING) { tablePtr->validate = 0; return TCL_OK; } tablePtr->flags |= VALIDATING; code = LangDoCallback(tablePtr->interp, tablePtr->valCmd, 1, 5, "%d %d %s %s %d", r, c, old, new, index); if (code != TCL_OK && code != TCL_RETURN) { Tcl_AddErrorInfo(interp, "\n\t(in validation command executed by table)"); Tcl_BackgroundError(interp); code = TCL_ERROR; } else if (Tcl_GetBooleanFromObj(interp, Tcl_GetObjResult(interp), &booln) != TCL_OK) { Tcl_AddErrorInfo(interp, "\n\tboolean not returned by validation command"); Tcl_BackgroundError(interp); code = TCL_ERROR; } else { code = (booln) ? TCL_OK : TCL_BREAK; } Tcl_SetStringObj(Tcl_GetObjResult(interp), (char *) NULL, 0); /* * If ->validate has become VALIDATE_NONE during the validation, * it means that a loop condition almost occured. Do not allow * this validation result to finish. */ if (tablePtr->validate == 0) { code = TCL_ERROR; } /* If validate will return ERROR, then disallow further validations */ if (code == TCL_ERROR) { tablePtr->validate = 0; } Tk_RestrictEvents(rstrct, cdata, &cdata); tablePtr->flags &= ~VALIDATING; return code; } /* *-------------------------------------------------------------- * * ExpandPercents -- * Given a command and an event, produce a new command * by replacing % constructs in the original command * with information from the X event. * * Results: * The new expanded command is appended to the dynamic string * given by dsPtr. * * Side effects: * None. * *-------------------------------------------------------------- */ void ExpandPercents(tablePtr, before, r, c, old, new, index, dsPtr, cmdType) Table *tablePtr; /* Table that needs validation. */ char *before; /* Command containing percent * expressions to be replaced. */ int r, c; /* row,col index of cell */ char *old; /* current value of cell */ char *new; /* potential new value of cell */ int index; /* index of insert/delete */ Tcl_DString *dsPtr; /* Dynamic string in which to append * new command. */ int cmdType; /* type of command to make %-subs for */ { int length, spaceNeeded, cvtFlags; #ifdef TCL_UTF_MAX Tcl_UniChar ch; #else char ch; #endif char *string, buf[INDEX_BUFSIZE]; /* This returns the static value of the string as set in the array */ if (old == NULL && cmdType == CMD_VALIDATE) { old = TableGetCellValue(tablePtr, r, c); } while (1) { if (*before == '\0') { break; } /* * Find everything up to the next % character and append it * to the result string. */ string = before; #ifdef TCL_UTF_MAX /* No need to convert '%', as it is in ascii range */ string = (char *) Tcl_UtfFindFirst(before, '%'); #else string = strchr(before, '%'); #endif if (string == (char *) NULL) { Tcl_DStringAppend(dsPtr, before, -1); break; } else if (string != before) { Tcl_DStringAppend(dsPtr, before, string-before); before = string; } /* * There's a percent sequence here. Process it. */ before++; /* skip over % */ if (*before != '\0') { #ifdef TCL_UTF_MAX before += Tcl_UtfToUniChar(before, &ch); #else ch = before[0]; before++; #endif } else { ch = '%'; } switch (ch) { case 'c': sprintf(buf, "%d", c); string = buf; break; case 'C': /* index of cell */ TableMakeArrayIndex(r, c, buf); string = buf; break; case 'r': sprintf(buf, "%d", r); string = buf; break; case 'i': /* index of cursor OR |number| of cells selected */ sprintf(buf, "%d", index); string = buf; break; case 's': /* Current cell value */ string = old; break; case 'S': /* Potential new value of cell */ string = (new?new:old); break; case 'W': /* widget name */ string = Tk_PathName(tablePtr->tkwin); break; default: #ifdef TCL_UTF_MAX length = Tcl_UniCharToUtf(ch, buf); #else buf[0] = ch; length = 1; #endif buf[length] = '\0'; string = buf; break; } /* perltk not supported */ /* spaceNeeded = Tcl_ScanElement(string, &cvtFlags); */ spaceNeeded = 0; length = Tcl_DStringLength(dsPtr); Tcl_DStringSetLength(dsPtr, length + spaceNeeded); /* perltk not supported */ /* spaceNeeded = Tcl_ConvertElement(string, Tcl_DStringValue(dsPtr) + length, cvtFlags | TCL_DONT_USE_BRACES); */ Tcl_DStringSetLength(dsPtr, length + spaceNeeded); } Tcl_DStringAppend(dsPtr, "", 1); } /* Function to call on loading the Table module */ #ifdef BUILD_Tktable # undef TCL_STORAGE_CLASS # define TCL_STORAGE_CLASS DLLEXPORT #endif #ifdef MAC_TCL #pragma export on #endif #if 0 /* perltk This not needed by perlTk */ EXTERN int Tktable_Init(interp) Tcl_Interp *interp; { /* This defines the static char initScript */ if ( #ifdef USE_TCL_STUBS Tcl_InitStubs(interp, "8.0", 0) #else Tcl_PkgRequire(interp, "Tcl", "8.0", 0) #endif == NULL) { return TCL_ERROR; } if ( #ifdef USE_TK_STUBS Tk_InitStubs(interp, "8.0", 0) #else # if (TK_MAJOR_VERSION == 8) && (TK_MINOR_VERSION == 0) /* We require 8.0 exact because of the Unicode in 8.1+ */ Tcl_PkgRequire(interp, "Tk", "8.0", 1) # else Tcl_PkgRequire(interp, "Tk", "8.0", 0) # endif #endif == NULL) { return TCL_ERROR; } if (Tcl_PkgProvide(interp, "Tktable", VERSION) != TCL_OK) { return TCL_ERROR; } Tcl_CreateObjCommand(interp, TBL_COMMAND, Tk_TableObjCmd, (ClientData) Tk_MainWindow(interp), (Tcl_CmdDeleteProc *) NULL); /* * The init script can't make certain calls in a safe interpreter, * so we always have to use the embedded runtime for it */ return Tcl_Eval(interp, Tcl_IsSafe(interp) ? tkTableSafeInitScript : tkTableInitScript); } EXTERN int Tktable_SafeInit(interp) Tcl_Interp *interp; { return Tktable_Init(interp); } #ifdef MAC_TCL #pragma export reset #endif #endif /* ifdef 0 */ #ifdef WIN32 /* *---------------------------------------------------------------------- * * DllEntryPoint -- * * This wrapper function is used by Windows to invoke the * initialization code for the DLL. If we are compiling * with Visual C++, this routine will be renamed to DllMain. * routine. * * Results: * Returns TRUE; * * Side effects: * None. * *---------------------------------------------------------------------- */ BOOL APIENTRY DllEntryPoint(hInst, reason, reserved) HINSTANCE hInst; /* Library instance handle. */ DWORD reason; /* Reason this function is being called. */ LPVOID reserved; /* Not used. */ { return TRUE; } #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable800/tkTable.h����������������������������������������������������0000644�0000000�0000000�00000063054�13745605157�017623� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * tkTable.h -- * * This is the header file for the module that implements * table widgets for the Tk toolkit. * * Copyright (c) 1997-2002 Jeffrey Hobbs * * See the file "license.txt" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tkTable.h,v 1.2 2004/02/08 03:09:47 cerney Exp $ */ #ifndef _TKTABLE_H_ #define _TKTABLE_H_ #include <string.h> #include <stdlib.h> #include <tk.h> #include "tkVMacro.h" #include "tkTableversion.h" #ifdef MAC_TCL # include <Xatom.h> #else # include <X11/Xatom.h> #endif /* MAC_TCL */ #if (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION == 0) /* Tcl8.0 stuff */ #define Tcl_GetString(objPtr) Tcl_GetStringFromObj(objPtr, (int *)NULL) #endif /* * Tcl/Tk 8.4 introduced better CONST-ness in the APIs, but we use CONST84 in * some cases for compatibility with earlier Tcl headers to prevent warnings. */ #ifndef CONST84 # define CONST84 #endif /* This EXTERN declaration is needed for Tcl < 8.0.3 */ #ifndef EXTERN # ifdef __cplusplus # define EXTERN extern "C" # else # define EXTERN extern # endif #endif #ifdef TCL_STORAGE_CLASS # undef TCL_STORAGE_CLASS #endif #ifdef BUILD_Tktable # define TCL_STORAGE_CLASS DLLEXPORT #else # define TCL_STORAGE_CLASS DLLIMPORT #endif #ifdef WIN32 # define WIN32_LEAN_AND_MEAN # include <windows.h> # undef WIN32_LEAN_AND_MEAN /* VC++ has an entry point called DllMain instead of DllEntryPoint */ # if defined(_MSC_VER) # define DllEntryPoint DllMain # endif #endif #if defined(WIN32) || defined(MAC_TCL) || defined(MAC_OSX_TK) /* XSync call defined in the internals for some reason */ # ifndef XSync # define XSync(display, bool) {display->request++;} # endif #endif /* defn of XSync */ #ifndef NORMAL_BG # ifdef WIN32 # define NORMAL_BG "SystemButtonFace" # define ACTIVE_BG NORMAL_BG # define SELECT_BG "SystemHighlight" # define SELECT_FG "SystemHighlightText" # define DISABLED "SystemDisabledText" # define HIGHLIGHT "SystemWindowFrame" # define DEF_TABLE_FONT "{MS Sans Serif} 8" # elif defined(MAC_TCL) || defined(MAC_OSX_TK) # define NORMAL_BG "systemWindowBody" # define ACTIVE_BG "#ececec" # define SELECT_BG "systemHighlight" # define SELECT_FG "systemHighlightText" # define DISABLED "#a3a3a3" # define HIGHLIGHT "Black" # define DEF_TABLE_FONT "Helvetica 12" # else # define NORMAL_BG "#d9d9d9" # define ACTIVE_BG "#fcfcfc" # define SELECT_BG "#c3c3c3" # define SELECT_FG "Black" # define DISABLED "#a3a3a3" # define HIGHLIGHT "Black" # define DEF_TABLE_FONT "Helvetica -12" # endif #endif /* NORMAL_BG */ #define MAX(A,B) (((A)>(B))?(A):(B)) #define MIN(A,B) (((A)>(B))?(B):(A)) #define BETWEEN(val,min,max) ( ((val)<(min)) ? (min) : \ ( ((val)>(max)) ? (max) : (val) ) ) #define CONSTRAIN(val,min,max) if ((val) < (min)) { (val) = (min); } \ else if ((val) > (max)) { (val) = (max); } #define STREQ(s1, s2) (strcmp((s1), (s2)) == 0) #define ARSIZE(A) (sizeof(A)/sizeof(*A)) #define INDEX_BUFSIZE 32 /* max size of buffer for indices */ #define TEST_KEY "#TEST KEY#" /* index for testing array existence */ /* * Assigned bits of "flags" fields of Table structures, and what those * bits mean: * * REDRAW_PENDING: Non-zero means a DoWhenIdle handler has * already been queued to redisplay the table. * REDRAW_BORDER: Non-zero means 3-D border must be redrawn * around window during redisplay. Normally * only text portion needs to be redrawn. * CURSOR_ON: Non-zero means insert cursor is displayed at * present. 0 means it isn't displayed. * TEXT_CHANGED: Non-zero means the active cell text is being edited. * HAS_FOCUS: Non-zero means this window has the input focus. * HAS_ACTIVE: Non-zero means the active cell is set. * HAS_ANCHOR: Non-zero means the anchor cell is set. * BROWSE_CMD: Non-zero means we're evaluating the -browsecommand. * VALIDATING: Non-zero means we are in a valCmd * SET_ACTIVE: About to set the active array element internally * ACTIVE_DISABLED: Non-zero means the active cell is -state disabled * OVER_BORDER: Non-zero means we are over a table cell border * REDRAW_ON_MAP: Forces a redraw on the unmap * AVOID_SPANS: prevent cell spans from being used * * FIX - consider adding UPDATE_SCROLLBAR a la entry */ #define REDRAW_PENDING (1L<<0) #define CURSOR_ON (1L<<1) #define HAS_FOCUS (1L<<2) #define TEXT_CHANGED (1L<<3) #define HAS_ACTIVE (1L<<4) #define HAS_ANCHOR (1L<<5) #define BROWSE_CMD (1L<<6) #define REDRAW_BORDER (1L<<7) #define VALIDATING (1L<<8) #define SET_ACTIVE (1L<<9) #define ACTIVE_DISABLED (1L<<10) #define OVER_BORDER (1L<<11) #define REDRAW_ON_MAP (1L<<12) #define AVOID_SPANS (1L<<13) /* Flags for TableInvalidate && TableRedraw */ #define ROW (1L<<0) #define COL (1L<<1) #define CELL (1L<<2) #define CELL_BAD (1<<0) #define CELL_OK (1<<1) #define CELL_SPAN (1<<2) #define CELL_HIDDEN (1<<3) #define CELL_VIEWABLE (CELL_OK|CELL_SPAN) #define INV_FILL (1L<<3) /* use for Redraw when the affected * row/col will affect neighbors */ #define INV_FORCE (1L<<4) #define INV_HIGHLIGHT (1L<<5) #define INV_NO_ERR_MSG (1L<<5) /* Don't leave an error message */ /* These alter how the selection set/clear commands behave */ #define SEL_ROW (1<<0) #define SEL_COL (1<<1) #define SEL_BOTH (1<<2) #define SEL_CELL (1<<3) #define SEL_NONE (1<<4) /* * Definitions for tablePtr->dataSource, by bit */ #define DATA_NONE 0 #define DATA_CACHE (1<<1) #define DATA_ARRAY (1<<2) #define DATA_COMMAND (1<<3) /* * Definitions for configuring -borderwidth */ #define BD_TABLE 0 #define BD_TABLE_TAG (1<<1) #define BD_TABLE_WIN (1<<2) /* * Possible state values for tags */ typedef enum { STATE_UNUSED, STATE_UNKNOWN, STATE_HIDDEN, STATE_NORMAL, STATE_DISABLED, STATE_ACTIVE, STATE_LAST } TableState; /* * Structure for use in parsing table commands/values. * Accessor functions defined in tkTableUtil.c */ typedef struct { char *name; /* name of the command/value */ int value; /* >0 because 0 represents an error or proc */ } Cmd_Struct; /* * The tag structure */ typedef struct { Tk_3DBorder bg; /* background color */ Tk_3DBorder fg; /* foreground color */ char * borderStr; /* border style */ int borders; /* number of borders specified (1, 2 or 4) */ int bd[4]; /* cell border width */ int relief; /* relief type */ Tk_Font tkfont; /* Information about text font, or NULL. */ Tk_Anchor anchor; /* default anchor point */ char * imageStr; /* name of image */ Tk_Image image; /* actual pointer to image, if any */ TableState state; /* state of the cell */ Tk_Justify justify; /* justification of text in the cell */ int multiline; /* wrapping style of multiline text */ int wrap; /* wrapping style of multiline text */ int showtext; /* whether to display text over image */ } TableTag; /* The widget structure for the table Widget */ typedef struct { /* basic information about the window and the interpreter */ Tk_Window tkwin; Display *display; Tcl_Interp *interp; Tcl_Command widgetCmd; /* Token for entry's widget command. */ /* * Configurable Options */ int autoClear; char *selectMode; /* single, browse, multiple, or extended */ int selectType; /* row, col, both, or cell */ int selectTitles; /* whether to do automatic title selection */ int rows, cols; /* number of rows and columns */ int defRowHeight; /* default row height in chars (positive) * or pixels (negative) */ int defColWidth; /* default column width in chars (positive) * or pixels (negative) */ int maxReqCols; /* the requested # cols to display */ int maxReqRows; /* the requested # rows to display */ int maxReqWidth; /* the maximum requested width in pixels */ int maxReqHeight; /* the maximum requested height in pixels */ Var arrayVar; /* name of traced array variable */ char *rowSep; /* separator string to place between * rows when getting selection */ char *colSep; /* separator string to place between * cols when getting selection */ TableTag defaultTag; /* the default tag colors/fonts etc */ LangCallback *yScrollCmd; /* the y-scroll command */ LangCallback *xScrollCmd; /* the x-scroll command */ LangCallback *browseCmd; /* the command that is called when the * active cell changes */ int caching; /* whether to cache values of table */ LangCallback *command; /* A command to eval when get/set occurs * for table values */ int useCmd; /* Signals whether to use command or the * array variable, will be 0 if command errs */ LangCallback *selCmd; /* the command that is called to when a * [selection get] call occurs for a table */ LangCallback *valCmd; /* Command prefix to use when invoking * validate command. NULL means don't * invoke commands. Malloc'ed. */ int validate; /* Non-zero means try to validate */ Tk_3DBorder insertBg; /* the cursor color */ Tk_Cursor cursor; /* the regular mouse pointer */ Tk_Cursor bdcursor; /* the mouse pointer when over borders */ #ifdef TITLE_CURSOR Tk_Cursor titleCursor; /* the mouse pointer when over titles */ #endif int exportSelection; /* Non-zero means tie internal table * to X selection. */ TableState state; /* Normal or disabled. Table is read-only * when disabled. */ int insertWidth; /* Total width of insert cursor. */ int insertBorderWidth; /* Width of 3-D border around insert cursor. */ int insertOnTime; /* Number of milliseconds cursor should spend * in "on" state for each blink. */ int insertOffTime; /* Number of milliseconds cursor should spend * in "off" state for each blink. */ int invertSelected; /* Whether to draw selected cells swapping * foreground and background */ int colStretch; /* The way to stretch columns if the window * is too large */ int rowStretch; /* The way to stretch rows if the window is * too large */ int colOffset; /* X index of leftmost col in the display */ int rowOffset; /* Y index of topmost row in the display */ int drawMode; /* The mode to use when redrawing */ int flashMode; /* Specifies whether flashing is enabled */ int flashTime; /* The number of ms to flash a cell for */ int resize; /* -resizeborders option for interactive * resizing of borders */ int sparse; /* Whether to use "sparse" arrays by * deleting empty array elements (default) */ LangCallback *rowTagCmd, *colTagCmd; /* script to eval for getting row/tag cmd */ int highlightWidth; /* Width in pixels of highlight to draw * around widget when it has the focus. * <= 0 means don't draw a highlight. */ XColor *highlightBgColorPtr;/* Color for drawing traversal highlight * area when highlight is off. */ XColor *highlightColorPtr; /* Color for drawing traversal highlight. */ char *takeFocus; /* Used only in Tcl to check if this * widget will accept focus */ int padX, padY; /* Extra space around text (pixels to leave * on each side). Ignored for bitmaps and * images. */ int ipadX, ipadY; /* Space to leave empty around cell borders. * This differs from pad* in that it is always * present for the cell (except windows). */ /* * Cached Information */ #ifdef TITLE_CURSOR Tk_Cursor *lastCursorPtr; /* pointer to last cursor defined. */ #endif int titleRows, titleCols; /* the number of rows|cols to use as a title */ /* these are kept in real coords */ int topRow, leftCol; /* The topleft cell to display excluding the * fixed title rows. This is just the * config request. The actual cell used may * be different to keep the screen full */ int anchorRow, anchorCol; /* the row,col of the anchor cell */ int activeRow, activeCol; /* the row,col of the active cell */ int oldTopRow, oldLeftCol; /* cached by TableAdjustParams */ int oldActRow, oldActCol; /* cached by TableAdjustParams */ int icursor; /* The index of the insertion cursor in the * active cell */ int flags; /* An or'ed combination of flags concerning * redraw/cursor etc. */ int dataSource; /* where our data comes from: * DATA_{NONE,CACHE,ARRAY,COMMAND} */ int maxWidth, maxHeight; /* max width|height required in pixels */ int charWidth, charHeight; /* size of a character in the default font */ int *colPixels, *rowPixels; /* Array of the pixel widths/heights */ int *colStarts, *rowStarts; /* Array of start pixels for rows|columns */ int scanMarkX, scanMarkY; /* Used by "scan" and "border" to mark */ int scanMarkRow, scanMarkCol;/* necessary information for dragto */ /* values in these are kept in user coords */ Tcl_HashTable *cache; /* value cache */ /* * colWidths and rowHeights are indexed from 0, so always adjust numbers * by the appropriate *Offset factor */ Tcl_HashTable *colWidths; /* hash table of non default column widths */ Tcl_HashTable *rowHeights; /* hash table of non default row heights */ Tcl_HashTable *spanTbl; /* table for spans */ Tcl_HashTable *spanAffTbl; /* table for cells affected by spans */ Tcl_HashTable *tagTable; /* table for style tags */ Tcl_HashTable *winTable; /* table for embedded windows */ Tcl_HashTable *rowStyles; /* table for row styles */ Tcl_HashTable *colStyles; /* table for col styles */ Tcl_HashTable *cellStyles; /* table for cell styles */ Tcl_HashTable *flashCells; /* table of flashing cells */ Tcl_HashTable *selCells; /* table of selected cells */ Tcl_TimerToken cursorTimer; /* timer token for the cursor blinking */ Tcl_TimerToken flashTimer; /* timer token for the cell flashing */ char *activeBuf; /* buffer where the selection is kept * for editing the active cell */ char **tagPrioNames; /* list of tag names in priority order */ TableTag **tagPrios; /* list of tag pointers in priority order */ TableTag *activeTagPtr; /* cache of active composite tag */ int activeX, activeY; /* cache offset of active layout in cell */ int tagPrioSize; /* size of tagPrios list */ int tagPrioMax; /* max allocated size of tagPrios list */ /* The invalid rectangle if there is an update pending */ int invalidX, invalidY, invalidWidth, invalidHeight; int seen[4]; /* see TableUndisplay */ #ifdef POSTSCRIPT /* Pointer to information used for generating Postscript for the canvas. * NULL means no Postscript is currently being generated. */ struct TkPostscriptInfo *psInfoPtr; #endif #ifdef PROCS Tcl_HashTable *inProc; /* cells where proc is being evaled */ int showProcs; /* whether to show embedded proc (1) or * its calculated value (0) */ int hasProcs; /* whether table has embedded procs or not */ #endif } Table; /* * HEADERS FOR EMBEDDED WINDOWS */ /* * A structure of the following type holds information for each window * embedded in a table widget. */ typedef struct TableEmbWindow { Table *tablePtr; /* Information about the overall table * widget. */ Tk_Window tkwin; /* Window for this segment. NULL means that * the window hasn't been created yet. */ Tcl_HashEntry *hPtr; /* entry into winTable */ LangCallback *create; /* Script to create window on-demand. * NULL means no such script. * Malloc-ed. */ Tk_3DBorder bg; /* background color */ char *borderStr; /* border style */ int borders; /* number of borders specified (1, 2 or 4) */ int bd[4]; /* border width for cell around window */ int relief; /* relief type */ int sticky; /* How to align window in space */ int padX, padY; /* Padding to leave around each side * of window, in pixels. */ int displayed; /* Non-zero means that the window has been * displayed on the screen recently. */ } TableEmbWindow; extern Tk_ConfigSpec tableSpecs[]; extern void EmbWinDisplay _ANSI_ARGS_((Table *tablePtr, Drawable window, TableEmbWindow *ewPtr, TableTag *tagPtr, int x, int y, int width, int height)); extern void EmbWinUnmap _ANSI_ARGS_((register Table *tablePtr, int rlo, int rhi, int clo, int chi)); extern void EmbWinDelete _ANSI_ARGS_((register Table *tablePtr, TableEmbWindow *ewPtr)); extern int Table_WinMove _ANSI_ARGS_((register Table *tablePtr, char *CONST srcPtr, char *CONST destPtr, int flags)); extern int Table_WinDelete _ANSI_ARGS_((register Table *tablePtr, char *CONST idxPtr)); extern int Table_WindowCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int TableValidateChange _ANSI_ARGS_((Table *tablePtr, int r, int c, char *oldVal, char *newVal, int idx)); extern void TableLostSelection _ANSI_ARGS_((ClientData clientData)); extern void TableSetActiveIndex _ANSI_ARGS_((register Table *tablePtr)); /* * HEADERS IN tkTableCmds.c */ extern int Table_ActivateCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_AdjustCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], int widthType)); extern int Table_BboxCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_BorderCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_ClearCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_CurselectionCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_CurvalueCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_GetCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_ScanCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_SeeCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_SelAnchorCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_SelClearCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_SelIncludesCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_SelSetCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_ViewCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); /* * HEADERS IN tkTableEdit.c */ extern int Table_EditCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern void TableDeleteChars _ANSI_ARGS_((register Table *tablePtr, int idx, int count)); extern void TableInsertChars _ANSI_ARGS_((register Table *tablePtr, int idx, char *string)); /* * HEADERS IN tkTableTag.c */ extern TableTag *TableNewTag _ANSI_ARGS_((Table *tablePtr)); extern void TableResetTag _ANSI_ARGS_((Table *tablePtr, TableTag *tagPtr)); extern void TableMergeTag _ANSI_ARGS_((Table *tablePtr, TableTag *baseTag, TableTag *addTag)); extern void TableInvertTag _ANSI_ARGS_((TableTag *baseTag)); extern int TableGetTagBorders _ANSI_ARGS_((TableTag *tagPtr, int *left, int *right, int *top, int *bottom)); extern void TableInitTags _ANSI_ARGS_((Table *tablePtr)); extern TableTag *FindRowColTag _ANSI_ARGS_((Table *tablePtr, int cell, int type)); extern void TableCleanupTag _ANSI_ARGS_((Table *tablePtr, TableTag *tagPtr)); extern int Table_TagCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); /* * HEADERS IN tkTableUtil.c */ extern void Table_ClearHashTable _ANSI_ARGS_((Tcl_HashTable *hashTblPtr)); extern int TableOptionBdSet _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, Arg value, char *widgRec, int offset)); extern Arg TableOptionBdGet _ANSI_ARGS_((ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)); extern int TableTagConfigureBd _ANSI_ARGS_((Table *tablePtr, TableTag *tagPtr, Arg oldValue, int nullOK)); extern int Cmd_OptionSet _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, Tk_Window unused, Arg value, char *widgRec, int offset)); extern Arg Cmd_OptionGet _ANSI_ARGS_((ClientData clientData, Tk_Window unused, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)); /* * HEADERS IN tkTableCell.c */ extern int TableTrueCell _ANSI_ARGS_((Table *tablePtr, int row, int col, int *trow, int *tcol)); extern int TableCellCoords _ANSI_ARGS_((Table *tablePtr, int row, int col, int *rx, int *ry, int *rw, int *rh)); extern int TableCellVCoords _ANSI_ARGS_((Table *tablePtr, int row, int col, int *rx, int *ry, int *rw, int *rh, int full)); extern void TableWhatCell _ANSI_ARGS_((register Table *tablePtr, int x, int y, int *row, int *col)); extern int TableAtBorder _ANSI_ARGS_((Table *tablePtr, int x, int y, int *row, int *col)); extern char * TableGetCellValue _ANSI_ARGS_((Table *tablePtr, int r, int c)); extern int TableSetCellValue _ANSI_ARGS_((Table *tablePtr, int r, int c, char *value)); extern int TableMoveCellValue _ANSI_ARGS_((Table *tablePtr, int fromr, int fromc, char *frombuf, int tor, int toc, char *tobuf, int outOfBounds)); extern int TableGetIcursor _ANSI_ARGS_((Table *tablePtr, char *arg, int *posn)); #define TableGetIcursorObj(tablePtr, objPtr, posnPtr) \ TableGetIcursor(tablePtr, Tcl_GetString(objPtr), posnPtr) extern int TableGetIndex _ANSI_ARGS_((register Table *tablePtr, char *str, int *row_p, int *col_p)); #define TableGetIndexObj(tablePtr, objPtr, rowPtr, colPtr) \ TableGetIndex(tablePtr, Tcl_GetString(objPtr), rowPtr, colPtr) extern int Table_SetCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_HiddenCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_SpanCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern void TableSpanSanCheck _ANSI_ARGS_((register Table *tablePtr)); /* * HEADERS IN TKTABLECELLSORT */ /* * We keep the old CellSort true because it is used for grabbing * the selection, so we really want them ordered */ extern Arg TableCellSort _ANSI_ARGS_((Table *tablePtr, char *str)); #ifdef NO_SORT_CELLS # define TableCellSortObj(interp, objPtr) (objPtr) #else extern Tcl_Obj* TableCellSortObj _ANSI_ARGS_((Tcl_Interp *interp, Tcl_Obj *listObjPtr)); #endif /* * HEADERS IN TKTABLEPS */ #ifdef POSTSCRIPT extern int Table_PostscriptCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern void Tcl_DStringAppendAll _ANSI_ARGS_(TCL_VARARGS(Tcl_DString *, arg1)); #endif /* * HEADERS IN TKTABLE */ EXTERN int Tktable_Init _ANSI_ARGS_((Tcl_Interp *interp)); EXTERN int Tktable_SafeInit _ANSI_ARGS_((Tcl_Interp *interp)); extern void TableGetActiveBuf _ANSI_ARGS_((register Table *tablePtr)); extern void ExpandPercents _ANSI_ARGS_((Table *tablePtr, char *before, int r, int c, char *oldVal, char *newVal, int idx, Tcl_DString *dsPtr, int cmdType)); extern void TableInvalidate _ANSI_ARGS_((Table *tablePtr, int x, int y, int width, int height, int force)); extern void TableRefresh _ANSI_ARGS_((register Table *tablePtr, int arg1, int arg2, int mode)); extern void TableGeometryRequest _ANSI_ARGS_((Table *tablePtr)); extern void TableAdjustActive _ANSI_ARGS_((register Table *tablePtr)); extern void TableAdjustParams _ANSI_ARGS_((register Table *tablePtr)); extern void TableConfigCursor _ANSI_ARGS_((register Table *tablePtr)); extern void TableAddFlash _ANSI_ARGS_((Table *tablePtr, int row, int col)); #define TableInvalidateAll(tablePtr, flags) \ TableInvalidate((tablePtr), 0, 0, Tk_Width((tablePtr)->tkwin),\ Tk_Height((tablePtr)->tkwin), (flags)) /* * Turn row/col into an index into the table */ #define TableMakeArrayIndex(r, c, i) sprintf((i), "%d,%d", (r), (c)) /* * Turn array index back into row/col * return the number of args parsed (should be two) */ #define TableParseArrayIndex(r, c, i) sscanf((i), "%d,%d", (r), (c)) /* * Macro for finding the last cell of the table */ #define TableGetLastCell(tablePtr, rowPtr, colPtr) \ TableWhatCell((tablePtr),\ Tk_Width((tablePtr)->tkwin)-(tablePtr)->highlightWidth-1,\ Tk_Height((tablePtr)->tkwin)-(tablePtr)->highlightWidth-1,\ (rowPtr), (colPtr)) EXTERN int Tk_TableObjCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); /* * end of header * reset TCL_STORAGE_CLASS to DLLIMPORT. */ #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT /* perltk tkTables replacement for TCL_unsetVar. deletes an element in a hash */ EXTERN void tkTableUnsetElement _ANSI_ARGS_((Var hashEntry, char * key)); #endif /* _TKTABLE_H_ */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable800/tkTableversion.h���������������������������������������������0000644�0000000�0000000�00000000317�13745605157�021222� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#if 0 TBL_MAJOR_VERSION = 2 TBL_MINOR_VERSION = 7 TBL_VERSION = $(TBL_MAJOR_VERSION).$(TBL_MINOR_VERSION) #endif #define TBL_MAJOR_VERSION 2 #define TBL_MINOR_VERSION 7 #define TBL_VERSION "2.7" �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable800/mac_tkTable_prefix.h�����������������������������������������0000644�0000000�0000000�00000002340�13745605157�022007� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Macintosh Tcl must be compiled with certain compiler options to * ensure that it will work correctly. The following pragmas are * used to ensure that those options are set correctly. An error * will occur at compile time if they are not set correctly. */ #if !__option(enumsalwaysint) #error Tcl requires the Metrowerks setting "Enums always ints". #endif #if !defined(__POWERPC__) #if !__option(far_data) #error Tcl requires the Metrowerks setting "Far data". #endif #endif #if !defined(__POWERPC__) #if !__option(fourbyteints) #error Tcl requires the Metrowerks setting "4 byte ints". #endif #endif #if !defined(__POWERPC__) #if !__option(IEEEdoubles) #error Tcl requires the Metrowerks setting "8 byte doubles". #endif #endif /* * The define is used most everywhere to tell Tcl (or any Tcl * extensions) that we are compiling for the Macintosh platform. */ #define MAC_TCL /* * The following defines control the behavior of the Macintosh * Universal Headers. */ #define SystemSevenOrLater 1 #define STRICT_CONTROLS 1 #define STRICT_WINDOWS 1 #define TBL_COMMAND "table" #define TBL_RUNTIME "tkTable.tcl" #define TBL_RUNTIME_DIR "{}" #include "../generic/version.h" ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable800/tkTableInitScript.h������������������������������������������0000644�0000000�0000000�00000005265�13745605157�021634� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * tkTableInitScript.h -- * * This file contains common init script for tkTable * * Copyright (c) 1998 Jeffrey Hobbs * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. */ /* * The following string is the startup script executed when the table is * loaded. It looks on disk in several different directories for a script * "TBL_RUNTIME" (as defined in Makefile) that is compatible with this * version of tkTable. The sourced script has all key bindings defined. */ static char tkTableInitScript[] = "if {[info proc tkTableInit]==\"\"} {\n\ proc tkTableInit {} {\n\ global tk_library tcl_pkgPath errorInfo env\n\ rename tkTableInit {}\n\ set errors {}\n\ if {![info exists env(TK_TABLE_LIBRARY_FILE)]} {\n\ set env(TK_TABLE_LIBRARY_FILE) " TBL_RUNTIME "\n\ }\n\ if {[info exists env(TK_TABLE_LIBRARY)]} {\n\ lappend dirs $env(TK_TABLE_LIBRARY)\n\ }\n\ lappend dirs " TBL_RUNTIME_DIR "\n\ if {[info exists tcl_pkgPath]} {\n\ foreach i $tcl_pkgPath {\n\ lappend dirs [file join $i Tktable" VERSION "] \\\n\ [file join $i Tktable] $i\n\ }\n\ }\n\ lappend dirs $tk_library [pwd]\n\ foreach i $dirs {\n\ set try [file join $i $env(TK_TABLE_LIBRARY_FILE)]\n\ if {[file exists $try]} {\n\ if {![catch {uplevel #0 [list source $try]} msg]} {\n\ set env(TK_TABLE_LIBRARY) $i\n\ return\n\ } else {\n\ append errors \"$try: $msg\n$errorInfo\n\"\n\ }\n\ }\n\ }\n" #ifdef NO_EMBEDDED_RUNTIME " set msg \"Can't find a $env(TK_TABLE_LIBRARY_FILE) in the following directories: \n\"\n\ append msg \" $dirs\n\n$errors\n\n\"\n\ append msg \"This probably means that TkTable wasn't installed properly.\"\n\ return -code error $msg\n" #else " set env(TK_TABLE_LIBRARY) EMBEDDED_RUNTIME\n" # ifdef MAC_TCL " source -rsrc tkTable" # else " uplevel #0 {" # include "tkTable.tcl.h" " }" # endif #endif " }\n\ }\n\ tkTableInit"; /* * The init script can't make certain calls in a safe interpreter, * so we always have to use the embedded runtime for it */ static char tkTableSafeInitScript[] = "if {[info proc tkTableInit]==\"\"} {\n\ proc tkTableInit {} {\n\ set env(TK_TABLE_LIBRARY) EMBEDDED_RUNTIME\n" #ifdef NO_EMBEDDED_RUNTIME " append msg \"tkTable requires embedded runtime to be compiled for\"\n\ append msg \" use in safe interpreters\"\n\ return -code error $msg\n" #endif # ifdef MAC_TCL " source -rsrc tkTable" # else " uplevel #0 {" # include "tkTable.tcl.h" " }" # endif " }\n\ }\n\ tkTableInit"; �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable800/tkTableCmds.c������������������������������������������������0000644�0000000�0000000�00000115161�13745605157�020422� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * tkTableCmds.c -- * * This module implements general commands of a table widget, * based on the major/minor command structure. * * Copyright (c) 1998-2002 Jeffrey Hobbs * * See the file "license.txt" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * */ #include "tkVMacro.h" #include "tkTable.h" /* *-------------------------------------------------------------- * * Table_ActivateCmd -- * This procedure is invoked to process the activate method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_ActivateCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int result = TCL_OK; int row, col; if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "index"); return TCL_ERROR; } else if (TableGetIndexObj(tablePtr, objv[2], &row, &col) != TCL_OK) { return TCL_ERROR; } else { int x, y, w, dummy; char buf1[INDEX_BUFSIZE], buf2[INDEX_BUFSIZE]; /* convert to valid active index in real coords */ row -= tablePtr->rowOffset; col -= tablePtr->colOffset; /* we do this regardless, to avoid cell commit problems */ if ((tablePtr->flags & HAS_ACTIVE) && (tablePtr->flags & TEXT_CHANGED)) { tablePtr->flags &= ~TEXT_CHANGED; TableSetCellValue(tablePtr, tablePtr->activeRow+tablePtr->rowOffset, tablePtr->activeCol+tablePtr->colOffset, tablePtr->activeBuf); } if (row != tablePtr->activeRow || col != tablePtr->activeCol) { if (tablePtr->flags & HAS_ACTIVE) { TableMakeArrayIndex(tablePtr->activeRow+tablePtr->rowOffset, tablePtr->activeCol+tablePtr->colOffset, buf1); } else { buf1[0] = '\0'; } tablePtr->flags |= HAS_ACTIVE; tablePtr->flags &= ~ACTIVE_DISABLED; tablePtr->activeRow = row; tablePtr->activeCol = col; if (tablePtr->activeTagPtr != NULL) { ckfree((char *) (tablePtr->activeTagPtr)); tablePtr->activeTagPtr = NULL; } TableAdjustActive(tablePtr); TableConfigCursor(tablePtr); if (!(tablePtr->flags & BROWSE_CMD) && tablePtr->browseCmd != NULL) { tablePtr->flags |= BROWSE_CMD; row = tablePtr->activeRow+tablePtr->rowOffset; col = tablePtr->activeCol+tablePtr->colOffset; TableMakeArrayIndex(row, col, buf2); result = LangDoCallback(interp, tablePtr->browseCmd, 1, 2, "%s %s",buf1,buf2); if (result == TCL_OK || result == TCL_RETURN) { Tcl_ResetResult(interp); } tablePtr->flags &= ~BROWSE_CMD; } } else { char *p = Tcl_GetString(objv[2]); if ((tablePtr->activeTagPtr != NULL) && *p == '@' && !(tablePtr->flags & ACTIVE_DISABLED) && TableCellVCoords(tablePtr, row, col, &x, &y, &w, &dummy, 0)) { /* we are clicking into the same cell * If it was activated with @x,y indexing, * find the closest char */ Tk_TextLayout textLayout; TableTag *tagPtr = tablePtr->activeTagPtr; /* no error checking because GetIndex did it for us */ p++; x = strtol(p, &p, 0) - x - tablePtr->activeX; y = strtol(++p, &p, 0) - y - tablePtr->activeY; textLayout = Tk_ComputeTextLayout(tagPtr->tkfont, tablePtr->activeBuf, -1, (tagPtr->wrap) ? w : 0, tagPtr->justify, 0, &dummy, &dummy); tablePtr->icursor = Tk_PointToChar(textLayout, x, y); Tk_FreeTextLayout(textLayout); TableRefresh(tablePtr, row, col, CELL|INV_FORCE); } } tablePtr->flags |= HAS_ACTIVE; } return result; } /* *-------------------------------------------------------------- * * Table_AdjustCmd -- * This procedure is invoked to process the width/height method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_AdjustCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], int widthType) { /* widthType is a Flag = 1 if this is a col width change command, otherwise assumed to be a row height change command */ register Table *tablePtr = (Table *) clientData; Tcl_HashEntry *entryPtr; Tcl_HashSearch search; Tcl_HashTable *hashTablePtr; int i, dummy, value, posn, offset; char buf1[INDEX_BUFSIZE]; /* changes the width/height of certain selected columns */ if (objc != 3 && (objc & 1)) { Tcl_WrongNumArgs(interp, 2, objv, widthType ? "?col? ?width col width ...?" : "?row? ?height row height ...?"); return TCL_ERROR; } if (widthType) { hashTablePtr = tablePtr->colWidths; offset = tablePtr->colOffset; } else { hashTablePtr = tablePtr->rowHeights; offset = tablePtr->rowOffset; } if (objc == 2) { /* print out all the preset column widths or row heights */ entryPtr = Tcl_FirstHashEntry(hashTablePtr, &search); while (entryPtr != NULL) { posn = ((int) Tcl_GetHashKey(hashTablePtr, entryPtr)) + offset; value = (int) Tcl_GetHashValue(entryPtr); sprintf(buf1, "%d %d", posn, value); /* OBJECTIFY */ Tcl_AppendElement(interp, buf1); entryPtr = Tcl_NextHashEntry(&search); } } else if (objc == 3) { /* get the width/height of a particular row/col */ if (Tcl_GetIntFromObj(interp, objv[2], &posn) != TCL_OK) { return TCL_ERROR; } /* no range check is done, why bother? */ posn -= offset; entryPtr = Tcl_FindHashEntry(hashTablePtr, (char *) posn); if (entryPtr != NULL) { Tcl_SetIntObj(Tcl_GetObjResult(interp), (int) Tcl_GetHashValue(entryPtr)); } else { Tcl_SetIntObj(Tcl_GetObjResult(interp), widthType ? tablePtr->defColWidth : tablePtr->defRowHeight); } } else { for (i=2; i<objc; i++) { /* set new width|height here */ value = -999999; if (Tcl_GetIntFromObj(interp, objv[i++], &posn) != TCL_OK || (strcmp(Tcl_GetString(objv[i]), "default") && Tcl_GetIntFromObj(interp, objv[i], &value) != TCL_OK)) { return TCL_ERROR; } posn -= offset; if (value == -999999) { /* reset that field */ entryPtr = Tcl_FindHashEntry(hashTablePtr, (char *) posn); if (entryPtr != NULL) { Tcl_DeleteHashEntry(entryPtr); } } else { entryPtr = Tcl_CreateHashEntry(hashTablePtr, (char *) posn, &dummy); Tcl_SetHashValue(entryPtr, (ClientData) value); } } TableAdjustParams(tablePtr); /* rerequest geometry */ TableGeometryRequest(tablePtr); /* * Invalidate the whole window as TableAdjustParams * will only check to see if the top left cell has moved * FIX: should just move from lowest order visible cell * to edge of window */ TableInvalidateAll(tablePtr, 0); } return TCL_OK; } /* *-------------------------------------------------------------- * * Table_BboxCmd -- * This procedure is invoked to process the bbox method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_BboxCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int x, y, w, h, row, col, key; Tcl_Obj *resultPtr; /* Returns bounding box of cell(s) */ if (objc < 3 || objc > 4) { Tcl_WrongNumArgs(interp, 2, objv, "first ?last?"); return TCL_ERROR; } else if (TableGetIndexObj(tablePtr, objv[2], &row, &col) == TCL_ERROR || (objc == 4 && TableGetIndexObj(tablePtr, objv[3], &x, &y) == TCL_ERROR)) { return TCL_ERROR; } resultPtr = Tcl_GetObjResult(interp); if (objc == 3) { row -= tablePtr->rowOffset; col -= tablePtr->colOffset; if (TableCellVCoords(tablePtr, row, col, &x, &y, &w, &h, 0)) { Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewIntObj(x)); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewIntObj(y)); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewIntObj(w)); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewIntObj(h)); } return TCL_OK; } else { int r1, c1, r2, c2, minX = 99999, minY = 99999, maxX = 0, maxY = 0; row -= tablePtr->rowOffset; col -= tablePtr->colOffset; x -= tablePtr->rowOffset; y -= tablePtr->colOffset; r1 = MIN(row,x); r2 = MAX(row,x); c1 = MIN(col,y); c2 = MAX(col,y); key = 0; for (row = r1; row <= r2; row++) { for (col = c1; col <= c2; col++) { if (TableCellVCoords(tablePtr, row, col, &x, &y, &w, &h, 0)) { /* Get max bounding box */ if (x < minX) minX = x; if (y < minY) minY = y; if (x+w > maxX) maxX = x+w; if (y+h > maxY) maxY = y+h; key++; } } } if (key) { Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewIntObj(minX)); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewIntObj(minY)); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewIntObj(maxX-minX)); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewIntObj(maxY-minY)); } } return TCL_OK; } static CONST84 char *bdCmdNames[] = { "mark", "dragto", (char *)NULL }; enum bdCmd { BD_MARK, BD_DRAGTO }; /* *-------------------------------------------------------------- * * Table_BorderCmd -- * This procedure is invoked to process the bbox method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_BorderCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; Tcl_HashEntry *entryPtr; int x, y, w, h, row, col, key, dummy, value, cmdIndex; char *rc = NULL; Tcl_Obj *objPtr, *resultPtr; if (objc < 5 || objc > 6) { Tcl_WrongNumArgs(interp, 2, objv, "mark|dragto x y ?row|col?"); return TCL_ERROR; } if (Tcl_GetIndexFromObj(interp, objv[2], bdCmdNames, "option", 0, &cmdIndex) != TCL_OK || Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK || Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK) { return TCL_ERROR; } if (objc == 6) { rc = Tcl_GetStringFromObj(objv[5], &w); if ((w < 1) || (strncmp(rc, "row", w) && strncmp(rc, "col", w))) { Tcl_WrongNumArgs(interp, 2, objv, "mark|dragto x y ?row|col?"); return TCL_ERROR; } } resultPtr = Tcl_GetObjResult(interp); switch ((enum bdCmd) cmdIndex) { case BD_MARK: /* Use x && y to determine if we are over a border */ value = TableAtBorder(tablePtr, x, y, &row, &col); /* Cache the row && col for use in DRAGTO */ tablePtr->scanMarkRow = row; tablePtr->scanMarkCol = col; if (!value) { return TCL_OK; } TableCellCoords(tablePtr, row, col, &x, &y, &dummy, &dummy); tablePtr->scanMarkX = x; tablePtr->scanMarkY = y; if (objc == 5 || *rc == 'r') { if (row < 0) { objPtr = Tcl_NewStringObj("", 0); } else { objPtr = Tcl_NewIntObj(row+tablePtr->rowOffset); } Tcl_ListObjAppendElement(NULL, resultPtr, objPtr); } if (objc == 5 || *rc == 'c') { if (col < 0) { objPtr = Tcl_NewStringObj("", 0); } else { objPtr = Tcl_NewIntObj(col+tablePtr->colOffset); } Tcl_ListObjAppendElement(NULL, resultPtr, objPtr); } return TCL_OK; /* BORDER MARK */ case BD_DRAGTO: /* check to see if we want to resize any borders */ if (tablePtr->resize == SEL_NONE) { return TCL_OK; } row = tablePtr->scanMarkRow; col = tablePtr->scanMarkCol; TableCellCoords(tablePtr, row, col, &w, &h, &dummy, &dummy); key = 0; if (row >= 0 && (tablePtr->resize & SEL_ROW)) { /* row border was active, move it */ value = y-h; if (value < -1) value = -1; if (value != tablePtr->scanMarkY) { entryPtr = Tcl_CreateHashEntry(tablePtr->rowHeights, (char *) row, &dummy); /* -value means rowHeight will be interp'd as pixels, not lines */ Tcl_SetHashValue(entryPtr, (ClientData) MIN(0,-value)); tablePtr->scanMarkY = value; key++; } } if (col >= 0 && (tablePtr->resize & SEL_COL)) { /* col border was active, move it */ value = x-w; if (value < -1) value = -1; if (value != tablePtr->scanMarkX) { entryPtr = Tcl_CreateHashEntry(tablePtr->colWidths, (char *) col, &dummy); /* -value means colWidth will be interp'd as pixels, not chars */ Tcl_SetHashValue(entryPtr, (ClientData) MIN(0,-value)); tablePtr->scanMarkX = value; key++; } } /* Only if something changed do we want to update */ if (key) { TableAdjustParams(tablePtr); /* Only rerequest geometry if the basis is the #rows &| #cols */ if (tablePtr->maxReqCols || tablePtr->maxReqRows) TableGeometryRequest(tablePtr); TableInvalidateAll(tablePtr, 0); } return TCL_OK; /* BORDER DRAGTO */ } return TCL_OK; } /* clear subcommands */ static CONST84 char *clearNames[] = { "all", "cache", "sizes", "tags", (char *)NULL }; enum clearCommand { CLEAR_ALL, CLEAR_CACHE, CLEAR_SIZES, CLEAR_TAGS }; /* *-------------------------------------------------------------- * * Table_ClearCmd -- * This procedure is invoked to process the clear method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * Cached info can be lost. Returns valid Tcl result. * * Side effects: * Can cause redraw. * See the user documentation. * *-------------------------------------------------------------- */ int Table_ClearCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int cmdIndex, redraw = 0; if (objc < 3 || objc > 5) { Tcl_WrongNumArgs(interp, 2, objv, "option ?first? ?last?"); return TCL_ERROR; } if (Tcl_GetIndexFromObj(interp, objv[2], clearNames, "clear option", 0, &cmdIndex) != TCL_OK) { return TCL_ERROR; } if (objc == 3) { if (cmdIndex == CLEAR_TAGS || cmdIndex == CLEAR_ALL) { Tcl_DeleteHashTable(tablePtr->rowStyles); Tcl_DeleteHashTable(tablePtr->colStyles); Tcl_DeleteHashTable(tablePtr->cellStyles); Tcl_DeleteHashTable(tablePtr->flashCells); Tcl_DeleteHashTable(tablePtr->selCells); /* style hash tables */ Tcl_InitHashTable(tablePtr->rowStyles, TCL_ONE_WORD_KEYS); Tcl_InitHashTable(tablePtr->colStyles, TCL_ONE_WORD_KEYS); Tcl_InitHashTable(tablePtr->cellStyles, TCL_STRING_KEYS); /* special style hash tables */ Tcl_InitHashTable(tablePtr->flashCells, TCL_STRING_KEYS); Tcl_InitHashTable(tablePtr->selCells, TCL_STRING_KEYS); } if (cmdIndex == CLEAR_SIZES || cmdIndex == CLEAR_ALL) { Tcl_DeleteHashTable(tablePtr->colWidths); Tcl_DeleteHashTable(tablePtr->rowHeights); /* style hash tables */ Tcl_InitHashTable(tablePtr->colWidths, TCL_ONE_WORD_KEYS); Tcl_InitHashTable(tablePtr->rowHeights, TCL_ONE_WORD_KEYS); } if (cmdIndex == CLEAR_CACHE || cmdIndex == CLEAR_ALL) { Table_ClearHashTable(tablePtr->cache); Tcl_InitHashTable(tablePtr->cache, TCL_STRING_KEYS); /* If we were caching and we have no other data source, * invalidate all the cells */ if (tablePtr->dataSource == DATA_CACHE) { TableGetActiveBuf(tablePtr); } } redraw = 1; } else { int row, col, r1, r2, c1, c2; Tcl_HashEntry *entryPtr; char buf[INDEX_BUFSIZE], *value; if (TableGetIndexObj(tablePtr, objv[3], &row, &col) != TCL_OK || ((objc == 5) && TableGetIndexObj(tablePtr, objv[4], &r2, &c2) != TCL_OK)) { return TCL_ERROR; } if (objc == 4) { r1 = r2 = row; c1 = c2 = col; } else { r1 = MIN(row,r2); r2 = MAX(row,r2); c1 = MIN(col,c2); c2 = MAX(col,c2); } for (row = r1; row <= r2; row++) { /* Note that *Styles entries are user based (no offset) * while size entries are 0-based (real) */ if ((cmdIndex == CLEAR_TAGS || cmdIndex == CLEAR_ALL) && (entryPtr = Tcl_FindHashEntry(tablePtr->rowStyles, (char *) row))) { Tcl_DeleteHashEntry(entryPtr); redraw = 1; } if ((cmdIndex == CLEAR_SIZES || cmdIndex == CLEAR_ALL) && (entryPtr = Tcl_FindHashEntry(tablePtr->rowHeights, (char *) row-tablePtr->rowOffset))) { Tcl_DeleteHashEntry(entryPtr); redraw = 1; } for (col = c1; col <= c2; col++) { TableMakeArrayIndex(row, col, buf); if (cmdIndex == CLEAR_TAGS || cmdIndex == CLEAR_ALL) { if ((row == r1) && (entryPtr = Tcl_FindHashEntry(tablePtr->colStyles, (char *) col))) { Tcl_DeleteHashEntry(entryPtr); redraw = 1; } if ((entryPtr = Tcl_FindHashEntry(tablePtr->cellStyles, buf))) { Tcl_DeleteHashEntry(entryPtr); redraw = 1; } if ((entryPtr = Tcl_FindHashEntry(tablePtr->flashCells, buf))) { Tcl_DeleteHashEntry(entryPtr); redraw = 1; } if ((entryPtr = Tcl_FindHashEntry(tablePtr->selCells, buf))) { Tcl_DeleteHashEntry(entryPtr); redraw = 1; } } if ((cmdIndex == CLEAR_SIZES || cmdIndex == CLEAR_ALL) && row == r1 && (entryPtr = Tcl_FindHashEntry(tablePtr->colWidths, (char *) col-tablePtr->colOffset))) { Tcl_DeleteHashEntry(entryPtr); redraw = 1; } if ((cmdIndex == CLEAR_CACHE || cmdIndex == CLEAR_ALL) && (entryPtr = Tcl_FindHashEntry(tablePtr->cache, buf))) { value = (char *) Tcl_GetHashValue(entryPtr); if (value) { ckfree(value); } Tcl_DeleteHashEntry(entryPtr); /* if the cache is our data source, * we need to invalidate the cells changed */ if ((tablePtr->dataSource == DATA_CACHE) && (row-tablePtr->rowOffset == tablePtr->activeRow && col-tablePtr->colOffset == tablePtr->activeCol)) TableGetActiveBuf(tablePtr); redraw = 1; } } } } /* This could be more sensitive about what it updates, * but that can actually be a lot more costly in some cases */ if (redraw) { if (cmdIndex == CLEAR_SIZES || cmdIndex == CLEAR_ALL) { TableAdjustParams(tablePtr); /* rerequest geometry */ TableGeometryRequest(tablePtr); } TableInvalidateAll(tablePtr, 0); } return TCL_OK; } /* *-------------------------------------------------------------- * * Table_CurselectionCmd -- * This procedure is invoked to process the bbox method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_CurselectionCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; Tcl_HashEntry *entryPtr; Tcl_HashSearch search; char *value = NULL; int row, col; if (objc > 3) { Tcl_WrongNumArgs(interp, 2, objv, "?value?"); return TCL_ERROR; } if (objc == 3) { /* make sure there is a data source to accept a set value */ if ((tablePtr->state == STATE_DISABLED) || (tablePtr->dataSource == DATA_NONE)) { return TCL_OK; } value = Tcl_GetString(objv[2]); for (entryPtr = Tcl_FirstHashEntry(tablePtr->selCells, &search); entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { TableParseArrayIndex(&row, &col, Tcl_GetHashKey(tablePtr->selCells, entryPtr)); TableSetCellValue(tablePtr, row, col, value); row -= tablePtr->rowOffset; col -= tablePtr->colOffset; if (row == tablePtr->activeRow && col == tablePtr->activeCol) { TableGetActiveBuf(tablePtr); } TableRefresh(tablePtr, row, col, CELL); } } else { Tcl_Obj *objPtr = Tcl_NewObj(); for (entryPtr = Tcl_FirstHashEntry(tablePtr->selCells, &search); entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { value = Tcl_GetHashKey(tablePtr->selCells, entryPtr); Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj(value, -1)); } Tcl_SetObjResult(interp, TableCellSortObj(interp, objPtr)); } return TCL_OK; } /* *-------------------------------------------------------------- * * Table_CurvalueCmd -- * This procedure is invoked to process the curvalue method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_CurvalueCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; if (objc > 3) { Tcl_WrongNumArgs(interp, 2, objv, "?<value>?"); return TCL_ERROR; } else if (!(tablePtr->flags & HAS_ACTIVE)) { return TCL_OK; } if (objc == 3) { char *value; int len; value = Tcl_GetStringFromObj(objv[2], &len); if (STREQ(value, tablePtr->activeBuf)) { Tcl_SetObjResult(interp, objv[2]); return TCL_OK; } /* validate potential new active buffer contents * only accept if validation returns acceptance. */ if (tablePtr->validate && TableValidateChange(tablePtr, tablePtr->activeRow+tablePtr->rowOffset, tablePtr->activeCol+tablePtr->colOffset, tablePtr->activeBuf, value, tablePtr->icursor) != TCL_OK) { return TCL_OK; } tablePtr->activeBuf = (char *)ckrealloc(tablePtr->activeBuf, len+1); strcpy(tablePtr->activeBuf, value); /* mark the text as changed */ tablePtr->flags |= TEXT_CHANGED; TableSetActiveIndex(tablePtr); /* check for possible adjustment of icursor */ TableGetIcursor(tablePtr, "insert", (int *)0); TableRefresh(tablePtr, tablePtr->activeRow, tablePtr->activeCol, CELL); } Tcl_SetStringObj(Tcl_GetObjResult(interp), tablePtr->activeBuf, -1); return TCL_OK; } /* *-------------------------------------------------------------- * * Table_GetCmd -- * This procedure is invoked to process the bbox method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_GetCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int result = TCL_OK; int r1, c1, r2, c2, row, col; if (objc < 3 || objc > 4) { Tcl_WrongNumArgs(interp, 2, objv, "first ?last?"); result = TCL_ERROR; } else if (TableGetIndexObj(tablePtr, objv[2], &row, &col) == TCL_ERROR) { result = TCL_ERROR; } else if (objc == 3) { Tcl_SetObjResult(interp, Tcl_NewStringObj(TableGetCellValue(tablePtr, row, col), -1)); } else if (TableGetIndexObj(tablePtr, objv[3], &r2, &c2) == TCL_ERROR) { result = TCL_ERROR; } else { Tcl_Obj *objPtr = Tcl_NewObj(); r1 = MIN(row,r2); r2 = MAX(row,r2); c1 = MIN(col,c2); c2 = MAX(col,c2); for ( row = r1; row <= r2; row++ ) { for ( col = c1; col <= c2; col++ ) { Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj(TableGetCellValue(tablePtr, row, col), -1)); } } Tcl_SetObjResult(interp, objPtr); } return result; } /* *-------------------------------------------------------------- * * Table_ScanCmd -- * This procedure is invoked to process the scan method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_ScanCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int x, y, row, col, cmdIndex; if (objc != 5) { Tcl_WrongNumArgs(interp, 2, objv, "mark|dragto x y"); return TCL_ERROR; } else if (Tcl_GetIndexFromObj(interp, objv[2], bdCmdNames, "option", 0, &cmdIndex) != TCL_OK || Tcl_GetIntFromObj(interp, objv[3], &x) == TCL_ERROR || Tcl_GetIntFromObj(interp, objv[4], &y) == TCL_ERROR) { return TCL_ERROR; } switch ((enum bdCmd) cmdIndex) { case BD_MARK: TableWhatCell(tablePtr, x, y, &row, &col); tablePtr->scanMarkRow = row-tablePtr->topRow; tablePtr->scanMarkCol = col-tablePtr->leftCol; tablePtr->scanMarkX = x; tablePtr->scanMarkY = y; break; case BD_DRAGTO: { int oldTop = tablePtr->topRow, oldLeft = tablePtr->leftCol; y += (5*(y-tablePtr->scanMarkY)); x += (5*(x-tablePtr->scanMarkX)); TableWhatCell(tablePtr, x, y, &row, &col); /* maintain appropriate real index */ tablePtr->topRow = BETWEEN(row-tablePtr->scanMarkRow, tablePtr->titleRows, tablePtr->rows-1); tablePtr->leftCol = BETWEEN(col-tablePtr->scanMarkCol, tablePtr->titleCols, tablePtr->cols-1); /* Adjust the table if new top left */ if (oldTop != tablePtr->topRow || oldLeft != tablePtr->leftCol) { TableAdjustParams(tablePtr); } break; } } return TCL_OK; } /* *-------------------------------------------------------------- * * Table_SelAnchorCmd -- * This procedure is invoked to process the selection anchor method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_SelAnchorCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int row, col; if (objc != 4) { Tcl_WrongNumArgs(interp, 3, objv, "index"); return TCL_ERROR; } else if (TableGetIndexObj(tablePtr, objv[3], &row, &col) != TCL_OK) { return TCL_ERROR; } tablePtr->flags |= HAS_ANCHOR; /* maintain appropriate real index */ if (tablePtr->selectTitles) { tablePtr->anchorRow = BETWEEN(row-tablePtr->rowOffset, 0, tablePtr->rows-1); tablePtr->anchorCol = BETWEEN(col-tablePtr->colOffset, 0, tablePtr->cols-1); } else { tablePtr->anchorRow = BETWEEN(row-tablePtr->rowOffset, tablePtr->titleRows, tablePtr->rows-1); tablePtr->anchorCol = BETWEEN(col-tablePtr->colOffset, tablePtr->titleCols, tablePtr->cols-1); } return TCL_OK; } /* *-------------------------------------------------------------- * * Table_SelClearCmd -- * This procedure is invoked to process the selection clear method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_SelClearCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int result = TCL_OK; char buf1[INDEX_BUFSIZE]; int row, col, key, clo=0,chi=0,r1,c1,r2,c2; Tcl_HashEntry *entryPtr; if (objc < 4 || objc > 5) { Tcl_WrongNumArgs(interp, 3, objv, "all|<first> ?<last>?"); return TCL_ERROR; } if (STREQ(Tcl_GetString(objv[3]), "all")) { Tcl_HashSearch search; for(entryPtr = Tcl_FirstHashEntry(tablePtr->selCells, &search); entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { TableParseArrayIndex(&row, &col, Tcl_GetHashKey(tablePtr->selCells,entryPtr)); Tcl_DeleteHashEntry(entryPtr); TableRefresh(tablePtr, row-tablePtr->rowOffset, col-tablePtr->colOffset, CELL); } return TCL_OK; } if (TableGetIndexObj(tablePtr, objv[3], &row, &col) == TCL_ERROR || (objc==5 && TableGetIndexObj(tablePtr, objv[4], &r2, &c2) == TCL_ERROR)) { return TCL_ERROR; } key = 0; if (objc == 4) { r1 = r2 = row; c1 = c2 = col; } else { r1 = MIN(row,r2); r2 = MAX(row,r2); c1 = MIN(col,c2); c2 = MAX(col,c2); } switch (tablePtr->selectType) { case SEL_BOTH: clo = c1; chi = c2; c1 = tablePtr->colOffset; c2 = tablePtr->cols-1+c1; key = 1; goto CLEAR_CELLS; CLEAR_BOTH: key = 0; c1 = clo; c2 = chi; case SEL_COL: r1 = tablePtr->rowOffset; r2 = tablePtr->rows-1+r1; break; case SEL_ROW: c1 = tablePtr->colOffset; c2 = tablePtr->cols-1+c1; break; } /* row/col are in user index coords */ CLEAR_CELLS: for ( row = r1; row <= r2; row++ ) { for ( col = c1; col <= c2; col++ ) { TableMakeArrayIndex(row, col, buf1); entryPtr = Tcl_FindHashEntry(tablePtr->selCells, buf1); if (entryPtr != NULL) { Tcl_DeleteHashEntry(entryPtr); TableRefresh(tablePtr, row-tablePtr->rowOffset, col-tablePtr->colOffset, CELL); } } } if (key) goto CLEAR_BOTH; return result; } /* *-------------------------------------------------------------- * * Table_SelIncludesCmd -- * This procedure is invoked to process the selection includes method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_SelIncludesCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int row, col; if (objc != 4) { Tcl_WrongNumArgs(interp, 3, objv, "index"); return TCL_ERROR; } else if (TableGetIndexObj(tablePtr, objv[3], &row, &col) == TCL_ERROR) { return TCL_ERROR; } else { char buf[INDEX_BUFSIZE]; TableMakeArrayIndex(row, col, buf); Tcl_SetBooleanObj(Tcl_GetObjResult(interp), (Tcl_FindHashEntry(tablePtr->selCells, buf)!=NULL)); } return TCL_OK; } /* *-------------------------------------------------------------- * * Table_SelSetCmd -- * This procedure is invoked to process the selection set method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_SelSetCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int row, col, dummy, key; char buf1[INDEX_BUFSIZE]; Tcl_HashSearch search; Tcl_HashEntry *entryPtr; int clo=0, chi=0, r1, c1, r2, c2, firstRow, firstCol, lastRow, lastCol; if (objc < 4 || objc > 5) { Tcl_WrongNumArgs(interp, 3, objv, "first ?last?"); return TCL_ERROR; } if (TableGetIndexObj(tablePtr, objv[3], &row, &col) == TCL_ERROR || (objc==5 && TableGetIndexObj(tablePtr, objv[4], &r2, &c2) == TCL_ERROR)) { return TCL_ERROR; } key = 0; lastRow = tablePtr->rows-1+tablePtr->rowOffset; lastCol = tablePtr->cols-1+tablePtr->colOffset; if (tablePtr->selectTitles) { firstRow = tablePtr->rowOffset; firstCol = tablePtr->colOffset; } else { firstRow = tablePtr->titleRows+tablePtr->rowOffset; firstCol = tablePtr->titleCols+tablePtr->colOffset; } /* maintain appropriate user index */ CONSTRAIN(row, firstRow, lastRow); CONSTRAIN(col, firstCol, lastCol); if (objc == 4) { r1 = r2 = row; c1 = c2 = col; } else { CONSTRAIN(r2, firstRow, lastRow); CONSTRAIN(c2, firstCol, lastCol); r1 = MIN(row,r2); r2 = MAX(row,r2); c1 = MIN(col,c2); c2 = MAX(col,c2); } switch (tablePtr->selectType) { case SEL_BOTH: if (firstCol > lastCol) c2--; /* No selectable columns in table */ if (firstRow > lastRow) r2--; /* No selectable rows in table */ clo = c1; chi = c2; c1 = firstCol; c2 = lastCol; key = 1; goto SET_CELLS; SET_BOTH: key = 0; c1 = clo; c2 = chi; case SEL_COL: r1 = firstRow; r2 = lastRow; if (firstCol > lastCol) c2--; /* No selectable columns in table */ break; case SEL_ROW: c1 = firstCol; c2 = lastCol; if (firstRow>lastRow) r2--; /* No selectable rows in table */ break; } SET_CELLS: entryPtr = Tcl_FirstHashEntry(tablePtr->selCells, &search); for ( row = r1; row <= r2; row++ ) { for ( col = c1; col <= c2; col++ ) { TableMakeArrayIndex(row, col, buf1); if (Tcl_FindHashEntry(tablePtr->selCells, buf1) == NULL) { Tcl_CreateHashEntry(tablePtr->selCells, buf1, &dummy); TableRefresh(tablePtr, row-tablePtr->rowOffset, col-tablePtr->colOffset, CELL); } } } if (key) goto SET_BOTH; /* Adjust the table for top left, selection on screen etc */ TableAdjustParams(tablePtr); /* If the table was previously empty and we want to export the * selection, we should grab it now */ if (entryPtr == NULL && tablePtr->exportSelection) { Tk_OwnSelection(tablePtr->tkwin, XA_PRIMARY, TableLostSelection, (ClientData) tablePtr); } return TCL_OK; } /* *-------------------------------------------------------------- * * Table_ViewCmd -- * This procedure is invoked to process the x|yview method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_ViewCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int row, col, value; char *xy; /* Check xview or yview */ if (objc > 5) { Tcl_WrongNumArgs(interp, 2, objv, "?args?"); return TCL_ERROR; } xy = Tcl_GetString(objv[1]); if (objc == 2) { Tcl_Obj *resultPtr; int diff, x, y, w, h; double first, last; resultPtr = Tcl_GetObjResult(interp); TableGetLastCell(tablePtr, &row, &col); TableCellVCoords(tablePtr, row, col, &x, &y, &w, &h, 0); if (*xy == 'y') { if (row < tablePtr->titleRows) { first = 0; last = 1; } else { diff = tablePtr->rowStarts[tablePtr->titleRows]; last = (double) (tablePtr->rowStarts[tablePtr->rows]-diff); first = (tablePtr->rowStarts[tablePtr->topRow]-diff) / last; last = (h+tablePtr->rowStarts[row]-diff) / last; } } else { if (col < tablePtr->titleCols) { first = 0; last = 1; } else { diff = tablePtr->colStarts[tablePtr->titleCols]; last = (double) (tablePtr->colStarts[tablePtr->cols]-diff); first = (tablePtr->colStarts[tablePtr->leftCol]-diff) / last; last = (w+tablePtr->colStarts[col]-diff) / last; } } Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewDoubleObj(first)); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewDoubleObj(last)); } else { /* cache old topleft to see if it changes */ int oldTop = tablePtr->topRow, oldLeft = tablePtr->leftCol; if (objc == 3) { if (Tcl_GetIntFromObj(interp, objv[2], &value) != TCL_OK) { return TCL_ERROR; } if (*xy == 'y') { tablePtr->topRow = value + tablePtr->titleRows; } else { tablePtr->leftCol = value + tablePtr->titleCols; } } else { int result; double frac; #if (TK_MINOR_VERSION > 0) /* 8.1+ */ result = Tk_GetScrollInfoObj(interp, objc, objv, &frac, &value); #else int i; Arg * args = (Arg *) ckalloc((objc + 1) * sizeof(Arg)); for (i = 0; i < objc; i++) { args[i] = LangStringArg(Tcl_GetString(objv[i])); } args[i] = NULL; result = Tk_GetScrollInfo(interp, objc, args, &frac, &value); ckfree ((char * ) args); #endif switch (result) { case TK_SCROLL_ERROR: return TCL_ERROR; case TK_SCROLL_MOVETO: if (frac < 0) frac = 0; if (*xy == 'y') { tablePtr->topRow = (int)(frac*tablePtr->rows) +tablePtr->titleRows; } else { tablePtr->leftCol = (int)(frac*tablePtr->cols) +tablePtr->titleCols; } break; case TK_SCROLL_PAGES: TableGetLastCell(tablePtr, &row, &col); if (*xy == 'y') { tablePtr->topRow += value * (row-tablePtr->topRow+1); } else { tablePtr->leftCol += value * (col-tablePtr->leftCol+1); } break; case TK_SCROLL_UNITS: if (*xy == 'y') { tablePtr->topRow += value; } else { tablePtr->leftCol += value; } break; } } /* maintain appropriate real index */ CONSTRAIN(tablePtr->topRow, tablePtr->titleRows, tablePtr->rows-1); CONSTRAIN(tablePtr->leftCol, tablePtr->titleCols, tablePtr->cols-1); /* Do the table adjustment if topRow || leftCol changed */ if (oldTop != tablePtr->topRow || oldLeft != tablePtr->leftCol) { TableAdjustParams(tablePtr); } } return TCL_OK; } #if 0 /* *-------------------------------------------------------------- * * Table_Cmd -- * This procedure is invoked to process the CMD method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_Cmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int result = TCL_OK; return result; } #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable800/makefile.vc��������������������������������������������������0000644�0000000�0000000�00000011144�13745605157�020164� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Makefile.vc # # This makefile builds Tktable.dll, a table widget as a dynamically # loadable Tk extension. This makefile is suitable for use with # Microsoft Visual C++ 4-5. # TkTable assumes that Tcl/Tk has already been installed on Windows. # # This does not provide support for static builds on Windows # !include <ntwin32.mak> #Get version info (this is in Makefile and C format) !include "version.h" PROJECT = Tktable TBL_COMMAND = table TBL_RUNTIME = tkTable.tcl # Project directories -- these may need to be customized for your site # # ROOT -- location of the source files. # TMPDIR -- location for .obj files. # TOOLS32 -- location of VC++ compiler installation. # DESTDIR -- location of Tcl/Tk installation hierarchy # DESTDIRU -- same as above with "/" as path separator # ROOT = . TMPDIR = . TOOLS32 = C:\Progra~1\DevStudio\Vc DESTDIR = C:\Progra~1\Tcl DESTDIRU = C:/Progra~1/Tcl # Set your version of Tcl TCL_VERSION = 8.1 TK_VERSION = 8.1 TCL_LIB_V = 81 TK_LIB_V = 81 INST_RUNTIME = $(DESTDIR)\lib\tkTable$(TBL_VERSION) INST_RUNTIMEU = $(DESTDIRU)/lib/tkTable$(TBL_VERSION) # NO_EMBEDDED_RUNTIME means that the tkTable.tcl file will not be embedded # into the executable, thus the default tkTable.tcl library file will not # be available when the library is loaded. # If this is defined, the tkTable.tcl file must be available in a # predefined set of directories (see docs). #TBL_CFLAGS += -DNO_EMBEDDED_RUNTIME # comment the following line to compile with symbols NODEBUG=1 # Necessary for some partially-installed VC++ setups: #INCLUDE="$(TOOLS32)\include" #LIB="$(TOOLS32)\lib" # # Visual C++ tools # PATH=$(TOOLS32)\bin;$(PATH) cc32 = "$(TOOLS32)\bin\cl" -I"$(TOOLS32)\include" CP = copy RM = del ###################################################################### # Project specific targets ###################################################################### TBL_LIBDIR = $(ROOT)\..\lib # Assume that WISH is already INSTALLED TCLSH = $(DESTDIR)\bin\tclsh$(TCL_LIB_V) WISH = $(DESTDIR)\bin\wish$(TK_LIB_V) LIBS = $(DESTDIR)\lib\tcl$(TCL_LIB_V).lib $(DESTDIR)\lib\tk$(TK_LIB_V).lib INCLUDES = -I"$(TOOLS32)\include" -I"$(DESTDIR)\include" DEFINES = -DDLL_BUILD -DBUILD_tkTable $(TBL_CFLAGS) \ -DTBL_VERSION=\"$(TBL_VERSION)\" \ -DTBL_COMMAND=\"$(TBL_COMMAND)\" \ -DTBL_RUNTIME="\"$(TBL_RUNTIME)\"" \ -DTBL_RUNTIME_DIR="\"$(INST_RUNTIMEU)\"" # # Global makefile settings # DLLOBJS = $(TMPDIR)\tkTable.obj $(TMPDIR)\tkTableWin.obj $(TMPDIR)\tkTableTag.obj $(TMPDIR)\tkTableEdit.obj $(TMPDIR)\tkTableCell.obj $(TMPDIR)\tkTableCmds.obj $(TMPDIR)\cmd.obj # $(TMPDIR)\tkTablePs.obj DLL=$(PROJECT).dll # Targets all: pkgIndex.tcl test: pkgIndex.tcl @"$(WISH)" << lappend auto_path $(ROOT) set code [catch { package require $(PROJECT) pack [$(TBL_COMMAND) .t] } msg] if {$$code != 0} { tk_messageBox -type ok -message\ "$(PROJECT) failed to load and run: $$msg" } else { tk_messageBox -type ok -message\ "everything seems OK for 'package require $(PROJECT)'" } exit $$code << pkgIndex.tcl: $(DLL) "$(TCLSH)" << pkgIndex.tcl set out [open [lindex $$argv 0] w] puts $$out {if {[catch {package require Tcl $(TCL_VERSION)}]} return} puts -nonewline $$out {package ifneeded $(PROJECT) $(TBL_VERSION) } puts -nonewline $$out {"package require Tk $(TK_VERSION); } puts $$out {[list load [file join $$dir $(DLL)] $(PROJECT)]"} close $$out << $(DLLOBJS): tkTable.tcl.h $(DLL): $(DLLOBJS) $(link) $(linkdebug) $(dlllflags) $(LIBS) \ $(guilibsdll) -out:$(DLL) $(DLLOBJS) tkTable.tcl.h: $(TBL_LIBDIR)\tkTable.tcl "$(TCLSH)" << $(TBL_LIBDIR)\tkTable.tcl >$(TMPDIR)\tkTable.tcl.h set in [open [lindex $$argv 0] r] while {[gets $$in line] != -1} { switch -regexp -- $$line "^$$" - {^#} continue regsub -all {\\} $$line {\\\\} line regsub -all {"} $$line {\"} line puts "\"$$line\\n\"" } << # Implicit Targets .c.obj: $(cc32) $(cdebug) $(cflags) $(cvarsdll) \ $(INCLUDES) $(DEFINES) -Fo$(TMPDIR)\ $< install: if not exist "$(INST_RUNTIME)\" mkdir "$(INST_RUNTIME)" copy "$(TBL_LIBDIR)\tkTable.tcl" "$(INST_RUNTIME)" copy "$(DLL)" "$(INST_RUNTIME)" copy pkgIndex.tcl "$(INST_RUNTIME)" uninstall: -$(RM) "$(INST_RUNTIME)\tkTable.tcl" -$(RM) "$(INST_RUNTIME)\$(DLL)" -$(RM) "$(INST_RUNTIME)\pkgIndex.tcl" clean: -$(RM) $(TMPDIR)\*.obj 2>nul -$(RM) $(DLL) 2>nul -$(RM) $(PROJECT).lib 2>nul -$(RM) $(PROJECT).exp 2>nul -$(RM) pkgIndex.tcl 2>nul -$(RM) $(TMPDIR)\tkTable.tcl.h 2>nul ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable800/tkTablePs.c��������������������������������������������������0000644�0000000�0000000�00000123643�13745605157�020122� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * tkTablePs.c -- * * This module implements postscript output for table widgets. * Based off of Tk8.1a2 tkCanvPs.c. * * Copyright (c) 1991-1994 The Regents of the University of California. * Copyright (c) 1994-1997 Sun Microsystems, Inc. * changes 1998 Copyright (c) 1998 Jeffrey Hobbs * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * */ /* Currently generating postscript */ #define POSTSCRIPT #include "tkVMacro.h" #include "tkTable.h" /* This is for Tcl_DStringAppendAll */ #if defined(__STDC__) || defined(HAS_STDARG) #include <stdarg.h> #else #include <varargs.h> #endif #ifndef TCL_INTEGER_SPACE /* This appears in 8.1 */ #define TCL_INTEGER_SPACE 24 #endif /* * One of the following structures is created to keep track of Postscript * output being generated. It consists mostly of information provided on * the widget command line. */ typedef struct TkPostscriptInfo { int x, y, width, height; /* Area to print, in table pixel * coordinates. */ int x2, y2; /* x+width and y+height. */ char *pageXString; /* String value of "-pagex" option or NULL. */ char *pageYString; /* String value of "-pagey" option or NULL. */ double pageX, pageY; /* Postscript coordinates (in points) * corresponding to pageXString and * pageYString. Don't forget that y-values * grow upwards for Postscript! */ char *pageWidthString; /* Printed width of output. */ char *pageHeightString; /* Printed height of output. */ double scale; /* Scale factor for conversion: each pixel * maps into this many points. */ Tk_Anchor pageAnchor; /* How to anchor bbox on Postscript page. */ int rotate; /* Non-zero means output should be rotated * on page (landscape mode). */ Var fontVar; /* If non-NULL, gives name of global variable * containing font mapping information. * Malloc'ed. */ Var colorVar; /* If non-NULL, give name of global variable * containing color mapping information. * Malloc'ed. */ char *colorMode; /* Mode for handling colors: "monochrome", * "gray", or "color". Malloc'ed. */ int colorLevel; /* Numeric value corresponding to colorMode: * 0 for mono, 1 for gray, 2 for color. */ char *fileName; /* Name of file in which to write Postscript; * NULL means return Postscript info as * result. Malloc'ed. */ char *channelName; /* If -channel is specified, the name of * the channel to use. */ Tcl_Channel chan; /* Open channel corresponding to fileName. */ Tcl_HashTable fontTable; /* Hash table containing names of all font * families used in output. The hash table * values are not used. */ char *first, *last; /* table indices to start and end at */ } TkPostscriptInfo; /* * The table below provides a template that's used to process arguments * to the table "postscript" command and fill in TkPostscriptInfo * structures. */ static Tk_ConfigSpec configSpecs[] = { {TK_CONFIG_SCALARVAR, "-colormap", (char *) NULL, (char *) NULL, "", Tk_Offset(TkPostscriptInfo, colorVar), 0}, {TK_CONFIG_STRING, "-colormode", (char *) NULL, (char *) NULL, "", Tk_Offset(TkPostscriptInfo, colorMode), 0}, {TK_CONFIG_STRING, "-file", (char *) NULL, (char *) NULL, "", Tk_Offset(TkPostscriptInfo, fileName), 0}, {TK_CONFIG_STRING, "-channel", (char *) NULL, (char *) NULL, "", Tk_Offset(TkPostscriptInfo, channelName), 0}, {TK_CONFIG_STRING, "-first", (char *) NULL, (char *) NULL, "", Tk_Offset(TkPostscriptInfo, first), 0}, {TK_CONFIG_SCALARVAR, "-fontmap", (char *) NULL, (char *) NULL, "", Tk_Offset(TkPostscriptInfo, fontVar), 0}, {TK_CONFIG_PIXELS, "-height", (char *) NULL, (char *) NULL, "", Tk_Offset(TkPostscriptInfo, height), 0}, {TK_CONFIG_STRING, "-last", (char *) NULL, (char *) NULL, "", Tk_Offset(TkPostscriptInfo, last), 0}, {TK_CONFIG_ANCHOR, "-pageanchor", (char *) NULL, (char *) NULL, "", Tk_Offset(TkPostscriptInfo, pageAnchor), 0}, {TK_CONFIG_STRING, "-pageheight", (char *) NULL, (char *) NULL, "", Tk_Offset(TkPostscriptInfo, pageHeightString), 0}, {TK_CONFIG_STRING, "-pagewidth", (char *) NULL, (char *) NULL, "", Tk_Offset(TkPostscriptInfo, pageWidthString), 0}, {TK_CONFIG_STRING, "-pagex", (char *) NULL, (char *) NULL, "", Tk_Offset(TkPostscriptInfo, pageXString), 0}, {TK_CONFIG_STRING, "-pagey", (char *) NULL, (char *) NULL, "", Tk_Offset(TkPostscriptInfo, pageYString), 0}, {TK_CONFIG_BOOLEAN, "-rotate", (char *) NULL, (char *) NULL, "", Tk_Offset(TkPostscriptInfo, rotate), 0}, {TK_CONFIG_PIXELS, "-width", (char *) NULL, (char *) NULL, "", Tk_Offset(TkPostscriptInfo, width), 0}, {TK_CONFIG_PIXELS, "-x", (char *) NULL, (char *) NULL, "", Tk_Offset(TkPostscriptInfo, x), 0}, {TK_CONFIG_PIXELS, "-y", (char *) NULL, (char *) NULL, "", Tk_Offset(TkPostscriptInfo, y), 0}, {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL, (char *) NULL, 0, 0} }; /* * The prolog data. Generated by str2c from prolog.ps * This was split in small chunks by str2c because * some C compiler have limitations on the size of static strings. * (str2c is a small tcl script in tcl's tool directory (source release)) */ /* * This is a stripped down version of that found in tkCanvPs.c of Tk8.1a2. * Comments, and stuff pertaining to stipples and other unused entities * have been removed */ static CONST char * CONST prolog[]= { /* Start of part 1 */ "%%BeginProlog\n\ 50 dict begin\n\ \n\ % This is standard prolog for Postscript generated by Tk's table widget.\n\ % Based of standard prolog for Tk's canvas widget.\n\ \n\ % INITIALIZING VARIABLES\n\ \n\ /baseline 0 def\n\ /height 0 def\n\ /justify 0 def\n\ /cellHeight 0 def\n\ /cellWidth 0 def\n\ /spacing 0 def\n\ /strings 0 def\n\ /xoffset 0 def\n\ /yoffset 0 def\n\ /x 0 def\n\ /y 0 def\n\ \n\ % Define the array ISOLatin1Encoding, if it isn't already present.\n\ \n\ systemdict /ISOLatin1Encoding known not {\n\ /ISOLatin1Encoding [\n\ /space /space /space /space /space /space /space /space\n\ /space /space /space /space /space /space /space /space\n\ /space /space /space /space /space /space /space /space\n\ /space /space /space /space /space /space /space /space\n\ /space /exclam /quotedbl /numbersign /dollar /percent /ampersand\n\ /quoteright\n\ /parenleft /parenright /asterisk /plus /comma /minus /period /slash\n\ /zero /one /two /three /four /five /six /seven\n\ /eight /nine /colon /semicolon /less /equal /greater /question\n\ /at /A /B /C /D /E /F /G\n\ /H /I /J /K /L /M /N /O\n\ /P /Q /R /S /T /U /V /W\n\ /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore\n\ /quoteleft /a /b /c /d /e /f /g\n\ /h /i /j /k /l /m /n /o\n\ /p /q /r /s /t /u /v /w\n\ /x /y /z /braceleft /bar /braceright /asciitilde /space\n\ /space /space /space /space /space /space /space /space\n\ /space /space /space /space /space /space /space /space\n\ /dotlessi /grave /acute /circumflex /tilde /macron /breve /dotaccent\n\ /dieresis /space /ring /cedilla /space /hungarumlaut /ogonek /caron\n\ /space /exclamdown /cent /sterling /currency /yen /brokenbar /section\n\ /dieresis /copyright /ordfem", "inine /guillemotleft /logicalnot /hyphen\n\ /registered /macron\n\ /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph\n\ /periodcentered\n\ /cedillar /onesuperior /ordmasculine /guillemotright /onequarter\n\ /onehalf /threequarters /questiondown\n\ /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla\n\ /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex\n\ /Idieresis\n\ /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply\n\ /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn\n\ /germandbls\n\ /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla\n\ /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex\n\ /idieresis\n\ /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide\n\ /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn\n\ /ydieresis\n\ ] def\n\ } if\n", "\n\ % font ISOEncode font\n\ % This procedure changes the encoding of a font from the default\n\ % Postscript encoding to ISOLatin1. It's typically invoked just\n\ % before invoking \"setfont\". The body of this procedure comes from\n\ % Section 5.6.1 of the Postscript book.\n\ \n\ /ISOEncode {\n\ dup length dict begin\n\ {1 index /FID ne {def} {pop pop} ifelse} forall\n\ /Encoding ISOLatin1Encoding def\n\ currentdict\n\ end\n\ \n\ % I'm not sure why it's necessary to use \"definefont\" on this new\n\ % font, but it seems to be important; just use the name \"Temporary\"\n\ % for the font.\n\ \n\ /Temporary exch definefont\n\ } bind def\n\ \n\ % -- AdjustColor --\n\ % Given a color value already set for output by the caller, adjusts\n\ % that value to a grayscale or mono value if requested by the CL variable.\n\ \n\ /AdjustColor {\n\ setrgbcolor\n\ CL 2 lt {\n\ currentgray\n\ CL 0 eq {\n\ .5 lt {0} {1} ifelse\n\ } if\n\ setgray\n\ } if\n\ } bind def\n\ \n\ % pointSize fontName SetFont\n\ % The ISOEncode shouldn't be done to Symbol fonts...\n\ /SetFont {\n\ findfont exch scalefont ISOEncode setfont\n\ } def\n\ \n", "% x y strings spacing xoffset yoffset justify ... DrawText --\n\ % This procedure does all of the real work of drawing text. The\n\ % color and font must already have been set by the caller, and the\n\ % following arguments must be on the stack:\n\ %\n\ % x, y - Coordinates at which to draw text.\n\ % strings - An array of strings, one for each line of the text item,\n\ % in order from top to bottom.\n\ % spacing - Spacing between lines.\n\ % xoffset - Horizontal offset for text bbox relative to x and y: 0 for\n\ % nw/w/sw anchor, -0.5 for n/center/s, and -1.0 for ne/e/se.\n\ % yoffset - Vertical offset for text bbox relative to x and y: 0 for\n\ % nw/n/ne anchor, +0.5 for w/center/e, and +1.0 for sw/s/se.\n\ % justify - 0 for left justification, 0.5 for center, 1 for right justify.\n\ % cellWidth - width for this cell\n\ % cellHeight - height for this cell\n\ %\n\ % Also, when this procedure is invoked, the color and font must already\n\ % have been set for the text.\n\ \n", "/DrawCellText {\n\ /cellHeight exch def\n\ /cellWidth exch def\n\ /justify exch def\n\ /yoffset exch def\n\ /xoffset exch def\n\ /spacing exch def\n\ /strings exch def\n\ /y exch def\n\ /x exch def\n\ \n\ % Compute the baseline offset and the actual font height.\n\ \n\ 0 0 moveto (TXygqPZ) false charpath\n\ pathbbox dup /baseline exch def\n\ exch pop exch sub /height exch def pop\n\ newpath\n\ \n\ % Translate coordinates first so that the origin is at the upper-left\n\ % corner of the text's bounding box. Remember that x and y for\n\ % positioning are still on the stack.\n\ \n\ col0 x sub row0 y sub translate\n\ cellWidth xoffset mul\n\ strings length 1 sub spacing mul height add yoffset mul translate\n\ \n\ % Now use the baseline and justification information to translate so\n\ % that the origin is at the baseline and positioning point for the\n\ % first line of text.\n\ \n\ justify cellWidth mul baseline neg translate\n\ \n\ % Iterate over each of the lines to output it. For each line,\n\ % compute its width again so it can be properly justified, then\n\ % display it.\n\ \n\ strings {\n\ dup stringwidth pop\n\ justify neg mul 0 moveto\n\ show\n\ 0 spacing neg translate\n\ } forall\n\ } bind def\n\ \n", "%\n\ % x, y - Coordinates at which to draw text.\n\ % strings - An array of strings, one for each line of the text item,\n\ % in order from top to bottom.\n\ % spacing - Spacing between lines.\n\ % xoffset - Horizontal offset for text bbox relative to x and y: 0 for\n\ % nw/w/sw anchor, -0.5 for n/center/s, and -1.0 for ne/e/se.\n\ % yoffset - Vertical offset for text bbox relative to x and y: 0 for\n\ % nw/n/ne anchor, +0.5 for w/center/e, and +1.0 for sw/s/se.\n\ % justify - 0 for left justification, 0.5 for center, 1 for right justify.\n\ % cellWidth - width for this cell\n\ % cellHeight - height for this cell\n\ %\n\ % Also, when this procedure is invoked, the color and font must already\n\ % have been set for the text.\n\ \n\ /DrawCellTextOld {\n\ /cellHeight exch def\n\ /cellWidth exch def\n\ /justify exch def\n\ /yoffset exch def\n\ /xoffset exch def\n\ /spacing exch def\n\ /strings exch def\n\ \n\ % Compute the baseline offset and the actual font height.\n\ \n\ 0 0 moveto (TXygqPZ) false charpath\n\ pathbbox dup /baseline exch def\n\ exch pop exch sub /height exch def pop\n\ newpath\n\ \n\ % Translate coordinates first so that the origin is at the upper-left\n\ % corner of the text's bounding box. Remember that x and y for\n\ % positioning are still on the stack.\n\ \n\ translate\n\ cellWidth xoffset mul\n\ strings length 1 sub spacing mul height add yoffset mul translate\n\ \n\ % Now use the baseline and justification information to translate so\n\ % that the origin is at the baseline and positioning point for the\n\ % first line of text.\n\ \n\ justify cellWidth mul baseline neg translate\n\ \n\ % Iterate over each of the lines to output it. For each line,\n\ % compute its width again so it can be properly justified, then\n\ % display it.\n\ \n\ strings {\n\ dup stringwidth pop\n\ justify neg mul 0 moveto\n\ show\n\ 0 spacing neg translate\n\ } forall\n\ } bind def\n\ \n\ %%EndProlog\n\ ", /* End of part 5 */ NULL /* End of data marker */ }; /* * Forward declarations for procedures defined later in this file: */ static int GetPostscriptPoints _ANSI_ARGS_((Tcl_Interp *interp, char *string, double *doublePtr)); int Tk_TablePsFont _ANSI_ARGS_((Tcl_Interp *interp, Table *tablePtr, Tk_Font tkfont)); int Tk_TablePsColor _ANSI_ARGS_((Tcl_Interp *interp, Table *tablePtr, XColor *colorPtr)); static int TextToPostscript _ANSI_ARGS_((Tcl_Interp *interp, Table *tablePtr, TableTag *tagPtr, int tagX, int tagY, int width, int height, int row, int col, Tk_TextLayout textLayout)); /* * Tcl could really use some more convenience routines... * This is just Tcl_DStringAppend for multiple lines, including * the full text of each line */ void Tcl_DStringAppendAll TCL_VARARGS_DEF(Tcl_DString *, arg1) { va_list argList; Tcl_DString *dstringPtr; char *string; dstringPtr = TCL_VARARGS_START(Tcl_DString *, arg1, argList); while ((string = va_arg(argList, char *)) != NULL) { Tcl_DStringAppend(dstringPtr, string, -1); } va_end(argList); } /* *-------------------------------------------------------------- * * Table_PostscriptCmd -- * * This procedure is invoked to process the "postscript" options * of the widget command for table widgets. See the user * documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ /* ARGSUSED */ int Table_PostscriptCmd(clientData, interp, objc, objv) ClientData clientData; /* Information about table widget. */ Tcl_Interp *interp; /* Current interpreter. */ int objc; /* Number of argument objects. */ Tcl_Obj *CONST objv[]; { #ifdef _WIN32 /* * At the moment, it just doesn't like this code... */ return TCL_OK; #else register Table *tablePtr = (Table *) clientData; TkPostscriptInfo psInfo, *oldInfoPtr; int result; int row, col, firstRow, firstCol, lastRow, lastCol; /* dimensions of first and last cell to output */ int x0, y0, w0, h0, xn, yn, wn, hn; int x, y, w, h, i; #define STRING_LENGTH 400 char string[STRING_LENGTH+1], *p; Arg *args; size_t length; int deltaX = 0, deltaY = 0; /* Offset of lower-left corner of area to * be marked up, measured in table units * from the positioning point on the page * (reflects anchor position). Initial * values needed only to stop compiler * warnings. */ Tcl_HashSearch search; Tcl_HashEntry *hPtr; CONST char * CONST *chunk; Tk_TextLayout textLayout = NULL; char *value; int rowHeight, total, *colWidths, iW, iH; TableTag *tagPtr, *colPtr, *rowPtr, *titlePtr; Tcl_DString postscript, buffer; if (objc < 2) { Tcl_WrongNumArgs(interp, 2, objv, "?option value ...?"); return TCL_ERROR; } /* *---------------------------------------------------------------- * Initialize the data structure describing Postscript generation, * then process all the arguments to fill the data structure in. *---------------------------------------------------------------- */ Tcl_DStringInit(&postscript); Tcl_DStringInit(&buffer); oldInfoPtr = tablePtr->psInfoPtr; tablePtr->psInfoPtr = &psInfo; /* This is where in the window that we start printing from */ psInfo.x = 0; psInfo.y = 0; psInfo.width = -1; psInfo.height = -1; psInfo.pageXString = NULL; psInfo.pageYString = NULL; psInfo.pageX = 72*4.25; psInfo.pageY = 72*5.5; psInfo.pageWidthString = NULL; psInfo.pageHeightString = NULL; psInfo.scale = 1.0; psInfo.pageAnchor = TK_ANCHOR_CENTER; psInfo.rotate = 0; psInfo.fontVar = NULL; psInfo.colorVar = NULL; psInfo.colorMode = NULL; psInfo.colorLevel = 0; psInfo.fileName = NULL; psInfo.channelName = NULL; psInfo.chan = NULL; psInfo.first = NULL; psInfo.last = NULL; Tcl_InitHashTable(&psInfo.fontTable, TCL_STRING_KEYS); /* * The magic StringifyObjects */ args = (Arg *) ckalloc((objc + 1) * sizeof(Arg)); for (i = 0; i < objc; i++) args[i] = LangStringArg(Tcl_GetString(objv[i])); args[i] = NULL; result = Tk_ConfigureWidget(interp, tablePtr->tkwin, configSpecs, objc-2, args+2, (char *) &psInfo, TK_CONFIG_ARGV_ONLY); if (result != TCL_OK) { goto cleanup; } if (psInfo.first == NULL) { firstRow = 0; firstCol = 0; } else if (TableGetIndex(tablePtr, psInfo.first, &firstRow, &firstCol) != TCL_OK) { result = TCL_ERROR; goto cleanup; } if (psInfo.last == NULL) { lastRow = tablePtr->rows-1; lastCol = tablePtr->cols-1; } else if (TableGetIndex(tablePtr, psInfo.last, &lastRow, &lastCol) != TCL_OK) { result = TCL_ERROR; goto cleanup; } if (psInfo.fileName != NULL) { /* Check that -file and -channel are not both specified. */ if (psInfo.channelName != NULL) { Tcl_AppendResult(interp, "can't specify both -file", " and -channel", (char *) NULL); result = TCL_ERROR; goto cleanup; } /* * Check that we are not in a safe interpreter. If we are, disallow * the -file specification. */ if (Tcl_IsSafe(interp)) { Tcl_AppendResult(interp, "can't specify -file in a", " safe interpreter", (char *) NULL); result = TCL_ERROR; goto cleanup; } p = Tcl_TranslateFileName(interp, psInfo.fileName, &buffer); if (p == NULL) { result = TCL_ERROR; goto cleanup; } psInfo.chan = Tcl_OpenFileChannel(interp, p, "w", 0666); Tcl_DStringFree(&buffer); Tcl_DStringInit(&buffer); if (psInfo.chan == NULL) { result = TCL_ERROR; goto cleanup; } } if (psInfo.channelName != NULL) { int mode; /* * Check that the channel is found in this interpreter and that it * is open for writing. */ psInfo.chan = Tcl_GetChannel(interp, psInfo.channelName, &mode); if (psInfo.chan == (Tcl_Channel) NULL) { result = TCL_ERROR; goto cleanup; } if ((mode & TCL_WRITABLE) == 0) { Tcl_AppendResult(interp, "channel \"", psInfo.channelName, "\" wasn't opened for writing", (char *) NULL); result = TCL_ERROR; goto cleanup; } } if (psInfo.colorMode == NULL) { psInfo.colorLevel = 2; } else { length = strlen(psInfo.colorMode); if (strncmp(psInfo.colorMode, "monochrome", length) == 0) { psInfo.colorLevel = 0; } else if (strncmp(psInfo.colorMode, "gray", length) == 0) { psInfo.colorLevel = 1; } else if (strncmp(psInfo.colorMode, "color", length) == 0) { psInfo.colorLevel = 2; } else { Tcl_AppendResult(interp, "bad color mode \"", psInfo.colorMode, "\": must be monochrome, gray or color", (char *) NULL); goto cleanup; } } TableCellCoords(tablePtr, firstRow, firstCol, &x0, &y0, &w0, &h0); TableCellCoords(tablePtr, lastRow, lastCol, &xn, &yn, &wn, &hn); psInfo.x = x0; psInfo.y = y0; if (psInfo.width == -1) { psInfo.width = xn+wn; } if (psInfo.height == -1) { psInfo.height = yn+hn; } psInfo.x2 = psInfo.x + psInfo.width; psInfo.y2 = psInfo.y + psInfo.height; if (psInfo.pageXString != NULL) { if (GetPostscriptPoints(interp, psInfo.pageXString, &psInfo.pageX) != TCL_OK) { goto cleanup; } } if (psInfo.pageYString != NULL) { if (GetPostscriptPoints(interp, psInfo.pageYString, &psInfo.pageY) != TCL_OK) { goto cleanup; } } if (psInfo.pageWidthString != NULL) { if (GetPostscriptPoints(interp, psInfo.pageWidthString, &psInfo.scale) != TCL_OK) { goto cleanup; } psInfo.scale /= psInfo.width; } else if (psInfo.pageHeightString != NULL) { if (GetPostscriptPoints(interp, psInfo.pageHeightString, &psInfo.scale) != TCL_OK) { goto cleanup; } psInfo.scale /= psInfo.height; } else { psInfo.scale = (72.0/25.4)*WidthMMOfScreen(Tk_Screen(tablePtr->tkwin)) / WidthOfScreen(Tk_Screen(tablePtr->tkwin)); } switch (psInfo.pageAnchor) { case TK_ANCHOR_NW: case TK_ANCHOR_W: case TK_ANCHOR_SW: deltaX = 0; break; case TK_ANCHOR_N: case TK_ANCHOR_CENTER: case TK_ANCHOR_S: deltaX = -psInfo.width/2; break; case TK_ANCHOR_NE: case TK_ANCHOR_E: case TK_ANCHOR_SE: deltaX = -psInfo.width; break; } switch (psInfo.pageAnchor) { case TK_ANCHOR_NW: case TK_ANCHOR_N: case TK_ANCHOR_NE: deltaY = - psInfo.height; break; case TK_ANCHOR_W: case TK_ANCHOR_CENTER: case TK_ANCHOR_E: deltaY = -psInfo.height/2; break; case TK_ANCHOR_SW: case TK_ANCHOR_S: case TK_ANCHOR_SE: deltaY = 0; break; } /* *-------------------------------------------------------- * Make a PREPASS over all of the tags * to collect information about all the fonts in use, so that * we can output font information in the proper form required * by the Document Structuring Conventions. *-------------------------------------------------------- */ Tk_TablePsFont(interp, tablePtr, tablePtr->defaultTag.tkfont); Tcl_ResetResult(interp); for (hPtr = Tcl_FirstHashEntry(tablePtr->tagTable, &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { tagPtr = (TableTag *) Tcl_GetHashValue(hPtr); if (tagPtr->tkfont != NULL) { Tk_TablePsFont(interp, tablePtr, tagPtr->tkfont); } } Tcl_ResetResult(interp); /* *-------------------------------------------------------- * Generate the header and prolog for the Postscript. *-------------------------------------------------------- */ sprintf(string, " %d,%d => %d,%d\n", firstRow, firstCol, lastRow, lastCol); Tcl_DStringAppendAll(&postscript, "%!PS-Adobe-3.0 EPSF-3.0\n", "%%Creator: Tk Table Widget ", TBL_VERSION, "\n", "%%Title: Window ", Tk_PathName(tablePtr->tkwin), string, "%%BoundingBox: ", (char *) NULL); if (!psInfo.rotate) { sprintf(string, "%d %d %d %d\n", (int) (psInfo.pageX + psInfo.scale*deltaX), (int) (psInfo.pageY + psInfo.scale*deltaY), (int) (psInfo.pageX + psInfo.scale*(deltaX + psInfo.width) + 1.0), (int) (psInfo.pageY + psInfo.scale*(deltaY + psInfo.height) + 1.0)); } else { sprintf(string, "%d %d %d %d\n", (int) (psInfo.pageX - psInfo.scale*(deltaY + psInfo.height)), (int) (psInfo.pageY + psInfo.scale*deltaX), (int) (psInfo.pageX - psInfo.scale*deltaY + 1.0), (int) (psInfo.pageY + psInfo.scale*(deltaX + psInfo.width) + 1.0)); } Tcl_DStringAppendAll(&postscript, string, "%%Pages: 1\n%%DocumentData: Clean7Bit\n", "%%Orientation: ", psInfo.rotate?"Landscape\n":"Portrait\n", (char *) NULL); p = "%%DocumentNeededResources: font "; for (hPtr = Tcl_FirstHashEntry(&psInfo.fontTable, &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { sprintf(string, "%s%s\n", p, Tcl_GetHashKey(&psInfo.fontTable, hPtr)); Tcl_DStringAppend(&postscript, string, -1); p = "%%+ font "; } Tcl_DStringAppend(&postscript, "%%EndComments\n\n", -1); /* * Insert the prolog */ for (chunk=prolog; *chunk; chunk++) { Tcl_DStringAppend(&postscript, *chunk, -1); } if (psInfo.chan != NULL) { Tcl_Write(psInfo.chan, Tcl_DStringValue(&postscript), -1); Tcl_DStringFree(&postscript); Tcl_DStringInit(&postscript); } /* * Document setup: set the color level and include fonts. * This is where we start using &postscript */ sprintf(string, "/CL %d def\n", psInfo.colorLevel); Tcl_DStringAppendAll(&postscript, "%%BeginSetup\n", string, (char *) NULL); for (hPtr = Tcl_FirstHashEntry(&psInfo.fontTable, &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { sprintf(string, "%s%s\n", "%%IncludeResource: font ", Tcl_GetHashKey(&psInfo.fontTable, hPtr)); Tcl_DStringAppend(&postscript, string, -1); } Tcl_DStringAppend(&postscript, "%%EndSetup\n\n", -1); /* * Page setup: move to page positioning point, rotate if * needed, set scale factor, offset for proper anchor position, * and set clip region. */ sprintf(string, "%.1f %.1f translate\n", psInfo.pageX, psInfo.pageY); Tcl_DStringAppendAll(&postscript, "%%Page: 1 1\nsave\n", string, psInfo.rotate?"90 rotate\n":"", (char *) NULL); sprintf(string, "%.4g %.4g scale\n%d %d translate\n", psInfo.scale, psInfo.scale, deltaX - psInfo.x, deltaY); Tcl_DStringAppend(&postscript, string, -1); sprintf(string, "%d %.15g moveto %d %.15g lineto %d %.15g lineto %d %.15g", psInfo.x, (double) psInfo.y2-psInfo.y, psInfo.x2,(double) psInfo.y2-psInfo.y, psInfo.x2, 0.0, psInfo.x, 0.0); Tcl_DStringAppend(&postscript, string, -1); Tcl_DStringAppend(&postscript, " lineto closepath clip newpath\n", -1); if (psInfo.chan != NULL) { Tcl_Write(psInfo.chan, Tcl_DStringValue(&postscript), -1); Tcl_DStringFree(&postscript); Tcl_DStringInit(&postscript); } /* * Go through each cell, calculating full desired height */ result = TCL_OK; hPtr = Tcl_FindHashEntry(tablePtr->tagTable, "title"); titlePtr = (TableTag *) Tcl_GetHashValue(hPtr); total = 0; colWidths = (int *) ckalloc((lastCol-firstCol) * sizeof(int)); for (col = 0; col <= lastCol-firstCol; col++) colWidths[col] = 0; Tcl_DStringAppend(&buffer, "gsave\n", -1); for (row = firstRow; row <= lastRow; row++) { rowHeight = 0; rowPtr = FindRowColTag(tablePtr, row+tablePtr->rowOffset, ROW); for (col = firstCol; col <= lastCol; col++) { /* get the coordinates for the cell */ TableCellCoords(tablePtr, row, col, &x, &y, &w, &h); if ((x >= psInfo.x2) || (x+w < psInfo.x) || (y >= psInfo.y2) || (y+h < psInfo.y)) { continue; } if (row == tablePtr->activeRow && col == tablePtr->activeCol) { value = tablePtr->activeBuf; } else { value = TableGetCellValue(tablePtr, row+tablePtr->rowOffset, col+tablePtr->colOffset); } if (!strlen(value)) { continue; } /* Create the tag here */ tagPtr = TableNewTag(); /* First, merge in the default tag */ TableMergeTag(tagPtr, &(tablePtr->defaultTag)); colPtr = FindRowColTag(tablePtr, col+tablePtr->colOffset, COL); if (colPtr != (TableTag *) NULL) TableMergeTag(tagPtr, colPtr); if (rowPtr != (TableTag *) NULL) TableMergeTag(tagPtr, rowPtr); /* Am I in the titles */ if (row < tablePtr->topRow || col < tablePtr->leftCol) { TableMergeTag(tagPtr, titlePtr); } /* Does this have a cell tag */ TableMakeArrayIndex(row+tablePtr->rowOffset, col+tablePtr->colOffset, string); hPtr = Tcl_FindHashEntry(tablePtr->cellStyles, string); if (hPtr != NULL) { TableMergeTag(tagPtr, (TableTag *) Tcl_GetHashValue(hPtr)); } /* * the use of -1 instead of Tcl_NumUtfChars means we don't * pass NULLs to postscript */ textLayout = Tk_ComputeTextLayout(tagPtr->tkfont, value, -1, (tagPtr->wrap>0) ? w : 0, tagPtr->justify, (tagPtr->multiline>0) ? 0 : TK_IGNORE_NEWLINES, &iW, &iH); rowHeight = MAX(rowHeight, iH); colWidths[col-firstCol] = MAX(colWidths[col-firstCol], iW); result = TextToPostscript(interp, tablePtr, tagPtr, x, y, iW, iH, row, col, textLayout); Tk_FreeTextLayout(textLayout); if (result != TCL_OK) { char msg[64 + TCL_INTEGER_SPACE]; sprintf(msg, "\n (generating Postscript for cell %s)", string); Tcl_AddErrorInfo(interp, msg); goto cleanup; } Tcl_DStringAppend(&buffer, Tcl_GetResult(interp), -1); } sprintf(string, "/row%d %d def\n", row, tablePtr->psInfoPtr->y2 - total); Tcl_DStringAppend(&postscript, string, -1); total += rowHeight + 2*tablePtr->defaultTag.bd; } Tcl_DStringAppend(&buffer, "grestore\n", -1); sprintf(string, "/row%d %d def\n", row, tablePtr->psInfoPtr->y2 - total); Tcl_DStringAppend(&postscript, string, -1); total = tablePtr->defaultTag.bd; for (col = firstCol; col <= lastCol; col++) { sprintf(string, "/col%d %d def\n", col, total); Tcl_DStringAppend(&postscript, string, -1); total += colWidths[col-firstCol] + 2*tablePtr->defaultTag.bd; } sprintf(string, "/col%d %d def\n", col, total); Tcl_DStringAppend(&postscript, string, -1); Tcl_DStringAppend(&postscript, Tcl_DStringValue(&buffer), -1); /* * Output to channel at the end of it all * This should more incremental, but that can't be avoided in order * to post-define width/height of the cols/rows */ if (psInfo.chan != NULL) { Tcl_Write(psInfo.chan, Tcl_DStringValue(&postscript), -1); Tcl_DStringFree(&postscript); Tcl_DStringInit(&postscript); } /* *--------------------------------------------------------------------- * Output page-end information, such as commands to print the page * and document trailer stuff. *--------------------------------------------------------------------- */ Tcl_DStringAppend(&postscript, "restore showpage\n\n%%Trailer\nend\n%%EOF\n", -1); if (psInfo.chan != NULL) { Tcl_Write(psInfo.chan, Tcl_DStringValue(&postscript), -1); Tcl_DStringFree(&postscript); Tcl_DStringInit(&postscript); } /* * Clean up psInfo to release malloc'ed stuff. */ cleanup: ckfree((char *) args); Tcl_DStringResult(interp, &postscript); Tcl_DStringFree(&postscript); Tcl_DStringFree(&buffer); if (psInfo.first != NULL) { ckfree(psInfo.first); } if (psInfo.last != NULL) { ckfree(psInfo.last); } if (psInfo.pageXString != NULL) { ckfree(psInfo.pageXString); } if (psInfo.pageYString != NULL) { ckfree(psInfo.pageYString); } if (psInfo.pageWidthString != NULL) { ckfree(psInfo.pageWidthString); } if (psInfo.pageHeightString != NULL) { ckfree(psInfo.pageHeightString); } if (psInfo.fontVar != NULL) { LangFreeVar(psInfo.fontVar); } if (psInfo.colorVar != NULL) { LangFreeVar(psInfo.colorVar); } if (psInfo.colorMode != NULL) { ckfree(psInfo.colorMode); } if (psInfo.fileName != NULL) { ckfree(psInfo.fileName); } if ((psInfo.chan != NULL) && (psInfo.channelName == NULL)) { Tcl_Close(interp, psInfo.chan); } if (psInfo.channelName != NULL) { ckfree(psInfo.channelName); } Tcl_DeleteHashTable(&psInfo.fontTable); tablePtr->psInfoPtr = oldInfoPtr; return result; #endif } /* *-------------------------------------------------------------- * * Tk_TablePsColor -- * * This procedure is called by individual table items when * they want to set a color value for output. Given information * about an X color, this procedure will generate Postscript * commands to set up an appropriate color in Postscript. * * Results: * Returns a standard Tcl return value. If an error occurs * then an error message will be left in the interp's result. * If no error occurs, then additional Postscript will be * appended to the interp's result. * * Side effects: * None. * *-------------------------------------------------------------- */ int Tk_TablePsColor(interp, tablePtr, colorPtr) Tcl_Interp *interp; /* Interpreter for returning Postscript * or error message. */ Table *tablePtr; /* Information about table. */ XColor *colorPtr; /* Information about color. */ { TkPostscriptInfo *psInfoPtr = tablePtr->psInfoPtr; int tmp; double red, green, blue; char string[200]; /* * If there is a color map defined, then look up the color's name * in the map and use the Postscript commands found there, if there * are any. */ if (psInfoPtr->colorVar != NULL) { Arg cmdString; cmdString = Tcl_GetVar2(interp, psInfoPtr->colorVar, Tk_NameOfColor(colorPtr), 0); if (cmdString != NULL) { Tcl_AppendResult(interp, LangString(cmdString), "\n", (char *) NULL); return TCL_OK; } } /* * No color map entry for this color. Grab the color's intensities * and output Postscript commands for them. Special note: X uses * a range of 0-65535 for intensities, but most displays only use * a range of 0-255, which maps to (0, 256, 512, ... 65280) in the * X scale. This means that there's no way to get perfect white, * since the highest intensity is only 65280 out of 65535. To * work around this problem, rescale the X intensity to a 0-255 * scale and use that as the basis for the Postscript colors. This * scheme still won't work if the display only uses 4 bits per color, * but most diplays use at least 8 bits. */ tmp = colorPtr->red; red = ((double) (tmp >> 8))/255.0; tmp = colorPtr->green; green = ((double) (tmp >> 8))/255.0; tmp = colorPtr->blue; blue = ((double) (tmp >> 8))/255.0; sprintf(string, "%.3f %.3f %.3f AdjustColor\n", red, green, blue); Tcl_AppendResult(interp, string, (char *) NULL); return TCL_OK; } /* *-------------------------------------------------------------- * * Tk_TablePsFont -- * * This procedure is called by individual table items when * they want to output text. Given information about an X * font, this procedure will generate Postscript commands * to set up an appropriate font in Postscript. * * Results: * Returns a standard Tcl return value. If an error occurs * then an error message will be left in the interp's result. * If no error occurs, then additional Postscript will be * appended to the interp's result. * * Side effects: * The Postscript font name is entered into psInfoPtr->fontTable * if it wasn't already there. * *-------------------------------------------------------------- */ int Tk_TablePsFont(interp, tablePtr, tkfont) Tcl_Interp *interp; /* Interpreter for returning Postscript * or error message. */ Table *tablePtr; /* Information about table. */ Tk_Font tkfont; /* Information about font in which text * is to be printed. */ { TkPostscriptInfo *psInfoPtr = tablePtr->psInfoPtr; char *end; char pointString[TCL_INTEGER_SPACE]; Tcl_DString ds; int i, points; /* * First, look up the font's name in the font map, if there is one. * If there is an entry for this font, it consists of a list * containing font name and size. Use this information. */ Tcl_DStringInit(&ds); if (psInfoPtr->fontVar != NULL) { Arg list; Arg *objv; int objc; double size; char *name; name = Tk_NameOfFont(tkfont); list = Tcl_GetVar2(interp, psInfoPtr->fontVar, name, 0); if (list != NULL) { if (Tcl_ListObjGetElements(interp, list, &objc, &objv) != TCL_OK) { badMapEntry: Tcl_ResetResult(interp); Tcl_AppendResult(interp, "bad font map entry for \"", name, "\": \"", list, "\"", (char *) NULL); return TCL_ERROR; } if (objc != 2) { goto badMapEntry; } size = strtod(LangString(objv[1]), &end); if ((size <= 0) || (*end != 0)) { goto badMapEntry; } Tcl_DStringAppend(&ds, LangString(objv[0]), -1); points = (int) size; ckfree((char *) objv); goto findfont; } } points = Tk_PostscriptFontName(tkfont, &ds); findfont: sprintf(pointString, "%d", points); Tcl_AppendResult(interp, pointString, " /", Tcl_DStringValue(&ds), " SetFont\n", (char *) NULL); Tcl_CreateHashEntry(&psInfoPtr->fontTable, Tcl_DStringValue(&ds), &i); Tcl_DStringFree(&ds); return TCL_OK; } /* *-------------------------------------------------------------- * * GetPostscriptPoints -- * * Given a string, returns the number of Postscript points * corresponding to that string. * * Results: * The return value is a standard Tcl return result. If * TCL_OK is returned, then everything went well and the * screen distance is stored at *doublePtr; otherwise * TCL_ERROR is returned and an error message is left in * the interp's result. * * Side effects: * None. * *-------------------------------------------------------------- */ static int GetPostscriptPoints(interp, string, doublePtr) Tcl_Interp *interp; /* Use this for error reporting. */ char *string; /* String describing a screen distance. */ double *doublePtr; /* Place to store converted result. */ { char *end; double d; d = strtod(string, &end); if (end == string) { error: Tcl_AppendResult(interp, "bad distance \"", string, "\"", (char *) NULL); return TCL_ERROR; } #define UCHAR(c) ((unsigned char) (c)) while ((*end != '\0') && isspace(UCHAR(*end))) { end++; } switch (*end) { case 'c': d *= 72.0/2.54; end++; break; case 'i': d *= 72.0; end++; break; case 'm': d *= 72.0/25.4; end++; break; case 0: break; case 'p': end++; break; default: goto error; } while ((*end != '\0') && isspace(UCHAR(*end))) { end++; } if (*end != 0) { goto error; } *doublePtr = d; return TCL_OK; } /* *-------------------------------------------------------------- * * TextToPostscript -- * * This procedure is called to generate Postscript for * text items. * * Results: * The return value is a standard Tcl result. If an error * occurs in generating Postscript then an error message is * left in the interp's result, replacing whatever used * to be there. If no error occurs, then Postscript for the * item is appended to the result. * * Side effects: * None. * *-------------------------------------------------------------- */ static int TextToPostscript(interp, tablePtr, tagPtr, tagX, tagY, width, height, row, col, textLayout) Tcl_Interp *interp; /* Leave Postscript or error message here. */ Table *tablePtr; /* Information about overall canvas. */ TableTag *tagPtr; /* */ int tagX, tagY; /* */ int width, height; /* */ int row, col; /* */ Tk_TextLayout textLayout; /* */ { int x, y; Tk_FontMetrics fm; char *justify; char buffer[500]; Tk_3DBorder fg = tagPtr->fg; if (fg == NULL) { fg = tablePtr->defaultTag.fg; } if (Tk_TablePsFont(interp, tablePtr, tagPtr->tkfont) != TCL_OK) { return TCL_ERROR; } if (Tk_TablePsColor(interp, tablePtr, Tk_3DBorderColor(fg)) != TCL_OK) { return TCL_ERROR; } sprintf(buffer, "%% %.15g %.15g [\n", (tagX+width)/2.0, tablePtr->psInfoPtr->y2 - ((tagY+height)/2.0)); Tcl_AppendResult(interp, buffer, (char *) NULL); sprintf(buffer, "col%d row%d [\n", col, row); Tcl_AppendResult(interp, buffer, (char *) NULL); Tk_TextLayoutToPostscript(interp, textLayout); x = 0; y = 0; justify = NULL; /* lint. */ switch (tagPtr->anchor) { case TK_ANCHOR_NW: x = 0; y = 0; break; case TK_ANCHOR_N: x = 1; y = 0; break; case TK_ANCHOR_NE: x = 2; y = 0; break; case TK_ANCHOR_E: x = 2; y = 1; break; case TK_ANCHOR_SE: x = 2; y = 2; break; case TK_ANCHOR_S: x = 1; y = 2; break; case TK_ANCHOR_SW: x = 0; y = 2; break; case TK_ANCHOR_W: x = 0; y = 1; break; case TK_ANCHOR_CENTER: x = 1; y = 1; break; } switch (tagPtr->justify) { case TK_JUSTIFY_RIGHT: justify = "1"; break; case TK_JUSTIFY_CENTER: justify = "0.5";break; case TK_JUSTIFY_LEFT: justify = "0"; } Tk_GetFontMetrics(tagPtr->tkfont, &fm); sprintf(buffer, "] %d %g %g %s %d %d DrawCellText\n", fm.linespace, (x / -2.0), (y / 2.0), justify, width, height); Tcl_AppendResult(interp, buffer, (char *) NULL); return TCL_OK; } ���������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable800/tkTableCellSort.c��������������������������������������������0000644�0000000�0000000�00000007715�13745605157�021270� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * tkTableCell.c -- * * This module implements cell sort functions for table * widgets. The MergeSort algorithm and other aux sorting * functions were taken from tclCmdIL.c lsort command: * tclCmdIL.c -- * * This file contains the top-level command routines for most of * the Tcl built-in commands whose names begin with the letters * I through L. It contains only commands in the generic core * (i.e. those that don't depend much upon UNIX facilities). * * Copyright (c) 1987-1993 The Regents of the University of California. * Copyright (c) 1993-1997 Lucent Technologies. * Copyright (c) 1994-1997 Sun Microsystems, Inc. * Copyright (c) 1998-1999 by Scriptics Corporation. * * Copyright (c) 1998-2002 Jeffrey Hobbs * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * */ #include "tkTable.h" #ifndef UCHAR #define UCHAR(c) ((unsigned char) (c)) #endif /* *---------------------------------------------------------------------- * * TableSortCompareProc -- * This procedure is invoked by qsort to determine the proper * ordering between two elements. * * Results: * < 0 means first is "smaller" than "second", > 0 means "first" * is larger than "second", and 0 means they should be treated * as equal. * * Side effects: * None, unless a user-defined comparison command does something * weird. * *---------------------------------------------------------------------- */ static int TableSortCompareProc(first, second) CONST VOID *first, *second; /* Elements to be compared. */ { int r1, c1, r2, c2; char *firstString; char *secondString; firstString = LangString( *((Arg*) first)); secondString = LangString(*((Arg*) second)); /* This doesn't account for badly formed indices */ sscanf(firstString, "%d,%d", &r1, &c1); sscanf(secondString, "%d,%d", &r2, &c2); if (r1 > r2) { return 1; } else if (r1 < r2) { return -1; } else if (c1 > c2) { return 1; } else if (c1 < c2) { return -1; } return 0; } /* *---------------------------------------------------------------------- * * TableCellSort -- * Sort a list of table cell elements (of form row,col) * * Results: * Returns the sorted list of elements. Because Tcl_Merge allocs * the space for result, it must later be Tcl_Free'd by caller. * * Side effects: * Behaviour undefined for ill-formed input list of elements. * *---------------------------------------------------------------------- */ Arg TableCellSort(Table *tablePtr, char *str) { int listArgc; Arg *listArgv; Arg result; Arg argstr; argstr = LangStringArg(str); if (Tcl_ListObjGetElements(tablePtr->interp, argstr, &listArgc, &listArgv) != TCL_OK) { ckfree((char *) argstr); return LangStringArg(str); } qsort((VOID *) listArgv, (size_t) listArgc, sizeof (char *), TableSortCompareProc); result = Tcl_NewListObj(listArgc, listArgv); return result; } /* *---------------------------------------------------------------------- * * TableCellSortObj -- * Sorts a list of table cell elements (of form row,col) in place * * Results: * Sorts list of elements in place. * * Side effects: * Behaviour undefined for ill-formed input list of elements. * *---------------------------------------------------------------------- */ Tcl_Obj * TableCellSortObj(Tcl_Interp *interp, Tcl_Obj *listObjPtr) { int length, i; Tcl_Obj* result; Tcl_Obj *sortedObjPtr, **listObjPtrs; if (Tcl_ListObjGetElements(interp, listObjPtr, &length, &listObjPtrs) != TCL_OK) { return NULL; } if (length <= 0) { return listObjPtr; } qsort((VOID *) listObjPtrs, (size_t) length, sizeof (char *), TableSortCompareProc); result = Tcl_NewListObj(length, listObjPtrs); return result; } ���������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable800/tkTableTag.c�������������������������������������������������0000644�0000000�0000000�00000121265�13745605157�020251� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * tkTableTag.c -- * * This module implements tags for table widgets. * * Copyright (c) 1998-2002 Jeffrey Hobbs * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tkTableTag.c,v 1.2 2004/02/08 03:09:47 cerney Exp $ */ #include "tkVMacro.h" #include "tkTable.h" static TableTag *TableTagGetEntry _ANSI_ARGS_((Table *tablePtr, char *name, int objc, char **argv)); static unsigned int TableTagGetPriority _ANSI_ARGS_((Table *tablePtr, TableTag *tagPtr)); static void TableImageProc _ANSI_ARGS_((ClientData clientData, int x, int y, int width, int height, int imageWidth, int imageHeight)); static int TableOptionReliefSet _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, Arg value, char *widgRec, int offset)); static Arg TableOptionReliefGet _ANSI_ARGS_((ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)); static CONST84 char *tagCmdNames[] = { "celltag", "cget", "coltag", "configure", "delete", "exists", "includes", "lower", "names", "raise", "rowtag", (char *) NULL }; enum tagCmd { TAG_CELLTAG, TAG_CGET, TAG_COLTAG, TAG_CONFIGURE, TAG_DELETE, TAG_EXISTS, TAG_INCLUDES, TAG_LOWER, TAG_NAMES, TAG_RAISE, TAG_ROWTAG }; static Cmd_Struct tagState_vals[]= { {"unknown", STATE_UNKNOWN}, {"normal", STATE_NORMAL}, {"disabled", STATE_DISABLED}, {"", 0 } }; static Tk_CustomOption tagStateOpt = { Cmd_OptionSet, Cmd_OptionGet, (ClientData) (&tagState_vals) }; static Tk_CustomOption tagBdOpt = { TableOptionBdSet, TableOptionBdGet, (ClientData) BD_TABLE_TAG }; static Tk_CustomOption tagReliefOpt = { TableOptionReliefSet, TableOptionReliefGet, (ClientData) NULL }; /* * The default specification for configuring tags * Done like this to make the command line parsing easy */ static Tk_ConfigSpec tagConfig[] = { {TK_CONFIG_ANCHOR, "-anchor", "anchor", "Anchor", "center", Tk_Offset(TableTag, anchor), TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK }, {TK_CONFIG_BORDER, "-background", "background", "Background", NULL, Tk_Offset(TableTag, bg), TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK }, {TK_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL, 0, 0}, {TK_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0}, {TK_CONFIG_CUSTOM, "-borderwidth", "borderWidth", "BorderWidth", "", 0 /* no offset */, TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK, &tagBdOpt }, {TK_CONFIG_BORDER, "-foreground", "foreground", "Foreground", NULL, Tk_Offset(TableTag, fg), TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK }, {TK_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL, (char *)NULL, 0, 0}, {TK_CONFIG_FONT, "-font", "font", "Font", NULL, Tk_Offset(TableTag, tkfont), TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK }, {TK_CONFIG_STRING, "-image", "image", "Image", NULL, Tk_Offset(TableTag, imageStr), TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK }, {TK_CONFIG_JUSTIFY, "-justify", "justify", "Justify", "left", Tk_Offset(TableTag, justify), TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK }, {TK_CONFIG_INT, "-multiline", "multiline", "Multiline", "-1", Tk_Offset(TableTag, multiline), TK_CONFIG_DONT_SET_DEFAULT }, {TK_CONFIG_CUSTOM, "-relief", "relief", "Relief", "flat", Tk_Offset(TableTag, relief), TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK, &tagReliefOpt }, {TK_CONFIG_INT, "-showtext", "showText", "ShowText", "-1", Tk_Offset(TableTag, showtext), TK_CONFIG_DONT_SET_DEFAULT }, {TK_CONFIG_CUSTOM, "-state", "state", "State", "unknown", Tk_Offset(TableTag, state), TK_CONFIG_DONT_SET_DEFAULT, &tagStateOpt }, {TK_CONFIG_INT, "-wrap", "wrap", "Wrap", "-1", Tk_Offset(TableTag, wrap), TK_CONFIG_DONT_SET_DEFAULT }, {TK_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; /* * The join tag structure is used to create a combined tag, so it * keeps priority info. */ typedef struct { TableTag tag; /* must be first */ unsigned int magic; unsigned int pbg, pfg, pborders, prelief, ptkfont, panchor, pimage; unsigned int pstate, pjustify, pmultiline, pwrap, pshowtext; } TableJoinTag; /* *---------------------------------------------------------------------- * * TableImageProc -- * Called when an image associated with a tag is changed. * * Results: * None. * * Side effects: * Invalidates the whole table. * This should only invalidate affected cells, but that info * is not managed... * *---------------------------------------------------------------------- */ static void TableImageProc(ClientData clientData, int x, int y, int width, int height, int imageWidth, int imageHeight) { TableInvalidateAll((Table *)clientData, 0); } /* *---------------------------------------------------------------------- * * TableNewTag -- * ckallocs space for a new tag structure and inits the structure. * * Results: * Returns a pointer to the new structure. Must be freed later. * * Side effects: * None. * *---------------------------------------------------------------------- */ TableTag * TableNewTag(Table *tablePtr) { TableTag *tagPtr; /* * If tablePtr is NULL, make a regular tag, otherwise make a join tag. */ if (tablePtr == NULL) { tagPtr = (TableTag *) ckalloc(sizeof(TableTag)); memset((VOID *) tagPtr, 0, sizeof(TableTag)); /* * Set the values that aren't 0/NULL by default */ tagPtr->anchor = (Tk_Anchor)-1; tagPtr->justify = (Tk_Justify)-1; tagPtr->multiline = -1; tagPtr->relief = -1; tagPtr->showtext = -1; tagPtr->state = STATE_UNKNOWN; tagPtr->wrap = -1; } else { TableJoinTag *jtagPtr = (TableJoinTag *) ckalloc(sizeof(TableJoinTag)); memset((VOID *) jtagPtr, 0, sizeof(TableJoinTag)); tagPtr = (TableTag *) jtagPtr; tagPtr->anchor = (Tk_Anchor)-1; tagPtr->justify = (Tk_Justify)-1; tagPtr->multiline = -1; tagPtr->relief = -1; tagPtr->showtext = -1; tagPtr->state = STATE_UNKNOWN; tagPtr->wrap = -1; jtagPtr->magic = 0x99ABCDEF; jtagPtr->pbg = -1; jtagPtr->pfg = -1; jtagPtr->pborders = -1; jtagPtr->prelief = -1; jtagPtr->ptkfont = -1; jtagPtr->panchor = -1; jtagPtr->pimage = -1; jtagPtr->pstate = -1; jtagPtr->pjustify = -1; jtagPtr->pmultiline = -1; jtagPtr->pwrap = -1; jtagPtr->pshowtext = -1; } return (TableTag *) tagPtr; } /* *---------------------------------------------------------------------- * * TableResetTag -- * This routine resets a given tag to the table defaults. * * Results: * Tag will have values changed. * * Side effects: * None. * *---------------------------------------------------------------------- */ void TableResetTag(Table *tablePtr, TableTag *tagPtr) { TableJoinTag *jtagPtr = (TableJoinTag *) tagPtr; if (jtagPtr->magic != 0x99ABCDEF) { panic("bad mojo in TableResetTag"); } memset((VOID *) jtagPtr, 0, sizeof(TableJoinTag)); tagPtr->anchor = (Tk_Anchor)-1; tagPtr->justify = (Tk_Justify)-1; tagPtr->multiline = -1; tagPtr->relief = -1; tagPtr->showtext = -1; tagPtr->state = STATE_UNKNOWN; tagPtr->wrap = -1; jtagPtr->magic = 0x99ABCDEF; jtagPtr->pbg = -1; jtagPtr->pfg = -1; jtagPtr->pborders = -1; jtagPtr->prelief = -1; jtagPtr->ptkfont = -1; jtagPtr->panchor = -1; jtagPtr->pimage = -1; jtagPtr->pstate = -1; jtagPtr->pjustify = -1; jtagPtr->pmultiline = -1; jtagPtr->pwrap = -1; jtagPtr->pshowtext = -1; /* * Merge in the default tag. */ memcpy((VOID *) jtagPtr, (VOID *) &(tablePtr->defaultTag), sizeof(TableTag)); } /* *---------------------------------------------------------------------- * * TableMergeTag -- * This routine merges two tags by adding any fields from the addTag * that are set to the baseTag. * * Results: * baseTag will inherit all set characteristics of addTag * (addTag thus has the priority). * * Side effects: * None. * *---------------------------------------------------------------------- */ void TableMergeTag(Table *tablePtr, TableTag *baseTag, TableTag *addTag) { TableJoinTag *jtagPtr = (TableJoinTag *) baseTag; unsigned int prio; if (jtagPtr->magic != 0x99ABCDEF) { panic("bad mojo in TableMergeTag"); } #ifndef NO_TAG_PRIORITIES /* * Find priority for the tag to merge */ prio = TableTagGetPriority(tablePtr, addTag); if ((addTag->anchor != -1) && (prio < jtagPtr->panchor)) { baseTag->anchor = addTag->anchor; jtagPtr->panchor = prio; } if ((addTag->bg != NULL) && (prio < jtagPtr->pbg)) { baseTag->bg = addTag->bg; jtagPtr->pbg = prio; } if ((addTag->fg != NULL) && (prio < jtagPtr->pfg)) { baseTag->fg = addTag->fg; jtagPtr->pfg = prio; } if ((addTag->tkfont != NULL) && (prio < jtagPtr->ptkfont)) { baseTag->tkfont = addTag->tkfont; jtagPtr->ptkfont = prio; } if ((addTag->imageStr != NULL) && (prio < jtagPtr->pimage)) { baseTag->imageStr = addTag->imageStr; baseTag->image = addTag->image; jtagPtr->pimage = prio; } if ((addTag->multiline >= 0) && (prio < jtagPtr->pmultiline)) { baseTag->multiline = addTag->multiline; jtagPtr->pmultiline = prio; } if ((addTag->relief != -1) && (prio < jtagPtr->prelief)) { baseTag->relief = addTag->relief; jtagPtr->prelief = prio; } if ((addTag->showtext >= 0) && (prio < jtagPtr->pshowtext)) { baseTag->showtext = addTag->showtext; jtagPtr->pshowtext = prio; } if ((addTag->state != STATE_UNKNOWN) && (prio < jtagPtr->pstate)) { baseTag->state = addTag->state; jtagPtr->pstate = prio; } if ((addTag->justify != -1) && (prio < jtagPtr->pjustify)) { baseTag->justify = addTag->justify; jtagPtr->pjustify = prio; } if ((addTag->wrap >= 0) && (prio < jtagPtr->pwrap)) { baseTag->wrap = addTag->wrap; jtagPtr->pwrap = prio; } if ((addTag->borders) && (prio < jtagPtr->pborders)) { baseTag->borderStr = addTag->borderStr; baseTag->borders = addTag->borders; baseTag->bd[0] = addTag->bd[0]; baseTag->bd[1] = addTag->bd[1]; baseTag->bd[2] = addTag->bd[2]; baseTag->bd[3] = addTag->bd[3]; jtagPtr->pborders = prio; } #else if (addTag->anchor != -1) baseTag->anchor = addTag->anchor; if (addTag->bg != NULL) baseTag->bg = addTag->bg; if (addTag->fg != NULL) baseTag->fg = addTag->fg; if (addTag->tkfont != NULL) baseTag->tkfont = addTag->tkfont; if (addTag->imageStr != NULL) { baseTag->imageStr = addTag->imageStr; baseTag->image = addTag->image; } if (addTag->multiline >= 0) baseTag->multiline = addTag->multiline; if (addTag->relief != -1) baseTag->relief = addTag->relief; if (addTag->showtext >= 0) baseTag->showtext = addTag->showtext; if (addTag->state != STATE_UNKNOWN) baseTag->state = addTag->state; if (addTag->justify != -1) baseTag->justify = addTag->justify; if (addTag->wrap >= 0) baseTag->wrap = addTag->wrap; if (addTag->borders) { baseTag->borderStr = addTag->borderStr; baseTag->borders = addTag->borders; baseTag->bd[0] = addTag->bd[0]; baseTag->bd[1] = addTag->bd[1]; baseTag->bd[2] = addTag->bd[2]; baseTag->bd[3] = addTag->bd[3]; } #endif } /* *---------------------------------------------------------------------- * * TableInvertTag -- * This routine swaps background and foreground for the selected tag. * * Results: * Inverts fg and bg of tag. * * Side effects: * None. * *---------------------------------------------------------------------- */ void TableInvertTag(TableTag *baseTag) { Tk_3DBorder tmpBg; tmpBg = baseTag->fg; baseTag->fg = baseTag->bg; baseTag->bg = tmpBg; } /* *---------------------------------------------------------------------- * * TableGetTagBorders -- * This routine gets the border values based on a tag. * * Results: * It returns the values in the int*'s (if not NULL), and the * total number of defined borders as a result. * * Side effects: * None. * *---------------------------------------------------------------------- */ int TableGetTagBorders(TableTag *tagPtr, int *left, int *right, int *top, int *bottom) { switch (tagPtr->borders) { case 0: if (left) { *left = 0; } if (right) { *right = 0; } if (top) { *top = 0; } if (bottom) { *bottom = 0; } break; case 1: if (left) { *left = tagPtr->bd[0]; } if (right) { *right = tagPtr->bd[0]; } if (top) { *top = tagPtr->bd[0]; } if (bottom) { *bottom = tagPtr->bd[0]; } break; case 2: if (left) { *left = tagPtr->bd[0]; } if (right) { *right = tagPtr->bd[1]; } if (top) { *top = 0; } if (bottom) { *bottom = 0; } break; case 4: if (left) { *left = tagPtr->bd[0]; } if (right) { *right = tagPtr->bd[1]; } if (top) { *top = tagPtr->bd[2]; } if (bottom) { *bottom = tagPtr->bd[3]; } break; default: panic("invalid border value '%d'\n", tagPtr->borders); break; } return tagPtr->borders; } /* *---------------------------------------------------------------------- * * TableTagGetEntry -- * Takes a name and optional args and creates a tag entry in the * table's tag table. * * Results: * A new tag entry will be created and returned. * * Side effects: * None. * *---------------------------------------------------------------------- */ static TableTag * TableTagGetEntry(Table *tablePtr, char *name, int objc, char **argv) { Tcl_HashEntry *entryPtr; TableTag *tagPtr = NULL; int new; entryPtr = Tcl_CreateHashEntry(tablePtr->tagTable, name, &new); if (new) { tagPtr = TableNewTag(NULL); Tcl_SetHashValue(entryPtr, (ClientData) tagPtr); if (tablePtr->tagPrioSize >= tablePtr->tagPrioMax) { int i; /* * Increase the priority list size in blocks of 10 */ tablePtr->tagPrioMax += 10; tablePtr->tagPrioNames = (char **) ckrealloc( (char *) tablePtr->tagPrioNames, sizeof(TableTag *) * tablePtr->tagPrioMax); tablePtr->tagPrios = (TableTag **) ckrealloc( (char *) tablePtr->tagPrios, sizeof(TableTag *) * tablePtr->tagPrioMax); for (i = tablePtr->tagPrioSize; i < tablePtr->tagPrioMax; i++) { tablePtr->tagPrioNames[i] = (char *) NULL; tablePtr->tagPrios[i] = (TableTag *) NULL; } } tablePtr->tagPrioNames[tablePtr->tagPrioSize] = (char *) Tcl_GetHashKey(tablePtr->tagTable, entryPtr); tablePtr->tagPrios[tablePtr->tagPrioSize] = tagPtr; tablePtr->tagPrioSize++; } else { tagPtr = (TableTag *) Tcl_GetHashValue(entryPtr); } if (objc) { Tk_ConfigureWidget(tablePtr->interp, tablePtr->tkwin, tagConfig, objc, argv, (char *)tagPtr, TK_CONFIG_ARGV_ONLY); } return tagPtr; } /* *---------------------------------------------------------------------- * * TableTagGetPriority -- * Get the priority value for a tag. * * Results: * returns the priority. * * Side effects: * None. * *---------------------------------------------------------------------- */ static unsigned int TableTagGetPriority(Table *tablePtr, TableTag *tagPtr) { unsigned int prio = 0; while (tagPtr != tablePtr->tagPrios[prio]) { prio++; } return prio; } /* *---------------------------------------------------------------------- * * TableInitTags -- * Creates the static table tags. * * Results: * active, sel, title and flash are created as tags. * * Side effects: * None. * *---------------------------------------------------------------------- */ void TableInitTags(Table *tablePtr) { Arg activeArgs[4]; Arg selArgs[6]; Arg titleArgs[8]; Arg flashArgs[2]; activeArgs[0]= LangStringArg("-bg"); activeArgs[1]= LangStringArg(ACTIVE_BG); activeArgs[2]=LangStringArg("-relief"); activeArgs[3]=LangStringArg("flat"); selArgs[0]= LangStringArg("-bg"); selArgs[1]=LangStringArg(SELECT_BG); selArgs[2]=LangStringArg("-fg"); selArgs[3]=LangStringArg(SELECT_FG); selArgs[4]=LangStringArg("-relief"); selArgs[5]=LangStringArg("sunken"); titleArgs[0]=LangStringArg("-bg"), titleArgs[1]=LangStringArg(DISABLED), titleArgs[2]=LangStringArg("-fg"), titleArgs[3]=LangStringArg("white"), titleArgs[4]=LangStringArg("-relief"), titleArgs[5]=LangStringArg("flat"), titleArgs[6]=LangStringArg("-state"), titleArgs[7]=LangStringArg("disabled"); flashArgs[0]= LangStringArg("-bg"); flashArgs[1]=LangStringArg("red"); /* * The order of creation is important to priority. */ TableTagGetEntry(tablePtr, "flash", ARSIZE(flashArgs), flashArgs); TableTagGetEntry(tablePtr, "active", ARSIZE(activeArgs), activeArgs); TableTagGetEntry(tablePtr, "sel", ARSIZE(selArgs), selArgs); TableTagGetEntry(tablePtr, "title", ARSIZE(titleArgs), titleArgs); } /* *---------------------------------------------------------------------- * * FindRowColTag -- * Finds a row/col tag based on the row/col styles and tagCommand. * * Results: * Returns tag associated with row/col cell, if any. * * Side effects: * Possible side effects from eval of tagCommand. * IMPORTANT: This plays with the interp result object, * so use of resultPtr in prior command may be invalid after * calling this function. * *---------------------------------------------------------------------- */ TableTag * FindRowColTag(Table *tablePtr, int cell, int mode) { Tcl_HashEntry *entryPtr; TableTag *tagPtr = NULL; /* kill(0,2); */ entryPtr = Tcl_FindHashEntry((mode == ROW) ? tablePtr->rowStyles : tablePtr->colStyles, (char *) cell); if (entryPtr == NULL) { LangCallback *cmd = (mode == ROW) ? tablePtr->rowTagCmd : tablePtr->colTagCmd; if (cmd) { register Tcl_Interp *interp = tablePtr->interp; char buf[INDEX_BUFSIZE]; /* * Since no specific row/col tag exists, eval the given command * with row/col appended */ sprintf(buf, " %d", cell); Tcl_Preserve((ClientData) interp); if ( LangDoCallback(interp, cmd, 1, 1, " %d", cell) == TCL_OK) { CONST char *name = Tcl_GetResult(interp); if (name && *name) { /* * If a result was returned, check to see if it is * a valid tag. */ entryPtr = Tcl_FindHashEntry(tablePtr->tagTable, name); } } Tcl_Release((ClientData) interp); Tcl_ResetResult(interp); } } if (entryPtr != NULL) { /* * This can be either the one in row|colStyles, * or that returned by eval'ing the row|colTagCmd */ tagPtr = (TableTag *) Tcl_GetHashValue(entryPtr); } return tagPtr; } /* *---------------------------------------------------------------------- * * TableCleanupTag -- * Releases the resources used by a tag before it is freed up. * * Results: * None. * * Side effects: * The tag is no longer valid. * *---------------------------------------------------------------------- */ void TableCleanupTag(Table *tablePtr, TableTag *tagPtr) { /* * Free resources that the optionSpec doesn't specifically know about */ if (tagPtr->image) { Tk_FreeImage(tagPtr->image); } Tk_FreeOptions(tagConfig, (char *) tagPtr, tablePtr->display, 0); } /* *-------------------------------------------------------------- * * Table_TagCmd -- * This procedure is invoked to process the tag method * that corresponds to a widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_TagCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *)clientData; int result = TCL_OK, cmdIndex, i, newEntry, value, len; int row, col, tagPrio, refresh = 0; TableTag *tagPtr, *tag2Ptr; Tcl_HashEntry *entryPtr, *scanPtr; Tcl_HashTable *hashTblPtr; Tcl_HashSearch search; Tk_Image image; Tcl_Obj *objPtr, *resultPtr; char buf[INDEX_BUFSIZE], *keybuf, *tagname; if (objc < 3) { Tcl_WrongNumArgs(interp, 2, objv, "option ?arg arg ...?"); return TCL_ERROR; } result = Tcl_GetIndexFromObj(interp, objv[2], tagCmdNames, "tag option", 0, &cmdIndex); if (result != TCL_OK) { return result; } /* * Before using this object, make sure there aren't any calls that * could have changed the interp result, thus freeing the object. */ resultPtr = Tcl_GetObjResult(interp); switch ((enum tagCmd) cmdIndex) { case TAG_CELLTAG: /* add named tag to a (group of) cell(s) */ if (objc < 4) { Tcl_WrongNumArgs(interp, 3, objv, "tag ?arg arg ...?"); return TCL_ERROR; } tagname = Tcl_GetStringFromObj(objv[3], &len); if (len == 0) { /* * An empty string was specified, so just delete the tag. */ tagPtr = NULL; } else { /* * Get the pointer to the tag structure. If it doesn't * exist, it will be created. */ tagPtr = TableTagGetEntry(tablePtr, tagname, 0, NULL); } if (objc == 4) { /* * The user just wants the cells with this tag returned. * Handle specially tags named: active, flash, sel, title */ if ((tablePtr->flags & HAS_ACTIVE) && STREQ(tagname, "active")) { TableMakeArrayIndex( tablePtr->activeRow+tablePtr->rowOffset, tablePtr->activeCol+tablePtr->colOffset, buf); Tcl_SetStringObj(resultPtr, buf, -1); } else if ((tablePtr->flashMode && STREQ(tagname, "flash")) || STREQ(tagname, "sel")) { hashTblPtr = (*tagname == 's') ? tablePtr->selCells : tablePtr->flashCells; for (scanPtr = Tcl_FirstHashEntry(hashTblPtr, &search); scanPtr != NULL; scanPtr = Tcl_NextHashEntry(&search)) { keybuf = (char *) Tcl_GetHashKey(hashTblPtr, scanPtr); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewStringObj(keybuf, -1)); } } else if (STREQ(tagname, "title") && (tablePtr->titleRows || tablePtr->titleCols)) { for (row = tablePtr->rowOffset; row < tablePtr->rowOffset+tablePtr->rows; row++) { for (col = tablePtr->colOffset; col < tablePtr->colOffset+tablePtr->titleCols; col++) { TableMakeArrayIndex(row, col, buf); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewStringObj(buf, -1)); } } for (row = tablePtr->rowOffset; row < tablePtr->rowOffset+tablePtr->titleRows; row++) { for (col = tablePtr->colOffset+tablePtr->titleCols; col < tablePtr->colOffset+tablePtr->cols; col++) { TableMakeArrayIndex(row, col, buf); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewStringObj(buf, -1)); } } } else { /* * Check this tag pointer amongst all tagged cells */ for (scanPtr = Tcl_FirstHashEntry(tablePtr->cellStyles, &search); scanPtr != NULL; scanPtr = Tcl_NextHashEntry(&search)) { if ((TableTag *) Tcl_GetHashValue(scanPtr) == tagPtr) { keybuf = (char *) Tcl_GetHashKey( tablePtr->cellStyles, scanPtr); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewStringObj(keybuf, -1)); } } } return TCL_OK; } /* * Loop through the arguments and fill in the hash table */ for (i = 4; i < objc; i++) { /* * Try and parse the index */ if (TableGetIndexObj(tablePtr, objv[i], &row, &col) != TCL_OK) { return TCL_ERROR; } /* * Get the hash key ready */ TableMakeArrayIndex(row, col, buf); if (tagPtr == NULL) { /* * This is a deletion */ entryPtr = Tcl_FindHashEntry(tablePtr->cellStyles, buf); if (entryPtr != NULL) { Tcl_DeleteHashEntry(entryPtr); refresh = 1; } } else { /* * Add a key to the hash table and set it to point to the * Tag structure if it wasn't the same as an existing one */ entryPtr = Tcl_CreateHashEntry(tablePtr->cellStyles, buf, &newEntry); if (newEntry || (tagPtr != (TableTag *) Tcl_GetHashValue(entryPtr))) { Tcl_SetHashValue(entryPtr, (ClientData) tagPtr); refresh = 1; } } /* * Now invalidate this cell for redraw */ if (refresh) { TableRefresh(tablePtr, row-tablePtr->rowOffset, col-tablePtr->colOffset, CELL); } } return TCL_OK; case TAG_COLTAG: case TAG_ROWTAG: { /* tag a row or a column */ int forRows = (cmdIndex == TAG_ROWTAG); if (objc < 4) { Tcl_WrongNumArgs(interp, 3, objv, "tag ?arg arg ..?"); return TCL_ERROR; } tagname = Tcl_GetStringFromObj(objv[3], &len); if (len == 0) { /* * Empty string, so we want to delete this element */ tagPtr = NULL; } else { /* * Get the pointer to the tag structure. If it doesn't * exist, it will be created. */ tagPtr = TableTagGetEntry(tablePtr, tagname, 0, NULL); } /* * Choose the correct hash table based on args */ hashTblPtr = forRows ? tablePtr->rowStyles : tablePtr->colStyles; if (objc == 4) { /* the user just wants the tagged cells to be returned */ /* Special handling for tags: active, flash, sel, title */ if ((tablePtr->flags & HAS_ACTIVE) && strcmp(tagname, "active") == 0) { Tcl_SetIntObj(resultPtr, (forRows ? tablePtr->activeRow+tablePtr->rowOffset : tablePtr->activeCol+tablePtr->colOffset)); } else if ((tablePtr->flashMode && STREQ(tagname, "flash")) || STREQ(tagname, "sel")) { Tcl_HashTable *cacheTblPtr; cacheTblPtr = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(cacheTblPtr, TCL_ONE_WORD_KEYS); hashTblPtr = (*tagname == 's') ? tablePtr->selCells : tablePtr->flashCells; for (scanPtr = Tcl_FirstHashEntry(hashTblPtr, &search); scanPtr != NULL; scanPtr = Tcl_NextHashEntry(&search)) { TableParseArrayIndex(&row, &col, Tcl_GetHashKey(hashTblPtr, scanPtr)); value = forRows ? row : col; entryPtr = Tcl_CreateHashEntry(cacheTblPtr, (char *)value, &newEntry); if (newEntry) { Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewIntObj(value)); } } Tcl_DeleteHashTable(cacheTblPtr); ckfree((char *) (cacheTblPtr)); } else if (STREQ(tagname, "title") && (forRows?tablePtr->titleRows:tablePtr->titleCols)) { if (forRows) { for (row = tablePtr->rowOffset; row < tablePtr->rowOffset+tablePtr->titleRows; row++) { Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewIntObj(row)); } } else { for (col = tablePtr->colOffset; col < tablePtr->colOffset+tablePtr->titleCols; col++) { Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewIntObj(col)); } } } else { for (scanPtr = Tcl_FirstHashEntry(hashTblPtr, &search); scanPtr != NULL; scanPtr = Tcl_NextHashEntry(&search)) { /* is this the tag pointer on this row */ if ((TableTag *) Tcl_GetHashValue(scanPtr) == tagPtr) { objPtr = Tcl_NewIntObj( (int) Tcl_GetHashKey(hashTblPtr, scanPtr)); Tcl_ListObjAppendElement(NULL, resultPtr, objPtr); } } } return TCL_OK; } /* * Loop through the arguments and fill in the hash table */ for (i = 4; i < objc; i++) { /* * Try and parse the index */ if (Tcl_GetIntFromObj(interp, objv[i], &value) != TCL_OK) { return TCL_ERROR; } if (tagPtr == NULL) { /* * This is a deletion */ entryPtr = Tcl_FindHashEntry(hashTblPtr, (char *)value); if (entryPtr != NULL) { Tcl_DeleteHashEntry(entryPtr); refresh = 1; } } else { /* * Add a key to the hash table and set it to point to the * Tag structure if it wasn't the same as an existing one */ entryPtr = Tcl_CreateHashEntry(hashTblPtr, (char *) value, &newEntry); if (newEntry || (tagPtr != (TableTag *) Tcl_GetHashValue(entryPtr))) { Tcl_SetHashValue(entryPtr, (ClientData) tagPtr); refresh = 1; } } /* and invalidate the row or column affected */ if (refresh) { if (cmdIndex == TAG_ROWTAG) { TableRefresh(tablePtr, value-tablePtr->rowOffset, 0, ROW); } else { TableRefresh(tablePtr, 0, value-tablePtr->colOffset, COL); } } } return TCL_OK; /* COLTAG && ROWTAG */ } case TAG_CGET: if (objc != 5) { Tcl_WrongNumArgs(interp, 3, objv, "tagName option"); return TCL_ERROR; } tagname = Tcl_GetString(objv[3]); entryPtr = Tcl_FindHashEntry(tablePtr->tagTable, tagname); if (entryPtr == NULL) { goto invalidtag; } else { tagPtr = (TableTag *) Tcl_GetHashValue (entryPtr); result = Tk_ConfigureValue(interp, tablePtr->tkwin, tagConfig, (char *) tagPtr, Tcl_GetString(objv[4]), 0); /* * This is a work-around to fix a bug in Tk_ConfigureValue * that would set interp->result to NULL for -borderwidth * which has no associated tag offset value. This was fixed * in 8.3.5 and 8.4b1. [Bug #522882] */ if (Tcl_GetResult(interp) == NULL) { interp->result = ""; } } return result; /* CGET */ case TAG_CONFIGURE: if (objc < 4) { Tcl_WrongNumArgs(interp, 3, objv, "tagName ?arg arg ...?"); return TCL_ERROR; } /* * Get the pointer to the tag structure. If it doesn't * exist, it will be created. */ tagPtr = TableTagGetEntry(tablePtr, Tcl_GetString(objv[3]), 0, NULL); /* * If there were less than 6 args, we return the configuration * (for all or just one option), even for new tags */ if (objc < 6) { result = Tk_ConfigureInfo(interp, tablePtr->tkwin, tagConfig, (char *) tagPtr, (objc == 5) ? Tcl_GetString(objv[4]) : NULL, 0); } else { Arg *args; /* Stringify */ args = (Arg *) ckalloc((objc + 1) * sizeof(Arg)); for (i = 0; i < objc; i++) args[i] = LangStringArg(Tcl_GetString(objv[i])); args[objc] = NULL; result = Tk_ConfigureWidget(interp, tablePtr->tkwin, tagConfig, objc-4, args+4, (char *) tagPtr, TK_CONFIG_ARGV_ONLY); ckfree((char *) args); if (result == TCL_ERROR) { return TCL_ERROR; } /* * Handle change of image name */ if (tagPtr->imageStr) { image = Tk_GetImage(interp, tablePtr->tkwin, tagPtr->imageStr, TableImageProc, (ClientData)tablePtr); if (image == NULL) { result = TCL_ERROR; } } else { image = NULL; } if (tagPtr->image) { Tk_FreeImage(tagPtr->image); } tagPtr->image = image; /* * We reconfigured, so invalidate the table to redraw */ TableInvalidateAll(tablePtr, 0); } return result; case TAG_DELETE: /* delete a tag */ if (objc < 4) { Tcl_WrongNumArgs(interp, 3, objv, "tagName ?tagName ...?"); return TCL_ERROR; } /* run through the remaining arguments */ for (i = 3; i < objc; i++) { tagname = Tcl_GetString(objv[i]); /* cannot delete the title tag */ if (STREQ(tagname, "title") || STREQ(tagname, "sel") || STREQ(tagname, "flash") || STREQ(tagname, "active")) { Tcl_AppendStringsToObj(resultPtr, "cannot delete ", tagname, " tag", (char *) NULL); return TCL_ERROR; } entryPtr = Tcl_FindHashEntry(tablePtr->tagTable, tagname); if (entryPtr != NULL) { /* get the tag pointer */ tagPtr = (TableTag *) Tcl_GetHashValue(entryPtr); /* delete all references to this tag in rows */ scanPtr = Tcl_FirstHashEntry(tablePtr->rowStyles, &search); for (; scanPtr != NULL; scanPtr = Tcl_NextHashEntry(&search)) { if ((TableTag *)Tcl_GetHashValue(scanPtr) == tagPtr) { Tcl_DeleteHashEntry(scanPtr); refresh = 1; } } /* delete all references to this tag in cols */ scanPtr = Tcl_FirstHashEntry(tablePtr->colStyles, &search); for (; scanPtr != NULL; scanPtr = Tcl_NextHashEntry(&search)) { if ((TableTag *)Tcl_GetHashValue(scanPtr) == tagPtr) { Tcl_DeleteHashEntry(scanPtr); refresh = 1; } } /* delete all references to this tag in cells */ scanPtr = Tcl_FirstHashEntry(tablePtr->cellStyles, &search); for (; scanPtr != NULL; scanPtr = Tcl_NextHashEntry(&search)) { if ((TableTag *)Tcl_GetHashValue(scanPtr) == tagPtr) { Tcl_DeleteHashEntry(scanPtr); refresh = 1; } } /* * Remove the tag from the prio list and collapse * the rest of the tags. We could check for shrinking * the prio list as well. */ for (i = 0; i < tablePtr->tagPrioSize; i++) { if (tablePtr->tagPrios[i] == tagPtr) break; } for ( ; i < tablePtr->tagPrioSize; i++) { tablePtr->tagPrioNames[i] = tablePtr->tagPrioNames[i+1]; tablePtr->tagPrios[i] = tablePtr->tagPrios[i+1]; } tablePtr->tagPrioSize--; /* Release the tag structure */ TableCleanupTag(tablePtr, tagPtr); ckfree((char *) tagPtr); /* And free the hash table entry */ Tcl_DeleteHashEntry(entryPtr); } } /* since we deleted a tag, redraw the screen */ if (refresh) { TableInvalidateAll(tablePtr, 0); } return result; case TAG_EXISTS: if (objc != 4) { Tcl_WrongNumArgs(interp, 3, objv, "tagName"); return TCL_ERROR; } Tcl_SetBooleanObj(resultPtr, (Tcl_FindHashEntry(tablePtr->tagTable, Tcl_GetString(objv[3])) != NULL)); return TCL_OK; case TAG_INCLUDES: /* does a tag contain a index ? */ if (objc != 5) { Tcl_WrongNumArgs(interp, 3, objv, "tag index"); return TCL_ERROR; } tagname = Tcl_GetString(objv[3]); /* check to see if the tag actually exists */ entryPtr = Tcl_FindHashEntry(tablePtr->tagTable, tagname); if (entryPtr == NULL) { /* Unknown tag, just return 0 */ Tcl_SetBooleanObj(resultPtr, 0); return TCL_OK; } /* parse index */ if (TableGetIndexObj(tablePtr, objv[4], &row, &col) != TCL_OK) { return TCL_ERROR; } /* create hash key */ TableMakeArrayIndex(row, col, buf); if (STREQ(tagname, "active")) { result = (tablePtr->activeRow+tablePtr->rowOffset==row && tablePtr->activeCol+tablePtr->colOffset==col); } else if (STREQ(tagname, "flash")) { result = (tablePtr->flashMode && (Tcl_FindHashEntry(tablePtr->flashCells, buf) != NULL)); } else if (STREQ(tagname, "sel")) { result = (Tcl_FindHashEntry(tablePtr->selCells, buf) != NULL); } else if (STREQ(tagname, "title")) { result = (row < tablePtr->titleRows+tablePtr->rowOffset || col < tablePtr->titleCols+tablePtr->colOffset); } else { /* get the pointer to the tag structure */ tagPtr = (TableTag *) Tcl_GetHashValue(entryPtr); scanPtr = Tcl_FindHashEntry(tablePtr->cellStyles, buf); /* * Look to see if there is a cell, row, or col tag * for this cell */ result = ((scanPtr && (tagPtr == (TableTag *) Tcl_GetHashValue(scanPtr))) || (tagPtr == FindRowColTag(tablePtr, row, ROW)) || (tagPtr == FindRowColTag(tablePtr, col, COL))); } /* * Because we may call FindRowColTag above, we can't use * the resultPtr, but this is almost equivalent, and is SAFE */ Tcl_SetObjResult(interp, Tcl_NewIntObj(result)); return TCL_OK; case TAG_NAMES: /* * Print out the tag names in priority order */ if (objc < 3 || objc > 4) { Tcl_WrongNumArgs(interp, 3, objv, "?pattern?"); return TCL_ERROR; } tagname = (objc == 4) ? Tcl_GetString(objv[3]) : NULL; for (i = 0; i < tablePtr->tagPrioSize; i++) { keybuf = tablePtr->tagPrioNames[i]; if (objc == 3 || LangStringMatch(keybuf, LangStringArg(tagname))) { objPtr = Tcl_NewStringObj(keybuf, -1); Tcl_ListObjAppendElement(NULL, resultPtr, objPtr); } } return TCL_OK; case TAG_LOWER: case TAG_RAISE: /* * Change priority of the named tag */ if (objc != 4 && objc != 5) { Tcl_WrongNumArgs(interp, 3, objv, (cmdIndex == TAG_LOWER) ? "tagName ?belowThis?" : "tagName ?aboveThis?"); return TCL_ERROR; } tagname = Tcl_GetString(objv[3]); /* check to see if the tag actually exists */ entryPtr = Tcl_FindHashEntry(tablePtr->tagTable, tagname); if (entryPtr == NULL) { goto invalidtag; } tagPtr = (TableTag *) Tcl_GetHashValue(entryPtr); tagPrio = TableTagGetPriority(tablePtr, tagPtr); keybuf = tablePtr->tagPrioNames[tagPrio]; /* * In the RAISE case, the priority is one higher (-1) because * we want the named tag to move above the other in priority. */ if (objc == 5) { tagname = Tcl_GetString(objv[4]); entryPtr = Tcl_FindHashEntry(tablePtr->tagTable, tagname); if (entryPtr == NULL) { goto invalidtag; } tag2Ptr = (TableTag *) Tcl_GetHashValue(entryPtr); if (cmdIndex == TAG_LOWER) { value = TableTagGetPriority(tablePtr, tag2Ptr); } else { value = TableTagGetPriority(tablePtr, tag2Ptr) - 1; } } else { if (cmdIndex == TAG_LOWER) { /* * Lower this tag's priority to the bottom. */ value = tablePtr->tagPrioSize - 1; } else { /* * Raise this tag's priority to the top. */ value = -1; } } if (value < tagPrio) { /* * Move tag up in priority. */ for (i = tagPrio; i > value; i--) { tablePtr->tagPrioNames[i] = tablePtr->tagPrioNames[i-1]; tablePtr->tagPrios[i] = tablePtr->tagPrios[i-1]; } i++; tablePtr->tagPrioNames[i] = keybuf; tablePtr->tagPrios[i] = tagPtr; refresh = 1; } else if (value > tagPrio) { /* * Move tag down in priority. */ for (i = tagPrio; i < value; i++) { tablePtr->tagPrioNames[i] = tablePtr->tagPrioNames[i+1]; tablePtr->tagPrios[i] = tablePtr->tagPrios[i+1]; } tablePtr->tagPrioNames[i] = keybuf; tablePtr->tagPrios[i] = tagPtr; refresh = 1; } /* since we deleted a tag, redraw the screen */ if (refresh) { TableInvalidateAll(tablePtr, 0); } return TCL_OK; } return TCL_OK; invalidtag: /* * When jumping here, ensure the invalid 'tagname' is set already. */ Tcl_AppendStringsToObj(resultPtr, "invalid tag name \"", tagname, "\"", (char *) NULL); return TCL_ERROR; } /* *---------------------------------------------------------------------- * * TableOptionReliefSet -- * * This routine configures the borderwidth value for a tag. * * Results: * A standard Tcl result. * * Side effects: * It may adjust the tag struct values of relief[0..4] and borders. * *---------------------------------------------------------------------- */ static int TableOptionReliefSet(clientData, interp, tkwin, value, widgRec, offset) ClientData clientData; /* Type of struct being set. */ Tcl_Interp *interp; /* Used for reporting errors. */ Tk_Window tkwin; /* Window containing table widget. */ Arg value; /* Value of option. */ char *widgRec; /* Pointer to record for item. */ int offset; /* Offset into item. */ { TableTag *tagPtr = (TableTag *) widgRec; if (STREQ(LangString(value),"")) { tagPtr->relief = -1; } else { return Tk_GetRelief(interp, LangString(value), &(tagPtr->relief)); } return TCL_OK; } /* *---------------------------------------------------------------------- * * TableOptionReliefGet -- * * Results: * Value of the tag's -relief option. * * Side effects: * None. * *---------------------------------------------------------------------- */ static Arg TableOptionReliefGet(clientData, tkwin, widgRec, offset, freeProcPtr) ClientData clientData; /* Type of struct being set. */ Tk_Window tkwin; /* Window containing canvas widget. */ char *widgRec; /* Pointer to record for item. */ int offset; /* Offset into item. */ Tcl_FreeProc **freeProcPtr; /* Pointer to variable to fill in with * information about how to reclaim * storage for return string. */ { return LangStringArg( Tk_NameOfRelief(((TableTag *) widgRec)->relief)); } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable800/confdefs.h���������������������������������������������������0000644�0000000�0000000�00000000002�13745605157�020004� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable800/config.log���������������������������������������������������0000644�0000000�0000000�00000000270�13742524721�020015� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. configure:565: checking for a BSD compatible install ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable800/tkAppInit.c��������������������������������������������������0000644�0000000�0000000�00000007356�13745605157�020136� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * tkAppInit.c -- * * Provides a default version of the Tcl_AppInit procedure for * use in wish and similar Tk-based applications. * * Copyright (c) 1993 The Regents of the University of California. * Copyright (c) 1994-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * SCCS: @(#) tkAppInit.c 1.24 98/01/13 17:21:40 */ #include "tk.h" #include "locale.h" /* * The following variable is a special hack that is needed in order for * Sun shared libraries to be used for Tcl. */ extern int matherr(); int *tclDummyMathPtr = (int *) matherr; EXTERN int Tktable_Init _ANSI_ARGS_((Tcl_Interp *interp)); #ifdef TK_TEST EXTERN int Tcltest_Init _ANSI_ARGS_((Tcl_Interp *interp)); EXTERN int Tktest_Init _ANSI_ARGS_((Tcl_Interp *interp)); #endif /* TK_TEST */ /* *---------------------------------------------------------------------- * * main -- * * This is the main program for the application. * * Results: * None: Tk_Main never returns here, so this procedure never * returns either. * * Side effects: * Whatever the application does. * *---------------------------------------------------------------------- */ int main(argc, argv) int argc; /* Number of command-line arguments. */ char **argv; /* Values of command-line arguments. */ { Tk_Main(argc, argv, Tcl_AppInit); return 0; /* Needed only to prevent compiler warning. */ } /* *---------------------------------------------------------------------- * * Tcl_AppInit -- * * This procedure performs application-specific initialization. * Most applications, especially those that incorporate additional * packages, will have their own version of this procedure. * * Results: * Returns a standard Tcl completion code, and leaves an error * message in interp->result if an error occurs. * * Side effects: * Depends on the startup script. * *---------------------------------------------------------------------- */ int Tcl_AppInit(interp) Tcl_Interp *interp; /* Interpreter for application. */ { if (Tcl_Init(interp) == TCL_ERROR) { return TCL_ERROR; } if (Tk_Init(interp) == TCL_ERROR) { return TCL_ERROR; } Tcl_StaticPackage(interp, "Tk", Tk_Init, (Tcl_PackageInitProc *) NULL); #ifdef TK_TEST if (Tcltest_Init(interp) == TCL_ERROR) { return TCL_ERROR; } Tcl_StaticPackage(interp, "Tcltest", Tcltest_Init, (Tcl_PackageInitProc *) NULL); if (Tktest_Init(interp) == TCL_ERROR) { return TCL_ERROR; } Tcl_StaticPackage(interp, "Tktest", Tktest_Init, (Tcl_PackageInitProc *) NULL); #endif /* TK_TEST */ /* * Call the init procedures for included packages. Each call should * look like this: * * if (Mod_Init(interp) == TCL_ERROR) { * return TCL_ERROR; * } * * where "Mod" is the name of the module. */ if (Tktable_Init(interp) == TCL_ERROR) { return TCL_ERROR; } Tcl_StaticPackage(interp, "Tktable", Tktable_Init, Tktable_SafeInit); /* * Call Tcl_CreateCommand for application-specific commands, if * they weren't already created by the init procedures called above. */ /* * Specify a user-specific startup file to invoke if the application * is run interactively. Typically the startup file is "~/.apprc" * where "app" is the name of the application. If this line is deleted * then no user-specific startup file will be run under any conditions. */ Tcl_SetVar(interp, "tcl_rcFileName", "~/.wishrc", TCL_GLOBAL_ONLY); return TCL_OK; } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable800/tkTableCell.c������������������������������������������������0000644�0000000�0000000�00000125504�13745605157�020415� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * tkTableCell.c -- * * This module implements cell oriented functions for table * widgets. * * Copyright (c) 1998-2000 Jeffrey Hobbs * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tkTableCell.c,v 1.2 2004/02/08 03:09:47 cerney Exp $ */ #include "tkVMacro.h" #include "tkTable.h" static int TableSortCompareProc _ANSI_ARGS_((CONST VOID *first, CONST VOID *second)); /* *---------------------------------------------------------------------- * * TableTrueCell -- * Takes a row,col pair in user coords and returns the true * cell that it relates to, either dimension bounded, or a * span cell if it was hidden. * * Results: * The true row, col in user coords are placed in the pointers. * If the value changed for some reasons, 0 is returned (it was not * the /true/ cell). * * Side effects: * None. * *---------------------------------------------------------------------- */ int TableTrueCell(Table *tablePtr, int r, int c, int *row, int *col) { *row = r; *col = c; /* * We check spans before constraints, because we don't want to * constrain and then think we ended up in a span */ if (tablePtr->spanAffTbl && !(tablePtr->flags & AVOID_SPANS)) { char buf[INDEX_BUFSIZE]; Tcl_HashEntry *entryPtr; TableMakeArrayIndex(r, c, buf); entryPtr = Tcl_FindHashEntry(tablePtr->spanAffTbl, buf); if ((entryPtr != NULL) && ((char *)Tcl_GetHashValue(entryPtr) != NULL)) { /* * This cell is covered by another spanning cell. * We need to return the coords for that spanning cell. */ TableParseArrayIndex(row, col, (char *)Tcl_GetHashValue(entryPtr)); return 0; } } *row = BETWEEN(r, tablePtr->rowOffset, tablePtr->rows-1+tablePtr->rowOffset); *col = BETWEEN(c, tablePtr->colOffset, tablePtr->cols-1+tablePtr->colOffset); return ((*row == r) && (*col == c)); } /* *---------------------------------------------------------------------- * * TableCellCoords -- * Takes a row,col pair in real coords and finds it position * on the virtual screen. * * Results: * The virtual x, y, width, and height of the cell * are placed in the pointers. * * Side effects: * None. * *---------------------------------------------------------------------- */ int TableCellCoords(Table *tablePtr, int row, int col, int *x, int *y, int *w, int *h) { register int hl = tablePtr->highlightWidth; int result = CELL_OK; if (tablePtr->rows <= 0 || tablePtr->cols <= 0) { *w = *h = *x = *y = 0; return CELL_BAD; } /* * Real coords required, always should be passed acceptable values, * but this is a possible seg fault otherwise */ CONSTRAIN(row, 0, tablePtr->rows-1); CONSTRAIN(col, 0, tablePtr->cols-1); *w = tablePtr->colPixels[col]; *h = tablePtr->rowPixels[row]; /* * Adjust for sizes of spanning cells * and ensure that this cell isn't "hidden" */ if (tablePtr->spanAffTbl && !(tablePtr->flags & AVOID_SPANS)) { char buf[INDEX_BUFSIZE]; Tcl_HashEntry *entryPtr; TableMakeArrayIndex(row+tablePtr->rowOffset, col+tablePtr->colOffset, buf); entryPtr = Tcl_FindHashEntry(tablePtr->spanAffTbl, buf); if (entryPtr != NULL) { int rs, cs; char *cell; cell = (char *) Tcl_GetHashValue(entryPtr); if (cell != NULL) { /* This cell is covered by another spanning cell */ /* We need to return the coords for that cell */ TableParseArrayIndex(&rs, &cs, cell); *w = rs; *h = cs; result = CELL_HIDDEN; goto setxy; } /* Get the actual span values out of spanTbl */ entryPtr = Tcl_FindHashEntry(tablePtr->spanTbl, buf); cell = (char *) Tcl_GetHashValue(entryPtr); TableParseArrayIndex(&rs, &cs, cell); if (rs > 0) { /* * Make sure we don't overflow our space */ if (row < tablePtr->titleRows) { rs = MIN(tablePtr->titleRows-1, row+rs); } else { rs = MIN(tablePtr->rows-1, row+rs); } *h = tablePtr->rowStarts[rs+1]-tablePtr->rowStarts[row]; result = CELL_SPAN; } else if (rs <= 0) { /* currently negative spans are not supported */ } if (cs > 0) { /* * Make sure we don't overflow our space */ if (col < tablePtr->titleCols) { cs = MIN(tablePtr->titleCols-1, col+cs); } else { cs = MIN(tablePtr->cols-1, col+cs); } *w = tablePtr->colStarts[cs+1]-tablePtr->colStarts[col]; result = CELL_SPAN; } else if (cs <= 0) { /* currently negative spans are not supported */ } } } setxy: *x = hl + tablePtr->colStarts[col]; if (col >= tablePtr->titleCols) { *x -= tablePtr->colStarts[tablePtr->leftCol] - tablePtr->colStarts[tablePtr->titleCols]; } *y = hl + tablePtr->rowStarts[row]; if (row >= tablePtr->titleRows) { *y -= tablePtr->rowStarts[tablePtr->topRow] - tablePtr->rowStarts[tablePtr->titleRows]; } return result; } /* *---------------------------------------------------------------------- * * TableCellVCoords -- * Takes a row,col pair in real coords and finds it position * on the actual screen. The full arg specifies whether * only 100% visible cells should be considered visible. * * Results: * The x, y, width, and height of the cell are placed in the pointers, * depending upon visibility of the cell. * Returns 0 for hidden and 1 for visible cells. * * Side effects: * None. * *---------------------------------------------------------------------- */ int TableCellVCoords(Table *tablePtr, int row, int col, int *rx, int *ry, int *rw, int *rh, int full) { int x, y, w, h, w0, h0, cellType, hl = tablePtr->highlightWidth; if (tablePtr->tkwin == NULL) return 0; /* * Necessary to use separate vars in case dummies are passed in */ cellType = TableCellCoords(tablePtr, row, col, &x, &y, &w, &h); *rx = x; *ry = y; *rw = w; *rh = h; if (cellType == CELL_OK) { if ((row < tablePtr->topRow && row >= tablePtr->titleRows) || (col < tablePtr->leftCol && col >= tablePtr->titleCols)) { /* * A non-spanning cell hiding in "dead" space * between title areas and visible cells */ return 0; } } else if (cellType == CELL_SPAN) { /* * we might need to treat full better is CELL_SPAN but primary * cell is visible */ int topX = tablePtr->colStarts[tablePtr->titleCols]+hl; int topY = tablePtr->rowStarts[tablePtr->titleRows]+hl; if ((col < tablePtr->leftCol) && (col >= tablePtr->titleCols)) { if (full || (x+w < topX)) { return 0; } else { w -= topX-x; x = topX; } } if ((row < tablePtr->topRow) && (row >= tablePtr->titleRows)) { if (full || (y+h < topY)) { return 0; } else { h -= topY-y; y = topY; } } /* * re-set these according to changed coords */ *rx = x; *ry = y; *rw = w; *rh = h; } else { /* * If it is a hidden cell, then w,h is the row,col in user coords * of the cell that spans over this one */ return 0; } /* * At this point, we know it is on the screen, * but not if we can see 100% of it (if we care) */ if (full) { w0 = w; h0 = h; } else { /* * if we don't care about seeing the whole thing, then * make sure we at least see a pixel worth */ w0 = h0 = 1; } /* * Is the cell visible? */ if ((x < hl) || (y < hl) || ((x+w0) > (Tk_Width(tablePtr->tkwin)-hl)) || ((y+h0) > (Tk_Height(tablePtr->tkwin)-hl))) { /* definitely off the screen */ return 0; } else { /* if it was full, then w,h are already be properly constrained */ if (!full) { *rw = MIN(w, Tk_Width(tablePtr->tkwin)-hl-x); *rh = MIN(h, Tk_Height(tablePtr->tkwin)-hl-y); } return 1; } } /* *---------------------------------------------------------------------- * * TableWhatCell -- * Takes a x,y screen coordinate and determines what cell contains. * that point. This will return cells that are beyond the right/bottom * edge of the viewable screen. * * Results: * The row,col of the cell are placed in the pointers. * * Side effects: * None. * *---------------------------------------------------------------------- */ void TableWhatCell(register Table *tablePtr, int x, int y, int *row, int *col) { int i; x = MAX(0, x); y = MAX(0, y); /* Adjust for table's global highlightthickness border */ x -= tablePtr->highlightWidth; y -= tablePtr->highlightWidth; /* Adjust the x coord if not in the column titles to change display coords * into internal coords */ x += (x < tablePtr->colStarts[tablePtr->titleCols]) ? 0 : tablePtr->colStarts[tablePtr->leftCol] - tablePtr->colStarts[tablePtr->titleCols]; y += (y < tablePtr->rowStarts[tablePtr->titleRows]) ? 0 : tablePtr->rowStarts[tablePtr->topRow] - tablePtr->rowStarts[tablePtr->titleRows]; x = MIN(x, tablePtr->maxWidth-1); y = MIN(y, tablePtr->maxHeight-1); for (i = 1; x >= tablePtr->colStarts[i]; i++); *col = i - 1; for (i = 1; y >= tablePtr->rowStarts[i]; i++); *row = i - 1; if (tablePtr->spanAffTbl && !(tablePtr->flags & AVOID_SPANS)) { char buf[INDEX_BUFSIZE]; Tcl_HashEntry *entryPtr; /* We now correct the returned cell if this was "hidden" */ TableMakeArrayIndex(*row+tablePtr->rowOffset, *col+tablePtr->colOffset, buf); entryPtr = Tcl_FindHashEntry(tablePtr->spanAffTbl, buf); if ((entryPtr != NULL) && /* We have to make sure this was not already hidden * that's an error */ ((char *)Tcl_GetHashValue(entryPtr) != NULL)) { /* this is a "hidden" cell */ TableParseArrayIndex(row, col, (char *)Tcl_GetHashValue(entryPtr)); *row -= tablePtr->rowOffset; *col -= tablePtr->colOffset; } } } /* *---------------------------------------------------------------------- * * TableAtBorder -- * Takes a x,y screen coordinate and determines if that point is * over a border. * * Results: * The left/top row,col corresponding to that point are placed in * the pointers. The number of borders (+1 for row, +1 for col) * hit is returned. * * Side effects: * None. * *---------------------------------------------------------------------- */ int TableAtBorder(Table * tablePtr, int x, int y, int *row, int *col) { int i, brow, bcol, borders = 2, bd[6]; TableGetTagBorders(&(tablePtr->defaultTag), &bd[0], &bd[1], &bd[2], &bd[3]); bd[4] = (bd[0] + bd[1])/2; bd[5] = (bd[2] + bd[3])/2; /* * Constrain x && y appropriately, and adjust x if it is not in the * column titles to change display coords into internal coords. */ x = MAX(0, x); y = MAX(0, y); x -= tablePtr->highlightWidth; y -= tablePtr->highlightWidth; x += (x < tablePtr->colStarts[tablePtr->titleCols]) ? 0 : tablePtr->colStarts[tablePtr->leftCol] - tablePtr->colStarts[tablePtr->titleCols]; x = MIN(x, tablePtr->maxWidth - 1); for (i = 1; (i <= tablePtr->cols) && (x + (bd[0] + bd[1])) >= tablePtr->colStarts[i]; i++); if (x > tablePtr->colStarts[--i] + bd[4]) { borders--; *col = -1; bcol = (i < tablePtr->leftCol && i >= tablePtr->titleCols) ? tablePtr->titleCols-1 : i-1; } else { bcol = *col = (i < tablePtr->leftCol && i >= tablePtr->titleCols) ? tablePtr->titleCols-1 : i-1; } y += (y < tablePtr->rowStarts[tablePtr->titleRows]) ? 0 : tablePtr->rowStarts[tablePtr->topRow] - tablePtr->rowStarts[tablePtr->titleRows]; y = MIN(y, tablePtr->maxHeight - 1); for (i = 1; i <= tablePtr->rows && (y + (bd[2] + bd[3])) >= tablePtr->rowStarts[i]; i++); if (y > tablePtr->rowStarts[--i]+bd[5]) { borders--; *row = -1; brow = (i < tablePtr->topRow && i >= tablePtr->titleRows) ? tablePtr->titleRows-1 : i-1; } else { brow = *row = (i < tablePtr->topRow && i >= tablePtr->titleRows) ? tablePtr->titleRows-1 : i-1; } /* * We have to account for spanning cells, which may hide cells. * In that case, we have to decrement our border count. */ if (tablePtr->spanAffTbl && !(tablePtr->flags & AVOID_SPANS) && borders) { Tcl_HashEntry *entryPtr1, *entryPtr2 ; char buf1[INDEX_BUFSIZE], buf2[INDEX_BUFSIZE]; char *val; if (*row != -1) { TableMakeArrayIndex(brow+tablePtr->rowOffset, bcol+tablePtr->colOffset+1, buf1); TableMakeArrayIndex(brow+tablePtr->rowOffset+1, bcol+tablePtr->colOffset+1, buf2); entryPtr1 = Tcl_FindHashEntry(tablePtr->spanAffTbl, buf1); entryPtr2 = Tcl_FindHashEntry(tablePtr->spanAffTbl, buf2); if (entryPtr1 != NULL && entryPtr2 != NULL) { if ((val = (char *) Tcl_GetHashValue(entryPtr1)) != NULL) { strcpy(buf1, val); } if ((val = (char *) Tcl_GetHashValue(entryPtr2)) != NULL) { strcpy(buf2, val); } if (strcmp(buf1, buf2) == 0) { borders--; *row = -1; } } } if (*col != -1) { TableMakeArrayIndex(brow+tablePtr->rowOffset+1, bcol+tablePtr->colOffset, buf1); TableMakeArrayIndex(brow+tablePtr->rowOffset+1, bcol+tablePtr->colOffset+1, buf2); entryPtr1 = Tcl_FindHashEntry(tablePtr->spanAffTbl, buf1); entryPtr2 = Tcl_FindHashEntry(tablePtr->spanAffTbl, buf2); if (entryPtr1 != NULL && entryPtr2 != NULL) { if ((val = (char *) Tcl_GetHashValue(entryPtr1)) != NULL) { strcpy(buf1, val); } if ((val = (char *) Tcl_GetHashValue(entryPtr2)) != NULL) { strcpy(buf2, val); } if (strcmp(buf1, buf2) == 0) { borders--; *col = -1; } } } } return borders; } /* *---------------------------------------------------------------------- * * TableGetCellValue -- * Takes a row,col pair in user coords and returns the value for * that cell. This varies depending on what data source the * user has selected. * * Results: * The value of the cell is returned. The return value is VOLATILE * (do not free). * * Side effects: * The value will be cached if caching is turned on. * *---------------------------------------------------------------------- */ char * TableGetCellValue(Table *tablePtr, int r, int c) { register Tcl_Interp *interp = tablePtr->interp; char *result = NULL; char buf[INDEX_BUFSIZE]; Tcl_HashEntry *entryPtr = NULL; int new = 1; TableMakeArrayIndex(r, c, buf); if (tablePtr->caching) { /* * If we are caching, let's see if we have the value cached */ entryPtr = Tcl_CreateHashEntry(tablePtr->cache, buf, &new); if (!new) { result = (char *) Tcl_GetHashValue(entryPtr); if (result == NULL) { result = ""; } goto VALUE; } } if (tablePtr->command && tablePtr->useCmd) { if (LangDoCallback(interp, tablePtr->command, 1, 3, "%d %d %d",0,r,c) == TCL_ERROR) { tablePtr->useCmd = 0; tablePtr->dataSource &= ~DATA_COMMAND; if (tablePtr->arrayVar) tablePtr->dataSource |= DATA_ARRAY; Tcl_AddErrorInfo(interp, "\n\t(in -command evaled by table)"); Tcl_BackgroundError(interp); TableInvalidateAll(tablePtr, 0); } else { result = (char *) Tcl_GetResult(interp); } /* Tcl_FreeResult(interp); not support for perl/tk */ } else if (tablePtr->arrayVar) { result = LangString(Tcl_GetVar2(interp, tablePtr->arrayVar, buf, TCL_GLOBAL_ONLY)); } if (result == NULL) result = ""; if (tablePtr->caching && entryPtr != NULL) { /* * If we are caching, make sure we cache the returned value * * entryPtr will have been set from above, but check to make sure * someone didn't change caching during -command evaluation. */ char *val; val = (char *)ckalloc(strlen(result)+1); strcpy(val, result); Tcl_SetHashValue(entryPtr, val); } VALUE: #ifdef PROCS if (result != NULL) { /* Do we have procs, are we showing their value, is this a proc? */ if (tablePtr->hasProcs && !tablePtr->showProcs && *result == '=' && !(r-tablePtr->rowOffset == tablePtr->activeRow && c-tablePtr->colOffset == tablePtr->activeCol)) { Tcl_DString script; /* provides a rough mutex on preventing proc loops */ entryPtr = Tcl_CreateHashEntry(tablePtr->inProc, buf, &new); if (!new) { Tcl_SetHashValue(entryPtr, 1); Tcl_AddErrorInfo(interp, "\n\t(loop hit in proc evaled by table)"); return result; } Tcl_SetHashValue(entryPtr, 0); Tcl_DStringInit(&script); ExpandPercents(tablePtr, result+1, r, c, result+1, (char *)NULL, 0, &script, 0); if (Tcl_GlobalEval(interp, Tcl_DStringValue(&script)) != TCL_OK || Tcl_GetHashValue(entryPtr) == 1) { Tcl_AddErrorInfo(interp, "\n\tin proc evaled by table:\n"); Tcl_AddErrorInfo(interp, Tcl_DStringValue(&script)); Tcl_BackgroundError(interp); } else { result = Tcl_GetResult(interp); } /* Tcl_FreeResult(interp); Not Supported for perl/tk */ Tcl_DStringFree(&script); Tcl_DeleteHashEntry(entryPtr); } } #endif return (result?result:""); } /* *---------------------------------------------------------------------- * * TableSetCellValue -- * Takes a row,col pair in user coords and saves the given value for * that cell. This varies depending on what data source the * user has selected. * * Results: * Returns TCL_ERROR or TCL_OK, depending on whether an error * occured during set (ie: during evaluation of -command). * * Side effects: * If the value is NULL (empty string), it will be unset from * an array rather than set to the empty string. * *---------------------------------------------------------------------- */ int TableSetCellValue(Table *tablePtr, int r, int c, char *value) { register Tcl_Interp *interp = tablePtr->interp; char buf[INDEX_BUFSIZE]; int code = TCL_OK, flash = 0; TableMakeArrayIndex(r, c, buf); if (tablePtr->state == STATE_DISABLED) { return TCL_OK; } if (tablePtr->command && tablePtr->useCmd) { if (LangDoCallback(interp, tablePtr->command, 1, 4, "%d %d %d %_",1,r,c, LangStringArg(value)) == TCL_ERROR) { /* An error resulted. Prevent further triggering of the command * and set up the error message. */ tablePtr->useCmd = 0; tablePtr->dataSource &= ~DATA_COMMAND; if (tablePtr->arrayVar) tablePtr->dataSource |= DATA_ARRAY; Tcl_AddErrorInfo(interp, "\n\t(in command executed by table)"); Tcl_BackgroundError(interp); code = TCL_ERROR; } else { flash = 1; } Tcl_SetResult(interp, (char *) NULL, TCL_STATIC); } else if (tablePtr->arrayVar) { /* Warning: checking for \0 as the first char could invalidate * allowing it as a valid first char */ if ((value == NULL || *value == '\0') && tablePtr->sparse) { /* perltk not supported */ /* Tcl_UnsetVar2(interp, LangString(Tcl_GetVar(interp, tablePtr->arrayVar, TCL_GLOBAL_ONLY)), buf, TCL_GLOBAL_ONLY); */ /* Replaced with This (defined in tkTable.xs) */ tkTableUnsetElement(tablePtr->arrayVar, buf); } else if (Tcl_SetVar2(interp, tablePtr->arrayVar, buf, value, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) { code = TCL_ERROR; } } if (code == TCL_ERROR) { return TCL_ERROR; } if (tablePtr->caching) { Tcl_HashEntry *entryPtr; int new; char *val; entryPtr = Tcl_CreateHashEntry(tablePtr->cache, buf, &new); if (!new) { val = (char *) Tcl_GetHashValue(entryPtr); if (val) ckfree(val); } val = (char *)ckalloc(strlen(value)+1); strcpy(val, value); Tcl_SetHashValue(entryPtr, val); flash = 1; } /* We do this conditionally because the var array already has * it's own check to flash */ if (flash && tablePtr->flashMode) { r -= tablePtr->rowOffset; c -= tablePtr->colOffset; TableAddFlash(tablePtr, r, c); TableRefresh(tablePtr, r, c, CELL); } return TCL_OK; } /* *---------------------------------------------------------------------- * * TableMoveCellValue -- * To move cells faster on delete/insert line or col when cache is on * and variable, command is off. * To avoid another call to TableMakeArrayIndex(r, c, buf), * we optionally provide the buffers. * outOfBounds means we will just set the cell value to "" * * Results: * Returns TCL_ERROR or TCL_OK, depending on whether an error * occured during set (ie: during evaluation of -command). * * Side effects: * If the value is NULL (empty string), it will be unset from * an array rather than set to the empty string. * *---------------------------------------------------------------------- */ int TableMoveCellValue(Table *tablePtr, int fromr, int fromc, char *frombuf, int tor, int toc, char *tobuf, int outOfBounds) { int new; char *result = NULL; Tcl_Interp *interp = tablePtr->interp; if (outOfBounds) { return TableSetCellValue(tablePtr, tor, toc, ""); } if (tablePtr->caching && (!(tablePtr->command && tablePtr->useCmd))) { Tcl_HashEntry *entryPtr; /* * if we are caching, let's see if we have the value cached */ entryPtr = Tcl_CreateHashEntry(tablePtr->cache, frombuf, &new); if (!new) { char *val; result = (char *) Tcl_GetHashValue(entryPtr); /* * we set tho old value to NULL */ Tcl_SetHashValue(entryPtr, NULL); /* * set the destination to the source pointer without new mallocing! */ entryPtr = Tcl_CreateHashEntry(tablePtr->cache, tobuf, &new); /* * free old value */ if (!new) { val = (char *) Tcl_GetHashValue(entryPtr); if (val) ckfree(val); } Tcl_SetHashValue(entryPtr, result); if (tablePtr->arrayVar) { /* * first, delete from var. */ /* perltk not supported */ /*Tcl_UnsetVar2(interp, tablePtr->arrayVar, frombuf, TCL_GLOBAL_ONLY); */ /* Replaced with This (defined in tkTable.xs) */ tkTableUnsetElement(tablePtr->arrayVar, frombuf); /* * Warning: checking for \0 as the first char could invalidate * allowing it as a valid first char */ if (Tcl_SetVar2(interp, tablePtr->arrayVar, tobuf, result, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) { return TCL_ERROR; } } return TCL_OK; } } /* * We have to do it the old way */ return TableSetCellValue(tablePtr, tor, toc, TableGetCellValue(tablePtr, fromr, fromc)); } /* *---------------------------------------------------------------------- * * TableGetIcursor -- * Parses the argument as an index into the active cell string. * Recognises 'end', 'insert' or an integer. Constrains it to the * size of the buffer. This acts like a "SetIcursor" when *posn is NULL. * * Results: * If (posn != NULL), then it gets the cursor position. * * Side effects: * Can move cursor position. * *---------------------------------------------------------------------- */ int TableGetIcursor(Table *tablePtr, char *arg, int *posn) { int tmp, len; len = strlen(tablePtr->activeBuf); #ifdef TCL_UTF_MAX /* Need to base it off strlen to account for \x00 (Unicode null) */ len = Tcl_NumUtfChars(tablePtr->activeBuf, len); #endif /* ensure icursor didn't get out of sync */ if (tablePtr->icursor > len) tablePtr->icursor = len; /* is this end */ if (strcmp(arg, "end") == 0) { tmp = len; } else if (strcmp(arg, "insert") == 0) { tmp = tablePtr->icursor; } else { if (Tcl_GetInt(tablePtr->interp, LangStringArg(arg), &tmp) != TCL_OK) { return TCL_ERROR; } CONSTRAIN(tmp, 0, len); } if (posn) { *posn = tmp; } else { tablePtr->icursor = tmp; } return TCL_OK; } /* *-------------------------------------------------------------- * * TableGetIndex -- * Parse an index into a table and return either its value * or an error. * * Results: * A standard Tcl result. If all went well, then *row,*col is * filled in with the index corresponding to string. If an * error occurs then an error message is left in interp result. * The index returned is in user coords. * * Side effects: * Sets row,col index to an appropriately constrained user index. * *-------------------------------------------------------------- */ int TableGetIndex(tablePtr, str, row_p, col_p) register Table *tablePtr; /* Table for which the index is being * specified. */ char *str; /* Symbolic specification of cell in table. */ int *row_p; /* Where to store converted row. */ int *col_p; /* Where to store converted col. */ { int r, c, len = strlen(str); char dummy; /* * Note that all of these values will be adjusted by row/ColOffset */ if (str[0] == '@') { /* @x,y coordinate */ int x, y; if (sscanf(str+1, "%d,%d%c", &x, &y, &dummy) != 2) { /* Make sure it won't work for "2,3extrastuff" */ goto IndexError; } TableWhatCell(tablePtr, x, y, &r, &c); r += tablePtr->rowOffset; c += tablePtr->colOffset; } else if (*str == '-' || isdigit(str[0])) { if (sscanf(str, "%d,%d%c", &r, &c, &dummy) != 2) { /* Make sure it won't work for "2,3extrastuff" */ goto IndexError; } /* ensure appropriate user index */ CONSTRAIN(r, tablePtr->rowOffset, tablePtr->rows-1+tablePtr->rowOffset); CONSTRAIN(c, tablePtr->colOffset, tablePtr->cols-1+tablePtr->colOffset); } else if (len > 1 && strncmp(str, "active", len) == 0 ) { /* active */ if (tablePtr->flags & HAS_ACTIVE) { r = tablePtr->activeRow+tablePtr->rowOffset; c = tablePtr->activeCol+tablePtr->colOffset; } else { Tcl_SetStringObj(Tcl_GetObjResult(tablePtr->interp), "no \"active\" cell in table", -1); return TCL_ERROR; } } else if (len > 1 && strncmp(str, "anchor", len) == 0) { /* anchor */ if (tablePtr->flags & HAS_ANCHOR) { r = tablePtr->anchorRow+tablePtr->rowOffset; c = tablePtr->anchorCol+tablePtr->colOffset; } else { Tcl_SetStringObj(Tcl_GetObjResult(tablePtr->interp), "no \"anchor\" cell in table", -1); return TCL_ERROR; } } else if (strncmp(str, "end", len) == 0) { /* end */ r = tablePtr->rows-1+tablePtr->rowOffset; c = tablePtr->cols-1+tablePtr->colOffset; } else if (strncmp(str, "origin", len) == 0) { /* origin */ r = tablePtr->titleRows+tablePtr->rowOffset; c = tablePtr->titleCols+tablePtr->colOffset; } else if (strncmp(str, "topleft", len) == 0) { /* topleft */ r = tablePtr->topRow+tablePtr->rowOffset; c = tablePtr->leftCol+tablePtr->colOffset; } else if (strncmp(str, "bottomright", len) == 0) { /* bottomright */ /* * FIX: Should this avoid spans, or consider them in the bottomright? tablePtr->flags |= AVOID_SPANS; tablePtr->flags &= ~AVOID_SPANS; */ TableGetLastCell(tablePtr, &r, &c); r += tablePtr->rowOffset; c += tablePtr->colOffset; } else { IndexError: Tcl_AppendStringsToObj(Tcl_GetObjResult(tablePtr->interp), "bad table index \"", str, "\": must be active, anchor, end, ", "origin, topleft, bottomright, @x,y, or <row>,<col>", (char *)NULL); return TCL_ERROR; } /* Note: values are expected to be properly constrained * as a user index by this point */ if (row_p) *row_p = r; if (col_p) *col_p = c; return TCL_OK; } /* *-------------------------------------------------------------- * * Table_SetCmd -- * This procedure is invoked to process the set method * that corresponds to a widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_SetCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *)clientData; int row, col, len, i, j, max; char *str; /* sets any number of tags/indices to a given value */ if (objc < 3) { CMD_SET_USAGE: Tcl_WrongNumArgs(interp, 2, objv, "?row|col? index ?value? ?index value ...?"); return TCL_ERROR; } /* make sure there is a data source to accept set */ if (tablePtr->dataSource == DATA_NONE) { return TCL_OK; } str = Tcl_GetStringFromObj(objv[2], &len); if (strncmp(str, "row", len) == 0 || strncmp(str, "col", len) == 0) { Tcl_Obj *resultPtr = Tcl_GetObjResult(interp); /* set row index list ?index list ...? */ if (objc < 4) { goto CMD_SET_USAGE; } else if (objc == 4) { if (TableGetIndexObj(tablePtr, objv[3], &row, &col) != TCL_OK) { return TCL_ERROR; } if (*str == 'r') { max = tablePtr->cols+tablePtr->colOffset; for (i=col; i<max; i++) { str = TableGetCellValue(tablePtr, row, i); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewStringObj(str, -1)); } } else { max = tablePtr->rows+tablePtr->rowOffset; for (i=row; i<max; i++) { str = TableGetCellValue(tablePtr, i, col); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewStringObj(str, -1)); } } } else if (tablePtr->state == STATE_NORMAL) { int listc; Tcl_Obj **listv; /* make sure there are an even number of index/list pairs */ if (objc & 0) { goto CMD_SET_USAGE; } for (i = 3; i < objc-1; i += 2) { if ((TableGetIndexObj(tablePtr, objv[i], &row, &col) != TCL_OK) || (Tcl_ListObjGetElements(interp, objv[i+1], &listc, &listv) != TCL_OK)) { return TCL_ERROR; } if (*str == 'r') { max = col+MIN(tablePtr->cols+tablePtr->colOffset-col, listc); for (j = col; j < max; j++) { if (TableSetCellValue(tablePtr, row, j, Tcl_GetString(listv[j-col])) != TCL_OK) { return TCL_ERROR; } if (row-tablePtr->rowOffset == tablePtr->activeRow && j-tablePtr->colOffset == tablePtr->activeCol) { TableGetActiveBuf(tablePtr); } TableRefresh(tablePtr, row-tablePtr->rowOffset, j-tablePtr->colOffset, CELL); } } else { max = row+MIN(tablePtr->rows+tablePtr->rowOffset-row, listc); for (j = row; j < max; j++) { if (TableSetCellValue(tablePtr, j, col, Tcl_GetString(listv[j-row])) != TCL_OK) { return TCL_ERROR; } if (j-tablePtr->rowOffset == tablePtr->activeRow && col-tablePtr->colOffset == tablePtr->activeCol) { TableGetActiveBuf(tablePtr); } TableRefresh(tablePtr, j-tablePtr->rowOffset, col-tablePtr->colOffset, CELL); } } } } } else if (objc == 3) { /* set index */ if (TableGetIndexObj(tablePtr, objv[2], &row, &col) != TCL_OK) { return TCL_ERROR; } else { /* * Cannot use Tcl_GetObjResult here because TableGetCellValue * can corrupt the resultPtr. */ Tcl_SetObjResult(interp, Tcl_NewStringObj( TableGetCellValue(tablePtr, row, col),-1)); } } else { /* set index val ?index val ...? */ /* make sure there are an even number of index/value pairs */ if (objc & 1) { goto CMD_SET_USAGE; } for (i = 2; i < objc-1; i += 2) { if ((TableGetIndexObj(tablePtr, objv[i], &row, &col) != TCL_OK) || (TableSetCellValue(tablePtr, row, col, Tcl_GetString(objv[i+1])) != TCL_OK)) { return TCL_ERROR; } row -= tablePtr->rowOffset; col -= tablePtr->colOffset; if (row == tablePtr->activeRow && col == tablePtr->activeCol) { TableGetActiveBuf(tablePtr); } TableRefresh(tablePtr, row, col, CELL); } } return TCL_OK; } /* *-------------------------------------------------------------- * * Table_SpanSet -- * Takes row,col in user coords and sets a span on the * cell if possible * * Results: * A standard Tcl result * * Side effects: * The span can be constrained * *-------------------------------------------------------------- */ static int Table_SpanSet(register Table *tablePtr, int urow, int ucol, int rs, int cs) { Tcl_Interp *interp = tablePtr->interp; int i, j, new, ors, ocs, result = TCL_OK; int row, col; Tcl_HashEntry *entryPtr; Tcl_HashSearch search; char *dbuf, buf[INDEX_BUFSIZE], cell[INDEX_BUFSIZE], span[INDEX_BUFSIZE]; row = urow - tablePtr->rowOffset; col = ucol - tablePtr->colOffset; TableMakeArrayIndex(urow, ucol, cell); if (tablePtr->spanTbl == NULL) { tablePtr->spanTbl = (Tcl_HashTable *)ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(tablePtr->spanTbl, TCL_STRING_KEYS); tablePtr->spanAffTbl = (Tcl_HashTable *)ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(tablePtr->spanAffTbl, TCL_STRING_KEYS); } /* first check in the affected cells table */ if ((entryPtr=Tcl_FindHashEntry(tablePtr->spanAffTbl, cell)) != NULL) { /* We have to make sure this was not already hidden * that's an error */ if ((char *)Tcl_GetHashValue(entryPtr) != NULL) { Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "cannot set spanning on hidden cell ", cell, (char *) NULL); return TCL_ERROR; } } /* do constraints on the spans * title cells must not expand beyond the titles * other cells can't expand negatively into title area */ if ((row < tablePtr->titleRows) && (row + rs >= tablePtr->titleRows)) { rs = tablePtr->titleRows - row - 1; } if ((col < tablePtr->titleCols) && (col + cs >= tablePtr->titleCols)) { cs = tablePtr->titleCols - col - 1; } rs = MAX(0, rs); cs = MAX(0, cs); /* then work in the span cells table */ if ((entryPtr = Tcl_FindHashEntry(tablePtr->spanTbl, cell)) != NULL) { /* We have to readjust for what was there first */ TableParseArrayIndex(&ors, &ocs, (char *)Tcl_GetHashValue(entryPtr)); ckfree((char *) Tcl_GetHashValue(entryPtr)); Tcl_DeleteHashEntry(entryPtr); for (i = urow; i <= urow+ors; i++) { for (j = ucol; j <= ucol+ocs; j++) { TableMakeArrayIndex(i, j, buf); entryPtr = Tcl_FindHashEntry(tablePtr->spanAffTbl, buf); if (entryPtr != NULL) { Tcl_DeleteHashEntry(entryPtr); } TableRefresh(tablePtr, i-tablePtr->rowOffset, j-tablePtr->colOffset, CELL); } } } else { ors = ocs = 0; } /* calc to make sure that span is OK */ for (i = urow; i <= urow+rs; i++) { for (j = ucol; j <= ucol+cs; j++) { TableMakeArrayIndex(i, j, buf); entryPtr = Tcl_FindHashEntry(tablePtr->spanAffTbl, buf); if (entryPtr != NULL) { /* Something already spans here */ Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "cannot overlap already spanned cell ", buf, (char *) NULL); result = TCL_ERROR; rs = ors; cs = ocs; break; } } if (result == TCL_ERROR) break; } /* 0,0 span means set to unspanned again */ if (rs == 0 && cs == 0) { entryPtr = Tcl_FindHashEntry(tablePtr->spanTbl, cell); if (entryPtr != NULL) { ckfree((char *) Tcl_GetHashValue(entryPtr)); Tcl_DeleteHashEntry(entryPtr); } entryPtr = Tcl_FindHashEntry(tablePtr->spanAffTbl, cell); if (entryPtr != NULL) { Tcl_DeleteHashEntry(entryPtr); } if (Tcl_FirstHashEntry(tablePtr->spanTbl, &search) == NULL) { /* There are no more spans, so delete tables to improve * performance of TableCellCoords */ Tcl_DeleteHashTable(tablePtr->spanTbl); ckfree((char *) (tablePtr->spanTbl)); Tcl_DeleteHashTable(tablePtr->spanAffTbl); ckfree((char *) (tablePtr->spanAffTbl)); tablePtr->spanTbl = NULL; tablePtr->spanAffTbl = NULL; } return result; } /* Make sure there is no extra stuff */ TableMakeArrayIndex(rs, cs, span); /* Set affected cell table to a NULL value */ entryPtr = Tcl_CreateHashEntry(tablePtr->spanAffTbl, cell, &new); Tcl_SetHashValue(entryPtr, (char *) NULL); /* set the spanning cells table with span value */ entryPtr = Tcl_CreateHashEntry(tablePtr->spanTbl, cell, &new); dbuf = (char *)ckalloc(strlen(span)+1); strcpy(dbuf, span); Tcl_SetHashValue(entryPtr, dbuf); dbuf = Tcl_GetHashKey(tablePtr->spanTbl, entryPtr); /* Set other affected cells */ EmbWinUnmap(tablePtr, row, row + rs, col, col + cs); for (i = urow; i <= urow+rs; i++) { for (j = ucol; j <= ucol+cs; j++) { TableMakeArrayIndex(i, j, buf); entryPtr = Tcl_CreateHashEntry(tablePtr->spanAffTbl, buf, &new); if (!(i == urow && j == ucol)) { Tcl_SetHashValue(entryPtr, (char *) dbuf); } } } TableRefresh(tablePtr, row, col, CELL); return result; } /* *-------------------------------------------------------------- * * Table_SpanCmd -- * This procedure is invoked to process the span method * that corresponds to a widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_SpanCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int rs, cs, row, col, i; Tcl_HashEntry *entryPtr; Tcl_Obj *objPtr, *resultPtr; if (objc < 2 || (objc > 4 && (objc&1))) { Tcl_WrongNumArgs(interp, 2, objv, "?index? ?rows,cols index rows,cols ...?"); return TCL_ERROR; } resultPtr = Tcl_GetObjResult(interp); if (objc == 2) { if (tablePtr->spanTbl) { Tcl_HashSearch search; for (entryPtr = Tcl_FirstHashEntry(tablePtr->spanTbl, &search); entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { objPtr = Tcl_NewStringObj(Tcl_GetHashKey(tablePtr->spanTbl, entryPtr), -1); Tcl_ListObjAppendElement(NULL, resultPtr, objPtr); objPtr = Tcl_NewStringObj((char *) Tcl_GetHashValue(entryPtr), -1); Tcl_ListObjAppendElement(NULL, resultPtr, objPtr); } } return TCL_OK; } else if (objc == 3) { if (TableGetIndexObj(tablePtr, objv[2], &row, &col) == TCL_ERROR) { return TCL_ERROR; } /* Just return the spanning values of the one cell */ if (tablePtr->spanTbl && (entryPtr = Tcl_FindHashEntry(tablePtr->spanTbl, Tcl_GetString(objv[2]))) != NULL) { Tcl_SetStringObj(resultPtr, (char *)Tcl_GetHashValue(entryPtr), -1); } return TCL_OK; } else { for (i = 2; i < objc-1; i += 2) { if (TableGetIndexObj(tablePtr, objv[i], &row, &col) == TCL_ERROR || (TableParseArrayIndex(&rs, &cs, Tcl_GetString(objv[i+1])) != 2) || Table_SpanSet(tablePtr, row, col, rs, cs) == TCL_ERROR) { return TCL_ERROR; } } } return TCL_OK; } /* *-------------------------------------------------------------- * * Table_HiddenCmd -- * This procedure is invoked to process the hidden method * that corresponds to a widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_HiddenCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int i, row, col; Tcl_HashEntry *entryPtr; char *span; if (objc < 2) { Tcl_WrongNumArgs(interp, 2, objv, "?index? ?index ...?"); return TCL_ERROR; } if (tablePtr->spanTbl == NULL) { /* Avoid the whole thing if we have no spans */ if (objc > 3) { Tcl_SetBooleanObj(Tcl_GetObjResult(interp), 0); } return TCL_OK; } if (objc == 2) { /* return all "hidden" cells */ Tcl_DString cells; Tcl_HashSearch search; Tcl_DStringInit(&cells); for (entryPtr = Tcl_FirstHashEntry(tablePtr->spanAffTbl, &search); entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { if ((span = (char *) Tcl_GetHashValue(entryPtr)) == NULL) { /* this is actually a spanning cell */ continue; } Tcl_DStringAppendElement(&cells, Tcl_GetHashKey(tablePtr->spanAffTbl, entryPtr)); } span = LangString(TableCellSort(tablePtr, Tcl_DStringValue(&cells))); if (span != NULL) { Tcl_SetResult(interp, span, TCL_DYNAMIC); } Tcl_DStringFree(&cells); return TCL_OK; } if (objc == 3) { if (TableGetIndexObj(tablePtr, objv[2], &row, &col) != TCL_OK) { return TCL_ERROR; } /* Just return the spanning values of the one cell */ entryPtr = Tcl_FindHashEntry(tablePtr->spanAffTbl, Tcl_GetString(objv[2])); if (entryPtr != NULL && (span = (char *)Tcl_GetHashValue(entryPtr)) != NULL) { /* this is a hidden cell */ Tcl_SetStringObj(Tcl_GetObjResult(interp), span, -1); } return TCL_OK; } for (i = 2; i < objc; i++) { if (TableGetIndexObj(tablePtr, objv[i], &row, &col) == TCL_ERROR) { return TCL_ERROR; } entryPtr = Tcl_FindHashEntry(tablePtr->spanAffTbl, Tcl_GetString(objv[i])); if (entryPtr != NULL && (char *)Tcl_GetHashValue(entryPtr) != NULL) { /* this is a hidden cell */ continue; } /* We only reach here if it doesn't satisfy "hidden" criteria */ Tcl_SetBooleanObj(Tcl_GetObjResult(interp), 0); return TCL_OK; } Tcl_SetBooleanObj(Tcl_GetObjResult(interp), 1); return TCL_OK; } /* *-------------------------------------------------------------- * * TableSpanSanCheck -- * This procedure is invoked by TableConfigure to make sure * that spans are kept sane according to the docs. * See the user documentation for details on what it does. * * Results: * void. * * Side effects: * Spans in title areas can be reconstrained. * *-------------------------------------------------------------- */ void TableSpanSanCheck(register Table *tablePtr) { int rs, cs, row, col, reset; Tcl_HashEntry *entryPtr; Tcl_HashSearch search; if (tablePtr->spanTbl == NULL) { return; } for (entryPtr = Tcl_FirstHashEntry(tablePtr->spanTbl, &search); entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { reset = 0; TableParseArrayIndex(&row, &col, Tcl_GetHashKey(tablePtr->spanTbl, entryPtr)); TableParseArrayIndex(&rs, &cs, (char *) Tcl_GetHashValue(entryPtr)); if ((row-tablePtr->rowOffset < tablePtr->titleRows) && (row-tablePtr->rowOffset+rs >= tablePtr->titleRows)) { rs = tablePtr->titleRows-(row-tablePtr->rowOffset)-1; reset = 1; } if ((col-tablePtr->colOffset < tablePtr->titleCols) && (col-tablePtr->colOffset+cs >= tablePtr->titleCols)) { cs = tablePtr->titleCols-(col-tablePtr->colOffset)-1; reset = 1; } if (reset) { Table_SpanSet(tablePtr, row, col, rs, cs); } } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable800/mm.h���������������������������������������������������������0000644�0000000�0000000�00000007276�13745605157�016652� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * mm.h -- * * This is the header file for the module that implements * command structure lookups. * * Copyright (c) 1997,1998 Jeffrey Hobbs * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * */ #ifndef _MM_H_ #define _MM_H_ #include <string.h> #include <stdlib.h> #include <tk.h> /* Make sure this syncs with Makefile.in */ #define MM_MAJOR_VERSION 1 #define MM_MINOR_VERSION 0 #define MM_RELEASE_SERIAL 0 #define MM_VERSION "1.0" #define MM_PATCH_LEVEL "1.0.0" /* Now we start defining package specific stuff */ #define MM_ERROR 0 #define MM_VALUE (1<<0) #define MM_PROC (1<<1) #define MM_OBJPROC (1<<2) #define MM_SUBPROC (1<<3) #define MM_LAST ((char *) NULL) #define MM_OVERWRITE (1<<0) #define MM_MERGE (1<<1) /* structure for use in parsing general major/minor commands */ typedef struct { char *name; /* name of the command/value */ Tcl_CmdProc *proc; /* >0 because 0 represents an error or proc */ int type; /* whether it is proc or just value */ ClientData data; /* optional clientData arg */ } MajorMinor_Cmd; extern int MM_GetProcExact _ANSI_ARGS_((const MajorMinor_Cmd *cmds, const char *name, Tcl_CmdProc **proc)); extern void MM_GetError _ANSI_ARGS_((Tcl_Interp *interp, const MajorMinor_Cmd *cmds, const char *arg)); extern int MM_GetProc _ANSI_ARGS_((Tcl_Interp *interp, MajorMinor_Cmd *cmds, const char *arg, MajorMinor_Cmd **cmd)); extern int MM_HandleArgs _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, MajorMinor_Cmd *cmds, int argc, char **argv)); extern int MM_HandleCmds _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv)); extern MajorMinor_Cmd *MM_InitCmds _ANSI_ARGS_((Tcl_Interp *interp, char *name, MajorMinor_Cmd *cmds, ClientData clientData, int flags)); extern int MM_InsertCmd _ANSI_ARGS_((Tcl_Interp *interp, MajorMinor_Cmd *cmds, const char *name, Tcl_CmdProc **proc, int type)); extern int MM_RemoveCmd _ANSI_ARGS_((Tcl_Interp *interp, MajorMinor_Cmd *cmds, const char *name)); EXTERN int Majmin_Init _ANSI_ARGS_((Tcl_Interp *interp)); EXTERN int Majmin_SafeInit _ANSI_ARGS_((Tcl_Interp *interp)); EXTERN int Tcl_MajminCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv)); /* structure for use in parsing table commands/values */ typedef struct { char *name; /* name of the command/value */ int value; /* >0 because 0 represents an error or proc */ } Cmd_Struct; extern char * Cmd_GetName _ANSI_ARGS_((const Cmd_Struct *cmds, int val)); extern int Cmd_GetValue _ANSI_ARGS_((const Cmd_Struct *cmds, Arg arg)); extern void Cmd_GetError _ANSI_ARGS_((Tcl_Interp *interp, const Cmd_Struct *cmds, Arg arg)); extern int Cmd_Parse _ANSI_ARGS_((Tcl_Interp *interp, Cmd_Struct *cmds, const char *arg)); extern int Cmd_OptionSet _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, Tk_Window unused, Arg value, char *widgRec, int offset)); extern Arg Cmd_OptionGet _ANSI_ARGS_((ClientData clientData, Tk_Window unused, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)); extern int Cmd_BitSet _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, Tk_Window unused, Arg value, char *widgRec, int offset)); extern char * Cmd_BitGet _ANSI_ARGS_((ClientData clientData, Tk_Window unused, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)); #endif /* _MM_H_ */ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable800/mac_tkTable.r������������������������������������������������0000644�0000000�0000000�00000002504�13745605157�020446� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include <Types.r> #include <SysTypes.r> #include "../generic/version.h" resource 'vers' (1) { TBL_MAJOR_VERSION, TBL_MINOR_VERSION, final, 0x00, verUS, TBL_VERSION, "tkTable " TBL_VERSION " by Jeffrey Hobbs\n" "Macintosh Port by Chuck Houpt" }; resource 'vers' (2) { TBL_MAJOR_VERSION, TBL_MINOR_VERSION, final, 0x00, verUS, TBL_VERSION, "tkTable " TBL_VERSION " © 1997-2000" }; /* * The -16397 string will be displayed by Finder when a user * tries to open the shared library. The string should * give the user a little detail about the library's capabilities * and enough information to install the library in the correct location. * A similar string should be placed in all shared libraries. */ resource 'STR ' (-16397, purgeable) { "tkTable Library\n\n" "This library provides the ability to create tables " " from Tcl/Tk programs. To work properly, it " "should be placed in the ÔTool Command LanguageŐ folder " "within the Extensions folder." }; read 'TEXT' (3000, "tkTable", purgeable, preload) "tkTable.tcl"; /* * We now load the Tk library into the resource fork of the library. */ data 'TEXT' (4000, "pkgIndex", purgeable, preload) { "package ifneeded Tktable " TBL_VERSION " " "\"package require Tk; [list load [file join $dir Tktable.shlb] Tktable]\"" }; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable800/Makefile.in��������������������������������������������������0000644�0000000�0000000�00000012641�13745605157�020125� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# version info in Makefile and C format include @srcdir@/version.h # This sets the name that tkTable will define for itself when loaded # If you change this, then the demos won't work, but it might be necessary # for those with another built-in "table" command TBL_COMMAND = table TBL_RUNTIME = tkTable.tcl SRCDIR = @srcdir@ TOPDIR = @srcdir@/.. LIBDIR = $(TOPDIR)/lib DOCDIR = $(TOPDIR)/doc PACKAGE = Tktable OBJS = tkTable.o tkTableWin.o tkTableTag.o tkTableEdit.o \ tkTableCell.o tkTableCmds.o cmd.o ## PostScript is on the drawing board #OBJS += tkTablePs.o MANS = tkTable.n #------------------------------------------------- prefix = @prefix@ exec_prefix = @exec_prefix@ TCL_VERSION = @TCL_VERSION@ TK_VERSION = @TK_VERSION@ WISH = wish$(TK_VERSION) TCL_SRC_DIR = @TCL_SRC_DIR@ TK_SRC_DIR = @TK_SRC_DIR@ TCL_BUILD_LIB_SPEC = @TCL_BUILD_LIB_SPEC@ TK_BUILD_LIB_SPEC = @TK_BUILD_LIB_SPEC@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TK_LIB_SPEC = @TK_LIB_SPEC@ TCL_LIBS = @TCL_LIBS@ TK_LIBS = @TK_LIBS@ TBL_CFLAGS = -O ## NO_EMBEDDED_RUNTIME means that the tkTable.tcl file will not be embedded ## into the executable, thus the default tkTable.tcl library file will not ## be available when the library is loaded. ## If this is defined, the tkTable.tcl file must be available in a ## predefined set of directories (see docs). #TBL_CFLAGS += -DNO_EMBEDDED_RUNTIME ## USE_EXIT_HANDLER is necessary for 8.1 before b3 and 8.0 ## It is a work-around for the improper unloading of DLLs when exiting #TBL_CFLAGS += -DUSE_EXIT_HANDLER ## Experimental, not documented, not complete... #TBL_CFLAGS += -DPROCS ## I use this for helping hunt down the slightest error #TBL_CFLAGS += -DDEBUG -g -Wall -Wno-implicit -Wshadow \ -Wpointer-arith -Wmissing-prototypes \ -Wmissing-declarations -Wnested-externs -Winline INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ CC = @CC@ RM = rm -f RANLIB = @TCL_RANLIB@ SHLIB_CFLAGS = @TCL_SHLIB_CFLAGS@ SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ SHLIB_LD = @TCL_SHLIB_LD@ TCL_PREFIX = @TCL_PREFIX@ ## HP cc sometimes requires -Aa for proper ansi compilation TCL_CFLAGS = $(TBL_CFLAGS) @TCL_DEFS@ @TCL_CFLAGS@ TCL_LD_FLAGS = @TCL_LD_FLAGS@ TK_LD_SEARCH_FLAGS = @TK_LD_SEARCH_FLAGS@ TK_XINCLUDES = @TK_XINCLUDES@ LIB_RUNTIME_DIR = @libdir@ INCLUDES = -I@includedir@ $(TK_XINCLUDES)\ -I$(TCL_SRC_DIR)/generic\ -I$(TK_SRC_DIR)/generic DLL = $(PACKAGE)$(SHLIB_SUFFIX) STATIC_LIB = $(PACKAGE).a PACKAGEDIR = $(PACKAGE)$(TBL_VERSION) STATIC_EXEC = tablewish DLLDIR = ${exec_prefix}/lib/$(PACKAGEDIR) RUNDIR = ${prefix}/lib/$(PACKAGEDIR) CFLAGS = -I. -I$(SRCDIR) $(TCL_CFLAGS) $(SHLIB_CFLAGS) $(INCLUDES)\ -DTBL_VERSION=\"$(TBL_VERSION)\"\ -DTBL_COMMAND=\"$(TBL_COMMAND)\"\ -DTBL_RUNTIME=\"$(TBL_RUNTIME)\"\ -DTBL_RUNTIME_DIR=\"$(RUNDIR)\" MAN_INSTALL_DIR = @mandir@/mann #COMPRESS = tar cvf $(PACKAGEDIR).tar $(PACKAGEDIR); compress $(PACKAGEDIR).tar COMPRESS = gtar zcvf $(PACKAGEDIR).tar.gz $(PACKAGEDIR) all: $(DLL) pkgIndex.tcl $(DLL): $(OBJS) $(SHLIB_LD) -o $@ $(OBJS) static $(STATIC_LIB): $(OBJS) pkgIndex.tcl $(RM) $(STATIC_LIB) ar cr $(STATIC_LIB) $(OBJS) $(RANLIB) $(STATIC_LIB) tkTable.o: $(SRCDIR)/tkTable.h $(SRCDIR)/tkTable.c \ $(SRCDIR)/tkTableInitScript.h tkTable.tcl.h tkTableCmds.o: $(SRCDIR)/tkTable.h $(SRCDIR)/tkTableCmds.c tkTableCell.o: $(SRCDIR)/tkTable.h $(SRCDIR)/tkTableCell.c tkTablePs.o: $(SRCDIR)/tkTable.h $(SRCDIR)/tkTablePs.c tkTableTag.o: $(SRCDIR)/tkTable.h $(SRCDIR)/tkTableTag.c tkTableWin.o: $(SRCDIR)/tkTable.h $(SRCDIR)/tkTableWin.c .c.o: $(CC) $(CFLAGS) $(CPPFLAGS) -c $(SRCDIR)/$*.c pkgIndex.tcl: (\ echo 'if {[catch {package require Tcl $(TCL_VERSION)}]} return';\ echo 'package ifneeded $(PACKAGE) $(TBL_VERSION)\ "package require Tk $(TK_VERSION);\ [list load [file join $$dir $(DLL).$(TBL_VERSION)] $(PACKAGE)]"'\ ) > pkgIndex.tcl install: all if test ! -d "$(DLLDIR)"; then mkdir "$(DLLDIR)"; fi if test ! -d "$(RUNDIR)"; then mkdir "$(RUNDIR)"; fi $(INSTALL_PROGRAM) $(DLL) "$(DLLDIR)/$(DLL).$(TBL_VERSION)" $(INSTALL_DATA) pkgIndex.tcl "$(DLLDIR)/pkgIndex.tcl" $(INSTALL_DATA) $(LIBDIR)/tkTable.tcl "$(RUNDIR)/tkTable.tcl" $(INSTALL_DATA) $(DOCDIR)/$(MANS) $(MAN_INSTALL_DIR)/ # Leaves behind created directories uninstall: $(RM) "$(DLLDIR)/$(DLL).$(TBL_VERSION)" "$(DLLDIR)/pkgIndex.tcl" "$(RUNDIR)/tkTable.tcl" $(MAN_INSTALL_DIR)/$(MANS) test: all $(WISH) $(TOPDIR)/demos/basic.tcl clean: $(RM) $(OBJS) $(DLL) $(STATIC_LIB) $(STATIC_EXEC) core pkgIndex.tcl tkTable.tcl.h distclean: clean $(RM) Makefile config.cache config.log config.status tkTable.tcl.h: $(LIBDIR)/tkTable.tcl sed -e '/^$\#/d' -e '/^$$/d' -e 's/\"/\\"/g' -e 's/^/"/' -e 's/$$/\\n"/' <$(LIBDIR)/tkTable.tcl > $@ || { $(RM) $@; exit 1; } tablewish: tkAppInit.o $(OBJS) wish: tkAppInit.o $(OBJS) $(CC) $(TK_LD_SEARCH_FLAGS) -o $(STATIC_EXEC) tkAppInit.o $(OBJS) \ $(LIBS) $(TK_BUILD_LIB_SPEC) $(TK_LIB_SPEC) $(TCL_BUILD_LIB_SPEC) $(TCL_LIB_SPEC) $(TK_LIBS) $(TCL_LIBS) distrib-clean: rm -rf ../../$(PACKAGEDIR) ../../$(PACKAGEDIR).tar.* distrib: $(RM) $(DOCDIR)/tkTable.html nroff -man $(DOCDIR)/tkTable.n | rman -f HTML > $(DOCDIR)/tkTable.html (cd ../..; \ cp -r tkTable $(PACKAGEDIR); \ cd $(PACKAGEDIR)/src; \ make distclean >&1 > /dev/null; \ cd ../..; $(COMPRESS); \ ) �����������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable800/mac_tkTable.mcp����������������������������������������������0000644�0000000�0000000�00000334060�13742524721�020763� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cool�����(�¨Č�©đ��@������������CodeWarrior Project�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������m��€��Nů��P���m�˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙�������!°ŕ�������������"���!ˇĐ���)���!ˇ0���8�����*t���G����������T���!˘���a����ç¸���o��� �������s��� �������‚��� !˘P���”��� �ăČ���¤��� �������¶����������Č���!˘€���×����ďŕ���ä���˙p���ň���ë�����ů�����Ž�� ���!ˇĐ�����������)���������6���îČ<��F���!˘Đ��S������H��[��������n���������|���������Ś����@��–��������Ż������Â��� """"��Ú���!��€��ô���"������#���������$���(��!���%�wi��0���&ë����?���'������X���(��¦0��j���)��� ��|���*8086�����+�¶ô ��”���,˙˙÷H�� ���-�����ą���.�����Ń���/µň\��ę���05ĘŔ�����1��đ�����2������-���3������E���4������^���5������v���6������‰���7�¶ô@��ś���8˙˙÷��®���9���%��Ŕ���:���"��Ó���;���)��ć���<���*��ř���=���-�� ���>���0�����?���3��3���@���6��G���A������_���B������w���C������Ź���D������§���E������ą���F������Ĺ���G������Ď���H������Ý���I������ě���J������ú���K������ ���L���������M������3���N������N���O������d���P������Ś���Q������Ł���R������­���S������ą���T������Ă���U������Ě���V������Ř���W������ă���X������ó���Y���������Z���������[������#���\������0���]������<���^������H���_������W���`������e���a������w���b���������c������’���d������¤���e������µ���f������Ę���g������ĺ���h������ü���i���������j������+���k������9���l������?���m������M���n������Y���o������f���p������s���q���������r������ś���s�������������������������������������������������������������������������������������������������������������������������������������������������������������������s���€��¦������s�PortSetPBitsPortS������������������������ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ��� ��'���˙����˙����˙����˙�������������������������������������������������������������JavaClasses.zip����������������ZIP JAVA������������������������������� ��� ��+��������������� �������������������������������� �����mac_tkTable_prefix.h�������������������������������������������������������������������� ��� ��� ������ ��� ���������������������������������������������������������������� Merge Out������������������������������������������������������????APPL���DLGXckidProjWSPC��������˙����˙����˙����˙�������������������������&���JavaClasses.jar����������������ZIP MWZP������������������������������������������������������������������������������������������������������������������������������Tktable.PPC.shlbBUG PPC��������TclLshlb�����������������������������������������������������������������������������������������������������������������????���������������������� ������� MacHeaders.h�������������������������������������������������������������������������������������������������������������������������������������������������������@���B������,���.���L���K���P���M���N���5���1���3���9���6���"���O���I���J���T���e���`���_���)��� ���+���#���*������H���E������ ��� ���-���/���!������� ���<���k���Z���D������;���:������������F���G���0���2���4���8���7������j���p������?������&������>��� ������=������h������g������X������Y���f���'���(��������������� ������A���C���������������U���c���W���V���d���R���^���]���\���Q���i���S���a���b���[���l���q���m���n���o���$���%���r����������������������������������������������������������JavaClasses.jar����������������ZIP MWZP���������� �� ���� Tktable.shlb���������������������������������������������������TclLshlb���DLGXckidProjWSPC����������JavaClasses.zip����������������ZIP JAVA�����MacOS Toolbox DEBUG 68K\���������������������������������������????APPL��€XŔ������������������������������������������������������������������????���������U {��������������€���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JavaClasses.zip����������������ZIP JAVA�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MSIEInternet Explorer����������������������������������������������Iexplore.exe��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������TclMacInitializeFragment�����������������������������������__sta�_start���������������������������������������������������������TclMacTerminateFragment������������������������������������������������������������������������ NONAME.EXE����������������������@���������������U {�������������˙����˙����˙����˙���������������������������������������������������������������������������������������������������������������������������������������������� ��������������������������������������������������������������������������a.out���������������������������@���������������U {��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MSIEInternet Explorer����������������������������������������������Iexplore.exe������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ ��������������������������������������������������������������������������a.out���������������������������@���������������U {������������������������������tktable2.20����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ��������������������������������������������������������������������������a.out���������������������������@���������������U {����������������������±Ů(��T~���������������� ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������__start������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MSIEInternet Explorer����������������������������������������������Iexplore.exe�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������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��ť��ž��ź�� ��™��ś��ˇ��˘��Ł����›��¤��Ą��¦��§��¨��©��Ş��«��¬��­��®��Ż��°��±��š��˛��ł��´��µ���B���C���D���E���>���A���F���G���H���=���@���I���J���K���L���M���N���O���P���Q���R���S���T���U���V���?���W���X���Y���Z���$���%���&���'��� ���#���(���)���*������"���+���,���-���.���/���0���1���2���3���4���5���6���7���8���!���9���:���;���<���ś���ť���ž���ź������›��� ���ˇ���˘���—���š���Ł���¤���Ą���¦���§���¨���©���Ş���«���¬���­���™���ł���´���µ���¶���Ż���˛���·���¸���ą���®���±���ş���»���Ľ���˝���ľ���ż���Ŕ���Á���Â���Ă���Ä���°���~������€������z���}���‚������„���y���|���…���†���‡������‰���Š���‹���Ś���Ť���Ž���Ź������‘���’���{���“���”���•���–��������������������� ��� ��� ���������� ��� ������������������������������������������������������`���a���b���c���\���_���d���e���f���[���^���g���h���i���j���k���l���m���n���o���p���q���r���s���t���]���u���v���w���x��Ů��Ú��Ű��Ü��Ő��Ř��Ý��Ţ��ß��Ô��×��ŕ��á��â��ă��ä��ĺ��ć��ç��č��é��ę��ë��ě��í��Ö��î��ď��đ��ń���Ę���Ë���Ě���Í���Ć��J���É���Î���Ď���Đ���Ĺ���Č��K���Ń��L��M��N���Ň���Ó���Ô���Ő���Ö���×���Ř���Ů���Ú���Ű���Ç��O��P��Q��R���á���â���ă���ä���Ý��8���ŕ���ĺ���ć���ç���Ü���ß��9���č��:��;��<���é���ę���ë���ě���í���î���ď���đ���ń���ň���Ţ��=��>��?��@���ř���ů���ú���ű���ô��A���÷���ü���ý���ţ���ó���ö��B���˙��C��D��E��������������������� ���ő��F��G��H��I��&��'��(��)��"��%��*��+��,��!��$��-��.��/��0��1��2��3��4��5��6��7��#���������� ��S���������� �� ��T����U��V��W�������������������� �� ��X��Y��Z��[����€����‚��{��~����„��…��z��}��†��ň��‡����‰��ô��Š��‹��Ś��Ť��Ž��Ź����‘��’��“��|��”��•��–��—��»��Ľ��˝��ľ��·��ş��ż��Ŕ��Á��¶��ą��Â��ó��Ă��Ä��Ĺ��ő��Ć��Ç��Č��É��Ę��Ë��Ě��Í��Î��Ď��¸��Đ��Ń��Ň��Ó�����R��S��T��U��N��l��Q��V��W��X��M��P��Y��Z��[��\��]��^��_��`��a��b��c��d��e��O��f��g��h��i��5��6��7��8��1��j��4��9��:��;��0��3��<��=��>��?��@��A��B��C��D��E��F��G��H��2��I��J��K��L������������k���������������� ��!��"��#��$��%��&��'��(��)��*��+����,��-��.��/��ű��ü��ý��ţ��÷��ú��˙�������ö��ů���������������� �� �� �� �� ����ř������������������������������������������������������������������������������������������^���������������`±Đż/˙˙Ľő���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������] ���������������a±Ů&ő��Ď���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������_ ���������������f±Ů&ő��hM��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� NONAME.EXE����������������������@���������������U {�������������������������������������������������b������������������€�������������j������������������€�������������k��������������������������������k���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ����������������������������������������������������������������������������������????���������a.out����������������������������������������������������������????APPL��€XŔ������������������������������������������������������������������????���������U {��������������€����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PC�������������������������������������������������Basic Toolbox Multi�First Segment�:a.out�Lib Import 68K�MPW Import 68K�Balloon Help�MW C/C++ 68K�MW Pascal 68K�Rez�PEF Import 68K�Basic Toolbox 68k�:Toolbox68k.out�Basci Toolbox PPC�Basic Toolbox PPC�Lib Import PPC�MW C/C++ PPC�MW Pascal PPC�PPCAsm�XCOFF Import PPC�PEF Import PPC�:ToolboxPPC.out�SillyBalls.c�SillyBalls.rsrc�InterfaceLib�MathLib�MSL RuntimePPC.Lib�MSL C.PPC.Lib�MSL C++.PPC.Lib�MacOS.lib�MathLib68K Fa(4i/8d).Lib�MSL Runtime68K.Lib�MSL C.68K Fa(4i_8d).Lib�MSL C++.68K Fa(4i_8d).Lib�Basic Toolbox FAT�:Merge Out�:ToolboxFAT.out�Toolbox68k.out�ToolboxPPC.out�MathLib68K Fa(4i_8d).Lib�MSL SIOUX.68K.Lib�MSL SIOUX.PPC.Lib�:Toolbox68k�:ToolboxPPC�:ToolboxFAT�:Basic Toolbox DEBUG 68k�Basic Toolbox DEBUG 68k�:Basic Toolbox DEBUG PPC�Basic Toolbox DEBUG PPC�MacOS Toolbox 68K�:MacOS Toolbox DEBUG 68K�MacOS Toolbox DEBUG 68K�:MacOS Toolbox DEBUG PPC�MacOS Toolbox DEBUG PPC�:MacOS Toolbox 68K�:MacOS Toolbox PPC�MacOS Toolbox PPC�MacOS Toolbox FAT�:MacOS Toolbox FAT�GameCode Converter�Flex Preprocessor�Bison Preprocessor�MSL C.68K (2i).Lib�MSL C++.68K (2i).Lib�MathLib68K (2i).Lib�68K Debug MacOS Toolbox�PPC Debug MacOS Toolbox�68K Final MacOS Toolbox�PPC Final MacOS Toolbox�FAT MacOS Toolbox�Application�Libraries�Mac Libraries�ANSI Libraries�:SillyBalls.c�:SillyBalls.rsrc�:Bin:MSL C.PPC.Lib�:Bin:MSL C++.PPC.Lib�:MacOS Common:InterfaceLib�:MacOS Common:MathLib�:Runtime:Runtime PPC:MSL RuntimePPC.Lib�:Bin:MSL SIOUX.PPC.Lib�tkTable.c�tkAppInit.c�tkTable.h�:tkTable�Tcl8.0.shlb�Tk8.0.shlb�tclMacLibrary.c�MSL RuntimePPC.DLL�MSL ShLibRuntime.Lib�dummy.c�Tktable.shlb�Tktable PPC�Tktable Fat�Tktable CFM68k�:Tktable.shlb�:Tktable.PPC.shlb�Tktable.PPC.shlb�tkTable.r�Tcl8.0CFM68K.shlb�Tk8.0CFM68K.shlb�:Tktable.CFM68k.shlb�MSL ShLibRuntimeCFM68K.Lib�MSL MWRuntimeLibCFM68K�MSL C.CFM68K Fa(4i_8d).Lib�Tktable.CFM68k.shlb�mac_tkTable.r�cmd.c�tkTableCell.c�tkTablePs.c�tkTableTag.c�tkTableWin.c�mac_tkTable_prefix.h�tkTableInitScript.h�version.h����������������������������������������������������������������������������������������������MacOS PPC Linker��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tktable PPC�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������:��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������__start�������������������������������������������������������������������������������������������������������������������������� �� �� �� �� �� �� �� �� �� �� �� �� �� ��! ��" ��# ��$ ��& ��'����� ���@����::���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙�����:::Tcl/Tk Folder:tcl8.0:�:�8.0:����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙@����:::Tcl/Tk Folder:tk8.0:�:�8.0:�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙@����:Extensions:Tool Command Language:�ol Command Language:����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙�����:MacOS Support:Headers:Universal Headers:������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙@����:Metrowerks Standard Library:MSL C:������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙@����:Metrowerks Standard Library:MSL C++:����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙@����:MacOS Support:MacHeaders:���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙@����:MacOS Support:Libraries:����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙@�� ��:MacOS Support:��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙@��� �����mac_tkTable_prefix.h���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������reg���$����������E���illD���i���5¸ ���‹���Get���¬���tMou���Ě���tDia���ń���dDia����� Dial��0��� ialo��S��� wDia��v��� ialo��‘��� xt I��˛���vent��Ň���elec��ó���alog�����alog��5���Dial��Y���Item��}���topA��ť���eAle��Â���onAl��á���dAle��ý���lert�����xt E��>���dGe��_���etDI��‚���Text��˘���t Mo��Á���gDe��á���urce��ó��� urge�����!��€��4���"nded��V���#ist���v���$5ň°��•���%������ł���&������Ö���'������ó���(���������)��� ��2���*_cas��S���+5ă0��l���,�ĺŔ��‹���-�reg��©���.������Č���/illD��â���05¸ �����1Get��(���2tMou��J���3tDia��h���4dDia��‹���5Dial��¨���6ialo��Â���7wDia��ŕ���8ialo��˙���9xt I�����:vent��?���;elec��]���<alog��z���=alog�����>Dial��ş���?Item��Ů���@topA��ű���A��€�����BonAl��:���CdAle��X���Dlert��{���Ext E�����FdGe��¶���GetDI��×���HText��ř���It Mo�� ���JgDe�� 0���Kurce�� N���Lurge�� m���M����� ‡���N����� «���O����� Í���P��� �� ď���Q����� ���R����� 0���S����� M���T����� g���U����� …���V����� ¤���W����� Ă���X Get�� ä���Y���� ���Zc To�� ���[lti��� =���\gmen�� _���]�Lib�� ~���^68K���  ���_rt 6�� Ŕ���`on H�� ß���a��€�� ý���bPasc�� ���cez�P�� =���dt 68�� [���e!Żč�� |���f!Żđ�� ť���g!Żđ�� ¶���h!Żđ�� Ő���i!°��� ó���j!°Ř�� ���k!°Č�� ,���l!°Č�� P���m!°Č�� r���n!°Č�� ”���o!°Č�� ˛���p!°Č�� Ő���q!°Č�� ň���r!°Č�� ���s!°Č��*���t!°Ř��I���u!°Ř��h���v!°H��‰���w6~p��§���x�eÜ��Ä���ycall��â���zBŕCŕ�����{HŕIŕ��#���|NŕOŕ��E���}TŕUŕ��e���~Zŕ[ŕ��„���`ŕaŕ��˘���€fŕgŕ��Ĺ�����€��â���‚nded������ist���!���„Targ��B���…ct D��[���†Sett��z���‡ Set�����eSaf��·���‰��� ��Ń���Š_cas��ő���‹5ă0�����Ś�ĺŔ��9���Ť�reg��W���Ž������z���ŹillD��—���5¸ ��±���‘Get��Ď���’tMou��î���“tDia�� ���”dDia��.���•Dial��L���–ialo��i���—wDia��‡���ialo��Ż���™xt I��Ô���švent��ü���›elec��"���śalog��G���ťalog��k���žDial��”���źItem��·��� topA��Ű���ˇ���������˘������)���Ł������H���¤������m���Ą������—���¦������ż���§������ç���¨������ ���©������4���Ş������W���«������w���¬������›���­������Ŕ���®������ĺ���Ż������ ���°������2���±������Z���˛������€���ł������Ą���´������É���µ������ň���¶���������·������9���¸������`���ą������‡���ş������¦���»������Ë���Ľ������ő���˝���������ľ������E���ż������i���Ŕ������’���Á������µ���Â������Ő���Ă������ů���Ä���������Ĺ������C���Ć������e���Ç������„���Č������¦���É������Ć���Ę������ĺ���Ë���������Ě������&���Í������C���Î������a���Ď������‚���Đ������Ł���Ń������Ľ���Ň������Ű���Ó������˙���Ô������!���Ő������C���Ö������a���×������„���Ř������ˇ���Ů������»���Ú������Ů���Ű������ř���Ü���������Ý������?���Ţ������d���ß������Ś���ŕ������˛���á������×���â������ű���ă������$���ä������G���ĺ������k���ć������’���ç������ą���č������Ř���é������ý���ę������'���ë������O���ě������w���í������›���î������Ä���ď������ç���đ���������ń������+���ň������P���ó������u���ô������ť���ő������Â���ö������ę���÷������ ���ř������ 5���ů������ Y���ú������ ‚���ű������ Ą���ü������ É���ý������ đ���ţ������!���˙������!6���������![��������!…��������!­��������!Ő��������!ů��������""��������"E��������"e��������"‰�� ������"®�� ������"Ó�� ������"ő�� ������#�� ������#6��������#V��������#u��������#“��������#¶��������#Ó��������#ń��������$��������$3��������$L��������$k��������$Ź��������$±��������$Ó��������$ń��������%��������%1��������%K��������%i�� ������%��!������%§��"������%É��#������%č��$������& ��%������&*��&������&I��'������&g��(������&Š��)������&§��*������&Ĺ��+������&ć��,������'��-������' ��.������'?��/������'c��0������'…��1������'§��2������'Ĺ��3������'č��4������(��5������(��6������(=��7������(\��8������({��9������(ź��:������(Â��;������(ć��<������) ��=������)+��>������)R��?������)v��@������)™��A������)˝��B������)á��C������*��D������*(��E������*M��F������*m��G������*”��H������*¸��I������*Ű��J������*˙��K������+��L������+:��M������+X��N������+w��O������+‘��P������+˛��Q������+Đ��R������+í��S������, ��T������,)��U������,F��V������,d��W������,��X������,ť��Y������,ľ��Z������,Ü��[������,ů��\������-��]������-?��^������-d��_������-Ś��`������-˛��a������-×��b������-ű��c������.$��d������.G��e������.k��f������.’��g������.ą��h������.Ř��i������.ý��j������/!��k������/F��l������/f��m������/��n������/¸��o������/ŕ��p������0��q������0-��r������0P��s������0p��t������0”��u������0ą��v������0Ţ��w������1��x������1)��y������1L��z������1p��{������1��|������1˝��}������1ĺ��~������2 ��������20��€������2T��������2}��‚������2 ��������2Ä��„������2ë��…������3��†������31��‡������3V��������3z��‰������3ź��Š������3ż��‹������3é��Ś������4��Ť������49��Ž������4]��Ź������4†��������4©��‘������4É��’������4í��“������5��”������57��•������5^��–������5‚��—������5Ą��������5É��™������5ń��š������6��›������6>��ś������6d��ť������6‰��ž������6­��ź������6Ö�� ������6ů��ˇ������7��˘������7D��Ł������7k��¤������7Š��Ą������7Ż��¦������7Ó��§������7ř��¨������8��©������8B��Ş������8j��«������8’��¬������8¶��­������8ß��®������9��Ż������9"��°������9F��±������9k��˛������9��ł������9·��´������9Ű��µ������9ţ��¶������:"��·������:J��¸������:o��ą������:—��ş������:˝��»������:â��Ľ������;��˝������;/��ľ������;R��ż������;v��Ŕ������;ť��Á������;Ä��Â������;ă��Ă������<��Ä������<,��Ĺ������<Q��Ć������<q��Ç������<›��Č������<Ă��É������<ë��Ę������=��Ë������=8��Ě������=[��Í������={��Î������=ź��Ď������=Ä��Đ������=é��Ń������>��Ň������>4��Ó������>W��Ô������>{��Ő������>ť��Ö������>Ľ��×������>Ţ��Ř������>ţ��Ů������?��Ú������?;��Ű������?^��Ü������?{��Ý������?™��Ţ������?ş��ß������?Ű��ŕ������?ô��á������@��â������@1��ă������@P��ä������@j��ĺ������@Ž��ć������@°��ç������@Ň��č������@đ��é������A��ę������A0��ë������AJ��ě������Ah��í������A‡��î������A¦��ď������AÇ��đ������Aĺ��ń������B��ň������B ��ó������BF��ô������Bl��ő������B”��ö������BĽ��÷������BŮ��ř������Bó��ů������C��ú������C+��ű������CE��ü������C^��ý������C|��ţ������C”��˙������C­���������CÉ��������Cĺ��������Ců��������D��������D.��������DG��������Da��������D~��������Dť�� ������D¶�� ������DÔ�� ������Dě�� ������E�� ������E��������E4��������EN��������Ej��������E��������E›��������E´��������EĐ��������Eé��������F��������F��������F8��������FP��������Fm��������F„��������Fś��������F·��������FŇ��������Fĺ�� ������Fţ��!������G��"������G0��#������GI��$������Ge��%������G��&������G›��'������G¸��(������GĎ��)������Gă��*������Gű��+������H��,������H-��-������HH��.������H`��/������Hw��0������HŹ��1������H«��2������HÄ��3������Hŕ��4������Hú��5������I��6������I+��7������IH��8������I_��9������Iw��:������I’��;������I­��<������IŔ��=������IŮ��>������Ió��?������J ��@������J$��A������J@��B������J^��C������Jv��D������J“��E������JŞ��F������Jľ��G������JÖ��H������Jď��I������K��J������K#��K������K;��L������KR��M������Kj��N������K‰��O������KĄ��P������KÄ��Q������Ká��R������Ký��S������L��T������L8��U������LR��V������Lm��W������L‹��X������L©��Y������Lż��Z������LŰ��[������Lř��\������M��]������M/��^������MN��_������Mo��`������MŠ��a������MŞ��b������MÄ��c������MŰ��d������Mö��e������N��f������N.��g������NL��h������Ng��i������N��j������Nś��k������Nş��l������NŘ��m���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MSIEInternet Explorer����������������������������������������������Iexplore.exe���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/ uJIT�“Ň@�������“Ú �����:u��9u“ĎP�Řx¸Z´���J� MENU��bTarg���†STR#��’PPob���¶RidL���Âaete���ÎSTR ���Úpref���ćFlag���ňTMPL���ţvers� Drop��"h����������i� ���_����j����Ł�����€����ř����,˙˙�� ����.�( �Q����-�5�������€�@��˛�����€�J�� ®�������T��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������P��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'CODE' 'DATA' 'PICT'���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������@����::���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙�����:����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙@������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������__start�������������������������������������������������������������������������������������������������������������������������������a.out��������������������������????APPL��€��€���@��XŔ�������������������������������������������������������������������������������������������������????�����������������������������������������������������������������������������������������������������������������������������������������������������Tktable.CFM68k.shlb 68K����������������������������������������TclLshlb������������������������������������������������������������������������????���������U {������������������������������ �����mac_tkTable_prefix.h�������������������������������JavaClasses.jar����������������ZIP MWZP�������� Merge Out������������������������������������������������������????APPL���DLGXckidProjWSPC�����TclMacInitializeFragment�����������������������������������__sta�_start���������������������������������������������������������TclMacTerminateFragment��������������������������������������� NONAME.EXE����������������������@���������������U {���������� ��Basic Toolbox Multi:Custom Keywords�Basic Toolbox Multi:Access Paths�Basic Toolbox Multi:Target Settings�Basic Toolbox Multi:File Mappings�Basic Toolbox Multi:Build Extras�Basic Toolbox Multi:68K CodeGen�Basic Toolbox Multi:68K Disassembler�Basic Toolbox Multi:68K Linker�Basic Toolbox Multi:68K Project�Basic Toolbox Multi:C/C++ Compiler�Basic Toolbox Multi:C/C++ Warnings�Basic Toolbox Multi:CFM68K�Basic Toolbox Multi:IR Optimizer�Basic Toolbox Multi:Java Output�Basic Toolbox Multi:Java Project�Basic Toolbox Multi:Java VM�Basic Toolbox Multi:MacOS Merge Panel�Basic Toolbox Multi:Pascal Compiler�Basic Toolbox Multi:Pascal Warnings�Basic Toolbox Multi:PPC CodeGen�Basic Toolbox Multi:PPC Disassembler�Basic Toolbox Multi:PPC Linker�Basic Toolbox Multi:PPC PEF�Basic Toolbox Multi:PPC Project�Basic Toolbox Multi:PPCAsm Panel�Basic Toolbox Multi:Rez Compiler�Basic Toolbox Multi:WinRC Compiler�Basic Toolbox Multi:x86 CodeGen�Basic Toolbox Multi:x86 Linker�Basic Toolbox Multi:x86 Project�Project File List�Basic Toolbox 68k:Custom Keywords�Basic Toolbox 68k:Access Paths�Basic Toolbox 68k:Target Settings�Basic Toolbox 68k:File Mappings�Basic Toolbox 68k:Build Extras�Basic Toolbox 68k:68K CodeGen�Basic Toolbox 68k:68K Disassembler�Basic Toolbox 68k:68K Linker�Basic Toolbox 68k:68K Project�Basic Toolbox 68k:C/C++ Compiler�Basic Toolbox 68k:C/C++ Warnings�Basic Toolbox 68k:CFM68K�Basic Toolbox 68k:IR Optimizer�Basic Toolbox 68k:Java Output�Basic Toolbox 68k:Java Project�Basic Toolbox 68k:Java VM�Basic Toolbox 68k:MacOS Merge Panel�Basic Toolbox 68k:Pascal Compiler�Basic Toolbox 68k:Pascal Warnings�Basic Toolbox 68k:PPC CodeGen�Basic Toolbox 68k:PPC Disassembler�Basic Toolbox 68k:PPC Linker�Basic Toolbox 68k:PPC PEF�Basic Toolbox 68k:PPC Project�Basic Toolbox 68k:PPCAsm Panel�Basic Toolbox 68k:Rez Compiler�Basic Toolbox 68k:WinRC Compiler�Basic Toolbox 68k:x86 CodeGen�Basic Toolbox 68k:x86 Linker�Basic Toolbox 68k:x86 Project�Basci Toolbox PPC:Custom Keywords�Basci Toolbox PPC:Access Paths�Basci Toolbox PPC:Target Settings�Basci Toolbox PPC:File Mappings�Basci Toolbox PPC:Build Extras�Basci Toolbox PPC:68K CodeGen�Basci Toolbox PPC:68K Disassembler�Basci Toolbox PPC:68K Linker�Basci Toolbox PPC:68K Project�Basci Toolbox PPC:C/C++ Compiler�Basci Toolbox PPC:C/C++ Warnings�Basci Toolbox PPC:CFM68K�Basci Toolbox PPC:IR Optimizer�Basci Toolbox PPC:Java Output�Basci Toolbox PPC:Java Project�Basci Toolbox PPC:Java VM�Basci Toolbox PPC:MacOS Merge Panel�Basci Toolbox PPC:Pascal Compiler�Basci Toolbox PPC:Pascal Warnings�Basci Toolbox PPC:PPC CodeGen�Basci Toolbox PPC:PPC Disassembler�Basci Toolbox PPC:PPC Linker�Basci Toolbox PPC:PPC PEF�Basci Toolbox PPC:PPC Project�Basci Toolbox PPC:PPCAsm Panel�Basci Toolbox PPC:Rez Compiler�Basci Toolbox PPC:WinRC Compiler�Basci Toolbox PPC:x86 CodeGen�Basci Toolbox PPC:x86 Linker�Basci Toolbox PPC:x86 Project�Basic Toolbox PPC:Custom Keywords�Basic Toolbox PPC:Access Paths�Basic Toolbox PPC:Target Settings�Basic Toolbox PPC:File Mappings�Basic Toolbox PPC:Build Extras�Basic Toolbox PPC:68K CodeGen�Basic Toolbox PPC:68K Disassembler�Basic Toolbox PPC:68K Linker�Basic Toolbox PPC:68K Project�Basic Toolbox PPC:C/C++ Compiler�Basic Toolbox PPC:C/C++ Warnings�Basic Toolbox PPC:CFM68K�Basic Toolbox PPC:IR Optimizer�Basic Toolbox PPC:Java Output�Basic Toolbox PPC:Java Project�Basic Toolbox PPC:Java VM�Basic Toolbox PPC:MacOS Merge Panel�Basic Toolbox PPC:Pascal Compiler�Basic Toolbox PPC:Pascal Warnings�Basic Toolbox PPC:PPC CodeGen�Basic Toolbox PPC:PPC Disassembler�Basic Toolbox PPC:PPC Linker�Basic Toolbox PPC:PPC PEF�Basic Toolbox PPC:PPC Project�Basic Toolbox PPC:PPCAsm Panel�Basic Toolbox PPC:Rez Compiler�Basic Toolbox PPC:WinRC Compiler�Basic Toolbox PPC:x86 CodeGen�Basic Toolbox PPC:x86 Linker�Basic Toolbox PPC:x86 Project�Basic Toolbox FAT:Custom Keywords�Basic Toolbox FAT:Access Paths�Basic Toolbox FAT:Target Settings�Basic Toolbox FAT:File Mappings�Basic Toolbox FAT:Build Extras�Basic Toolbox FAT:68K CodeGen�Basic Toolbox FAT:68K Disassembler�Basic Toolbox FAT:68K Linker�Basic Toolbox FAT:68K Project�Basic Toolbox FAT:C/C++ Compiler�Basic Toolbox FAT:C/C++ Warnings�Basic Toolbox FAT:CFM68K�Basic Toolbox FAT:IR Optimizer�Basic Toolbox FAT:Java Output�Basic Toolbox FAT:Java Project�Basic Toolbox FAT:Java VM�Basic Toolbox FAT:MacOS Merge Panel�Basic Toolbox FAT:Pascal Compiler�Basic Toolbox FAT:Pascal Warnings�Basic Toolbox FAT:PPC CodeGen�Basic Toolbox FAT:PPC Disassembler�Basic Toolbox FAT:PPC Linker�Basic Toolbox FAT:PPC PEF�Basic Toolbox FAT:PPC Project�Basic Toolbox FAT:PPCAsm Panel�Basic Toolbox FAT:Rez Compiler�Basic Toolbox FAT:WinRC Compiler�Basic Toolbox FAT:x86 CodeGen�Basic Toolbox FAT:x86 Linker�Basic Toolbox FAT:x86 Project�Basic Toolbox DEBUG 68k:Custom Keywords�Basic Toolbox DEBUG 68k:Access Paths�Basic Toolbox DEBUG 68k:Target Settings�Basic Toolbox DEBUG 68k:File Mappings�Basic Toolbox DEBUG 68k:Build Extras�Basic Toolbox DEBUG 68k:68K CodeGen�Basic Toolbox DEBUG 68k:68K Disassembler�Basic Toolbox DEBUG 68k:68K Linker�Basic Toolbox DEBUG 68k:68K Project�Basic Toolbox DEBUG 68k:C/C++ Compiler�Basic Toolbox DEBUG 68k:C/C++ Warnings�Basic Toolbox DEBUG 68k:CFM68K�Basic Toolbox DEBUG 68k:IR Optimizer�Basic Toolbox DEBUG 68k:MacOS Merge Panel�Basic Toolbox DEBUG 68k:Pascal Compiler�Basic Toolbox DEBUG 68k:Pascal Warnings�Basic Toolbox DEBUG 68k:PPC CodeGen�Basic Toolbox DEBUG 68k:PPC Disassembler�Basic Toolbox DEBUG 68k:PPC Linker�Basic Toolbox DEBUG 68k:PPC PEF�Basic Toolbox DEBUG 68k:PPC Project�Basic Toolbox DEBUG 68k:PPCAsm Panel�Basic Toolbox DEBUG 68k:Rez Compiler�Basic Toolbox DEBUG PPC:Custom Keywords�Basic Toolbox DEBUG PPC:Access Paths�Basic Toolbox DEBUG PPC:Target Settings�Basic Toolbox DEBUG PPC:File Mappings�Basic Toolbox DEBUG PPC:Build Extras�Basic Toolbox DEBUG PPC:68K CodeGen�Basic Toolbox DEBUG PPC:68K Disassembler�Basic Toolbox DEBUG PPC:68K Linker�Basic Toolbox DEBUG PPC:68K Project�Basic Toolbox DEBUG PPC:C/C++ Compiler�Basic Toolbox DEBUG PPC:C/C++ Warnings�Basic Toolbox DEBUG PPC:CFM68K�Basic Toolbox DEBUG PPC:IR Optimizer�Basic Toolbox DEBUG PPC:MacOS Merge Panel�Basic Toolbox DEBUG PPC:Pascal Compiler�Basic Toolbox DEBUG PPC:Pascal Warnings�Basic Toolbox DEBUG PPC:PPC CodeGen�Basic Toolbox DEBUG PPC:PPC Disassembler�Basic Toolbox DEBUG PPC:PPC Linker�Basic Toolbox DEBUG PPC:PPC PEF�Basic Toolbox DEBUG PPC:PPC Project�Basic Toolbox DEBUG PPC:PPCAsm Panel�Basic Toolbox DEBUG PPC:Rez Compiler�MacOS Toolbox 68K:Custom Keywords�MacOS Toolbox 68K:Access Paths�MacOS Toolbox 68K:Target Settings�MacOS Toolbox 68K:File Mappings�MacOS Toolbox 68K:Build Extras�MacOS Toolbox 68K:68K CodeGen�MacOS Toolbox 68K:68K Disassembler�MacOS Toolbox 68K:68K Linker�MacOS Toolbox 68K:68K Project�MacOS Toolbox 68K:C/C++ Compiler�MacOS Toolbox 68K:C/C++ Warnings�MacOS Toolbox 68K:CFM68K�MacOS Toolbox 68K:IR Optimizer�MacOS Toolbox 68K:MacOS Merge Panel�MacOS Toolbox 68K:Pascal Compiler�MacOS Toolbox 68K:Pascal Warnings�MacOS Toolbox 68K:PPC CodeGen�MacOS Toolbox 68K:PPC Disassembler�MacOS Toolbox 68K:PPC Linker�MacOS Toolbox 68K:PPC PEF�MacOS Toolbox 68K:PPC Project�MacOS Toolbox 68K:PPCAsm Panel�MacOS Toolbox 68K:Rez Compiler�MacOS Toolbox DEBUG 68K:Custom Keywords�MacOS Toolbox DEBUG 68K:Access Paths�MacOS Toolbox DEBUG 68K:Target Settings�MacOS Toolbox DEBUG 68K:File Mappings�MacOS Toolbox DEBUG 68K:Build Extras�MacOS Toolbox DEBUG 68K:68K CodeGen�MacOS Toolbox DEBUG 68K:68K Disassembler�MacOS Toolbox DEBUG 68K:68K Linker�MacOS Toolbox DEBUG 68K:68K Project�MacOS Toolbox DEBUG 68K:C/C++ Compiler�MacOS Toolbox DEBUG 68K:C/C++ Warnings�MacOS Toolbox DEBUG 68K:CFM68K�MacOS Toolbox DEBUG 68K:IR Optimizer�MacOS Toolbox DEBUG 68K:MacOS Merge Panel�MacOS Toolbox DEBUG 68K:Pascal Compiler�MacOS Toolbox DEBUG 68K:Pascal Warnings�MacOS Toolbox DEBUG 68K:PPC CodeGen�MacOS Toolbox DEBUG 68K:PPC Disassembler�MacOS Toolbox DEBUG 68K:PPC Linker�MacOS Toolbox DEBUG 68K:PPC PEF�MacOS Toolbox DEBUG 68K:PPC Project�MacOS Toolbox DEBUG 68K:PPCAsm Panel�MacOS Toolbox DEBUG 68K:Rez Compiler�MacOS Toolbox DEBUG PPC:Custom Keywords�MacOS Toolbox DEBUG PPC:Access Paths�MacOS Toolbox DEBUG PPC:Target Settings�MacOS Toolbox DEBUG PPC:File Mappings�MacOS Toolbox DEBUG PPC:Build Extras�MacOS Toolbox DEBUG PPC:68K CodeGen�MacOS Toolbox DEBUG PPC:68K Disassembler�MacOS Toolbox DEBUG PPC:68K Linker�MacOS Toolbox DEBUG PPC:68K Project�MacOS Toolbox DEBUG PPC:C/C++ Compiler�MacOS Toolbox DEBUG PPC:C/C++ Warnings�MacOS Toolbox DEBUG PPC:CFM68K�MacOS Toolbox DEBUG PPC:IR Optimizer�MacOS Toolbox DEBUG PPC:MacOS Merge Panel�MacOS Toolbox DEBUG PPC:Pascal Compiler�MacOS Toolbox DEBUG PPC:Pascal Warnings�MacOS Toolbox DEBUG PPC:PPC CodeGen�MacOS Toolbox DEBUG PPC:PPC Disassembler�MacOS Toolbox DEBUG PPC:PPC Linker�MacOS Toolbox DEBUG PPC:PPC PEF�MacOS Toolbox DEBUG PPC:PPC Project�MacOS Toolbox DEBUG PPC:PPCAsm Panel�MacOS Toolbox DEBUG PPC:Rez Compiler�MacOS Toolbox PPC:Custom Keywords�MacOS Toolbox PPC:Access Paths�MacOS Toolbox PPC:Target Settings�MacOS Toolbox PPC:File Mappings�MacOS Toolbox PPC:Build Extras�MacOS Toolbox PPC:68K CodeGen�MacOS Toolbox PPC:68K Disassembler�MacOS Toolbox PPC:68K Linker�MacOS Toolbox PPC:68K Project�MacOS Toolbox PPC:C/C++ Compiler�MacOS Toolbox PPC:C/C++ Warnings�MacOS Toolbox PPC:CFM68K�MacOS Toolbox PPC:IR Optimizer�MacOS Toolbox PPC:MacOS Merge Panel�MacOS Toolbox PPC:Pascal Compiler�MacOS Toolbox PPC:Pascal Warnings�MacOS Toolbox PPC:PPC CodeGen�MacOS Toolbox PPC:PPC Disassembler�MacOS Toolbox PPC:PPC Linker�MacOS Toolbox PPC:PPC PEF�MacOS Toolbox PPC:PPC Project�MacOS Toolbox PPC:PPCAsm Panel�MacOS Toolbox PPC:Rez Compiler�MacOS Toolbox FAT:Custom Keywords�MacOS Toolbox FAT:Access Paths�MacOS Toolbox FAT:Target Settings�MacOS Toolbox FAT:File Mappings�MacOS Toolbox FAT:Build Extras�MacOS Toolbox FAT:68K CodeGen�MacOS Toolbox FAT:68K Disassembler�MacOS Toolbox FAT:68K Linker�MacOS Toolbox FAT:68K Project�MacOS Toolbox FAT:C/C++ Compiler�MacOS Toolbox FAT:C/C++ Warnings�MacOS Toolbox FAT:CFM68K�MacOS Toolbox FAT:IR Optimizer�MacOS Toolbox FAT:MacOS Merge Panel�MacOS Toolbox FAT:Pascal Compiler�MacOS Toolbox FAT:Pascal Warnings�MacOS Toolbox FAT:PPC CodeGen�MacOS Toolbox FAT:PPC Disassembler�MacOS Toolbox FAT:PPC Linker�MacOS Toolbox FAT:PPC PEF�MacOS Toolbox FAT:PPC Project�MacOS Toolbox FAT:PPCAsm Panel�MacOS Toolbox FAT:Rez Compiler�MacOS Toolbox DEBUG 68K:Bison Panel�MacOS Toolbox DEBUG 68K:Flex Panel�MacOS Toolbox DEBUG 68K:Java Output�MacOS Toolbox DEBUG 68K:Java Project�MacOS Toolbox DEBUG 68K:Java VM�MacOS Toolbox DEBUG 68K:WinRC Compiler�MacOS Toolbox DEBUG 68K:x86 CodeGen�MacOS Toolbox DEBUG 68K:x86 Linker�MacOS Toolbox DEBUG 68K:x86 Project�MacOS Toolbox DEBUG PPC:Bison Panel�MacOS Toolbox DEBUG PPC:Flex Panel�MacOS Toolbox DEBUG PPC:Java Output�MacOS Toolbox DEBUG PPC:Java Project�MacOS Toolbox DEBUG PPC:Java VM�MacOS Toolbox DEBUG PPC:WinRC Compiler�MacOS Toolbox DEBUG PPC:x86 CodeGen�MacOS Toolbox DEBUG PPC:x86 Linker�MacOS Toolbox DEBUG PPC:x86 Project�MacOS Toolbox 68K:Bison Panel�MacOS Toolbox 68K:Flex Panel�MacOS Toolbox 68K:Java Output�MacOS Toolbox 68K:Java Project�MacOS Toolbox 68K:Java VM�MacOS Toolbox 68K:WinRC Compiler�MacOS Toolbox 68K:x86 CodeGen�MacOS Toolbox 68K:x86 Linker�MacOS Toolbox 68K:x86 Project�MacOS Toolbox PPC:Bison Panel�MacOS Toolbox PPC:Flex Panel�MacOS Toolbox PPC:Java Output�MacOS Toolbox PPC:Java Project�MacOS Toolbox PPC:Java VM�MacOS Toolbox PPC:WinRC Compiler�MacOS Toolbox PPC:x86 CodeGen�MacOS Toolbox PPC:x86 Linker�MacOS Toolbox PPC:x86 Project�68K Debug MacOS Toolbox:Custom Keywords�68K Debug MacOS Toolbox:Access Paths�68K Debug MacOS Toolbox:Target Settings�68K Debug MacOS Toolbox:File Mappings�68K Debug MacOS Toolbox:Build Extras�68K Debug MacOS Toolbox:68K CodeGen�68K Debug MacOS Toolbox:68K Disassembler�68K Debug MacOS Toolbox:68K Linker�68K Debug MacOS Toolbox:68K Project�68K Debug MacOS Toolbox:C/C++ Compiler�68K Debug MacOS Toolbox:C/C++ Warnings�68K Debug MacOS Toolbox:CFM68K�68K Debug MacOS Toolbox:IR Optimizer�68K Debug MacOS Toolbox:Java Output�68K Debug MacOS Toolbox:Java Project�68K Debug MacOS Toolbox:Java VM�68K Debug MacOS Toolbox:MacOS Merge Panel�68K Debug MacOS Toolbox:Pascal Compiler�68K Debug MacOS Toolbox:Pascal Warnings�68K Debug MacOS Toolbox:PPC CodeGen�68K Debug MacOS Toolbox:PPC Disassembler�68K Debug MacOS Toolbox:PPC Linker�68K Debug MacOS Toolbox:PPC PEF�68K Debug MacOS Toolbox:PPC Project�68K Debug MacOS Toolbox:PPCAsm Panel�68K Debug MacOS Toolbox:Rez Compiler�68K Debug MacOS Toolbox:WinRC Compiler�68K Debug MacOS Toolbox:x86 CodeGen�68K Debug MacOS Toolbox:x86 Linker�68K Debug MacOS Toolbox:x86 Project�PPC Debug MacOS Toolbox:Custom Keywords�PPC Debug MacOS Toolbox:Access Paths�PPC Debug MacOS Toolbox:Target Settings�PPC Debug MacOS Toolbox:File Mappings�PPC Debug MacOS Toolbox:Build Extras�PPC Debug MacOS Toolbox:68K CodeGen�PPC Debug MacOS Toolbox:68K Disassembler�PPC Debug MacOS Toolbox:68K Linker�PPC Debug MacOS Toolbox:68K Project�PPC Debug MacOS Toolbox:C/C++ Compiler�PPC Debug MacOS Toolbox:C/C++ Warnings�PPC Debug MacOS Toolbox:CFM68K�PPC Debug MacOS Toolbox:IR Optimizer�PPC Debug MacOS Toolbox:Java Output�PPC Debug MacOS Toolbox:Java Project�PPC Debug MacOS Toolbox:Java VM�PPC Debug MacOS Toolbox:MacOS Merge Panel�PPC Debug MacOS Toolbox:Pascal Compiler�PPC Debug MacOS Toolbox:Pascal Warnings�PPC Debug MacOS Toolbox:PPC CodeGen�PPC Debug MacOS Toolbox:PPC Disassembler�PPC Debug MacOS Toolbox:PPC Linker�PPC Debug MacOS Toolbox:PPC PEF�PPC Debug MacOS Toolbox:PPC Project�PPC Debug MacOS Toolbox:PPCAsm Panel�PPC Debug MacOS Toolbox:Rez Compiler�PPC Debug MacOS Toolbox:WinRC Compiler�PPC Debug MacOS Toolbox:x86 CodeGen�PPC Debug MacOS Toolbox:x86 Linker�PPC Debug MacOS Toolbox:x86 Project�68K Final MacOS Toolbox:Custom Keywords�68K Final MacOS Toolbox:Access Paths�68K Final MacOS Toolbox:Target Settings�68K Final MacOS Toolbox:File Mappings�68K Final MacOS Toolbox:Build Extras�68K Final MacOS Toolbox:68K CodeGen�68K Final MacOS Toolbox:68K Disassembler�68K Final MacOS Toolbox:68K Linker�68K Final MacOS Toolbox:68K Project�68K Final MacOS Toolbox:C/C++ Compiler�68K Final MacOS Toolbox:C/C++ Warnings�68K Final MacOS Toolbox:CFM68K�68K Final MacOS Toolbox:IR Optimizer�68K Final MacOS Toolbox:Java Output�68K Final MacOS Toolbox:Java Project�68K Final MacOS Toolbox:Java VM�68K Final MacOS Toolbox:MacOS Merge Panel�68K Final MacOS Toolbox:Pascal Compiler�68K Final MacOS Toolbox:Pascal Warnings�68K Final MacOS Toolbox:PPC CodeGen�68K Final MacOS Toolbox:PPC Disassembler�68K Final MacOS Toolbox:PPC Linker�68K Final MacOS Toolbox:PPC PEF�68K Final MacOS Toolbox:PPC Project�68K Final MacOS Toolbox:PPCAsm Panel�68K Final MacOS Toolbox:Rez Compiler�68K Final MacOS Toolbox:WinRC Compiler�68K Final MacOS Toolbox:x86 CodeGen�68K Final MacOS Toolbox:x86 Linker�68K Final MacOS Toolbox:x86 Project�PPC Final MacOS Toolbox:Custom Keywords�PPC Final MacOS Toolbox:Access Paths�PPC Final MacOS Toolbox:Target Settings�PPC Final MacOS Toolbox:File Mappings�PPC Final MacOS Toolbox:Build Extras�PPC Final MacOS Toolbox:68K CodeGen�PPC Final MacOS Toolbox:68K Disassembler�PPC Final MacOS Toolbox:68K Linker�PPC Final MacOS Toolbox:68K Project�PPC Final MacOS Toolbox:C/C++ Compiler�PPC Final MacOS Toolbox:C/C++ Warnings�PPC Final MacOS Toolbox:CFM68K�PPC Final MacOS Toolbox:IR Optimizer�PPC Final MacOS Toolbox:Java Output�PPC Final MacOS Toolbox:Java Project�PPC Final MacOS Toolbox:Java VM�PPC Final MacOS Toolbox:MacOS Merge Panel�PPC Final MacOS Toolbox:Pascal Compiler�PPC Final MacOS Toolbox:Pascal Warnings�PPC Final MacOS Toolbox:PPC CodeGen�PPC Final MacOS Toolbox:PPC Disassembler�PPC Final MacOS Toolbox:PPC Linker�PPC Final MacOS Toolbox:PPC PEF�PPC Final MacOS Toolbox:PPC Project�PPC Final MacOS Toolbox:PPCAsm Panel�PPC Final MacOS Toolbox:Rez Compiler�PPC Final MacOS Toolbox:WinRC Compiler�PPC Final MacOS Toolbox:x86 CodeGen�PPC Final MacOS Toolbox:x86 Linker�PPC Final MacOS Toolbox:x86 Project�FAT MacOS Toolbox:Custom Keywords�FAT MacOS Toolbox:Access Paths�FAT MacOS Toolbox:Target Settings�FAT MacOS Toolbox:File Mappings�FAT MacOS Toolbox:Build Extras�FAT MacOS Toolbox:68K CodeGen�FAT MacOS Toolbox:68K Disassembler�FAT MacOS Toolbox:68K Linker�FAT MacOS Toolbox:68K Project�FAT MacOS Toolbox:C/C++ Compiler�FAT MacOS Toolbox:C/C++ Warnings�FAT MacOS Toolbox:CFM68K�FAT MacOS Toolbox:IR Optimizer�FAT MacOS Toolbox:Java Output�FAT MacOS Toolbox:Java Project�FAT MacOS Toolbox:Java VM�FAT MacOS Toolbox:MacOS Merge Panel�FAT MacOS Toolbox:Pascal Compiler�FAT MacOS Toolbox:Pascal Warnings�FAT MacOS Toolbox:PPC CodeGen�FAT MacOS Toolbox:PPC Disassembler�FAT MacOS Toolbox:PPC Linker�FAT MacOS Toolbox:PPC PEF�FAT MacOS Toolbox:PPC Project�FAT MacOS Toolbox:PPCAsm Panel�FAT MacOS Toolbox:Rez Compiler�FAT MacOS Toolbox:WinRC Compiler�FAT MacOS Toolbox:x86 CodeGen�FAT MacOS Toolbox:x86 Linker�FAT MacOS Toolbox:x86 Project�PPC Debug MacOS Toolbox:Java Language�PPC Final MacOS Toolbox:Java Language�PPC Debug MacOS Toolbox:JavaDoc Project�PPC Final MacOS Toolbox:JavaDoc Project�Tktable.shlb:Custom Keywords�Tktable.shlb:Access Paths�Tktable.shlb:Target Settings�Tktable.shlb:File Mappings�Tktable.shlb:Build Extras�Tktable.shlb:68K CodeGen�Tktable.shlb:68K Disassembler�Tktable.shlb:68K Linker�Tktable.shlb:68K Project�Tktable.shlb:C/C++ Compiler�Tktable.shlb:C/C++ Warnings�Tktable.shlb:CFM68K�Tktable.shlb:IR Optimizer�Tktable.shlb:Java Language�Tktable.shlb:Java Output�Tktable.shlb:Java Project�Tktable.shlb:JavaDoc Project�Tktable.shlb:MacOS Merge Panel�Tktable.shlb:PPC CodeGen�Tktable.shlb:PPC Disassembler�Tktable.shlb:PPC Linker�Tktable.shlb:PPC PEF�Tktable.shlb:PPC Project�Tktable.shlb:PPCAsm Panel�Tktable.shlb:Rez Compiler�Tktable.shlb:WinRC Compiler�Tktable.shlb:x86 CodeGen�Tktable.shlb:x86 Linker�Tktable.shlb:x86 Project�Tktable PPC:Custom Keywords�Tktable PPC:Access Paths�Tktable PPC:Target Settings�Tktable PPC:File Mappings�Tktable PPC:Build Extras�Tktable PPC:68K CodeGen�Tktable PPC:68K Disassembler�Tktable PPC:68K Linker�Tktable PPC:68K Project�Tktable PPC:C/C++ Compiler�Tktable PPC:C/C++ Warnings�Tktable PPC:CFM68K�Tktable PPC:IR Optimizer�Tktable PPC:Java Language�Tktable PPC:Java Output�Tktable PPC:Java Project�Tktable PPC:JavaDoc Project�Tktable PPC:MacOS Merge Panel�Tktable PPC:PPC CodeGen�Tktable PPC:PPC Disassembler�Tktable PPC:PPC Linker�Tktable PPC:PPC PEF�Tktable PPC:PPC Project�Tktable PPC:PPCAsm Panel�Tktable PPC:Rez Compiler�Tktable PPC:WinRC Compiler�Tktable PPC:x86 CodeGen�Tktable PPC:x86 Linker�Tktable PPC:x86 Project�Tktable Fat:Custom Keywords�Tktable Fat:Access Paths�Tktable Fat:Target Settings�Tktable Fat:File Mappings�Tktable Fat:Build Extras�Tktable Fat:68K CodeGen�Tktable Fat:68K Disassembler�Tktable Fat:68K Linker�Tktable Fat:68K Project�Tktable Fat:C/C++ Compiler�Tktable Fat:C/C++ Warnings�Tktable Fat:CFM68K�Tktable Fat:IR Optimizer�Tktable Fat:Java Language�Tktable Fat:Java Output�Tktable Fat:Java Project�Tktable Fat:JavaDoc Project�Tktable Fat:MacOS Merge Panel�Tktable Fat:PPC CodeGen�Tktable Fat:PPC Disassembler�Tktable Fat:PPC Linker�Tktable Fat:PPC PEF�Tktable Fat:PPC Project�Tktable Fat:PPCAsm Panel�Tktable Fat:Rez Compiler�Tktable Fat:WinRC Compiler�Tktable Fat:x86 CodeGen�Tktable Fat:x86 Linker�Tktable Fat:x86 Project�Tktable CFM68k:Custom Keywords�Tktable CFM68k:Access Paths�Tktable CFM68k:Target Settings�Tktable CFM68k:File Mappings�Tktable CFM68k:Build Extras�Tktable CFM68k:68K CodeGen�Tktable CFM68k:68K Disassembler�Tktable CFM68k:68K Linker�Tktable CFM68k:68K Project�Tktable CFM68k:C/C++ Compiler�Tktable CFM68k:C/C++ Warnings�Tktable CFM68k:CFM68K�Tktable CFM68k:IR Optimizer�Tktable CFM68k:Java Language�Tktable CFM68k:Java Output�Tktable CFM68k:Java Project�Tktable CFM68k:JavaDoc Project�Tktable CFM68k:MacOS Merge Panel�Tktable CFM68k:PPC CodeGen�Tktable CFM68k:PPC Disassembler�Tktable CFM68k:PPC Linker�Tktable CFM68k:PPC PEF�Tktable CFM68k:PPC Project�Tktable CFM68k:PPCAsm Panel�Tktable CFM68k:Rez Compiler�Tktable CFM68k:WinRC Compiler�Tktable CFM68k:x86 CodeGen�Tktable CFM68k:x86 Linker�Tktable CFM68k:x86 Project�Tktable Fat:Beyond HTML Panel�Tktable PPC:Beyond HTML Panel�Tktable CFM68k:Beyond HTML Panel��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������None�����������������������������MMPr����������������������������������������������������������������@���TEXT.l������������������������������Flex Preprocessor���������������€���TEXT.y������������������������������Bison Preprocessor��������������€���Java Linker����������������������APPL����������������������������������������������������������������`���Appl����������������������������������������������������������������`���COŚk��������������������������������MW Java�����������������������������Clss��������������������������������MW Java�����������������������������Jjrf.jrf���������������������������������������������������������������MWCD����������������������������������������������������������������`���RSRC����������������������������������������������������������������`���TEXT.bh�����������������������������Balloon Help������������������������TEXT.gc�����������������������������GameCode Converter��������������@���TEXT.html���������������������������������������������������������������TEXT.java���������������������������MW Java�����������������������������TEXT.l������������������������������Flex Preprocessor���������������€���TEXT.mf�����������������������������������������������������������������TEXT.r������������������������������Rez���������������������������������TEXT.y������������������������������Bison Preprocessor��������������€���ZIP ��������������������������������MW Java�������������������������@���ZipF��������������������������������MW Java�����������������������������docu����������������������������������������������������������������`���rsrc����������������������������������������������������������������`�������.class��������������������������MW Java���������������������������������.jar������������������������������������������������������������@�������.zip����������������������������MW Java�����������������������������MacOS 68K Linker����������������� APPL����������������������������������������������������������������`���Appl����������������������������������������������������������������`���MMLB��������������������������������Lib Import 68K����������������������MPLF��������������������������������Lib Import 68K����������������������MWCD����������������������������������������������������������������`���OBJ ��������������������������������MPW Import 68K����������������������PLob����������������������������������������������������������������`���RSRC����������������������������������������������������������������`���TEXT.bh�����������������������������Balloon Help������������������������TEXT.c������������������������������MW C/C++ 68K������������������������TEXT.c++����������������������������MW C/C++ 68K������������������������TEXT.cc�����������������������������MW C/C++ 68K������������������������TEXT.cp�����������������������������MW C/C++ 68K������������������������TEXT.cpp����������������������������MW C/C++ 68K������������������������TEXT.exp����������������������������������������������������������������TEXT.gc�����������������������������GameCode Converter��������������@���TEXT.h������������������������������MW C/C++ 68K�����������������������TEXT.l������������������������������Flex Preprocessor���������������€���TEXT.p������������������������������MW Pascal 68K�����������������������TEXT.pas����������������������������MW Pascal 68K�����������������������TEXT.pch����������������������������MW C/C++ 68K��������������������€���TEXT.pch++��������������������������MW C/C++ 68K��������������������€���TEXT.ppu����������������������������MW Pascal 68K�������������������€���TEXT.r������������������������������Rez���������������������������������TEXT.seg����������������������������������������������������������������TEXT.y������������������������������Bison Preprocessor��������������€���docu����������������������������������������������������������������`���rsrc����������������������������������������������������������������`���shlb��������������������������������PEF Import 68K����������������������stub��������������������������������PEF Import 68K��������������������������.doc������������������������������������������������������������P�������.rsrc�����������������������������������������������������������`���MacOS Merge���������������������� APPL����������������������������������������������������������������`���Appl����������������������������������������������������������������`���RSRC����������������������������������������������������������������`���TEXT.bh�����������������������������Balloon Help������������������������TEXT.gc�����������������������������GameCode Converter��������������@���TEXT.l������������������������������Flex Preprocessor���������������€���TEXT.r������������������������������Rez���������������������������������TEXT.y������������������������������Bison Preprocessor��������������€���rsrc����������������������������������������������������������������`���shlb��������������������������������������������������������������������MacOS PPC Linker�����������������APPL����������������������������������������������������������������`���Appl����������������������������������������������������������������`���MMLB��������������������������������Lib Import PPC����������������������MPLF��������������������������������Lib Import PPC����������������������MWCD����������������������������������������������������������������`���RSRC����������������������������������������������������������������`���TEXT.bh�����������������������������Balloon Help������������������������TEXT.c������������������������������MW C/C++ PPC������������������������TEXT.c++����������������������������MW C/C++ PPC������������������������TEXT.cc�����������������������������MW C/C++ PPC������������������������TEXT.cp�����������������������������MW C/C++ PPC������������������������TEXT.cpp����������������������������MW C/C++ PPC������������������������TEXT.exp����������������������������������������������������������������TEXT.gc�����������������������������GameCode Converter��������������@���TEXT.h������������������������������MW C/C++ PPC�����������������������TEXT.l������������������������������Flex Preprocessor���������������€���TEXT.p������������������������������MW Pascal PPC�����������������������TEXT.pas����������������������������MW Pascal PPC�����������������������TEXT.pch����������������������������MW C/C++ PPC��������������������€���TEXT.pch++��������������������������MW C/C++ PPC��������������������€���TEXT.ppu����������������������������MW Pascal PPC�������������������€���TEXT.r������������������������������Rez���������������������������������TEXT.s������������������������������PPCAsm������������������������������TEXT.y������������������������������Bison Preprocessor��������������€���XCOF��������������������������������XCOFF Import PPC��������������������docu����������������������������������������������������������������`���rsrc����������������������������������������������������������������`���shlb��������������������������������PEF Import PPC����������������������stub��������������������������������PEF Import PPC��������������������������.doc������������������������������������������������������������P���MC Linker������������������������CLUS����������������������������������������������������������������@���MMLB��������������������������������Lib Import 68K����������������������MPLF��������������������������������Lib Import 68K����������������������OBJ ��������������������������������MPW Import 68K����������������������TEXT.c������������������������������MW C/C++ 68K������������������������TEXT.c++����������������������������MW C/C++ 68K������������������������TEXT.cc�����������������������������MW C/C++ 68K������������������������TEXT.cls����������������������������MC Class Compiler���������������€���TEXT.cp�����������������������������MW C/C++ 68K������������������������TEXT.cpp����������������������������MW C/C++ 68K������������������������TEXT.def����������������������������������������������������������������TEXT.doc���������������������������������������������������������������TEXT.h������������������������������������������������������������������TEXT.p������������������������������MW Pascal 68K�����������������������TEXT.pas����������������������������MW Pascal 68K�����������������������TEXT.pch����������������������������MW C/C++ 68K��������������������€���TEXT.pch++��������������������������MW C/C++ 68K��������������������€���TEXT.ts�����������������������������������������������������������������Win32 x86 Linker�����������������TEXT.c������������������������������MW C/C++ x86������������������������TEXT.c++����������������������������MW C/C++ x86������������������������TEXT.cc�����������������������������MW C/C++ x86������������������������TEXT.cp�����������������������������MW C/C++ x86������������������������TEXT.cpp����������������������������MW C/C++ x86������������������������TEXT.def����������������������������������������������������������������TEXT.gc�����������������������������GameCode Converter��������������@���TEXT.h������������������������������MW C/C++ x86�����������������������TEXT.l������������������������������Flex Preprocessor���������������€���TEXT.p������������������������������MW Pascal x86�����������������������TEXT.pas����������������������������MW Pascal x86�����������������������TEXT.pch����������������������������MW C/C++ x86��������������������€���TEXT.pch++��������������������������MW C/C++ x86��������������������€���TEXT.ppu����������������������������MW Pascal x86�������������������€���TEXT.rc�����������������������������MW WinRC����������������������������TEXT.res����������������������������WinRes Import�����������������������TEXT.y������������������������������Bison Preprocessor��������������€�������.doc������������������������������������������������������������P�������.lib����������������������������Lib Import x86��������������������������.obj����������������������������Obj Import x86����������������������MW JavaDoc Linker���������������� COŚk��������������������������������MW JavaDoc��������������������������Clss��������������������������������MW JavaDoc��������������������������RSRC��������������������������������Rez�����������������������������`���TEXT.bh�����������������������������Balloon Help������������������������TEXT.html��������������������������������������������������������������TEXT.java���������������������������MW JavaDoc��������������������������TEXT.r������������������������������Rez���������������������������������ZIP ��������������������������������MW JavaDoc����������������������@���ZipF��������������������������������MW JavaDoc��������������������������rsrc��������������������������������Rez�����������������������������`�������.class��������������������������MW JavaDoc������������������������������.zip����������������������������MW JavaDoc�����������������������������MacOS Merge�nker��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tktable Fat�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������:�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������None�����������������������������MMPr����������������������������������������������������������������@���Java Linker����������������������APPL����������������������������������������������������������������`���Appl����������������������������������������������������������������`���COŚk��������������������������������MW Java�����������������������������Clss��������������������������������MW Java�����������������������������Jjrf.jrf���������������������������������������������������������������MWCD����������������������������������������������������������������`���RSRC����������������������������������������������������������������`���TEXT.bh�����������������������������Balloon Help������������������������TEXT.html��������������������������������������������������������������TEXT.java���������������������������MW Java�����������������������������TEXT.mf�����������������������������������������������������������������TEXT.r������������������������������Rez���������������������������������ZIP ��������������������������������MW Java�����������������������������ZipF��������������������������������MW Java�����������������������������docu����������������������������������������������������������������`���rsrc����������������������������������������������������������������`�������.class��������������������������MW Java���������������������������������.jar����������������������������MW Java���������������������������������.java���������������������������MW Java���������������������������������.zip����������������������������MW Java�����������������������������MacOS 68K Linker�����������������APPL����������������������������������������������������������������`���Appl����������������������������������������������������������������`���MMLB��������������������������������Lib Import 68K����������������������MPLF��������������������������������Lib Import 68K����������������������MWCD����������������������������������������������������������������`���OBJ ��������������������������������MPW Import 68K����������������������PLob����������������������������������������������������������������`���RSRC����������������������������������������������������������������`���TEXT.bh�����������������������������Balloon Help������������������������TEXT.c������������������������������MW C/C++ 68K������������������������TEXT.c++����������������������������MW C/C++ 68K������������������������TEXT.cc�����������������������������MW C/C++ 68K������������������������TEXT.cp�����������������������������MW C/C++ 68K������������������������TEXT.cpp����������������������������MW C/C++ 68K������������������������TEXT.exp����������������������������������������������������������������TEXT.h������������������������������MW C/C++ 68K�����������������������TEXT.pch����������������������������MW C/C++ 68K��������������������€���TEXT.pch++��������������������������MW C/C++ 68K��������������������€���TEXT.r������������������������������Rez���������������������������������TEXT.seg����������������������������������������������������������������docu����������������������������������������������������������������`���rsrc����������������������������������������������������������������`���shlb��������������������������������PEF Import 68K����������������������stub��������������������������������PEF Import 68K��������������������������.doc������������������������������������������������������������P�������.rsrc�����������������������������������������������������������`���MacOS Merge����������������������APPL����������������������������������������������������������������`���Appl����������������������������������������������������������������`���RSRC����������������������������������������������������������������`���TEXT.bh�����������������������������Balloon Help������������������������TEXT.r������������������������������Rez���������������������������������rsrc����������������������������������������������������������������`���shlb��������������������������������������������������������������������MacOS PPC Linker�����������������APPL����������������������������������������������������������������`���Appl����������������������������������������������������������������`���MMLB��������������������������������Lib Import PPC����������������������MPLF��������������������������������Lib Import PPC����������������������MWCD����������������������������������������������������������������`���RSRC����������������������������������������������������������������`���TEXT.bh�����������������������������Balloon Help������������������������TEXT.c������������������������������MW C/C++ PPC������������������������TEXT.c++����������������������������MW C/C++ PPC������������������������TEXT.cc�����������������������������MW C/C++ PPC������������������������TEXT.cp�����������������������������MW C/C++ PPC������������������������TEXT.cpp����������������������������MW C/C++ PPC������������������������TEXT.exp����������������������������������������������������������������TEXT.h������������������������������MW C/C++ PPC�����������������������TEXT.pch����������������������������MW C/C++ PPC��������������������€���TEXT.pch++��������������������������MW C/C++ PPC��������������������€���TEXT.r������������������������������Rez���������������������������������TEXT.s������������������������������PPCAsm������������������������������XCOF��������������������������������XCOFF Import PPC��������������������docu����������������������������������������������������������������`���rsrc����������������������������������������������������������������`���shlb��������������������������������PEF Import PPC����������������������stub��������������������������������PEF Import PPC��������������������������.doc������������������������������������������������������������P���MW JavaDoc Linker���������������� COŚk��������������������������������MW JavaDoc��������������������������Clss��������������������������������MW JavaDoc��������������������������RSRC��������������������������������Rez�����������������������������`���TEXT.bh�����������������������������Balloon Help������������������������TEXT.html��������������������������������������������������������������TEXT.java���������������������������MW JavaDoc��������������������������TEXT.r������������������������������Rez���������������������������������ZIP ��������������������������������MW JavaDoc����������������������@���ZipF��������������������������������MW JavaDoc��������������������������rsrc��������������������������������Rez�����������������������������`�������.class��������������������������MW JavaDoc������������������������������.zip����������������������������MW JavaDoc��������������������������Win32 x86 Linker�����������������TEXT.c������������������������������MW C/C++ x86������������������������TEXT.c++����������������������������MW C/C++ x86������������������������TEXT.cc�����������������������������MW C/C++ x86������������������������TEXT.cp�����������������������������MW C/C++ x86������������������������TEXT.cpp����������������������������MW C/C++ x86������������������������TEXT.def����������������������������������������������������������������TEXT.h������������������������������MW C/C++ x86�����������������������TEXT.pch����������������������������MW C/C++ x86��������������������€���TEXT.pch++��������������������������MW C/C++ x86��������������������€���TEXT.rc�����������������������������MW WinRC����������������������������TEXT.res����������������������������WinRes Import���������������������������.doc������������������������������������������������������������P�������.lib����������������������������Lib Import x86��������������������������.obj����������������������������Obj Import x86���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������DFLTInternet Explorer����������������������������������������������Internet Explorer����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������000DFLT����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������P��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'CODE' 'DATA' 'PICT'������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ ���@����::���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙�����:::Tcl/Tk Folder:tcl8.0:�:�8.0:����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙@����:::Tcl/Tk Folder:tk8.0:�:�8.0:�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙@����:Extensions:Tool Command Language:�ol Command Language:����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙�����:MacOS Support:Headers:Universal Headers:������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙@����:Metrowerks Standard Library:MSL C:������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙@����:Metrowerks Standard Library:MSL C++:����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙@����:MacOS Support:MacHeaders:���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙@����:MacOS Support:Libraries:����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙@�� ��:MacOS Support:��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙@�����MacOS 68K Linker��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tktable CFM68k����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������:���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� �tktable2.20����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������TclMacInitializeFragment�����������������������������������������_start���������������������������������������������������������TclMacTerminateFragment����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MSIEInternet Explorer����������������������������������������������Iexplore.exe���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/ uJIT�“Ň@�������“Ú �����:u��9u“ĎP�Řx¸Z´���J� MENU��bTarg���†STR#��’PPob���¶RidL���Âaete���ÎSTR ���Úpref���ćFlag���ňTMPL���ţvers� Drop��"h����������i� ���_����j����Ł�����€����ř����,˙˙�� ����.�( �Q����-�5�������€�@��˛�����€�J�� ®�������T��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tktable.PPC.shlbBUG PPC��������TclLshlb�����������������������������������������������������������������������������������������������������������������????��������P��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'CODE' 'DATA' 'PICT'����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ROOT������������FILE ��#FILE ��'GRUP�������Sources��� FILE ��$FILE ��FILE �� FILE ��FILE ��FILE �� FILE ��"FILE ��!FILE��FILE ��GRUP������� Tktable Libraries���FILE��FILE��GRUP������� Tcl/Tk Libraries���FILE ��FILE ��FILE ��FILE ��GRUP������� Mac Libraries���FILE ��FILE ��FILE ��FILE ��&FILE �� FILE ��FILE ��FILE ��o{o{o{o{o{o{o{o{o{o{o{o{o{o{o{o{������������� ��������������������� ��� ������ ��� ����������������������������������������������������������������� ��# ��$ ��& ��%��U {���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� �������������������������������� �� ���R�������������������������� �����T��������������������������� �����V�������������������������� �����W�������������������������� �����X�������������������������� �����Z�������������������������� �����Y�������������������������� ������������������������������� �����k�������������������������� �����l�������������������������� �����m�������������������������� �� ���o�������������������������� ��!���p�������������������������� ��"���n�������������������������� ��#���q��������������������������� ��$���r��������������������������� ��&����������������������������� ��'���s�������������������������������������˙˙˙˙����������������������������������˙˙˙˙����������������������������������˙˙˙˙����������������������������������˙˙˙˙��������������������������e?îŹ d0˙˙˙˙���@�·f������������·aĐ�·e`«�� � ˙˙˙˙�������îßŕ�·aĐë�� ���0˙˙ö|��˙˙˙˙���������������€�� îŃ,�·e k�P˙˙˙˙����������·aĐ������������������˙˙˙˙������ßŕ�·eĐ������� �·fp�������˙˙˙˙�·eĐ������đ�·h@������������·eĐ��˙˙˙˙����������������������ßŕ�·f0����°˙˙˙˙��������·eĐ�·fp�������·h@��˙˙˙˙ut���·fp������������������������������������������������������������������������������������� ����������������������������������������������������������������������� �������������������������������� �� ���R�������������������������� �����T��������������������������� �����d�������������������������� �����e�������������������������� �����g�������������������������� �����h�������������������������� �� ���i�������������������������� ��!���k�������������������������� ��"���l�������������������������� ��#���m�������������������������� ��%���o�������������������������� ��&���p�������������������������� ��'���X�������������������������� ��(���n�������������������������� ��)���q��������������������������� ��*���r��������������������������� ��+���s�������������������������������������˙˙˙˙����������������������������������˙˙˙˙����������������������������������˙˙˙˙����������������������������������˙˙˙˙����������������������������������˙˙˙˙��������������������������e?îŹ d0˙˙˙˙���@�·f������������·aĐ�·e`«�� � ˙˙˙˙�������îßŕ�·aĐë�� ���0˙˙ö|��˙˙˙˙���������������€�� îŃ,�·e k�P˙˙˙˙����������·aĐ������������������˙˙˙˙������ßŕ�·eĐ������� �·fp�������˙˙˙˙�·eĐ������đ�·h@������������·eĐ��˙˙˙˙����������������������ßŕ�·f0����°˙˙˙˙��������·eĐ�·fp�������·h@��˙˙˙˙ut���·fp���������������� �� �� ��! �� �� �� �� �� �� ��" ��# ��% ��& ��' ��( ��) ��* ��+��None�����������������������������MMPr����������������������������������������������������������������@���TEXT.l������������������������������Flex Preprocessor���������������€���TEXT.y������������������������������Bison Preprocessor��������������€���Java Linker����������������������APPL����������������������������������������������������������������`���Appl����������������������������������������������������������������`���COŚk��������������������������������MW Java�����������������������������Clss��������������������������������MW Java�����������������������������Jjrf.jrf���������������������������������������������������������������MWCD����������������������������������������������������������������`���RSRC����������������������������������������������������������������`���TEXT.bh�����������������������������Balloon Help������������������������TEXT.gc�����������������������������GameCode Converter��������������@���TEXT.html���������������������������������������������������������������TEXT.java���������������������������MW Java�����������������������������TEXT.l������������������������������Flex Preprocessor���������������€���TEXT.mf�����������������������������������������������������������������TEXT.r������������������������������Rez���������������������������������TEXT.y������������������������������Bison Preprocessor��������������€���ZIP ��������������������������������MW Java�������������������������@���ZipF��������������������������������MW Java�����������������������������docu����������������������������������������������������������������`���rsrc����������������������������������������������������������������`�������.class��������������������������MW Java���������������������������������.jar������������������������������������������������������������@�������.zip����������������������������MW Java�����������������������������MacOS 68K Linker����������������� APPL����������������������������������������������������������������`���Appl����������������������������������������������������������������`���MMLB��������������������������������Lib Import 68K����������������������MPLF��������������������������������Lib Import 68K����������������������MWCD����������������������������������������������������������������`���OBJ ��������������������������������MPW Import 68K����������������������PLob����������������������������������������������������������������`���RSRC����������������������������������������������������������������`���TEXT.bh�����������������������������Balloon Help������������������������TEXT.c������������������������������MW C/C++ 68K������������������������TEXT.c++����������������������������MW C/C++ 68K������������������������TEXT.cc�����������������������������MW C/C++ 68K������������������������TEXT.cp�����������������������������MW C/C++ 68K������������������������TEXT.cpp����������������������������MW C/C++ 68K������������������������TEXT.exp����������������������������������������������������������������TEXT.gc�����������������������������GameCode Converter��������������@���TEXT.h������������������������������MW C/C++ 68K�����������������������TEXT.l������������������������������Flex Preprocessor���������������€���TEXT.p������������������������������MW Pascal 68K�����������������������TEXT.pas����������������������������MW Pascal 68K�����������������������TEXT.pch����������������������������MW C/C++ 68K��������������������€���TEXT.pch++��������������������������MW C/C++ 68K��������������������€���TEXT.ppu����������������������������MW Pascal 68K�������������������€���TEXT.r������������������������������Rez���������������������������������TEXT.seg����������������������������������������������������������������TEXT.y������������������������������Bison Preprocessor��������������€���docu����������������������������������������������������������������`���rsrc����������������������������������������������������������������`���shlb��������������������������������PEF Import 68K����������������������stub��������������������������������PEF Import 68K��������������������������.doc������������������������������������������������������������P�������.rsrc�����������������������������������������������������������`���MacOS Merge���������������������� APPL����������������������������������������������������������������`���Appl����������������������������������������������������������������`���RSRC����������������������������������������������������������������`���TEXT.bh�����������������������������Balloon Help������������������������TEXT.gc�����������������������������GameCode Converter��������������@���TEXT.l������������������������������Flex Preprocessor���������������€���TEXT.r������������������������������Rez���������������������������������TEXT.y������������������������������Bison Preprocessor��������������€���rsrc����������������������������������������������������������������`���shlb��������������������������������������������������������������������MacOS PPC Linker�����������������APPL����������������������������������������������������������������`���Appl����������������������������������������������������������������`���MMLB��������������������������������Lib Import PPC����������������������MPLF��������������������������������Lib Import PPC����������������������MWCD����������������������������������������������������������������`���RSRC����������������������������������������������������������������`���TEXT.bh�����������������������������Balloon Help������������������������TEXT.c������������������������������MW C/C++ PPC������������������������TEXT.c++����������������������������MW C/C++ PPC������������������������TEXT.cc�����������������������������MW C/C++ PPC������������������������TEXT.cp�����������������������������MW C/C++ PPC������������������������TEXT.cpp����������������������������MW C/C++ PPC������������������������TEXT.exp����������������������������������������������������������������TEXT.gc�����������������������������GameCode Converter��������������@���TEXT.h������������������������������MW C/C++ PPC�����������������������TEXT.l������������������������������Flex Preprocessor���������������€���TEXT.p������������������������������MW Pascal PPC�����������������������TEXT.pas����������������������������MW Pascal PPC�����������������������TEXT.pch����������������������������MW C/C++ PPC��������������������€���TEXT.pch++��������������������������MW C/C++ PPC��������������������€���TEXT.ppu����������������������������MW Pascal PPC�������������������€���TEXT.r������������������������������Rez���������������������������������TEXT.s������������������������������PPCAsm������������������������������TEXT.y������������������������������Bison Preprocessor��������������€���XCOF��������������������������������XCOFF Import PPC��������������������docu����������������������������������������������������������������`���rsrc����������������������������������������������������������������`���shlb��������������������������������PEF Import PPC����������������������stub��������������������������������PEF Import PPC��������������������������.doc������������������������������������������������������������P���MC Linker������������������������CLUS����������������������������������������������������������������@���MMLB��������������������������������Lib Import 68K����������������������MPLF��������������������������������Lib Import 68K����������������������OBJ ��������������������������������MPW Import 68K����������������������TEXT.c������������������������������MW C/C++ 68K������������������������TEXT.c++����������������������������MW C/C++ 68K������������������������TEXT.cc�����������������������������MW C/C++ 68K������������������������TEXT.cls����������������������������MC Class Compiler���������������€���TEXT.cp�����������������������������MW C/C++ 68K������������������������TEXT.cpp����������������������������MW C/C++ 68K������������������������TEXT.def����������������������������������������������������������������TEXT.doc���������������������������������������������������������������TEXT.h������������������������������������������������������������������TEXT.p������������������������������MW Pascal 68K�����������������������TEXT.pas����������������������������MW Pascal 68K�����������������������TEXT.pch����������������������������MW C/C++ 68K��������������������€���TEXT.pch++��������������������������MW C/C++ 68K��������������������€���TEXT.ts�����������������������������������������������������������������Win32 x86 Linker�����������������TEXT.c������������������������������MW C/C++ x86������������������������TEXT.c++����������������������������MW C/C++ x86������������������������TEXT.cc�����������������������������MW C/C++ x86������������������������TEXT.cp�����������������������������MW C/C++ x86������������������������TEXT.cpp����������������������������MW C/C++ x86������������������������TEXT.def����������������������������������������������������������������TEXT.gc�����������������������������GameCode Converter��������������@���TEXT.h������������������������������MW C/C++ x86�����������������������TEXT.l������������������������������Flex Preprocessor���������������€���TEXT.p������������������������������MW Pascal x86�����������������������TEXT.pas����������������������������MW Pascal x86�����������������������TEXT.pch����������������������������MW C/C++ x86��������������������€���TEXT.pch++��������������������������MW C/C++ x86��������������������€���TEXT.ppu����������������������������MW Pascal x86�������������������€���TEXT.rc�����������������������������MW WinRC����������������������������TEXT.res����������������������������WinRes Import�����������������������TEXT.y������������������������������Bison Preprocessor��������������€�������.doc������������������������������������������������������������P�������.lib����������������������������Lib Import x86��������������������������.obj����������������������������Obj Import x86����������������������MW JavaDoc Linker���������������� COŚk��������������������������������MW JavaDoc��������������������������Clss��������������������������������MW JavaDoc��������������������������RSRC��������������������������������Rez�����������������������������`���TEXT.bh�����������������������������Balloon Help������������������������TEXT.html��������������������������������������������������������������TEXT.java���������������������������MW JavaDoc��������������������������TEXT.r������������������������������Rez���������������������������������ZIP ��������������������������������MW JavaDoc����������������������@���ZipF��������������������������������MW JavaDoc��������������������������rsrc��������������������������������Rez�����������������������������`�������.class��������������������������MW JavaDoc������������������������������.zip����������������������������MW JavaDoc����������������������������›��P�mstr��������������g���mstl��������������)D�� �mstn��������������(���(msti��������������AŢ���mstr��č����������P���mstl��č���������� 3���mstn��č����������P���(msti��č���������� Ž��,mpsi��č����������3D��Lmtgl��č���������qZ��€PLst�Qn���������á���.pref�›•���-��������Ipref�5đ���.������ -���pref����/������Ţ���$pref����:��������� pref�\���;������ ���’pref�•u���<������ž���Jpref�Ęs���=������é���.pref�˘ĺ���i������$ű��Ipref�ç���j������ /���pref�Š���k������ň���$pref�ä���v������č��� pref�Úń���w������˛���’pref�-���x������ D���Jpref�–e���y������Ţ���.pref�܆���‡��������Ipref�Ćź���������Ě���pref�˝‰���‰������ ���$pref�&���”������ #��� pref�ĘŐ���•������_���’pref�ěË���–������ń���Jpref�iá���—������€���pref�N˛��9��������� pref�Ő��:������ ]���pref�BL��B������ ť��� pref�ńs��C������ ]���pref�·F��K������ e��� pref�"`��L������ ���pref�©��T������g��� pref�ő™��U������Ę���pref�M ��Š������ e���8pref�LÜÎ��Ś������ş��� pref�MŠŕ��Ť������Ç���pref�MŻA��Ć������A¦���8pref�Lëí��Č������¶��� pref�Mń��É������9ţ���mtpl�������������Î���€mtps������������� Á��� mtsl�������������”���mtpi�������������N��� mtlo������������� ]��� mtsl��� ���������tŞ���mtpl��� ���������� Á���€mtps��� ����������Z���mtpi��� ����������P´���Lmtlo��� ����������j���pref�zU��������Q���°pref�–��������IŢ�� pref�·ú��������ë��*lpref�˛T��������x���pref�Ď•��������„���pref�y,��������ś��� pref�}ü��������¦���pref�zÓ�����������Ćpref�Ţđ�������� }���:pref�\��������Đ��� pref�Äi��������"ş��Úpref�{�������� ��� pref�î›�� ������Ő��pref�8¤��!������ á���2pref�˛S��"������…��Ppref�€Č��#������Šn��şpref�őé��$������ A���bpref�Çz��%������ A���pref�O»��&������ ��� pref�šF��'������`���Äpref�®��(������;��pref�t—��)������ ©���¨pref� Ţ��*������ ���.pref�†n��+������Ź(�� pref�С��,������$���"pref�-&��-������ ·��� pref�Vu��.������>ţ���’pref�C7��/������F���Jpref���0������ ­���pref�·„��1������‘4��0pref�°ó��2�����Š�� pref�…D��3�����–��2pref�ó��4������¤���pref�Żď��5������ Ç���pref�»a��6������ A��� pref�O~��7������ K���pref�G&��8������?¦���Ćpref�r[��9������ q���:pref�ý@��:������ «��� pref�č��;������•d��Úpref�n��<������ á��� pref�@��=������@l��pref�ţI��>������3���2pref�ĽŐ��?�����9Č��Ppref�­��@�����?��şpref�1y��A������w���bpref�{Ö��B������ í���pref�pú��C������ ·��� pref�Ş–��D������Oę���Ępref�®‡��E������eě��pref�†‰��F������—>���¨pref�đR��G������$”���.pref�âź��H�����CŇ�� pref�´÷��I������Q���"pref� e��J������Ă��� pref�¸L��K������—ć���’pref�ôu��L������9���Jpref�›N��M������g���mstp�������������Ş��� mtsl��� ���������z<���mtpl��� ���������rÚ���€mtps��� ���������� 1���mtpi��� ���������<���Hmtlo��� �������������pref�"Ĺ“��N�����EŢ��°pref�"+#��O�����ZŽ�� pref�"j��P�����„��*lpref�"]Ł��Q������´���pref�"u:��R������s���pref�""‘��S������ Ł��� pref�"\É��T������Í���pref�"Ťç��U������x���Ćpref�"6Ş��V������e°���:pref�!ç ��W������ Q��� pref�"`W��X�����`š��Úpref�!ő“��Y������Ş��� pref�"D��Z�����bt��pref�"“™��[������™x���2pref�"/d��\�����c†��Ppref�"FG��]�����hÖ��şpref�!úâ��^������™Ş���bpref�"!Ô��_������‹���pref�!˙m��`������ź��� pref�"M��a������š ���Äpref�"4��b�����m��pref�"Ťí��c�����n¦���¨pref�!âg��d������$Â���.pref�!ç§��e�����oN�� pref�"Ž{��f������9Ú���"pref�"- ��g������$đ��� pref�"‚��h�����yŞ���’pref�",Z��i������šĐ���Jpref�"˝€��j�����s~���dpref��š��k�����sâ���dpref��a–��l�����tF���dpref��I‹��m������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable800/config.cache�������������������������������������������������0000644�0000000�0000000�00000000000�13742524721�020266� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable800/configure.in�������������������������������������������������0000644�0000000�0000000�00000002705�13745605157�020371� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������AC_INIT(tkTable.c) if test "${prefix}" = "NONE"; then prefix=/usr/local echo "setting prefix to: ${prefix}" fi if test "${exec_prefix}" = "NONE"; then exec_prefix=$prefix echo "setting exec-prefix to: ${exec_prefix}" fi AC_PROG_INSTALL AC_ARG_WITH(tcl, [ --with-tcl=<directory> directory containing tclConfig.sh], [tcl_prefix=$withval], [tcl_prefix=${exec_prefix}/lib]) AC_ARG_WITH(tk, [ --with-tk=<directory> directory containing tkConfig.sh], [tk_prefix=$withval], [tk_prefix=${exec_prefix}/lib]) file=${tcl_prefix}/tclConfig.sh . $file file=${tk_prefix}/tkConfig.sh . $file CC=$TCL_CC AC_SUBST(CC) AC_SUBST(INSTALL) AC_SUBST(INSTALL_PROGRAM) AC_SUBST(INSTALL_DATA) AC_SUBST(TCL_SHLIB_CFLAGS) AC_SUBST(TCL_SHLIB_LD) AC_SUBST(TCL_SHLIB_SUFFIX) AC_SUBST(TCL_VERSION) AC_SUBST(TCL_RANLIB) AC_SUBST(TCL_XINCLUDES) AC_SUBST(TCL_PREFIX) AC_SUBST(TCL_EXEC_PREFIX) AC_SUBST(TCL_CFLAGS) AC_SUBST(TCL_DEFS) AC_SUBST(TCL_LIB_SPEC) AC_SUBST(TCL_LIBS) AC_SUBST(TCL_LD_FLAGS) AC_SUBST(TCL_COMPAT_OBJS) AC_SUBST(TCL_LD_SEARCH_FLAGS) AC_SUBST(TCL_SRC_DIR) AC_SUBST(TCL_BUILD_LIB_SPEC) AC_SUBST(prefix) AC_SUBST(exec_prefix) AC_SUBST(TK_VERSION) AC_SUBST(TK_XINCLUDES) AC_SUBST(TK_PREFIX) AC_SUBST(TK_EXEC_PREFIX) AC_SUBST(TK_DEFS) AC_SUBST(TK_LIBS) AC_SUBST(TK_LIB_SPEC) AC_SUBST(TK_LD_SEARCH_FLAGS) AC_SUBST(TK_SRC_DIR) AC_SUBST(TK_BUILD_LIB_SPEC) AC_OUTPUT(Makefile) �����������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable800/tkTableWin.c�������������������������������������������������0000644�0000000�0000000�00000070601�13745605157�020270� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * tkTableWin.c -- * * This module implements embedded windows for table widgets. * Much of this code is adapted from tkGrid.c and tkTextWind.c. * * Copyright (c) 1998-2002 Jeffrey Hobbs * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tkTableWin.c,v 1.2 2004/02/08 03:09:48 cerney Exp $ */ #include "tkVMacro.h" #include "tkTable.h" static int StickyParseProc _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, Arg value, char *widgRec, int offset)); Arg StickyPrintProc _ANSI_ARGS_((ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)); static void EmbWinLostSlaveProc _ANSI_ARGS_((ClientData clientData, Tk_Window tkwin)); static void EmbWinRequestProc _ANSI_ARGS_((ClientData clientData, Tk_Window tkwin)); static void EmbWinCleanup _ANSI_ARGS_((Table *tablePtr, TableEmbWindow *ewPtr)); static int EmbWinConfigure _ANSI_ARGS_((Table *tablePtr, TableEmbWindow *ewPtr, int objc, Tcl_Obj *CONST objv[])); static void EmbWinStructureProc _ANSI_ARGS_((ClientData clientData, XEvent *eventPtr)); static void EmbWinUnmapNow _ANSI_ARGS_((Tk_Window ewTkwin, Tk_Window tkwin)); static Tk_GeomMgr tableGeomType = { "table", /* name */ EmbWinRequestProc, /* requestProc */ EmbWinLostSlaveProc, /* lostSlaveProc */ }; /* windows subcommands */ static CONST84 char *winCmdNames[] = { "cget", "configure", "delete", "move", "names", (char *) NULL }; enum winCommand { WIN_CGET, WIN_CONFIGURE, WIN_DELETE, WIN_MOVE, WIN_NAMES }; /* Flag values for "sticky"ness The 16 combinations subsume the packer's * notion of anchor and fill. * * STICK_NORTH This window sticks to the top of its cavity. * STICK_EAST This window sticks to the right edge of its cavity. * STICK_SOUTH This window sticks to the bottom of its cavity. * STICK_WEST This window sticks to the left edge of its cavity. */ #define STICK_NORTH (1<<0) #define STICK_EAST (1<<1) #define STICK_SOUTH (1<<2) #define STICK_WEST (1<<3) /* * The default specification for configuring embedded windows * Done like this to make the command line parsing easy */ static Tk_CustomOption stickyOption = { StickyParseProc, StickyPrintProc, (ClientData) NULL }; static Tk_CustomOption tagBdOpt = { TableOptionBdSet, TableOptionBdGet, (ClientData) BD_TABLE_WIN }; static Tk_ConfigSpec winConfigSpecs[] = { {TK_CONFIG_BORDER, "-background", "background", "Background", NULL, Tk_Offset(TableEmbWindow, bg), TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK }, {TK_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL, 0, 0}, {TK_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0}, {TK_CONFIG_CUSTOM, "-borderwidth", "borderWidth", "BorderWidth", "", 0 /* no offset */, TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK, &tagBdOpt }, {TK_CONFIG_STRING, "-create", (char *)NULL, (char *)NULL, (char *)NULL, Tk_Offset(TableEmbWindow, create), TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK }, {TK_CONFIG_PIXELS, "-padx", (char *)NULL, (char *)NULL, (char *)NULL, Tk_Offset(TableEmbWindow, padX), TK_CONFIG_DONT_SET_DEFAULT }, {TK_CONFIG_PIXELS, "-pady", (char *)NULL, (char *)NULL, (char *)NULL, Tk_Offset(TableEmbWindow, padY), TK_CONFIG_DONT_SET_DEFAULT }, {TK_CONFIG_CUSTOM, "-sticky", (char *)NULL, (char *)NULL, (char *)NULL, Tk_Offset(TableEmbWindow, sticky), TK_CONFIG_DONT_SET_DEFAULT, &stickyOption}, {TK_CONFIG_RELIEF, "-relief", "relief", "Relief", NULL, Tk_Offset(TableEmbWindow, relief), 0 }, {TK_CONFIG_WINDOW, "-window", (char *)NULL, (char *)NULL, (char *)NULL, Tk_Offset(TableEmbWindow, tkwin), TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK }, {TK_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0 } }; /* *---------------------------------------------------------------------- * * StickyPrintProc -- * Converts the internal boolean combination of "sticky" bits onto * a TCL string element containing zero or more of n, s, e, or w. * * Results: * A string is placed into the "result" pointer. * * Side effects: * none. * *---------------------------------------------------------------------- */ Arg StickyPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr) ClientData clientData; /* Ignored. */ Tk_Window tkwin; /* Window for text widget. */ char *widgRec; /* Pointer to TkTextEmbWindow * structure. */ int offset; /* Ignored. */ Tcl_FreeProc **freeProcPtr; /* Pointer to variable to fill in with * information about how to reclaim * storage for return string. */ { int flags = ((TableEmbWindow *) widgRec)->sticky; int count = 0; char *result = (char *) ckalloc(5*sizeof(char)); if (flags&STICK_NORTH) result[count++] = 'n'; if (flags&STICK_EAST) result[count++] = 'e'; if (flags&STICK_SOUTH) result[count++] = 's'; if (flags&STICK_WEST) result[count++] = 'w'; *freeProcPtr = TCL_DYNAMIC; result[count] = '\0'; return LangStringArg(result); } /* *---------------------------------------------------------------------- * * StringParseProc -- * Converts an ascii string representing a widgets stickyness * into the boolean result. * * Results: * The boolean combination of the "sticky" bits is retuned. If an * error occurs, such as an invalid character, -1 is returned instead. * * Side effects: * none * *---------------------------------------------------------------------- */ static int StickyParseProc(clientData, interp, tkwin, value, widgRec, offset) ClientData clientData; /* Not used.*/ Tcl_Interp *interp; /* Used for reporting errors. */ Tk_Window tkwin; /* Window for text widget. */ Arg value; /* Value of option. */ char *widgRec; /* Pointer to TkTextEmbWindow * structure. */ int offset; /* Offset into item (ignored). */ { register TableEmbWindow *ewPtr = (TableEmbWindow *) widgRec; int sticky = 0; char c; char * valuestring = LangString(value); while ((c = *valuestring++) != '\0') { switch (c) { case 'n': case 'N': sticky |= STICK_NORTH; break; case 'e': case 'E': sticky |= STICK_EAST; break; case 's': case 'S': sticky |= STICK_SOUTH; break; case 'w': case 'W': sticky |= STICK_WEST; break; case ' ': case ',': case '\t': case '\r': case '\n': break; default: Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "bad sticky value \"", --valuestring, "\": must contain n, s, e or w", (char *) NULL); return TCL_ERROR; } } ewPtr->sticky = sticky; return TCL_OK; } /* * ckallocs space for a new embedded window structure and clears the structure * returns the pointer to the new structure */ static TableEmbWindow * TableNewEmbWindow(Table *tablePtr) { TableEmbWindow *ewPtr = (TableEmbWindow *) ckalloc(sizeof(TableEmbWindow)); memset((VOID *) ewPtr, 0, sizeof(TableEmbWindow)); /* * Set the values that aren't 0/NULL by default */ ewPtr->tablePtr = tablePtr; ewPtr->relief = -1; ewPtr->padX = -1; ewPtr->padY = -1; return ewPtr; } /* *---------------------------------------------------------------------- * * EmbWinCleanup -- * Releases resources used by an embedded window before it is freed up. * * Results: * Window will no longer be valid. * * Side effects: * None. * *---------------------------------------------------------------------- */ static void EmbWinCleanup(Table *tablePtr, TableEmbWindow *ewPtr) { Tk_FreeOptions(winConfigSpecs, (char *) ewPtr, tablePtr->display, 0); } /* *-------------------------------------------------------------- * * EmbWinDisplay -- * * This procedure is invoked by TableDisplay for * mapping windows into cells. * * Results: * Displays or moves window on table screen. * * Side effects: * None. * *-------------------------------------------------------------- */ void EmbWinDisplay(Table *tablePtr, Drawable window, TableEmbWindow *ewPtr, TableTag *tagPtr, int x, int y, int width, int height) { Tk_Window tkwin = tablePtr->tkwin; Tk_Window ewTkwin = ewPtr->tkwin; int diffx=0; /* Cavity width - slave width. */ int diffy=0; /* Cavity hight - slave height. */ int sticky = ewPtr->sticky; int padx, pady; if (ewPtr->bg) tagPtr->bg = ewPtr->bg; if (ewPtr->relief != -1) tagPtr->relief = ewPtr->relief; if (ewPtr->borders) { tagPtr->borderStr = ewPtr->borderStr; tagPtr->borders = ewPtr->borders; tagPtr->bd[0] = ewPtr->bd[0]; tagPtr->bd[1] = ewPtr->bd[1]; tagPtr->bd[2] = ewPtr->bd[2]; tagPtr->bd[3] = ewPtr->bd[3]; } padx = (ewPtr->padX < 0) ? tablePtr->padX : ewPtr->padX; pady = (ewPtr->padY < 0) ? tablePtr->padY : ewPtr->padY; x += padx; width -= padx*2; y += pady; height -= pady*2; if (width > Tk_ReqWidth(ewPtr->tkwin)) { diffx = width - Tk_ReqWidth(ewPtr->tkwin); width = Tk_ReqWidth(ewPtr->tkwin); } if (height > Tk_ReqHeight(ewPtr->tkwin)) { diffy = height - Tk_ReqHeight(ewPtr->tkwin); height = Tk_ReqHeight(ewPtr->tkwin); } if (sticky&STICK_EAST && sticky&STICK_WEST) { width += diffx; } if (sticky&STICK_NORTH && sticky&STICK_SOUTH) { height += diffy; } if (!(sticky&STICK_WEST)) { x += (sticky&STICK_EAST) ? diffx : diffx/2; } if (!(sticky&STICK_NORTH)) { y += (sticky&STICK_SOUTH) ? diffy : diffy/2; } /* * If we fall below a specific minimum width/height requirement, * we just unmap the window */ if (width < 4 || height < 4) { if (ewPtr->displayed) { EmbWinUnmapNow(ewTkwin, tkwin); } return; } if (tkwin == Tk_Parent(ewTkwin)) { if ((x != Tk_X(ewTkwin)) || (y != Tk_Y(ewTkwin)) || (width != Tk_Width(ewTkwin)) || (height != Tk_Height(ewTkwin))) { Tk_MoveResizeWindow(ewTkwin, x, y, width, height); } Tk_MapWindow(ewTkwin); } else { Tk_MaintainGeometry(ewTkwin, tkwin, x, y, width, height); } ewPtr->displayed = 1; } /* *-------------------------------------------------------------- * * EmbWinUnmapNow -- * Handles unmapping the window depending on parent. * tkwin should be tablePtr->tkwin. * ewTkwin should be ewPtr->tkwin. * * Results: * Removes the window. * * Side effects: * None. * *-------------------------------------------------------------- */ static void EmbWinUnmapNow(Tk_Window ewTkwin, Tk_Window tkwin) { if (tkwin != Tk_Parent(ewTkwin)) { Tk_UnmaintainGeometry(ewTkwin, tkwin); } Tk_UnmapWindow(ewTkwin); } /* *-------------------------------------------------------------- * * EmbWinUnmap -- * This procedure is invoked by TableAdjustParams for * unmapping windows managed moved offscreen. * rlo, ... should be in real coords. * * Results: * None. * * Side effects: * Unmaps embedded windows. * *-------------------------------------------------------------- */ void EmbWinUnmap(Table *tablePtr, int rlo, int rhi, int clo, int chi) { register TableEmbWindow *ewPtr; Tcl_HashEntry *entryPtr; int row, col, trow, tcol; char buf[INDEX_BUFSIZE]; /* * Transform numbers from real to user user coords */ rlo += tablePtr->rowOffset; rhi += tablePtr->rowOffset; clo += tablePtr->colOffset; chi += tablePtr->colOffset; for (row = rlo; row <= rhi; row++) { for (col = clo; col <= chi; col++) { TableTrueCell(tablePtr, row, col, &trow, &tcol); TableMakeArrayIndex(trow, tcol, buf); entryPtr = Tcl_FindHashEntry(tablePtr->winTable, buf); if (entryPtr != NULL) { ewPtr = (TableEmbWindow *) Tcl_GetHashValue(entryPtr); if (ewPtr->displayed) { ewPtr->displayed = 0; if (ewPtr->tkwin != NULL && tablePtr->tkwin != NULL) { EmbWinUnmapNow(ewPtr->tkwin, tablePtr->tkwin); } } } } } } /* *-------------------------------------------------------------- * * EmbWinRequestProc -- * This procedure is invoked by Tk_GeometryRequest for * windows managed by the Table. * * Results: * None. * * Side effects: * Arranges for tkwin, and all its managed siblings, to * be re-arranged at the next idle point. * *-------------------------------------------------------------- */ static void EmbWinRequestProc(clientData, tkwin) ClientData clientData; /* Table's information about * window that got new preferred * geometry. */ Tk_Window tkwin; /* Other Tk-related information * about the window. */ { register TableEmbWindow *ewPtr = (TableEmbWindow *) clientData; /* * Resize depends on the sticky */ if (ewPtr->displayed && ewPtr->hPtr != NULL) { Table *tablePtr = ewPtr->tablePtr; int row, col, x, y, width, height; TableParseArrayIndex(&row, &col, Tcl_GetHashKey(tablePtr->winTable, ewPtr->hPtr)); if (TableCellVCoords(tablePtr, row-tablePtr->rowOffset, col-tablePtr->colOffset, &x, &y, &width, &height, 0)) { TableInvalidate(tablePtr, x, y, width, height, 0); } } } static void EmbWinRemove(TableEmbWindow *ewPtr) { Table *tablePtr = ewPtr->tablePtr; if (ewPtr->tkwin != NULL) { Tk_DeleteEventHandler(ewPtr->tkwin, StructureNotifyMask, EmbWinStructureProc, (ClientData) ewPtr); ewPtr->tkwin = NULL; } ewPtr->displayed = 0; if (tablePtr->tkwin != NULL) { int row, col, x, y, width, height; TableParseArrayIndex(&row, &col, Tcl_GetHashKey(tablePtr->winTable, ewPtr->hPtr)); /* this will cause windows removed from the table to actually * cause the associated embdedded window hash data to be removed */ Tcl_DeleteHashEntry(ewPtr->hPtr); if (TableCellVCoords(tablePtr, row-tablePtr->rowOffset, col-tablePtr->colOffset, &x, &y, &width, &height, 0)) TableInvalidate(tablePtr, x, y, width, height, 1); } /* this will cause windows removed from the table to actually * cause the associated embdedded window hash data to be removed */ EmbWinCleanup(tablePtr, ewPtr); ckfree((char *) ewPtr); } /* *-------------------------------------------------------------- * * EmbWinLostSlaveProc -- * This procedure is invoked by Tk whenever some other geometry * claims control over a slave that used to be managed by us. * * Results: * None. * * Side effects: * Forgets all table-related information about the slave. * *-------------------------------------------------------------- */ static void EmbWinLostSlaveProc(clientData, tkwin) ClientData clientData; /* Table structure for slave window that * was stolen away. */ Tk_Window tkwin; /* Tk's handle for the slave window. */ { register TableEmbWindow *ewPtr = (TableEmbWindow *) clientData; #if 0 Tcl_CancelIdleCall(EmbWinDelayedUnmap, (ClientData) ewPtr); #endif EmbWinUnmapNow(tkwin, ewPtr->tablePtr->tkwin); EmbWinRemove(ewPtr); } /* *-------------------------------------------------------------- * * EmbWinStructureProc -- * This procedure is invoked by the Tk event loop whenever * StructureNotify events occur for a window that's embedded * in a table widget. This procedure's only purpose is to * clean up when windows are deleted. * * Results: * None. * * Side effects: * The window is disassociated from the window segment, and * the portion of the table is redisplayed. * *-------------------------------------------------------------- */ static void EmbWinStructureProc(clientData, eventPtr) ClientData clientData; /* Pointer to record describing window item. */ XEvent *eventPtr; /* Describes what just happened. */ { register TableEmbWindow *ewPtr = (TableEmbWindow *) clientData; if (eventPtr->type != DestroyNotify) { return; } EmbWinRemove(ewPtr); } /* *-------------------------------------------------------------- * * EmbWinDelete -- * This procedure is invoked by ... whenever * an embedded window is being deleted. * * Results: * None. * * Side effects: * The embedded window is deleted, if it exists, and any resources * associated with it are released. * *-------------------------------------------------------------- */ void EmbWinDelete(register Table *tablePtr, TableEmbWindow *ewPtr) { Tcl_HashEntry *entryPtr = ewPtr->hPtr; if (ewPtr->tkwin != NULL) { Tk_Window tkwin = ewPtr->tkwin; /* * Delete the event handler for the window before destroying * the window, so that EmbWinStructureProc doesn't get called * (we'll already do everything that it would have done, and * it will just get confused). */ ewPtr->tkwin = NULL; Tk_DeleteEventHandler(tkwin, StructureNotifyMask, EmbWinStructureProc, (ClientData) ewPtr); Tk_DestroyWindow(tkwin); } if (tablePtr->tkwin != NULL && entryPtr != NULL) { int row, col, x, y, width, height; TableParseArrayIndex(&row, &col, Tcl_GetHashKey(tablePtr->winTable, entryPtr)); Tcl_DeleteHashEntry(entryPtr); if (TableCellVCoords(tablePtr, row-tablePtr->rowOffset, col-tablePtr->colOffset, &x, &y, &width, &height, 0)) TableInvalidate(tablePtr, x, y, width, height, 0); } #if 0 Tcl_CancelIdleCall(EmbWinDelayedUnmap, (ClientData) ewPtr); #endif EmbWinCleanup(tablePtr, ewPtr); ckfree((char *) ewPtr); } /* *-------------------------------------------------------------- * * EmbWinConfigure -- * This procedure is called to handle configuration options * for an embedded window. * * Results: * The return value is a standard Tcl result. If TCL_ERROR is * returned, then the interp's result contains an error message.. * * Side effects: * Configuration information for the embedded window changes, * such as alignment, stretching, or name of the embedded * window. * *-------------------------------------------------------------- */ static int EmbWinConfigure(tablePtr, ewPtr, objc, objv) Table *tablePtr; /* Information about table widget that * contains embedded window. */ TableEmbWindow *ewPtr; /* Embedded window to be configured. */ int objc; /* Number of objs in objv. */ Tcl_Obj *CONST objv[]; /* Obj type options. */ { Tcl_Interp *interp = tablePtr->interp; Tk_Window oldWindow; int i, result; Arg *args; oldWindow = ewPtr->tkwin; /* Stringify */ args = (Arg *) ckalloc((objc + 1) * sizeof(Arg)); for (i = 0; i < objc; i++) args[i] = LangStringArg(Tcl_GetString(objv[i])); args[i] = NULL; result = Tk_ConfigureWidget(interp, tablePtr->tkwin, winConfigSpecs, objc, args, (char *) ewPtr, TK_CONFIG_ARGV_ONLY); ckfree((char *) args); if (result != TCL_OK) { return TCL_ERROR; } if (oldWindow != ewPtr->tkwin) { ewPtr->displayed = 0; if (oldWindow != NULL) { Tk_DeleteEventHandler(oldWindow, StructureNotifyMask, EmbWinStructureProc, (ClientData) ewPtr); Tk_ManageGeometry(oldWindow, (Tk_GeomMgr *) NULL, (ClientData) NULL); EmbWinUnmapNow(oldWindow, tablePtr->tkwin); } if (ewPtr->tkwin != NULL) { Tk_Window ancestor, parent; /* * Make sure that the table is either the parent of the * embedded window or a descendant of that parent. Also, * don't allow a top-level window to be managed inside * a table. */ parent = Tk_Parent(ewPtr->tkwin); for (ancestor = tablePtr->tkwin; ; ancestor = Tk_Parent(ancestor)) { if (ancestor == parent) { break; } if (Tk_IsTopLevel(ancestor)) { badMaster: Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "can't embed ", Tk_PathName(ewPtr->tkwin), " in ", Tk_PathName(tablePtr->tkwin), (char *)NULL); ewPtr->tkwin = NULL; return TCL_ERROR; } } if (Tk_IsTopLevel(ewPtr->tkwin) || (ewPtr->tkwin == tablePtr->tkwin)) { goto badMaster; } /* * Take over geometry management for the window, plus create * an event handler to find out when it is deleted. */ Tk_ManageGeometry(ewPtr->tkwin, &tableGeomType, (ClientData)ewPtr); Tk_CreateEventHandler(ewPtr->tkwin, StructureNotifyMask, EmbWinStructureProc, (ClientData) ewPtr); } } return TCL_OK; } /* *-------------------------------------------------------------- * * Table_WinMove -- * This procedure is invoked by ... whenever * an embedded window is being moved. * * Results: * A standard Tcl result. * * Side effects: * If an embedded window is in the dest cell, it is deleted. * *-------------------------------------------------------------- */ int Table_WinMove(register Table *tablePtr, char *CONST srcPtr, char *CONST destPtr, int flags) { int srow, scol, row, col, new; Tcl_HashEntry *entryPtr; TableEmbWindow *ewPtr; if (TableGetIndex(tablePtr, srcPtr, &srow, &scol) != TCL_OK || TableGetIndex(tablePtr, destPtr, &row, &col) != TCL_OK) { return TCL_ERROR; } entryPtr = Tcl_FindHashEntry(tablePtr->winTable, srcPtr); if (entryPtr == NULL) { if (flags & INV_NO_ERR_MSG) { return TCL_OK; } else { Tcl_AppendStringsToObj(Tcl_GetObjResult(tablePtr->interp), "no window at index \"", srcPtr, "\"", (char *) NULL); return TCL_ERROR; } } /* avoid moving it to the same location */ if (srow == row && scol == col) { return TCL_OK; } /* get the window pointer */ ewPtr = (TableEmbWindow *) Tcl_GetHashValue(entryPtr); /* and free the old hash table entry */ Tcl_DeleteHashEntry(entryPtr); entryPtr = Tcl_CreateHashEntry(tablePtr->winTable, destPtr, &new); if (!new) { /* window already there - just delete it */ TableEmbWindow *ewPtrDel; ewPtrDel = (TableEmbWindow *) Tcl_GetHashValue(entryPtr); /* This prevents the deletion of it's own entry, since we need it */ ewPtrDel->hPtr = NULL; EmbWinDelete(tablePtr, ewPtrDel); } /* set the new entry's value */ Tcl_SetHashValue(entryPtr, (ClientData) ewPtr); ewPtr->hPtr = entryPtr; if (flags & INV_FORCE) { int x, y, w, h; /* Invalidate old cell */ if (TableCellVCoords(tablePtr, srow-tablePtr->rowOffset, scol-tablePtr->colOffset, &x, &y, &w, &h, 0)) { TableInvalidate(tablePtr, x, y, w, h, 0); } /* Invalidate new cell */ if (TableCellVCoords(tablePtr, row-tablePtr->rowOffset, col-tablePtr->colOffset, &x, &y, &w, &h, 0)) { TableInvalidate(tablePtr, x, y, w, h, 0); } } return TCL_OK; } /* *-------------------------------------------------------------- * * Table_WinDelete -- * This procedure is invoked by ... whenever * an embedded window is being delete. * * Results: * A standard Tcl result. * * Side effects: * Window info will be deleted. * *-------------------------------------------------------------- */ int Table_WinDelete(register Table *tablePtr, char *CONST idxPtr) { Tcl_HashEntry *entryPtr; entryPtr = Tcl_FindHashEntry(tablePtr->winTable, idxPtr); if (entryPtr != NULL) { /* get the window pointer & clean up data associated with it */ EmbWinDelete(tablePtr, (TableEmbWindow *) Tcl_GetHashValue(entryPtr)); } return TCL_OK; } /* *-------------------------------------------------------------- * * Table_WindowCmd -- * This procedure is invoked to process the window method * that corresponds to a widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_WindowCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *)clientData; int result = TCL_OK, cmdIndex, row, col, x, y, width, height, i, new; TableEmbWindow *ewPtr; Tcl_HashEntry *entryPtr; Tcl_HashSearch search; char buf[INDEX_BUFSIZE], *keybuf, *winname; if (objc < 3) { Tcl_WrongNumArgs(interp, 2, objv, "option ?arg arg ...?"); return TCL_ERROR; } /* parse the next argument */ if (Tcl_GetIndexFromObj(interp, objv[2], winCmdNames, "option", 0, &cmdIndex) != TCL_OK) { return TCL_ERROR; } switch ((enum winCommand) cmdIndex) { case WIN_CGET: if (objc != 5) { Tcl_WrongNumArgs(interp, 3, objv, "index option"); return TCL_ERROR; } entryPtr = Tcl_FindHashEntry(tablePtr->winTable, Tcl_GetString(objv[3])); if (entryPtr == NULL) { Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "no window at index \"", Tcl_GetString(objv[3]), "\"", (char *)NULL); return TCL_ERROR; } else { ewPtr = (TableEmbWindow *) Tcl_GetHashValue(entryPtr); result = Tk_ConfigureValue(interp, tablePtr->tkwin, winConfigSpecs, (char *) ewPtr, Tcl_GetString(objv[4]), 0); } return result; /* CGET */ case WIN_CONFIGURE: if (objc < 4) { Tcl_WrongNumArgs(interp, 3, objv, "index ?arg arg ...?"); return TCL_ERROR; } if (TableGetIndexObj(tablePtr, objv[3], &row, &col) == TCL_ERROR) { return TCL_ERROR; } TableMakeArrayIndex(row, col, buf); entryPtr = Tcl_CreateHashEntry(tablePtr->winTable, buf, &new); if (new) { /* create the structure */ ewPtr = TableNewEmbWindow(tablePtr); /* insert it into the table */ Tcl_SetHashValue(entryPtr, (ClientData) ewPtr); ewPtr->hPtr = entryPtr; /* configure the window structure */ result = EmbWinConfigure(tablePtr, ewPtr, objc-4, objv+4); if (result == TCL_ERROR) { /* release the structure */ EmbWinCleanup(tablePtr, ewPtr); ckfree((char *) ewPtr); /* and free the hash table entry */ Tcl_DeleteHashEntry(entryPtr); } } else { /* window exists, do a reconfig if we have enough args */ /* get the window pointer from the table */ ewPtr = (TableEmbWindow *) Tcl_GetHashValue(entryPtr); /* 5 args means that there are values to replace */ if (objc > 5) { /* and do a reconfigure */ result = EmbWinConfigure(tablePtr, ewPtr, objc-4, objv+4); } } if (result == TCL_ERROR) { return TCL_ERROR; } /* * If there were less than 6 args, we need * to do a printout of the config, even for new windows */ if (objc < 6) { result = Tk_ConfigureInfo(interp, tablePtr->tkwin, winConfigSpecs, (char *) ewPtr, (objc == 5)? Tcl_GetString(objv[4]) : NULL, 0); } else { /* Otherwise we reconfigured so invalidate * the table for a redraw */ if (TableCellVCoords(tablePtr, row-tablePtr->rowOffset, col-tablePtr->colOffset, &x, &y, &width, &height, 0)) { TableInvalidate(tablePtr, x, y, width, height, 1); } } return result; /* CONFIGURE */ case WIN_DELETE: if (objc < 4) { Tcl_WrongNumArgs(interp, 3, objv, "index ?index ...?"); return TCL_ERROR; } for (i = 3; i < objc; i++) { Table_WinDelete(tablePtr, Tcl_GetString(objv[i])); } break; case WIN_MOVE: if (objc != 5) { Tcl_WrongNumArgs(interp, 3, objv, "srcIndex destIndex"); return TCL_ERROR; } result = Table_WinMove(tablePtr, Tcl_GetString(objv[3]), Tcl_GetString(objv[4]), INV_FORCE); break; case WIN_NAMES: { Tcl_Obj *objPtr = Tcl_NewObj(); /* just print out the window names */ if (objc < 3 || objc > 4) { Tcl_WrongNumArgs(interp, 3, objv, "?pattern?"); return TCL_ERROR; } winname = (objc == 4) ? Tcl_GetString(objv[3]) : NULL; entryPtr = Tcl_FirstHashEntry(tablePtr->winTable, &search); while (entryPtr != NULL) { keybuf = Tcl_GetHashKey(tablePtr->winTable, entryPtr); if (objc == 3 || LangStringMatch(keybuf, LangStringArg(winname)) ) { Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj(keybuf, -1)); } entryPtr = Tcl_NextHashEntry(&search); } Tcl_SetResult(interp, LangString(TableCellSort(tablePtr, Tcl_GetResult(interp))), TCL_DYNAMIC); break; } } return TCL_OK; } �������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable800/tkTableEdit.c������������������������������������������������0000644�0000000�0000000�00000052105�13745605157�020417� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * tkTableEdit.c -- * * This module implements editing functions of a table widget. * * Copyright (c) 1998-2000 Jeffrey Hobbs * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tkTableEdit.c,v 1.2 2004/02/08 03:09:47 cerney Exp $ */ #include "tkVMacro.h" #include "tkTable.h" static void TableModifyRC _ANSI_ARGS_((register Table *tablePtr, int doRows, int movetag, Tcl_HashTable *tagTblPtr, Tcl_HashTable *dimTblPtr, int offset, int from, int to, int lo, int hi, int outOfBounds)); /* insert/delete subcommands */ static CONST84 char *modCmdNames[] = { "active", "cols", "rows", (char *)NULL }; enum modCmd { MOD_ACTIVE, MOD_COLS, MOD_ROWS }; /* insert/delete row/col switches */ static CONST84 char *rcCmdNames[] = { "-keeptitles", "-holddimensions", "-holdselection", "-holdtags", "-holdwindows", "--", (char *) NULL }; enum rcCmd { OPT_TITLES, OPT_DIMS, OPT_SEL, OPT_TAGS, OPT_WINS, OPT_LAST }; #define HOLD_TITLES 1<<0 #define HOLD_DIMS 1<<1 #define HOLD_TAGS 1<<2 #define HOLD_WINS 1<<3 #define HOLD_SEL 1<<4 /* *-------------------------------------------------------------- * * Table_EditCmd -- * This procedure is invoked to process the insert/delete method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_EditCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int doInsert, cmdIndex, first, last; if (objc < 4) { Tcl_WrongNumArgs(interp, 2, objv, "option ?switches? arg ?arg?"); return TCL_ERROR; } if (Tcl_GetIndexFromObj(interp, objv[2], modCmdNames, "option", 0, &cmdIndex) != TCL_OK) { return TCL_ERROR; } doInsert = (*(Tcl_GetString(objv[1])) == 'i'); switch ((enum modCmd) cmdIndex) { case MOD_ACTIVE: if (doInsert) { /* INSERT */ if (objc != 5) { Tcl_WrongNumArgs(interp, 3, objv, "index string"); return TCL_ERROR; } if (TableGetIcursorObj(tablePtr, objv[3], &first) != TCL_OK) { return TCL_ERROR; } else if ((tablePtr->flags & HAS_ACTIVE) && !(tablePtr->flags & ACTIVE_DISABLED) && tablePtr->state == STATE_NORMAL) { TableInsertChars(tablePtr, first, Tcl_GetString(objv[4])); } } else { /* DELETE */ if (objc > 5) { Tcl_WrongNumArgs(interp, 3, objv, "first ?last?"); return TCL_ERROR; } if (TableGetIcursorObj(tablePtr, objv[3], &first) != TCL_OK) { return TCL_ERROR; } if (objc == 4) { last = first+1; } else if (TableGetIcursorObj(tablePtr, objv[4], &last) != TCL_OK) { return TCL_ERROR; } if ((last >= first) && (tablePtr->flags & HAS_ACTIVE) && !(tablePtr->flags & ACTIVE_DISABLED) && tablePtr->state == STATE_NORMAL) { TableDeleteChars(tablePtr, first, last-first); } } break; /* EDIT ACTIVE */ case MOD_COLS: case MOD_ROWS: { /* * ROW/COL INSERTION/DELETION * FIX: This doesn't handle spans */ int i, lo, hi, argsLeft, offset, minkeyoff, doRows; int maxrow, maxcol, maxkey, minkey, flags, count, *dimPtr; Tcl_HashTable *tagTblPtr, *dimTblPtr; Tcl_HashSearch search; doRows = (cmdIndex == MOD_ROWS); flags = 0; for (i = 3; i < objc; i++) { if (*(Tcl_GetString(objv[i])) != '-') { break; } if (Tcl_GetIndexFromObj(interp, objv[i], rcCmdNames, "switch", 0, &cmdIndex) != TCL_OK) { return TCL_ERROR; } if (cmdIndex == OPT_LAST) { i++; break; } switch (cmdIndex) { case OPT_TITLES: flags |= HOLD_TITLES; break; case OPT_DIMS: flags |= HOLD_DIMS; break; case OPT_SEL: flags |= HOLD_SEL; break; case OPT_TAGS: flags |= HOLD_TAGS; break; case OPT_WINS: flags |= HOLD_WINS; break; } } argsLeft = objc - i; if (argsLeft < 1 || argsLeft > 2) { Tcl_WrongNumArgs(interp, 3, objv, "?switches? index ?count?"); return TCL_ERROR; } count = 1; maxcol = tablePtr->cols-1+tablePtr->colOffset; maxrow = tablePtr->rows-1+tablePtr->rowOffset; if (strcmp(Tcl_GetString(objv[i]), "end") == 0) { /* allow "end" to be specified as an index */ first = (doRows) ? maxrow : maxcol; } else if (Tcl_GetIntFromObj(interp, objv[i], &first) != TCL_OK) { return TCL_ERROR; } if (argsLeft == 2 && Tcl_GetIntFromObj(interp, objv[++i], &count) != TCL_OK) { return TCL_ERROR; } if (count == 0 || (tablePtr->state == STATE_DISABLED)) { return TCL_OK; } if (doRows) { maxkey = maxrow; minkey = tablePtr->rowOffset; minkeyoff = tablePtr->rowOffset+tablePtr->titleRows; offset = tablePtr->rowOffset; tagTblPtr = tablePtr->rowStyles; dimTblPtr = tablePtr->rowHeights; dimPtr = &(tablePtr->rows); lo = tablePtr->colOffset + ((flags & HOLD_TITLES) ? tablePtr->titleCols : 0); hi = maxcol; } else { maxkey = maxcol; minkey = tablePtr->colOffset; minkeyoff = tablePtr->colOffset+tablePtr->titleCols; offset = tablePtr->colOffset; tagTblPtr = tablePtr->colStyles; dimTblPtr = tablePtr->colWidths; dimPtr = &(tablePtr->cols); lo = tablePtr->rowOffset + ((flags & HOLD_TITLES) ? tablePtr->titleRows : 0); hi = maxrow; } /* constrain the starting index */ if (first > maxkey) { first = maxkey; } else if (first < minkey) { first = minkey; } if (doInsert) { /* +count means insert after index, * -count means insert before index */ if (count < 0) { count = -count; } else { first++; } if ((flags & HOLD_TITLES) && (first < minkeyoff)) { count -= minkeyoff-first; if (count <= 0) { return TCL_OK; } first = minkeyoff; } if (!(flags & HOLD_DIMS)) { maxkey += count; *dimPtr += count; } /* * We need to call TableAdjustParams before TableModifyRC to * ensure that side effect code like var traces that might get * called will access the correct new dimensions. */ if (*dimPtr < 1) { *dimPtr = 1; } TableAdjustParams(tablePtr); for (i = maxkey; i >= first; i--) { /* move row/col style && width/height here */ TableModifyRC(tablePtr, doRows, flags, tagTblPtr, dimTblPtr, offset, i, i-count, lo, hi, ((i-count) < first)); } if (!(flags & HOLD_WINS)) { /* * This may be a little severe, but it does unmap the * windows that need to be unmapped, and those that should * stay do remap correctly. [Bug #551325] */ if (doRows) { EmbWinUnmap(tablePtr, first - tablePtr->rowOffset, maxkey - tablePtr->rowOffset, lo - tablePtr->colOffset, hi - tablePtr->colOffset); } else { EmbWinUnmap(tablePtr, lo - tablePtr->rowOffset, hi - tablePtr->rowOffset, first - tablePtr->colOffset, maxkey - tablePtr->colOffset); } } } else { /* (index = i && count = 1) == (index = i && count = -1) */ if (count < 0) { /* if the count is negative, make sure that the col count will * delete no greater than the original index */ if (first+count < minkey) { if (first-minkey < abs(count)) { /* * In this case, the user is asking to delete more rows * than exist before the minkey, so we have to shrink * the count down to the existing rows up to index. */ count = first-minkey; } else { count += first-minkey; } first = minkey; } else { first += count; count = -count; } } if ((flags & HOLD_TITLES) && (first <= minkeyoff)) { count -= minkeyoff-first; if (count <= 0) { return TCL_OK; } first = minkeyoff; } if (count > maxkey-first+1) { count = maxkey-first+1; } if (!(flags & HOLD_DIMS)) { *dimPtr -= count; } /* * We need to call TableAdjustParams before TableModifyRC to * ensure that side effect code like var traces that might get * called will access the correct new dimensions. */ if (*dimPtr < 1) { *dimPtr = 1; } TableAdjustParams(tablePtr); for (i = first; i <= maxkey; i++) { TableModifyRC(tablePtr, doRows, flags, tagTblPtr, dimTblPtr, offset, i, i+count, lo, hi, ((i+count) > maxkey)); } } if (!(flags & HOLD_SEL) && Tcl_FirstHashEntry(tablePtr->selCells, &search) != NULL) { /* clear selection - forceful, but effective */ Tcl_DeleteHashTable(tablePtr->selCells); Tcl_InitHashTable(tablePtr->selCells, TCL_STRING_KEYS); } /* * Make sure that the modified dimension is actually legal * after removing all that stuff. */ if (*dimPtr < 1) { *dimPtr = 1; TableAdjustParams(tablePtr); } /* change the geometry */ TableGeometryRequest(tablePtr); /* FIX: * This has to handle when the previous rows/cols resize because * of the *stretchmode. InvalidateAll does that, but could be * more efficient. */ TableInvalidateAll(tablePtr, 0); break; } } return TCL_OK; } /* *---------------------------------------------------------------------- * * TableDeleteChars -- * Remove one or more characters from an table widget. * * Results: * None. * * Side effects: * Memory gets freed, the table gets modified and (eventually) * redisplayed. * *---------------------------------------------------------------------- */ void TableDeleteChars(tablePtr, index, count) register Table *tablePtr; /* Table widget to modify. */ int index; /* Index of first character to delete. */ int count; /* How many characters to delete. */ { #ifdef TCL_UTF_MAX int byteIndex, byteCount, newByteCount, numBytes, numChars; char *new, *string; string = tablePtr->activeBuf; numBytes = strlen(string); numChars = Tcl_NumUtfChars(string, numBytes); if ((index + count) > numChars) { count = numChars - index; } if (count <= 0) { return; } byteIndex = Tcl_UtfAtIndex(string, index) - string; byteCount = Tcl_UtfAtIndex(string + byteIndex, count) - (string + byteIndex); newByteCount = numBytes + 1 - byteCount; new = (char *) ckalloc((unsigned) newByteCount); memcpy(new, string, (size_t) byteIndex); strcpy(new + byteIndex, string + byteIndex + byteCount); #else int oldlen; char *new; /* this gets the length of the string, as well as ensuring that * the cursor isn't beyond the end char */ TableGetIcursor(tablePtr, "end", &oldlen); if ((index+count) > oldlen) count = oldlen-index; if (count <= 0) return; new = (char *) ckalloc((unsigned)(oldlen-count+1)); strncpy(new, tablePtr->activeBuf, (size_t) index); strcpy(new+index, tablePtr->activeBuf+index+count); /* make sure this string is null terminated */ new[oldlen-count] = '\0'; #endif /* This prevents deletes on BREAK or validation error. */ if (tablePtr->validate && TableValidateChange(tablePtr, tablePtr->activeRow+tablePtr->rowOffset, tablePtr->activeCol+tablePtr->colOffset, tablePtr->activeBuf, new, index) != TCL_OK) { ckfree(new); return; } ckfree(tablePtr->activeBuf); tablePtr->activeBuf = new; /* mark the text as changed */ tablePtr->flags |= TEXT_CHANGED; if (tablePtr->icursor >= index) { if (tablePtr->icursor >= (index+count)) { tablePtr->icursor -= count; } else { tablePtr->icursor = index; } } TableSetActiveIndex(tablePtr); TableRefresh(tablePtr, tablePtr->activeRow, tablePtr->activeCol, CELL); } /* *---------------------------------------------------------------------- * * TableInsertChars -- * Add new characters to the active cell of a table widget. * * Results: * None. * * Side effects: * New information gets added to tablePtr; it will be redisplayed * soon, but not necessarily immediately. * *---------------------------------------------------------------------- */ void TableInsertChars(tablePtr, index, value) register Table *tablePtr; /* Table that is to get the new elements. */ int index; /* Add the new elements before this element. */ char *value; /* New characters to add (NULL-terminated * string). */ { #ifdef TCL_UTF_MAX int oldlen, byteIndex, byteCount; char *new, *string; byteCount = strlen(value); if (byteCount == 0) { return; } /* Is this an autoclear and this is the first update */ /* Note that this clears without validating */ if (tablePtr->autoClear && !(tablePtr->flags & TEXT_CHANGED)) { /* set the buffer to be empty */ tablePtr->activeBuf = (char *)ckrealloc(tablePtr->activeBuf, 1); tablePtr->activeBuf[0] = '\0'; /* the insert position now has to be 0 */ index = 0; tablePtr->icursor = 0; } string = tablePtr->activeBuf; byteIndex = Tcl_UtfAtIndex(string, index) - string; oldlen = strlen(string); new = (char *) ckalloc((unsigned)(oldlen + byteCount + 1)); memcpy(new, string, (size_t) byteIndex); strcpy(new + byteIndex, value); strcpy(new + byteIndex + byteCount, string + byteIndex); /* validate potential new active buffer */ /* This prevents inserts on either BREAK or validation error. */ if (tablePtr->validate && TableValidateChange(tablePtr, tablePtr->activeRow+tablePtr->rowOffset, tablePtr->activeCol+tablePtr->colOffset, tablePtr->activeBuf, new, byteIndex) != TCL_OK) { ckfree(new); return; } /* * The following construction is used because inserting improperly * formed UTF-8 sequences between other improperly formed UTF-8 * sequences could result in actually forming valid UTF-8 sequences; * the number of characters added may not be Tcl_NumUtfChars(string, -1), * because of context. The actual number of characters added is how * many characters were are in the string now minus the number that * used to be there. */ if (tablePtr->icursor >= index) { tablePtr->icursor += Tcl_NumUtfChars(new, oldlen+byteCount) - Tcl_NumUtfChars(tablePtr->activeBuf, oldlen); } ckfree(string); tablePtr->activeBuf = new; #else int oldlen, newlen; char *new; newlen = strlen(value); if (newlen == 0) return; /* Is this an autoclear and this is the first update */ /* Note that this clears without validating */ if (tablePtr->autoClear && !(tablePtr->flags & TEXT_CHANGED)) { /* set the buffer to be empty */ tablePtr->activeBuf = (char *)ckrealloc(tablePtr->activeBuf, 1); tablePtr->activeBuf[0] = '\0'; /* the insert position now has to be 0 */ index = 0; } oldlen = strlen(tablePtr->activeBuf); /* get the buffer to at least the right length */ new = (char *) ckalloc((unsigned)(oldlen+newlen+1)); strncpy(new, tablePtr->activeBuf, (size_t) index); strcpy(new+index, value); strcpy(new+index+newlen, (tablePtr->activeBuf)+index); /* make sure this string is null terminated */ new[oldlen+newlen] = '\0'; /* validate potential new active buffer */ /* This prevents inserts on either BREAK or validation error. */ if (tablePtr->validate && TableValidateChange(tablePtr, tablePtr->activeRow+tablePtr->rowOffset, tablePtr->activeCol+tablePtr->colOffset, tablePtr->activeBuf, new, index) != TCL_OK) { ckfree(new); return; } ckfree(tablePtr->activeBuf); tablePtr->activeBuf = new; if (tablePtr->icursor >= index) { tablePtr->icursor += newlen; } #endif /* mark the text as changed */ tablePtr->flags |= TEXT_CHANGED; TableSetActiveIndex(tablePtr); TableRefresh(tablePtr, tablePtr->activeRow, tablePtr->activeCol, CELL); } /* *---------------------------------------------------------------------- * * TableModifyRC -- * Helper function that does the core work of moving rows/cols * and associated tags. * * Results: * None. * * Side effects: * Moves cell data and possibly tag data * *---------------------------------------------------------------------- */ static void TableModifyRC(tablePtr, doRows, flags, tagTblPtr, dimTblPtr, offset, from, to, lo, hi, outOfBounds) Table *tablePtr; /* Information about text widget. */ int doRows; /* rows (1) or cols (0) */ int flags; /* flags indicating what to move */ Tcl_HashTable *tagTblPtr, *dimTblPtr; /* Pointers to the row/col tags * and width/height tags */ int offset; /* appropriate offset */ int from, to; /* the from and to row/col */ int lo, hi; /* the lo and hi col/row */ int outOfBounds; /* the boundary check for shifting items */ { int j, new; char buf[INDEX_BUFSIZE], buf1[INDEX_BUFSIZE]; Tcl_HashEntry *entryPtr, *newPtr; TableEmbWindow *ewPtr; /* * move row/col style && width/height here * If -holdtags is specified, we don't move the user-set widths/heights * of the absolute rows/columns, otherwise we enter here to move the * dimensions appropriately */ if (!(flags & HOLD_TAGS)) { entryPtr = Tcl_FindHashEntry(tagTblPtr, (char *)from); if (entryPtr != NULL) { Tcl_DeleteHashEntry(entryPtr); } entryPtr = Tcl_FindHashEntry(dimTblPtr, (char *)from-offset); if (entryPtr != NULL) { Tcl_DeleteHashEntry(entryPtr); } if (!outOfBounds) { entryPtr = Tcl_FindHashEntry(tagTblPtr, (char *)to); if (entryPtr != NULL) { newPtr = Tcl_CreateHashEntry(tagTblPtr, (char *)from, &new); Tcl_SetHashValue(newPtr, Tcl_GetHashValue(entryPtr)); Tcl_DeleteHashEntry(entryPtr); } entryPtr = Tcl_FindHashEntry(dimTblPtr, (char *)to-offset); if (entryPtr != NULL) { newPtr = Tcl_CreateHashEntry(dimTblPtr, (char *)from-offset, &new); Tcl_SetHashValue(newPtr, Tcl_GetHashValue(entryPtr)); Tcl_DeleteHashEntry(entryPtr); } } } for (j = lo; j <= hi; j++) { if (doRows /* rows */) { TableMakeArrayIndex(from, j, buf); TableMakeArrayIndex(to, j, buf1); TableMoveCellValue(tablePtr, to, j, buf1, from, j, buf, outOfBounds); } else { TableMakeArrayIndex(j, from, buf); TableMakeArrayIndex(j, to, buf1); TableMoveCellValue(tablePtr, j, to, buf1, j, from, buf, outOfBounds); } /* * If -holdselection is specified, we leave the selected cells in the * absolute cell values, otherwise we enter here to move the * selection appropriately */ if (!(flags & HOLD_SEL)) { entryPtr = Tcl_FindHashEntry(tablePtr->selCells, buf); if (entryPtr != NULL) { Tcl_DeleteHashEntry(entryPtr); } if (!outOfBounds) { entryPtr = Tcl_FindHashEntry(tablePtr->selCells, buf1); if (entryPtr != NULL) { Tcl_CreateHashEntry(tablePtr->selCells, buf, &new); Tcl_DeleteHashEntry(entryPtr); } } } /* * If -holdtags is specified, we leave the tags in the * absolute cell values, otherwise we enter here to move the * tags appropriately */ if (!(flags & HOLD_TAGS)) { entryPtr = Tcl_FindHashEntry(tablePtr->cellStyles, buf); if (entryPtr != NULL) { Tcl_DeleteHashEntry(entryPtr); } if (!outOfBounds) { entryPtr = Tcl_FindHashEntry(tablePtr->cellStyles, buf1); if (entryPtr != NULL) { newPtr = Tcl_CreateHashEntry(tablePtr->cellStyles, buf, &new); Tcl_SetHashValue(newPtr, Tcl_GetHashValue(entryPtr)); Tcl_DeleteHashEntry(entryPtr); } } } /* * If -holdwindows is specified, we leave the windows in the * absolute cell values, otherwise we enter here to move the * windows appropriately */ if (!(flags & HOLD_WINS)) { /* * Delete whatever window might be in our destination */ Table_WinDelete(tablePtr, buf); if (!outOfBounds) { /* * buf1 is where the window is * buf is where we want it to be * * This is an adaptation of Table_WinMove, which we can't * use because we are intermediately fiddling with boundaries */ entryPtr = Tcl_FindHashEntry(tablePtr->winTable, buf1); if (entryPtr != NULL) { /* * If there was a window in our source, * get the window pointer to move it */ ewPtr = (TableEmbWindow *) Tcl_GetHashValue(entryPtr); /* and free the old hash table entry */ Tcl_DeleteHashEntry(entryPtr); entryPtr = Tcl_CreateHashEntry(tablePtr->winTable, buf, &new); /* * We needn't check if a window was in buf, since the * Table_WinDelete above should guarantee that no window * is there. Just set the new entry's value. */ Tcl_SetHashValue(entryPtr, (ClientData) ewPtr); ewPtr->hPtr = entryPtr; } } } } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable800/version.h����������������������������������������������������0000644�0000000�0000000�00000000307�13742524721�017704� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#if 0 TBL_MAJOR_VERSION = 2 TBL_MINOR_VERSION = 8 VERSION = $(TBL_MAJOR_VERSION).$(TBL_MINOR_VERSION) #endif #define TBL_MAJOR_VERSION 2 #define TBL_MINOR_VERSION 8 #define VERSION "2.8" �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable800/configure����������������������������������������������������0000644�0000000�0000000�00000077354�13742524721�017772� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated automatically using autoconf version 2.12 # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. # Defaults: ac_help= ac_default_prefix=/usr/local # Any additions from configure.in: ac_help="$ac_help --with-tcl=<directory> directory containing tclConfig.sh" ac_help="$ac_help --with-tk=<directory> directory containing tkConfig.sh" # Initialize some variables set by options. # The variables have the same names as the options, with # dashes changed to underlines. build=NONE cache_file=./config.cache exec_prefix=NONE host=NONE no_create= nonopt=NONE no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= target=NONE verbose= x_includes=NONE x_libraries=NONE bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datadir='${prefix}/share' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' # Initialize some other variables. subdirs= MFLAGS= MAKEFLAGS= # Maximum number of lines to put in a shell here document. ac_max_here_lines=12 ac_prev= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval "$ac_prev=\$ac_option" ac_prev= continue fi case "$ac_option" in -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; *) ac_optarg= ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case "$ac_option" in -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir="$ac_optarg" ;; -build | --build | --buil | --bui | --bu) ac_prev=build ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build="$ac_optarg" ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file="$ac_optarg" ;; -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | --da=*) datadir="$ac_optarg" ;; -disable-* | --disable-*) ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` eval "enable_${ac_feature}=no" ;; -enable-* | --enable-*) ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "enable_${ac_feature}='$ac_optarg'" ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix="$ac_optarg" ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he) # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat << EOF Usage: configure [options] [host] Options: [defaults in brackets after descriptions] Configuration: --cache-file=FILE cache test results in FILE --help print this message --no-create do not create output files --quiet, --silent do not print \`checking...' messages --version print the version of autoconf that created configure Directory and file names: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [same as prefix] --bindir=DIR user executables in DIR [EPREFIX/bin] --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] --libexecdir=DIR program executables in DIR [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data in DIR [PREFIX/share] --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data in DIR [PREFIX/com] --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] --libdir=DIR object code libraries in DIR [EPREFIX/lib] --includedir=DIR C header files in DIR [PREFIX/include] --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] --infodir=DIR info documentation in DIR [PREFIX/info] --mandir=DIR man documentation in DIR [PREFIX/man] --srcdir=DIR find the sources in DIR [configure dir or ..] --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names EOF cat << EOF Host type: --build=BUILD configure for building on BUILD [BUILD=HOST] --host=HOST configure for HOST [guessed] --target=TARGET configure for TARGET [TARGET=HOST] Features and packages: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --x-includes=DIR X include files are in DIR --x-libraries=DIR X library files are in DIR EOF if test -n "$ac_help"; then echo "--enable and --with options recognized:$ac_help" fi exit 0 ;; -host | --host | --hos | --ho) ac_prev=host ;; -host=* | --host=* | --hos=* | --ho=*) host="$ac_optarg" ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir="$ac_optarg" ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir="$ac_optarg" ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir="$ac_optarg" ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir="$ac_optarg" ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst \ | --locals | --local | --loca | --loc | --lo) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* \ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) localstatedir="$ac_optarg" ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir="$ac_optarg" ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir="$ac_optarg" ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix="$ac_optarg" ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix="$ac_optarg" ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix="$ac_optarg" ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name="$ac_optarg" ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir="$ac_optarg" ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir="$ac_optarg" ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site="$ac_optarg" ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir="$ac_optarg" ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir="$ac_optarg" ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target="$ac_optarg" ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers) echo "configure generated by autoconf version 2.12" exit 0 ;; -with-* | --with-*) ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "with_${ac_package}='$ac_optarg'" ;; -without-* | --without-*) ac_package=`echo $ac_option|sed -e 's/-*without-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` eval "with_${ac_package}=no" ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes="$ac_optarg" ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries="$ac_optarg" ;; -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } ;; *) if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then echo "configure: warning: $ac_option: invalid host type" 1>&2 fi if test "x$nonopt" != xNONE; then { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } fi nonopt="$ac_option" ;; esac done if test -n "$ac_prev"; then { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } fi trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 # File descriptor usage: # 0 standard input # 1 file creation # 2 errors and warnings # 3 some systems may open it to /dev/tty # 4 used on the Kubota Titan # 6 checking for... messages and results # 5 compiler messages saved in config.log if test "$silent" = yes; then exec 6>/dev/null else exec 6>&1 fi exec 5>./config.log echo "\ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. " 1>&5 # Strip out --no-create and --no-recursion so they do not pile up. # Also quote any args containing shell metacharacters. ac_configure_args= for ac_arg do case "$ac_arg" in -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) ac_configure_args="$ac_configure_args '$ac_arg'" ;; *) ac_configure_args="$ac_configure_args $ac_arg" ;; esac done # NLS nuisances. # Only set these to C if already set. These must not be set unconditionally # because not all systems understand e.g. LANG=C (notably SCO). # Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! # Non-C LC_CTYPE values break the ctype check. if test "${LANG+set}" = set; then LANG=C; export LANG; fi if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -rf conftest* confdefs.h # AIX cpp loses on an empty file, so make sure it contains at least a newline. echo > confdefs.h # A filename unique to this package, relative to the directory that # configure is in, which we can look for to find out if srcdir is correct. ac_unique_file=tkTable.c # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then its parent. ac_prog=$0 ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. srcdir=$ac_confdir if test ! -r $srcdir/$ac_unique_file; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r $srcdir/$ac_unique_file; then if test "$ac_srcdir_defaulted" = yes; then { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } else { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } fi fi srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` # Prefer explicitly selected file to automatically selected ones. if test -z "$CONFIG_SITE"; then if test "x$prefix" != xNONE; then CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" else CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi fi for ac_site_file in $CONFIG_SITE; do if test -r "$ac_site_file"; then echo "loading site script $ac_site_file" . "$ac_site_file" fi done if test -r "$cache_file"; then echo "loading cache $cache_file" . $cache_file else echo "creating cache $cache_file" > $cache_file fi ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then ac_n= ac_c=' ' ac_t=' ' else ac_n=-n ac_c= ac_t= fi else ac_n= ac_c='\c' ac_t= fi if test "${prefix}" = "NONE"; then prefix=/usr/local echo "setting prefix to: ${prefix}" fi if test "${exec_prefix}" = "NONE"; then exec_prefix=$prefix echo "setting exec-prefix to: ${exec_prefix}" fi ac_aux_dir= for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do if test -f $ac_dir/install-sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f $ac_dir/install.sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break fi done if test -z "$ac_aux_dir"; then { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } fi ac_config_guess=$ac_aux_dir/config.guess ac_config_sub=$ac_aux_dir/config.sub ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 echo "configure:565: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="${IFS}:" for ac_dir in $PATH; do # Account for people who put trailing slashes in PATH elements. case "$ac_dir/" in /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. for ac_prog in ginstall installbsd scoinst install; do if test -f $ac_dir/$ac_prog; then if test $ac_prog = install && grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. # OSF/1 installbsd also uses dspmsg, but is usable. : else ac_cv_path_install="$ac_dir/$ac_prog -c" break 2 fi fi done ;; esac done IFS="$ac_save_IFS" fi if test "${ac_cv_path_install+set}" = set; then INSTALL="$ac_cv_path_install" else # As a last resort, use the slow shell script. We don't cache a # path for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the path is relative. INSTALL="$ac_install_sh" fi fi echo "$ac_t""$INSTALL" 1>&6 # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' # Check whether --with-tcl or --without-tcl was given. if test "${with_tcl+set}" = set; then withval="$with_tcl" tcl_prefix=$withval else tcl_prefix=${exec_prefix}/lib fi # Check whether --with-tk or --without-tk was given. if test "${with_tk+set}" = set; then withval="$with_tk" tk_prefix=$withval else tk_prefix=${exec_prefix}/lib fi file=${tcl_prefix}/tclConfig.sh . $file file=${tk_prefix}/tkConfig.sh . $file CC=$TCL_CC trap '' 1 2 15 cat > confcache <<\EOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs. It is not useful on other systems. # If it contains results you don't want to keep, you may remove or edit it. # # By default, configure uses ./config.cache as the cache file, # creating it if it does not exist already. You can give configure # the --cache-file=FILE option to use a different cache file; that is # what configure does when it calls configure scripts in # subdirectories, so they share the cache. # Giving --cache-file=/dev/null disables caching, for debugging configure. # config.status only pays attention to the cache file if you give it the # --recheck option to rerun configure. # EOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, don't put newlines in cache variables' values. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. (set) 2>&1 | case `(ac_space=' '; set) 2>&1` in *ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote substitution # turns \\\\ into \\, and sed turns \\ into \). sed -n \ -e "s/'/'\\\\''/g" \ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" ;; *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' ;; esac >> confcache if cmp -s $cache_file confcache; then : else if test -w $cache_file; then echo "updating cache $cache_file" cat confcache > $cache_file else echo "not updating unwritable cache $cache_file" fi fi rm -f confcache trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Any assignment to VPATH causes Sun make to only execute # the first set of double-colon rules, so remove it if not needed. # If there is a colon in the path, we need to keep it. if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' fi trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. cat > conftest.defs <<\EOF s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g s%\[%\\&%g s%\]%\\&%g s%\$%$$%g EOF DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` rm -f conftest.defs # Without the "./", some shells look in PATH for config.status. : ${CONFIG_STATUS=./config.status} echo creating $CONFIG_STATUS rm -f $CONFIG_STATUS cat > $CONFIG_STATUS <<EOF #! /bin/sh # Generated automatically by configure. # Run this file to recreate the current configuration. # This directory was configured as follows, # on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # # $0 $ac_configure_args # # Compiler output produced by configure, useful for debugging # configure, is in ./config.log if it exists. ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" for ac_option do case "\$ac_option" in -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; -version | --version | --versio | --versi | --vers | --ver | --ve | --v) echo "$CONFIG_STATUS generated by autoconf version 2.12" exit 0 ;; -help | --help | --hel | --he | --h) echo "\$ac_cs_usage"; exit 0 ;; *) echo "\$ac_cs_usage"; exit 1 ;; esac done ac_given_srcdir=$srcdir ac_given_INSTALL="$INSTALL" trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 EOF cat >> $CONFIG_STATUS <<EOF # Protect against being on the right side of a sed subst in config.status. sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g; s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF $ac_vpsub $extrasub s%@CFLAGS@%$CFLAGS%g s%@CPPFLAGS@%$CPPFLAGS%g s%@CXXFLAGS@%$CXXFLAGS%g s%@DEFS@%$DEFS%g s%@LDFLAGS@%$LDFLAGS%g s%@LIBS@%$LIBS%g s%@exec_prefix@%$exec_prefix%g s%@prefix@%$prefix%g s%@program_transform_name@%$program_transform_name%g s%@bindir@%$bindir%g s%@sbindir@%$sbindir%g s%@libexecdir@%$libexecdir%g s%@datadir@%$datadir%g s%@sysconfdir@%$sysconfdir%g s%@sharedstatedir@%$sharedstatedir%g s%@localstatedir@%$localstatedir%g s%@libdir@%$libdir%g s%@includedir@%$includedir%g s%@oldincludedir@%$oldincludedir%g s%@infodir@%$infodir%g s%@mandir@%$mandir%g s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g s%@INSTALL_DATA@%$INSTALL_DATA%g s%@CC@%$CC%g s%@INSTALL@%$INSTALL%g s%@TCL_SHLIB_CFLAGS@%$TCL_SHLIB_CFLAGS%g s%@TCL_SHLIB_LD@%$TCL_SHLIB_LD%g s%@TCL_SHLIB_SUFFIX@%$TCL_SHLIB_SUFFIX%g s%@TCL_VERSION@%$TCL_VERSION%g s%@TCL_RANLIB@%$TCL_RANLIB%g s%@TCL_XINCLUDES@%$TCL_XINCLUDES%g s%@TCL_PREFIX@%$TCL_PREFIX%g s%@TCL_EXEC_PREFIX@%$TCL_EXEC_PREFIX%g s%@TCL_CFLAGS@%$TCL_CFLAGS%g s%@TCL_DEFS@%$TCL_DEFS%g s%@TCL_LIB_SPEC@%$TCL_LIB_SPEC%g s%@TCL_LIBS@%$TCL_LIBS%g s%@TCL_LD_FLAGS@%$TCL_LD_FLAGS%g s%@TCL_COMPAT_OBJS@%$TCL_COMPAT_OBJS%g s%@TCL_LD_SEARCH_FLAGS@%$TCL_LD_SEARCH_FLAGS%g s%@TCL_SRC_DIR@%$TCL_SRC_DIR%g s%@TCL_BUILD_LIB_SPEC@%$TCL_BUILD_LIB_SPEC%g s%@TK_VERSION@%$TK_VERSION%g s%@TK_XINCLUDES@%$TK_XINCLUDES%g s%@TK_PREFIX@%$TK_PREFIX%g s%@TK_EXEC_PREFIX@%$TK_EXEC_PREFIX%g s%@TK_DEFS@%$TK_DEFS%g s%@TK_LIBS@%$TK_LIBS%g s%@TK_LIB_SPEC@%$TK_LIB_SPEC%g s%@TK_LD_SEARCH_FLAGS@%$TK_LD_SEARCH_FLAGS%g s%@TK_SRC_DIR@%$TK_SRC_DIR%g s%@TK_BUILD_LIB_SPEC@%$TK_BUILD_LIB_SPEC%g CEOF EOF cat >> $CONFIG_STATUS <<\EOF # Split the substitutions into bite-sized pieces for seds with # small command number limits, like on Digital OSF/1 and HP-UX. ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. ac_file=1 # Number of current file. ac_beg=1 # First line for current file. ac_end=$ac_max_sed_cmds # Line after last line for current file. ac_more_lines=: ac_sed_cmds="" while $ac_more_lines; do if test $ac_beg -gt 1; then sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file else sed "${ac_end}q" conftest.subs > conftest.s$ac_file fi if test ! -s conftest.s$ac_file; then ac_more_lines=false rm -f conftest.s$ac_file else if test -z "$ac_sed_cmds"; then ac_sed_cmds="sed -f conftest.s$ac_file" else ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" fi ac_file=`expr $ac_file + 1` ac_beg=$ac_end ac_end=`expr $ac_end + $ac_max_sed_cmds` fi done if test -z "$ac_sed_cmds"; then ac_sed_cmds=cat fi EOF cat >> $CONFIG_STATUS <<EOF CONFIG_FILES=\${CONFIG_FILES-"Makefile"} EOF cat >> $CONFIG_STATUS <<\EOF for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then # The file is in a subdirectory. test ! -d "$ac_dir" && mkdir "$ac_dir" ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" # A "../" for each directory in $ac_dir_suffix. ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` else ac_dir_suffix= ac_dots= fi case "$ac_given_srcdir" in .) srcdir=. if test -z "$ac_dots"; then top_srcdir=. else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; *) # Relative path. srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" top_srcdir="$ac_dots$ac_given_srcdir" ;; esac case "$ac_given_INSTALL" in [/$]*) INSTALL="$ac_given_INSTALL" ;; *) INSTALL="$ac_dots$ac_given_INSTALL" ;; esac echo creating "$ac_file" rm -f "$ac_file" configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." case "$ac_file" in *Makefile*) ac_comsub="1i\\ # $configure_input" ;; *) ac_comsub= ;; esac ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` sed -e "$ac_comsub s%@configure_input@%$configure_input%g s%@srcdir@%$srcdir%g s%@top_srcdir@%$top_srcdir%g s%@INSTALL@%$INSTALL%g " $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file fi; done rm -f conftest.s* EOF cat >> $CONFIG_STATUS <<EOF EOF cat >> $CONFIG_STATUS <<\EOF exit 0 EOF chmod +x $CONFIG_STATUS rm -fr confdefs* $ac_clean_files test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable800/pTk.exc������������������������������������������������������0000644�0000000�0000000�00000000121�13745605157�017305� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tkAppInit.c tkTableInitScript.h confdefs.h mac_tkTable_prefix.h tkTablePs.c �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable800/tkTableUtil.c������������������������������������������������0000644�0000000�0000000�00000023740�13742524721�020444� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * tkTableUtil.c -- * * This module contains utility functions for table widgets. * * Copyright (c) 2000-2002 Jeffrey Hobbs * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tkTableUtil.c,v 1.2 2004/02/08 03:09:48 cerney Exp $ */ #include "tkTable.h" static char * Cmd_GetName _ANSI_ARGS_((const Cmd_Struct *cmds, int val)); static int Cmd_GetValue _ANSI_ARGS_((const Cmd_Struct *cmds, Arg arg)); static void Cmd_GetError _ANSI_ARGS_((Tcl_Interp *interp, const Cmd_Struct *cmds, Arg arg)); /* *-------------------------------------------------------------- * * Table_ClearHashTable -- * This procedure is invoked to clear a STRING_KEY hash table, * freeing the string entries and then deleting the hash table. * The hash table cannot be used after calling this, except to * be freed or reinitialized. * * Results: * Cached info will be lost. * * Side effects: * Can cause redraw. * See the user documentation. * *-------------------------------------------------------------- */ void Table_ClearHashTable(Tcl_HashTable *hashTblPtr) { Tcl_HashEntry *entryPtr; Tcl_HashSearch search; char *value; for (entryPtr = Tcl_FirstHashEntry(hashTblPtr, &search); entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { value = (char *) Tcl_GetHashValue(entryPtr); if (value != NULL) ckfree(value); } Tcl_DeleteHashTable(hashTblPtr); } /* *---------------------------------------------------------------------- * * TableOptionBdSet -- * * This routine configures the borderwidth value for a tag. * * Results: * A standard Tcl result. * * Side effects: * It may adjust the tag struct values of bd[0..4] and borders. * *---------------------------------------------------------------------- */ int TableOptionBdSet(clientData, interp, tkwin, value, widgRec, offset) ClientData clientData; /* Type of struct being set. */ Tcl_Interp *interp; /* Used for reporting errors. */ Tk_Window tkwin; /* Window containing table widget. */ Arg value; /* Value of option. */ char *widgRec; /* Pointer to record for item. */ int offset; /* Offset into item. */ { char **borderStr; int *bordersPtr, *bdPtr; int type = (int) clientData; int result = TCL_OK; int argc; Arg *args; if ((type == BD_TABLE) && (STREQ(LangString(value),"") )) { /* * NULL strings aren't allowed for the table global -bd */ Tcl_AppendResult(interp, "borderwidth value may not be empty", (char *) NULL); return TCL_ERROR; } if ((type == BD_TABLE) || (type == BD_TABLE_TAG)) { TableTag *tagPtr = (TableTag *) (widgRec + offset); borderStr = &(tagPtr->borderStr); bordersPtr = &(tagPtr->borders); bdPtr = tagPtr->bd; } else if (type == BD_TABLE_WIN) { TableEmbWindow *tagPtr = (TableEmbWindow *) widgRec; borderStr = &(tagPtr->borderStr); bordersPtr = &(tagPtr->borders); bdPtr = tagPtr->bd; } else { panic("invalid type given to TableOptionBdSet\n"); return TCL_ERROR; /* lint */ } result = Tcl_ListObjGetElements(interp, value, &argc, &args); if (result == TCL_OK) { int i, bd[4]; if (((type == BD_TABLE) && (argc == 0)) || (argc == 3) || (argc > 4)) { Tcl_AppendResult(interp, "1, 2 or 4 values must be specified for borderwidth", (char *) NULL); result = TCL_ERROR; } else { /* * We use the shadow bd array first, in case we have an error * parsing arguments half way through. */ for (i = 0; i < argc; i++) { if (Tk_GetPixels(interp, tkwin, LangString(args[i]), &(bd[i])) != TCL_OK) { result = TCL_ERROR; break; } } /* * If everything is OK, store the parsed and given values for * easy retrieval. */ if (result == TCL_OK) { for (i = 0; i < argc; i++) { bdPtr[i] = MAX(0, bd[i]); } if (*borderStr) { ckfree(*borderStr); } if (value) { *borderStr = (char *) ckalloc( strlen( LangString(value) ) + 1); strcpy(*borderStr, LangString(value)); } else { *borderStr = NULL; } *bordersPtr = argc; } } /*ckfree ((char *) argv);*/ } return result; } /* *---------------------------------------------------------------------- * * TableOptionBdGet -- * * Results: * Value of the -bd option. * * Side effects: * None. * *---------------------------------------------------------------------- */ Arg TableOptionBdGet(clientData, tkwin, widgRec, offset, freeProcPtr) ClientData clientData; /* Type of struct being set. */ Tk_Window tkwin; /* Window containing canvas widget. */ char *widgRec; /* Pointer to record for item. */ int offset; /* Offset into item. */ Tcl_FreeProc **freeProcPtr; /* Pointer to variable to fill in with * information about how to reclaim * storage for return string. */ { register int type = (int) clientData; if (type == BD_TABLE) { return LangStringArg( ((TableTag *) (widgRec + offset))->borderStr); } else if (type == BD_TABLE_TAG) { return LangStringArg( ((TableTag *) widgRec)->borderStr); } else if (type == BD_TABLE_WIN) { return LangStringArg( ((TableEmbWindow *) widgRec)->borderStr); } else { panic("invalid type given to TableOptionBdSet\n"); return NULL; /* lint */ } } /* *---------------------------------------------------------------------- * * TableTagConfigureBd -- * This routine configures the border values based on a tag. * The previous value of the bd string (oldValue) is assumed to * be a valid value for this tag. * * Results: * A standard Tcl result. * * Side effects: * It may adjust the value used by -bd. * *---------------------------------------------------------------------- */ int TableTagConfigureBd(Table *tablePtr, TableTag *tagPtr, Arg oldValue, int nullOK) { int i, argc, result = TCL_OK; Arg *args; /* * First check to see if the value really changed. */ if (strcmp(tagPtr->borderStr ? tagPtr->borderStr : "", LangString(oldValue) ? LangString(oldValue) : "") == 0) { return TCL_OK; } tagPtr->borders = 0; if (!nullOK && ((tagPtr->borderStr == NULL) || (*(tagPtr->borderStr) == '\0'))) { /* * NULL strings aren't allowed for this tag */ result = TCL_ERROR; } else if (tagPtr->borderStr) { result = Tcl_ListObjGetElements(tablePtr->interp, LangStringArg(tagPtr->borderStr), &argc, &args); if (result == TCL_OK) { if ((!nullOK && (argc == 0)) || (argc == 3) || (argc > 4)) { Tcl_SetResult(tablePtr->interp, "1, 2 or 4 values must be specified to -borderwidth", TCL_STATIC); result = TCL_ERROR; } else { for (i = 0; i < argc; i++) { if (Tk_GetPixels(tablePtr->interp, tablePtr->tkwin, LangString(args[i]), &(tagPtr->bd[i])) != TCL_OK) { result = TCL_ERROR; break; } tagPtr->bd[i] = MAX(0, tagPtr->bd[i]); } tagPtr->borders = argc; } /* ckfree ((char *) argv); */ } } if (result != TCL_OK) { if (tagPtr->borderStr) { ckfree ((char *) tagPtr->borderStr); } if (oldValue != NULL) { size_t length = strlen(LangString(oldValue)) + 1; /* * We are making the assumption that oldValue is correct. * We have to reparse in case the bad new value had a couple * of correct args before failing on a bad pixel value. */ Tcl_ListObjGetElements(tablePtr->interp, oldValue, &argc, &args); for (i = 0; i < argc; i++) { Tk_GetPixels(tablePtr->interp, tablePtr->tkwin, LangString(args[i]), &(tagPtr->bd[i])); } /* ckfree ((char *) argv); */ tagPtr->borders = argc; tagPtr->borderStr = (char *) ckalloc(length); memcpy(tagPtr->borderStr, LangString(oldValue), length); } else { tagPtr->borders = 0; tagPtr->borderStr = (char *) NULL; } } return result; } /* *---------------------------------------------------------------------- * * Cmd_OptionSet -- * * * Results: * A standard Tcl result. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Cmd_OptionSet(ClientData clientData, Tcl_Interp *interp, Tk_Window unused, Arg value, char *widgRec, int offset) { Cmd_Struct *p = (Cmd_Struct *)clientData; int mode = Cmd_GetValue(p,value); if (!mode) { Cmd_GetError(interp,p,value); return TCL_ERROR; } *((int*)(widgRec+offset)) = mode; return TCL_OK; } /* *---------------------------------------------------------------------- * * Cmd_OptionGet -- * * * Results: * Value of the option. * * Side effects: * None. * *---------------------------------------------------------------------- */ Arg Cmd_OptionGet(ClientData clientData, Tk_Window unused, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr) { Cmd_Struct *p = (Cmd_Struct *)clientData; int mode = *((int*)(widgRec+offset)); return LangStringArg(Cmd_GetName(p,mode)); } /* * simple Cmd_Struct lookup functions */ char * Cmd_GetName(const Cmd_Struct *cmds, int val) { for(;cmds->name && cmds->name[0];cmds++) { if (cmds->value==val) return cmds->name; } return NULL; } int Cmd_GetValue(const Cmd_Struct *cmds, Arg arg) { unsigned int len = strlen(LangString(arg)); for(;cmds->name && cmds->name[0];cmds++) { if (!strncmp(cmds->name, LangString(arg), len)) return cmds->value; } return 0; } void Cmd_GetError(Tcl_Interp *interp, const Cmd_Struct *cmds, Arg arg) { int i; char *argstring = LangString(arg); Tcl_AppendResult(interp, "bad option \"", argstring, "\" must be ", (char *) 0); for(i=0;cmds->name && cmds->name[0];cmds++,i++) { Tcl_AppendResult(interp, (i?", ":""), cmds->name, (char *) 0); } } ��������������������������������Tk-TableMatrix-1.26/pTk/mTk/README������������������������������������������������������������������0000644�0000000�0000000�00000001044�13745605157�015115� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Similar to the perl/tk's build structure, this 'mTk' directory contains _complete_ sources of Tktable in their minimally modified forms. This is because 'munging' to pTk directory from either modified form or original Tk becomes very complex now Tk is split unix/generic. It should also makes merging changes less error prone. # Note that as for Tk800 and Tk804 compatibility, there are two directories here Tktable: Main-line TableMatrix code for Tk804 and above Tktable800: Tablematrix code compatible with the older Tk800-series. ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable/����������������������������������������������������������������0000755�0000000�0000000�00000000000�13746050164�015615� 5����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable/tkTable.c�������������������������������������������������������0000644�0000000�0000000�00000375451�13745605157�017375� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * tkTable.c -- * * This module implements table widgets for the Tk * toolkit. An table displays a 2D array of strings * and allows the strings to be edited. * * Based on Tk3 table widget written by Roland King * * Updates 1996 by: * Jeffrey Hobbs jeff.hobbs@acm.org * John Ellson ellson@lucent.com * Peter Bruecker peter@bj-ig.de * Tom Moore tmoore@spatial.ca * Sebastian Wangnick wangnick@orthogon.de * * Copyright (c) 1997-2002 Jeffrey Hobbs * * See the file "license.txt" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tkTable.c,v 1.32 2005/01/26 15:27:59 A0182636 Exp $ */ #include "tkTable.h" #include "tkPort.h" #include "tkInt.h" #include "tkVMacro.h" /* perltk debug only for picking up forward referenced definitions */ /* #include "myinc.h" */ /* Perltk: XSETCLIP doesn't Appear to be there for perltk so always define this : */ #define NO_XSETCLIP /* Not Needed??? */ /* static char ** StringifyObjects _ANSI_ARGS_((int objc, Tcl_Obj *CONST objv[])); */ static int TableWidgetObjCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj * CONST objv[])); static int TableConfigure _ANSI_ARGS_((Tcl_Interp *interp, Table *tablePtr, int objc, Tcl_Obj *CONST objv[], int flags, int forceUpdate)); static void TableDestroy _ANSI_ARGS_((ClientData clientdata)); static void TableEventProc _ANSI_ARGS_((ClientData clientData, XEvent *eventPtr)); static void TableCmdDeletedProc _ANSI_ARGS_((ClientData clientData)); static void TableRedrawHighlight _ANSI_ARGS_((Table *tablePtr)); static void TableGetGc _ANSI_ARGS_((Display *display, Drawable d, TableTag *tagPtr, GC *tagGc)); static void TableDisplay _ANSI_ARGS_((ClientData clientdata)); static void TableFlashEvent _ANSI_ARGS_((ClientData clientdata)); static char * TableVarProc _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, Var name, char *index, int flags)); static void TableCursorEvent _ANSI_ARGS_((ClientData clientData)); static int TableFetchSelection _ANSI_ARGS_((ClientData clientData, int offset, char *buffer, int maxBytes)); static Tk_RestrictAction TableRestrictProc _ANSI_ARGS_((ClientData arg, XEvent *eventPtr)); /* * The following tables define the widget commands (and sub- * commands) and map the indexes into the string tables into * enumerated types used to dispatch the widget command. */ static CONST char *selCmdNames[] = { "anchor", "clear", "includes", "present", "set", (char *)NULL }; enum selCommand { CMD_SEL_ANCHOR, CMD_SEL_CLEAR, CMD_SEL_INCLUDES, CMD_SEL_PRESENT, CMD_SEL_SET }; static CONST char *commandNames[] = { "activate", "bbox", "border", "cget", "clear", "configure", "curselection", "curvalue", "delete", "get", "rowHeight", "hidden", "icursor", "index", "insert", #ifdef POSTSCRIPT "postscript", #endif "reread", "scan", "see", "selection", "set", "spans", "tag", "validate", "version", "window", "colWidth", "xview", "yview", (char *)NULL }; enum command { CMD_ACTIVATE, CMD_BBOX, CMD_BORDER, CMD_CGET, CMD_CLEAR, CMD_CONFIGURE, CMD_CURSEL, CMD_CURVALUE, CMD_DELETE, CMD_GET, CMD_HEIGHT, CMD_HIDDEN, CMD_ICURSOR, CMD_INDEX, CMD_INSERT, #ifdef POSTSCRIPT CMD_POSTSCRIPT, #endif CMD_REREAD, CMD_SCAN, CMD_SEE, CMD_SELECTION, CMD_SET, CMD_SPANS, CMD_TAG, CMD_VALIDATE, CMD_VERSION, CMD_WINDOW, CMD_WIDTH, CMD_XVIEW, CMD_YVIEW }; /* -selecttype selection type options */ static Cmd_Struct sel_vals[]= { {"row", SEL_ROW}, {"col", SEL_COL}, {"both", SEL_BOTH}, {"cell", SEL_CELL}, {"", 0 } }; /* -resizeborders options */ static Cmd_Struct resize_vals[]= { {"row", SEL_ROW}, /* allow rows to be dragged */ {"col", SEL_COL}, /* allow cols to be dragged */ {"both", SEL_ROW|SEL_COL}, /* allow either to be dragged */ {"none", SEL_NONE}, /* allow nothing to be dragged */ {"", 0 } }; /* drawmode values */ /* The display redraws with a pixmap using TK function calls */ #define DRAW_MODE_SLOW (1<<0) /* The redisplay is direct to the screen, but TK function calls are still * used to give correct 3-d border appearance and thus remain compatible * with other TK apps */ #define DRAW_MODE_TK_COMPAT (1<<1) /* the redisplay goes straight to the screen and the 3d borders are rendered * with a single pixel wide line only. It cheats and uses the internal * border structure to do the borders */ #define DRAW_MODE_FAST (1<<2) #define DRAW_MODE_SINGLE (1<<3) static Cmd_Struct drawmode_vals[] = { {"fast", DRAW_MODE_FAST}, {"compatible", DRAW_MODE_TK_COMPAT}, {"slow", DRAW_MODE_SLOW}, {"single", DRAW_MODE_SINGLE}, {"", 0} }; /* stretchmode values */ #define STRETCH_MODE_NONE (1<<0) /* No additional pixels will be added to rows or cols */ #define STRETCH_MODE_UNSET (1<<1) /* All default rows or columns will be stretched to fill the screen */ #define STRETCH_MODE_ALL (1<<2) /* All rows/columns will be padded to fill the window */ #define STRETCH_MODE_LAST (1<<3) /* Stretch last elememt to fill window */ #define STRETCH_MODE_FILL (1<<4) /* More ROWS in Window */ static Cmd_Struct stretch_vals[] = { {"none", STRETCH_MODE_NONE}, {"unset", STRETCH_MODE_UNSET}, {"all", STRETCH_MODE_ALL}, {"last", STRETCH_MODE_LAST}, {"fill", STRETCH_MODE_FILL}, {"", 0} }; static Cmd_Struct state_vals[]= { {"normal", STATE_NORMAL}, {"disabled", STATE_DISABLED}, {"", 0 } }; /* The widget configuration table */ static Tk_CustomOption drawOpt = { Cmd_OptionSet, Cmd_OptionGet, (ClientData)(&drawmode_vals) }; static Tk_CustomOption resizeTypeOpt = { Cmd_OptionSet, Cmd_OptionGet, (ClientData)(&resize_vals) }; static Tk_CustomOption stretchOpt = { Cmd_OptionSet, Cmd_OptionGet, (ClientData)(&stretch_vals) }; static Tk_CustomOption selTypeOpt = { Cmd_OptionSet, Cmd_OptionGet, (ClientData)(&sel_vals) }; static Tk_CustomOption stateTypeOpt = { Cmd_OptionSet, Cmd_OptionGet, (ClientData)(&state_vals) }; static Tk_CustomOption bdOpt = { TableOptionBdSet, TableOptionBdGet, (ClientData) BD_TABLE }; Tk_ConfigSpec tableSpecs[] = { {TK_CONFIG_ANCHOR, "-anchor", "anchor", "Anchor", "center", Tk_Offset(Table, defaultTag.anchor), 0}, {TK_CONFIG_BOOLEAN, "-autoclear", "autoClear", "AutoClear", "0", Tk_Offset(Table, autoClear), 0}, {TK_CONFIG_BORDER, "-background", "background", "Background", NORMAL_BG, Tk_Offset(Table, defaultTag.bg), 0}, {TK_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL, 0, 0}, {TK_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0}, {TK_CONFIG_CURSOR, "-bordercursor", "borderCursor", "Cursor", "crosshair", Tk_Offset(Table, bdcursor), TK_CONFIG_NULL_OK }, {TK_CONFIG_CUSTOM, "-borderwidth", "borderWidth", "BorderWidth", "1", Tk_Offset(Table, defaultTag), TK_CONFIG_NULL_OK, &bdOpt }, {TK_CONFIG_CALLBACK, "-browsecommand", "browseCommand", "BrowseCommand", "", Tk_Offset(Table, browseCmd), TK_CONFIG_NULL_OK}, {TK_CONFIG_SYNONYM, "-browsecmd", "browseCommand", (char *)NULL, (char *)NULL, 0, TK_CONFIG_NULL_OK}, {TK_CONFIG_BOOLEAN, "-cache", "cache", "Cache", "0", Tk_Offset(Table, caching), 0}, {TK_CONFIG_INT, "-colorigin", "colOrigin", "Origin", "0", Tk_Offset(Table, colOffset), 0}, {TK_CONFIG_INT, "-cols", "cols", "Cols", "10", Tk_Offset(Table, cols), 0}, {TK_CONFIG_STRING, "-colseparator", "colSeparator", "Separator", "\t", Tk_Offset(Table, colSep), TK_CONFIG_NULL_OK }, {TK_CONFIG_CUSTOM, "-colstretchmode", "colStretch", "StretchMode", "none", Tk_Offset (Table, colStretch), 0 , &stretchOpt }, {TK_CONFIG_CALLBACK, "-coltagcommand", "colTagCommand", "TagCommand", NULL, Tk_Offset(Table, colTagCmd), TK_CONFIG_NULL_OK }, {TK_CONFIG_INT, "-colwidth", "colWidth", "ColWidth", "10", Tk_Offset(Table, defColWidth), 0}, {TK_CONFIG_CALLBACK, "-command", "command", "Command", "", Tk_Offset(Table, command), TK_CONFIG_NULL_OK}, {TK_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor", "xterm", Tk_Offset(Table, cursor), TK_CONFIG_NULL_OK }, {TK_CONFIG_CUSTOM, "-drawmode", "drawMode", "DrawMode", "compatible", Tk_Offset(Table, drawMode), 0, &drawOpt }, {TK_CONFIG_BOOLEAN, "-exportselection", "exportSelection", "ExportSelection", "1", Tk_Offset(Table, exportSelection), 0}, {TK_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL, (char *)NULL, 0, 0}, {TK_CONFIG_BOOLEAN, "-flashmode", "flashMode", "FlashMode", "0", Tk_Offset(Table, flashMode), 0}, {TK_CONFIG_INT, "-flashtime", "flashTime", "FlashTime", "2", Tk_Offset(Table, flashTime), 0}, {TK_CONFIG_FONT, "-font", "font", "Font", DEF_TABLE_FONT, Tk_Offset(Table, defaultTag.tkfont), 0}, {TK_CONFIG_BORDER, "-foreground", "foreground", "Foreground", "black", Tk_Offset(Table, defaultTag.fg), 0}, #ifdef PROCS {TK_CONFIG_BOOLEAN, "-hasprocs", "hasProcs", "hasProcs", "0", Tk_Offset(Table, hasProcs), 0}, #endif {TK_CONFIG_INT, "-height", "height", "Height", "0", Tk_Offset(Table, maxReqRows), 0}, {TK_CONFIG_COLOR, "-highlightbackground", "highlightBackground", "HighlightBackground", NORMAL_BG, Tk_Offset(Table, highlightBgColorPtr), 0}, {TK_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor", HIGHLIGHT, Tk_Offset(Table, highlightColorPtr), 0}, {TK_CONFIG_PIXELS, "-highlightthickness", "highlightThickness", "HighlightThickness", "2", Tk_Offset(Table, highlightWidth), 0}, {TK_CONFIG_BORDER, "-insertbackground", "insertBackground", "Foreground", "Black", Tk_Offset(Table, insertBg), 0}, {TK_CONFIG_PIXELS, "-insertborderwidth", "insertBorderWidth", "BorderWidth", "0", Tk_Offset(Table, insertBorderWidth), TK_CONFIG_COLOR_ONLY}, {TK_CONFIG_PIXELS, "-insertborderwidth", "insertBorderWidth", "BorderWidth", "0", Tk_Offset(Table, insertBorderWidth), TK_CONFIG_MONO_ONLY}, {TK_CONFIG_INT, "-insertofftime", "insertOffTime", "OffTime", "300", Tk_Offset(Table, insertOffTime), 0}, {TK_CONFIG_INT, "-insertontime", "insertOnTime", "OnTime", "600", Tk_Offset(Table, insertOnTime), 0}, {TK_CONFIG_PIXELS, "-insertwidth", "insertWidth", "InsertWidth", "2", Tk_Offset(Table, insertWidth), 0}, {TK_CONFIG_BOOLEAN, "-invertselected", "invertSelected", "InvertSelected", "0", Tk_Offset(Table, invertSelected), 0}, {TK_CONFIG_PIXELS, "-ipadx", "ipadX", "Pad", "0", Tk_Offset(Table, ipadX), 0}, {TK_CONFIG_PIXELS, "-ipady", "ipadY", "Pad", "0", Tk_Offset(Table, ipadY), 0}, {TK_CONFIG_JUSTIFY, "-justify", "justify", "Justify", "left", Tk_Offset(Table, defaultTag.justify), 0 }, {TK_CONFIG_PIXELS, "-maxheight", "maxHeight", "MaxHeight", "600", Tk_Offset(Table, maxReqHeight), 0}, {TK_CONFIG_PIXELS, "-maxwidth", "maxWidth", "MaxWidth", "800", Tk_Offset(Table, maxReqWidth), 0}, {TK_CONFIG_BOOLEAN, "-multiline", "multiline", "Multiline", "1", Tk_Offset(Table, defaultTag.multiline), 0}, {TK_CONFIG_PIXELS, "-padx", "padX", "Pad", "0", Tk_Offset(Table, padX), 0}, {TK_CONFIG_PIXELS, "-pady", "padY", "Pad", "0", Tk_Offset(Table, padY), 0}, {TK_CONFIG_RELIEF, "-relief", "relief", "Relief", "sunken", Tk_Offset(Table, defaultTag.relief), 0}, {TK_CONFIG_CUSTOM, "-resizeborders", "resizeBorders", "ResizeBorders", "both", Tk_Offset(Table, resize), 0, &resizeTypeOpt }, {TK_CONFIG_INT, "-rowheight", "rowHeight", "RowHeight", "1", Tk_Offset(Table, defRowHeight), 0}, {TK_CONFIG_INT, "-roworigin", "rowOrigin", "Origin", "0", Tk_Offset(Table, rowOffset), 0}, {TK_CONFIG_INT, "-rows", "rows", "Rows", "10", Tk_Offset(Table, rows), 0}, {TK_CONFIG_STRING, "-rowseparator", "rowSeparator", "Separator", "\n", Tk_Offset(Table, rowSep), TK_CONFIG_NULL_OK }, {TK_CONFIG_CUSTOM, "-rowstretchmode", "rowStretch", "StretchMode", "none", Tk_Offset(Table, rowStretch), 0 , &stretchOpt }, {TK_CONFIG_CALLBACK, "-rowtagcommand", "rowTagCommand", "TagCommand", NULL, Tk_Offset(Table, rowTagCmd), TK_CONFIG_NULL_OK }, {TK_CONFIG_SYNONYM, "-selcmd", "selectionCommand", (char *)NULL, (char *)NULL, 0, TK_CONFIG_NULL_OK}, {TK_CONFIG_CALLBACK, "-selectioncommand", "selectionCommand", "SelectionCommand", NULL, Tk_Offset(Table, selCmd), TK_CONFIG_NULL_OK }, {TK_CONFIG_STRING, "-selectmode", "selectMode", "SelectMode", "browse", Tk_Offset(Table, selectMode), TK_CONFIG_NULL_OK }, {TK_CONFIG_BOOLEAN, "-selecttitles", "selectTitles", "SelectTitles", "0", Tk_Offset(Table, selectTitles), 0}, {TK_CONFIG_CUSTOM, "-selecttype", "selectType", "SelectType", "cell", Tk_Offset(Table, selectType), 0, &selTypeOpt }, #ifdef PROCS {TK_CONFIG_BOOLEAN, "-showprocs", "showProcs", "showProcs", "0", Tk_Offset(Table, showProcs), 0}, #endif {TK_CONFIG_BOOLEAN, "-sparsearray", "sparseArray", "SparseArray", "1", Tk_Offset(Table, sparse), 0}, {TK_CONFIG_CUSTOM, "-state", "state", "State", "normal", Tk_Offset(Table, state), 0, &stateTypeOpt}, {TK_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus", (char *)NULL, Tk_Offset(Table, takeFocus), TK_CONFIG_NULL_OK }, {TK_CONFIG_INT, "-titlecols", "titleCols", "TitleCols", "0", Tk_Offset(Table, titleCols), TK_CONFIG_NULL_OK }, #ifdef TITLE_CURSOR {TK_CONFIG_CURSOR, "-titlecursor", "titleCursor", "Cursor", "arrow", Tk_Offset(Table, titleCursor), TK_CONFIG_NULL_OK }, #endif {TK_CONFIG_INT, "-titlerows", "titleRows", "TitleRows", "0", Tk_Offset(Table, titleRows), TK_CONFIG_NULL_OK }, {TK_CONFIG_BOOLEAN, "-usecommand", "useCommand", "UseCommand", "1", Tk_Offset(Table, useCmd), 0}, {TK_CONFIG_SCALARVAR, "-variable", "variable", "Variable", (char *)NULL, Tk_Offset(Table, arrayVar), TK_CONFIG_NULL_OK }, {TK_CONFIG_BOOLEAN, "-validate", "validate", "Validate", "0", Tk_Offset(Table, validate), 0}, {TK_CONFIG_CALLBACK, "-validatecommand", "validateCommand", "ValidateCommand", "", Tk_Offset(Table, valCmd), TK_CONFIG_NULL_OK}, {TK_CONFIG_SYNONYM, "-vcmd", "validateCommand", (char *)NULL, (char *)NULL, 0, TK_CONFIG_NULL_OK}, {TK_CONFIG_INT, "-width", "width", "Width", "0", Tk_Offset(Table, maxReqCols), 0}, {TK_CONFIG_BOOLEAN, "-wrap", "wrap", "Wrap", "0", Tk_Offset(Table, defaultTag.wrap), 0}, {TK_CONFIG_CALLBACK, "-xscrollcommand", "xScrollCommand", "ScrollCommand", NULL, Tk_Offset(Table, xScrollCmd), TK_CONFIG_NULL_OK }, {TK_CONFIG_CALLBACK, "-yscrollcommand", "yScrollCommand", "ScrollCommand", NULL, Tk_Offset(Table, yScrollCmd), TK_CONFIG_NULL_OK }, {TK_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; /* * This specifies the configure options that will cause an update to * occur, so we should have a quick lookup table for them. * Keep this in sync with the above values. */ static CONST char *updateOpts[] = { "-anchor", "-background", "-bg", "-bd", "-borderwidth", "-cache", "-command", "-colorigin", "-cols", "-colstretchmode", "-coltagcommand", "-drawmode", "-fg", "-font", "-foreground", "-hasprocs", "-height", "-highlightbackground", "-highlightcolor", "-highlightthickness", "-insertbackground", "-insertborderwidth", "-insertwidth", "-invertselected", "-ipadx", "-ipady", "-maxheight", "-maxwidth", "-multiline", "-padx", "-pady", "-relief", "-roworigin", "-rows", "-rowstretchmode", "-rowtagcommand", "-showprocs", "-state", "-titlecols", "-titlerows", "-usecommand", "-variable", "-width", "-wrap", "-xscrollcommand", "-yscrollcommand", (char *) NULL }; #ifdef WIN32 /* * Some code from TkWinInt.h that we use to correct and speed up * drawing of cells that need clipping in TableDisplay. */ typedef struct { int type; HWND handle; void *winPtr; } TkWinWindow; typedef struct { int type; HBITMAP handle; Colormap colormap; int depth; } TkWinBitmap; typedef struct { int type; HDC hdc; } TkWinDC; typedef union { int type; TkWinWindow window; TkWinBitmap bitmap; TkWinDC winDC; } TkWinDrawable; #endif /* * END HEADER INFORMATION */ /* *--------------------------------------------------------------------------- * * StringifyObjects -- (from tclCmdAH.c) * * Helper function to bridge the gap between an object-based procedure * and an older string-based procedure. * * Given an array of objects, allocate an array that consists of the * string representations of those objects. * * Results: * The return value is a pointer to the newly allocated array of * strings. Elements 0 to (objc-1) of the string array point to the * string representation of the corresponding element in the source * object array; element objc of the string array is NULL. * * Side effects: * Memory allocated. The caller must eventually free this memory * by calling ckfree() on the return value. * int result; char **argv; argv = StringifyObjects(objc, objv); result = StringBasedCmd(interp, objc, argv); ckfree((char *) argv); return result; * *--------------------------------------------------------------------------- */ /* Don't Need This becuase arrays of Objects equivalent to arrays of Args???? static Arg * StringifyObjects(objc, objv) int objc; /* Number of arguments. Tcl_Obj *CONST objv[]; Argument objects. { int i; Arg *args; /* This needs to not be autoconverted to a Arg, so change the name to argsv args = (Arg *) ckalloc((objc + 1) * sizeof(Arg *)); for (i = 0; i < objc; i++) { args[i] = Tcl_GetString(objv[i]); } args[i] = NULL; return args; } /* * As long as we wait for the Function in general * * This parses the "-class" option for the table. */ static int Tk_ClassOptionObjCmd(Tk_Window tkwin, char *defaultclass, int objc, Tcl_Obj *CONST objv[]) { char *classname = defaultclass; int offset = 0; if ((objc >= 4) && STREQ(Tcl_GetString(objv[2]),"-class")) { classname = Tcl_GetString(objv[3]); offset = 2; } Tk_SetClass(tkwin, classname); return offset; } /* *-------------------------------------------------------------- * * Tk_TableObjCmd -- * This procedure is invoked to process the "table" Tcl * command. See the user documentation for details on what * it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Tk_TableObjCmd(clientData, interp, objc, objv) ClientData clientData; /* Main window associated with interpreter. */ Tcl_Interp *interp; int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument objects. */ { register Table *tablePtr; Tk_Window tkwin, mainWin = (Tk_Window) clientData; int offset; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?"); return TCL_ERROR; } tkwin = Tk_CreateWindowFromPath(interp, mainWin, Tcl_GetString(objv[1]), (char *)NULL); if (tkwin == NULL) { return TCL_ERROR; } tablePtr = (Table *) ckalloc(sizeof(Table)); memset((VOID *) tablePtr, 0, sizeof(Table)); /* * Set the structure elments that aren't 0/NULL by default, * and that won't be set by the initial configure call. */ tablePtr->tkwin = tkwin; tablePtr->display = Tk_Display(tkwin); tablePtr->interp = interp; tablePtr->widgetCmd = Lang_CreateWidget(interp, tablePtr->tkwin, TableWidgetObjCmd, (ClientData) tablePtr, (Tcl_CmdDeleteProc *) TableCmdDeletedProc); tablePtr->anchorRow = -1; tablePtr->anchorCol = -1; tablePtr->activeRow = -1; tablePtr->activeCol = -1; tablePtr->oldTopRow = -1; tablePtr->oldLeftCol = -1; tablePtr->oldActRow = -1; tablePtr->oldActCol = -1; tablePtr->seen[0] = -1; tablePtr->dataSource = DATA_NONE; tablePtr->activeBuf = ckalloc(1); *(tablePtr->activeBuf) = '\0'; tablePtr->cursor = None; tablePtr->bdcursor = None; tablePtr->defaultTag.justify = TK_JUSTIFY_LEFT; tablePtr->defaultTag.state = STATE_UNKNOWN; /* misc tables */ tablePtr->tagTable = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(tablePtr->tagTable, TCL_STRING_KEYS); tablePtr->winTable = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(tablePtr->winTable, TCL_STRING_KEYS); /* internal value cache */ tablePtr->cache = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(tablePtr->cache, TCL_STRING_KEYS); /* style hash tables */ tablePtr->colWidths = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(tablePtr->colWidths, TCL_ONE_WORD_KEYS); tablePtr->rowHeights = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(tablePtr->rowHeights, TCL_ONE_WORD_KEYS); /* style hash tables */ tablePtr->rowStyles = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(tablePtr->rowStyles, TCL_ONE_WORD_KEYS); tablePtr->colStyles = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(tablePtr->colStyles, TCL_ONE_WORD_KEYS); tablePtr->cellStyles = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(tablePtr->cellStyles, TCL_STRING_KEYS); /* special style hash tables */ tablePtr->flashCells = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(tablePtr->flashCells, TCL_STRING_KEYS); tablePtr->selCells = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(tablePtr->selCells, TCL_STRING_KEYS); /* * List of tags in priority order. 30 is a good default number to alloc. */ tablePtr->tagPrioMax = 30; tablePtr->tagPrioNames = (char **) ckalloc( sizeof(char *) * tablePtr->tagPrioMax); tablePtr->tagPrios = (TableTag **) ckalloc( sizeof(TableTag *) * tablePtr->tagPrioMax); tablePtr->tagPrioSize = 0; for (offset = 0; offset < tablePtr->tagPrioMax; offset++) { tablePtr->tagPrioNames[offset] = (char *) NULL; tablePtr->tagPrios[offset] = (TableTag *) NULL; } #ifdef PROCS tablePtr->inProc = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(tablePtr->inProc, TCL_STRING_KEYS); #endif /* * Handle class name and selection handlers */ offset = 2 + Tk_ClassOptionObjCmd(tkwin, "Table", objc, objv); Tk_CreateEventHandler(tablePtr->tkwin, PointerMotionMask|ExposureMask|StructureNotifyMask|FocusChangeMask|VisibilityChangeMask, TableEventProc, (ClientData) tablePtr); Tk_CreateSelHandler(tablePtr->tkwin, XA_PRIMARY, XA_STRING, TableFetchSelection, (ClientData) tablePtr, XA_STRING); if (TableConfigure(interp, tablePtr, objc - offset, objv + offset, 0, 1 /* force update */) != TCL_OK) { Tk_DestroyWindow(tkwin); return TCL_ERROR; } TableInitTags(tablePtr); /*Tcl_SetStringObj(Tcl_GetObjResult(interp), Tk_PathName(tablePtr->tkwin), -1); */ /* Tk800.022 needs to old-style LangWidgetArg Call newer perltk's should be ok with the default. */ #ifdef USE_LANGWIDGETARG Tcl_SetObjResult(interp, LangWidgetArg(interp,tablePtr->tkwin)); #else Tcl_SetObjResult(interp, LangWidgetObj(interp,tablePtr->tkwin)); #endif return TCL_OK; } /* *-------------------------------------------------------------- * * TableWidgetObjCmd -- * This procedure is invoked to process the Tcl command * that corresponds to a widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ static int TableWidgetObjCmd(clientData, interp, objc, objv) ClientData clientData; Tcl_Interp *interp; int objc; /* Number of arguments. */ Tcl_Obj * CONST objv[]; /* Argument objects. */ { register Table *tablePtr = (Table *) clientData; int row, col, i, cmdIndex, result = TCL_OK; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?"); return TCL_ERROR; } /* parse the first parameter */ result = Tcl_GetIndexFromObj(interp, objv[1], commandNames, "option", 0, &cmdIndex); if (result != TCL_OK) { return result; } Tcl_Preserve((ClientData) tablePtr); switch ((enum command) cmdIndex) { case CMD_ACTIVATE: result = Table_ActivateCmd(clientData, interp, objc, objv); break; case CMD_BBOX: result = Table_BboxCmd(clientData, interp, objc, objv); break; case CMD_BORDER: result = Table_BorderCmd(clientData, interp, objc, objv); break; case CMD_CGET: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "option"); result = TCL_ERROR; } else { result = Tk_ConfigureValue(interp, tablePtr->tkwin, tableSpecs, (char *) tablePtr, Tcl_GetString(objv[2]), 0); } break; case CMD_CLEAR: result = Table_ClearCmd(clientData, interp, objc, objv); break; case CMD_CONFIGURE: if (objc < 4) { result = Tk_ConfigureInfo(interp, tablePtr->tkwin, tableSpecs, (char *) tablePtr, (objc == 3) ? Tcl_GetString(objv[2]) : (char *) NULL, 0); } else { result = TableConfigure(interp, tablePtr, objc - 2, objv + 2, TK_CONFIG_ARGV_ONLY, 0); } break; case CMD_CURSEL: result = Table_CurselectionCmd(clientData, interp, objc, objv); break; case CMD_CURVALUE: result = Table_CurvalueCmd(clientData, interp, objc, objv); break; case CMD_DELETE: case CMD_INSERT: result = Table_EditCmd(clientData, interp, objc, objv); break; case CMD_GET: result = Table_GetCmd(clientData, interp, objc, objv); break; case CMD_HEIGHT: result = Table_AdjustCmd(clientData, interp, objc, objv,0); break; case CMD_WIDTH: result = Table_AdjustCmd(clientData, interp, objc, objv,1); break; case CMD_HIDDEN: result = Table_HiddenCmd(clientData, interp, objc, objv); break; case CMD_ICURSOR: if (objc != 2 && objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "?cursorPos?"); result = TCL_ERROR; break; } if (!(tablePtr->flags & HAS_ACTIVE) || (tablePtr->flags & ACTIVE_DISABLED) || tablePtr->state == STATE_DISABLED) { Tcl_SetIntObj(Tcl_GetObjResult(interp), -1); break; } else if (objc == 3) { if (TableGetIcursorObj(tablePtr, objv[2], NULL) != TCL_OK) { result = TCL_ERROR; break; } TableRefresh(tablePtr, tablePtr->activeRow, tablePtr->activeCol, CELL); } Tcl_SetIntObj(Tcl_GetObjResult(interp), tablePtr->icursor); break; case CMD_INDEX: { char *which = NULL; if (objc == 4) { which = Tcl_GetString(objv[3]); } if ((objc < 3 || objc > 4) || ((objc == 4) && (strcmp(which, "row") && strcmp(which, "col")))) { Tcl_WrongNumArgs(interp, 2, objv, "<index> ?row|col?"); result = TCL_ERROR; } else if (TableGetIndexObj(tablePtr, objv[2], &row, &col) != TCL_OK) { result = TCL_ERROR; } else if (objc == 3) { char buf[INDEX_BUFSIZE]; /* recreate the index, just in case it got bounded */ TableMakeArrayIndex(row, col, buf); Tcl_SetStringObj(Tcl_GetObjResult(interp), buf, -1); } else { /* INDEX row|col */ Tcl_SetIntObj(Tcl_GetObjResult(interp), (*which == 'r') ? row : col); } break; } #ifdef POSTSCRIPT case CMD_POSTSCRIPT: result = Table_PostscriptCmd(clientData, interp, objc, objv); break; #endif case CMD_REREAD: if (objc != 2) { Tcl_WrongNumArgs(interp, 2, objv, NULL); result = TCL_ERROR; } else if ((tablePtr->flags & HAS_ACTIVE) && !(tablePtr->flags & ACTIVE_DISABLED) && tablePtr->state != STATE_DISABLED) { TableGetActiveBuf(tablePtr); TableRefresh(tablePtr, tablePtr->activeRow, tablePtr->activeCol, CELL|INV_FORCE); } break; case CMD_SCAN: result = Table_ScanCmd(clientData, interp, objc, objv); break; case CMD_SEE: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "index"); result = TCL_ERROR; } else if (TableGetIndexObj(tablePtr, objv[2], &row, &col) == TCL_ERROR) { result = TCL_ERROR; } else { /* Adjust from user to master coords */ row -= tablePtr->rowOffset; col -= tablePtr->colOffset; if (!TableCellVCoords(tablePtr, row, col, &i, &i, &i, &i, 1)) { tablePtr->topRow = row-1; tablePtr->leftCol = col-1; TableAdjustParams(tablePtr); } } break; case CMD_SELECTION: if (objc < 3) { Tcl_WrongNumArgs(interp, 2, objv, "option ?arg arg ...?"); result = TCL_ERROR; break; } if (Tcl_GetIndexFromObj(interp, objv[2], selCmdNames, "selection option", 0, &cmdIndex) != TCL_OK) { result = TCL_ERROR; break; } switch ((enum selCommand) cmdIndex) { case CMD_SEL_ANCHOR: result = Table_SelAnchorCmd(clientData, interp, objc, objv); break; case CMD_SEL_CLEAR: result = Table_SelClearCmd(clientData, interp, objc, objv); break; case CMD_SEL_INCLUDES: result = Table_SelIncludesCmd(clientData, interp, objc, objv); break; case CMD_SEL_PRESENT: { Tcl_HashSearch search; Tcl_SetBooleanObj(Tcl_GetObjResult(interp), (Tcl_FirstHashEntry(tablePtr->selCells, &search) != NULL)); break; } case CMD_SEL_SET: result = Table_SelSetCmd(clientData, interp, objc, objv); break; } break; case CMD_SET: result = Table_SetCmd(clientData, interp, objc, objv); break; case CMD_SPANS: result = Table_SpanCmd(clientData, interp, objc, objv); break; case CMD_TAG: result = Table_TagCmd(clientData, interp, objc, objv); break; case CMD_VALIDATE: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "index"); result = TCL_ERROR; } else if (TableGetIndexObj(tablePtr, objv[2], &row, &col) == TCL_ERROR) { result = TCL_ERROR; } else { i = tablePtr->validate; tablePtr->validate = 1; result = TableValidateChange(tablePtr, row, col, (char *) NULL, (char *) NULL, -1); tablePtr->validate = i; Tcl_SetBooleanObj(Tcl_GetObjResult(interp), (result == TCL_OK)); result = TCL_OK; } break; case CMD_VERSION: if (objc != 2) { Tcl_WrongNumArgs(interp, 2, objv, NULL); result = TCL_ERROR; } else { Tcl_SetStringObj(Tcl_GetObjResult(interp), VERSION, -1); } break; case CMD_WINDOW: result = Table_WindowCmd(clientData, interp, objc, objv); break; case CMD_XVIEW: case CMD_YVIEW: result = Table_ViewCmd(clientData, interp, objc, objv); break; } Tcl_Release((ClientData) tablePtr); return result; } /* *---------------------------------------------------------------------- * * TableDestroy -- * This procedure is invoked by Tcl_EventuallyFree * to clean up the internal structure of a table at a safe time * (when no-one is using it anymore). * * Results: * None. * * Side effects: * Everything associated with the table is freed up (hopefully). * *---------------------------------------------------------------------- */ static void TableDestroy(ClientData clientdata) { register Table *tablePtr = (Table *) clientdata; Tcl_HashEntry *entryPtr; Tcl_HashSearch search; /* These may be repetitive from DestroyNotify, but it doesn't hurt */ /* cancel any pending update or timer */ if (tablePtr->flags & REDRAW_PENDING) { Tcl_CancelIdleCall(TableDisplay, (ClientData) tablePtr); tablePtr->flags &= ~REDRAW_PENDING; } Tcl_DeleteTimerHandler(tablePtr->cursorTimer); Tcl_DeleteTimerHandler(tablePtr->flashTimer); /* delete the variable trace */ if (tablePtr->arrayVar != NULL) { Lang_UntraceVar(tablePtr->interp, tablePtr->arrayVar, TCL_TRACE_WRITES | TCL_TRACE_UNSETS | TCL_GLOBAL_ONLY, (Lang_VarTraceProc *)TableVarProc, (ClientData) tablePtr); } /* free the int arrays */ if (tablePtr->colPixels) ckfree((char *) tablePtr->colPixels); if (tablePtr->rowPixels) ckfree((char *) tablePtr->rowPixels); if (tablePtr->colStarts) ckfree((char *) tablePtr->colStarts); if (tablePtr->rowStarts) ckfree((char *) tablePtr->rowStarts); /* delete cached active tag and string */ if (tablePtr->activeTagPtr) ckfree((char *) tablePtr->activeTagPtr); if (tablePtr->activeBuf != NULL) ckfree(tablePtr->activeBuf); /* * Delete the various hash tables, make sure to clear the STRING_KEYS * tables that allocate their strings: * cache, spanTbl (spanAffTbl shares spanTbl info) */ Table_ClearHashTable(tablePtr->cache); ckfree((char *) (tablePtr->cache)); Tcl_DeleteHashTable(tablePtr->rowStyles); ckfree((char *) (tablePtr->rowStyles)); Tcl_DeleteHashTable(tablePtr->colStyles); ckfree((char *) (tablePtr->colStyles)); Tcl_DeleteHashTable(tablePtr->cellStyles); ckfree((char *) (tablePtr->cellStyles)); Tcl_DeleteHashTable(tablePtr->flashCells); ckfree((char *) (tablePtr->flashCells)); Tcl_DeleteHashTable(tablePtr->selCells); ckfree((char *) (tablePtr->selCells)); Tcl_DeleteHashTable(tablePtr->colWidths); ckfree((char *) (tablePtr->colWidths)); Tcl_DeleteHashTable(tablePtr->rowHeights); ckfree((char *) (tablePtr->rowHeights)); #ifdef PROCS Tcl_DeleteHashTable(tablePtr->inProc); ckfree((char *) (tablePtr->inProc)); #endif if (tablePtr->spanTbl) { Table_ClearHashTable(tablePtr->spanTbl); ckfree((char *) (tablePtr->spanTbl)); Tcl_DeleteHashTable(tablePtr->spanAffTbl); ckfree((char *) (tablePtr->spanAffTbl)); } /* Now free up all the tag information */ for (entryPtr = Tcl_FirstHashEntry(tablePtr->tagTable, &search); entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { TableCleanupTag(tablePtr, (TableTag *) Tcl_GetHashValue(entryPtr)); ckfree((char *) Tcl_GetHashValue(entryPtr)); } /* free up the stuff in the default tag */ TableCleanupTag(tablePtr, &(tablePtr->defaultTag)); /* And delete the actual hash table */ Tcl_DeleteHashTable(tablePtr->tagTable); ckfree((char *) (tablePtr->tagTable)); ckfree((char *) (tablePtr->tagPrios)); ckfree((char *) (tablePtr->tagPrioNames)); /* Now free up all the embedded window info */ for (entryPtr = Tcl_FirstHashEntry(tablePtr->winTable, &search); entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { EmbWinDelete(tablePtr, (TableEmbWindow *) Tcl_GetHashValue(entryPtr)); } /* And delete the actual hash table */ Tcl_DeleteHashTable(tablePtr->winTable); ckfree((char *) (tablePtr->winTable)); /* free the configuration options in the widget */ Tk_FreeOptions(tableSpecs, (char *) tablePtr, tablePtr->display, 0); /* and free the widget memory at last! */ ckfree((char *) (tablePtr)); } /* *---------------------------------------------------------------------- * * TableConfigure -- * This procedure is called to process an objc/objv list, plus * the Tk option database, in order to configure (or reconfigure) * a table widget. * * Results: * The return value is a standard Tcl result. If TCL_ERROR is * returned, then interp result contains an error message. * * Side effects: * Configuration information, such as colors, border width, etc. * get set for tablePtr; old resources get freed, if there were any. * Certain values might be constrained. * *---------------------------------------------------------------------- */ static int TableConfigure(interp, tablePtr, objc, objv, flags, forceUpdate) Tcl_Interp *interp; /* Used for error reporting. */ register Table *tablePtr; /* Information about widget; may or may * not already have values for some fields. */ int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument objects. */ int flags; /* Flags to pass to Tk_ConfigureWidget. */ int forceUpdate; /* Whether to force an update - required * for initial configuration */ { Tcl_HashSearch search; int oldUse, oldCaching, oldExport, oldTitleRows, oldTitleCols; int result = TCL_OK; Arg *objArray; Var oldVar = NULL; Tcl_DString error; Tk_FontMetrics fm; char *currentVarString; /* Name of the current array variable */ char *oldVarString = NULL; /* Name of the old array variable */ oldExport = tablePtr->exportSelection; oldCaching = tablePtr->caching; oldUse = tablePtr->useCmd; oldTitleRows = tablePtr->titleRows; oldTitleCols = tablePtr->titleCols; if (tablePtr->arrayVar != NULL) { oldVar = tablePtr->arrayVar; oldVarString = Tcl_GetString(Tcl_ObjGetVar2(interp, oldVar, NULL, TCL_GLOBAL_ONLY)); } /* Do the configuration */ /* argv = StringifyObjects(objc, objv); */ /* Don't Need this because arrays of Args like arrays of Obj?? */ objArray = (Tcl_Obj **) objv; /* Cast gets rid of warnings */ result = Tk_ConfigureWidget(interp, tablePtr->tkwin, tableSpecs, objc, objArray, (char *) tablePtr, flags); /* ckfree((char *) argv); */ if (result != TCL_OK) { return TCL_ERROR; } Tcl_DStringInit(&error); /* Any time we configure, reevaluate what our data source is */ tablePtr->dataSource = DATA_NONE; if (tablePtr->caching) { tablePtr->dataSource |= DATA_CACHE; } if (tablePtr->command && tablePtr->useCmd) { tablePtr->dataSource |= DATA_COMMAND; } else if (tablePtr->arrayVar) { tablePtr->dataSource |= DATA_ARRAY; } /* Check to see if the array variable was changed */ currentVarString = Tcl_GetString(Tcl_ObjGetVar2(interp, tablePtr->arrayVar, NULL, TCL_GLOBAL_ONLY)); if (strcmp((currentVarString?currentVarString:""), (oldVarString?oldVarString:""))) { /* only do the following if arrayVar is our data source */ if (tablePtr->dataSource & DATA_ARRAY) { /* * ensure that the cache will flush later * so it gets the new values */ oldCaching = !(tablePtr->caching); } /* remove the trace on the old array variable if there was one */ if (oldVar != NULL) Lang_UntraceVar(interp, oldVar, TCL_TRACE_WRITES|TCL_TRACE_UNSETS|TCL_GLOBAL_ONLY, (Lang_VarTraceProc *)TableVarProc, (ClientData) tablePtr); /* Check whether variable is an array and trace it if it is */ if (tablePtr->arrayVar != NULL) { /* does the variable exist as an array? */ if (Tcl_ObjSetVar2(interp, tablePtr->arrayVar, Tcl_NewStringObj(TEST_KEY,-1), Tcl_NewStringObj("",-1), TCL_GLOBAL_ONLY) == NULL) { Tcl_DStringAppend(&error, "invalid variable value \"", -1); Tcl_DStringAppend(&error, currentVarString, -1); Tcl_DStringAppend(&error, "\": could not be made an array", -1); ckfree(currentVarString); tablePtr->arrayVar = NULL; tablePtr->dataSource &= ~DATA_ARRAY; result = TCL_ERROR; } else { /* perltk not supported */ /* Tcl_UnsetVar2(interp, currentVarString, TEST_KEY, TCL_GLOBAL_ONLY); */ /* remove the effect of the evaluation */ /* set a trace on the variable */ Lang_TraceVar(interp, tablePtr->arrayVar, TCL_TRACE_WRITES|TCL_TRACE_UNSETS|TCL_GLOBAL_ONLY, (Lang_VarTraceProc *)TableVarProc, (ClientData) tablePtr); /* only do the following if arrayVar is our data source */ if (tablePtr->dataSource & DATA_ARRAY) { /* get the current value of the selection */ TableGetActiveBuf(tablePtr); } } } } /* Free oldVar if it was allocated */ /* if (oldVar != NULL) ckfree(oldVar); */ if ((tablePtr->command && tablePtr->useCmd && !oldUse) || (tablePtr->arrayVar && !(tablePtr->useCmd) && oldUse)) { /* * Our effective data source changed, so flush and * retrieve new active buffer */ Table_ClearHashTable(tablePtr->cache); Tcl_InitHashTable(tablePtr->cache, TCL_STRING_KEYS); TableGetActiveBuf(tablePtr); forceUpdate = 1; } else if (oldCaching != tablePtr->caching) { /* * Caching changed, so just clear the cache for safety */ Table_ClearHashTable(tablePtr->cache); Tcl_InitHashTable(tablePtr->cache, TCL_STRING_KEYS); forceUpdate = 1; } /* * Set up the default column width and row height */ Tk_GetFontMetrics(tablePtr->defaultTag.tkfont, &fm); tablePtr->charWidth = Tk_TextWidth(tablePtr->defaultTag.tkfont, "0", 1); tablePtr->charHeight = fm.linespace + 2; if (tablePtr->insertWidth <= 0) { tablePtr->insertWidth = 2; } if (tablePtr->insertBorderWidth > tablePtr->insertWidth/2) { tablePtr->insertBorderWidth = tablePtr->insertWidth/2; } tablePtr->highlightWidth = MAX(0,tablePtr->highlightWidth); /* * Ensure that certain values are within proper constraints */ tablePtr->rows = MAX(1, tablePtr->rows); tablePtr->cols = MAX(1, tablePtr->cols); tablePtr->padX = MAX(0, tablePtr->padX); tablePtr->padY = MAX(0, tablePtr->padY); tablePtr->ipadX = MAX(0, tablePtr->ipadX); tablePtr->ipadY = MAX(0, tablePtr->ipadY); tablePtr->maxReqCols = MAX(0, tablePtr->maxReqCols); tablePtr->maxReqRows = MAX(0, tablePtr->maxReqRows); CONSTRAIN(tablePtr->titleRows, 0, tablePtr->rows); CONSTRAIN(tablePtr->titleCols, 0, tablePtr->cols); /* * Handle change of default border style * The default borderwidth must be >= 0. */ if (tablePtr->drawMode & (DRAW_MODE_SINGLE|DRAW_MODE_FAST)) { /* * When drawing fast or single, the border must be <= 1. * We have to do this after the normal configuration * to base the borders off the first value given. */ tablePtr->defaultTag.bd[0] = MIN(1, tablePtr->defaultTag.bd[0]); tablePtr->defaultTag.borders = 1; ckfree((char *) tablePtr->defaultTag.borderStr); tablePtr->defaultTag.borderStr = (char *) ckalloc(2); strcpy(tablePtr->defaultTag.borderStr, tablePtr->defaultTag.bd[0] ? "1" : "0"); } /* * Claim the selection if we've suddenly started exporting it and * there is a selection to export. */ if (tablePtr->exportSelection && !oldExport && (Tcl_FirstHashEntry(tablePtr->selCells, &search) != NULL)) { Tk_OwnSelection(tablePtr->tkwin, XA_PRIMARY, TableLostSelection, (ClientData) tablePtr); } if ((tablePtr->titleRows < oldTitleRows) || (tablePtr->titleCols < oldTitleCols)) { /* * Prevent odd movement due to new possible topleft index */ if (tablePtr->titleRows < oldTitleRows) tablePtr->topRow -= oldTitleRows - tablePtr->titleRows; if (tablePtr->titleCols < oldTitleCols) tablePtr->leftCol -= oldTitleCols - tablePtr->titleCols; /* * If our title area shrank, we need to check that the items * within the new title area don't try to span outside it. */ TableSpanSanCheck(tablePtr); } /* * Only do the full reconfigure if absolutely necessary */ if (!forceUpdate) { int i, dummy; for (i = 0; i < objc-1; i += 2) { if (Tcl_GetIndexFromObj(NULL, objv[i], updateOpts, "", 0, &dummy) == TCL_OK) { forceUpdate = 1; break; } } } if (forceUpdate) { /* * Calculate the row and column starts * Adjust the top left corner of the internal display */ TableAdjustParams(tablePtr); /* reset the cursor */ TableConfigCursor(tablePtr); /* set up the background colour in the window */ Tk_SetBackgroundFromBorder(tablePtr->tkwin, tablePtr->defaultTag.bg); /* set the geometry and border */ TableGeometryRequest(tablePtr); Tk_SetInternalBorder(tablePtr->tkwin, tablePtr->highlightWidth); /* invalidate the whole table */ TableInvalidateAll(tablePtr, INV_HIGHLIGHT); } /* * FIX this is goofy because the result could be munged by other * functions. Could be improved. */ Tcl_ResetResult(interp); if (result == TCL_ERROR) { Tcl_AddErrorInfo(interp, "\t(configuring table widget)"); Tcl_DStringResult(interp, &error); } Tcl_DStringFree(&error); return result; } /* *-------------------------------------------------------------- * * TableEventProc -- * This procedure is invoked by the Tk dispatcher for various * events on tables. * * Results: * None. * * Side effects: * When the window gets deleted, internal structures get * cleaned up. When it gets exposed, it is redisplayed. * *-------------------------------------------------------------- */ static void TableEventProc(clientData, eventPtr) ClientData clientData; /* Information about window. */ XEvent *eventPtr; /* Information about event. */ { Table *tablePtr = (Table *) clientData; int row, col; switch (eventPtr->type) { case MotionNotify: if (!(tablePtr->resize & SEL_NONE) && (tablePtr->bdcursor != None) && TableAtBorder(tablePtr, eventPtr->xmotion.x, eventPtr->xmotion.y, &row, &col) && ((row>=0 && (tablePtr->resize & SEL_ROW)) || (col>=0 && (tablePtr->resize & SEL_COL)))) { /* * The bordercursor is defined and we meet the criteria for * being over a border. Set the cursor to border if not * already done. */ if (!(tablePtr->flags & OVER_BORDER)) { tablePtr->flags |= OVER_BORDER; Tk_DefineCursor(tablePtr->tkwin, tablePtr->bdcursor); } } else if (tablePtr->flags & OVER_BORDER) { tablePtr->flags &= ~OVER_BORDER; if (tablePtr->cursor != None) { Tk_DefineCursor(tablePtr->tkwin, tablePtr->cursor); } else { Tk_UndefineCursor(tablePtr->tkwin); } #ifdef TITLE_CURSOR } else if (tablePtr->flags & (OVER_BORDER|OVER_TITLE)) { Tk_Cursor cursor = tablePtr->cursor; //tablePtr->flags &= ~(OVER_BORDER|OVER_TITLE); if (tablePtr->titleCursor != None) { TableWhatCell(tablePtr, eventPtr->xmotion.x, eventPtr->xmotion.y, &row, &col); if ((row < tablePtr->titleRows) || (col < tablePtr->titleCols)) { if (tablePtr->flags & OVER_TITLE) { break; } tablePtr->flags |= OVER_TITLE; cursor = tablePtr->titleCursor; } } if (cursor != None) { Tk_DefineCursor(tablePtr->tkwin, cursor); } else { Tk_UndefineCursor(tablePtr->tkwin); } } else if (tablePtr->titleCursor != None) { Tk_Cursor cursor = tablePtr->cursor; TableWhatCell(tablePtr, eventPtr->xmotion.x, eventPtr->xmotion.y, &row, &col); if ((row < tablePtr->titleRows) || (col < tablePtr->titleCols)) { if (tablePtr->flags & OVER_TITLE) { break; } tablePtr->flags |= OVER_TITLE; cursor = tablePtr->titleCursor; } #endif } break; case Expose: TableInvalidate(tablePtr, eventPtr->xexpose.x, eventPtr->xexpose.y, eventPtr->xexpose.width, eventPtr->xexpose.height, INV_HIGHLIGHT); break; case DestroyNotify: /* remove the command from the interpreter */ if (tablePtr->tkwin != NULL) { tablePtr->tkwin = NULL; Tcl_DeleteCommandFromToken(tablePtr->interp, tablePtr->widgetCmd); } /* cancel any pending update or timer */ if (tablePtr->flags & REDRAW_PENDING) { Tcl_CancelIdleCall(TableDisplay, (ClientData) tablePtr); tablePtr->flags &= ~REDRAW_PENDING; } Tcl_DeleteTimerHandler(tablePtr->cursorTimer); Tcl_DeleteTimerHandler(tablePtr->flashTimer); Tcl_EventuallyFree((ClientData) tablePtr, (Tcl_FreeProc *) TableDestroy); break; case MapNotify: /* redraw table when remapped if it changed */ if (tablePtr->flags & REDRAW_ON_MAP) { tablePtr->flags &= ~REDRAW_ON_MAP; Tcl_Preserve((ClientData) tablePtr); TableAdjustParams(tablePtr); TableInvalidateAll(tablePtr, INV_HIGHLIGHT); Tcl_Release((ClientData) tablePtr); } break; case ConfigureNotify: Tcl_Preserve((ClientData) tablePtr); TableAdjustParams(tablePtr); TableInvalidateAll(tablePtr, INV_HIGHLIGHT); Tcl_Release((ClientData) tablePtr); break; case FocusIn: case FocusOut: if (eventPtr->xfocus.detail != NotifyInferior) { tablePtr->flags |= REDRAW_BORDER; if (eventPtr->type == FocusOut) { tablePtr->flags &= ~HAS_FOCUS; } else { tablePtr->flags |= HAS_FOCUS; } TableRedrawHighlight(tablePtr); /* cancel the timer */ TableConfigCursor(tablePtr); } break; } } /* *---------------------------------------------------------------------- * * TableCmdDeletedProc -- * * This procedure is invoked when a widget command is deleted. If * the widget isn't already in the process of being destroyed, * this command destroys it. * * Results: * None. * * Side effects: * The widget is destroyed. * *---------------------------------------------------------------------- */ static void TableCmdDeletedProc(ClientData clientData) { Table *tablePtr = (Table *) clientData; Tk_Window tkwin; /* * This procedure could be invoked either because the window was * destroyed and the command was then deleted (in which case tkwin * is NULL) or because the command was deleted, and then this procedure * destroys the widget. */ if (tablePtr->tkwin != NULL) { tkwin = tablePtr->tkwin; tablePtr->tkwin = NULL; Tk_DestroyWindow(tkwin); } } /* *---------------------------------------------------------------------- * * TableRedrawHighlight -- * Redraws just the highlight for the window * * Results: * None. * * Side effects: * None * *---------------------------------------------------------------------- */ static void TableRedrawHighlight(Table *tablePtr) { if ((tablePtr->flags & REDRAW_BORDER) && tablePtr->highlightWidth > 0) { GC gc = Tk_GCForColor((tablePtr->flags & HAS_FOCUS) ? tablePtr->highlightColorPtr : tablePtr->highlightBgColorPtr, Tk_WindowId(tablePtr->tkwin)); Tk_DrawFocusHighlight(tablePtr->tkwin, gc, tablePtr->highlightWidth, Tk_WindowId(tablePtr->tkwin)); } tablePtr->flags &= ~REDRAW_BORDER; } /* *---------------------------------------------------------------------- * * TableRefresh -- * Refreshes an area of the table based on the mode. * row,col in real coords (0-based) * * Results: * Will cause redraw for visible cells * * Side effects: * None. * *---------------------------------------------------------------------- */ void TableRefresh(register Table *tablePtr, int row, int col, int mode) { int x, y, w, h; if ((row < 0) || (col < 0)) { /* * Invalid coords passed in. This can happen when the "active" cell * is refreshed, but doesn't really exist (row==-1 && col==-1). */ return; } if (mode & CELL) { if (TableCellVCoords(tablePtr, row, col, &x, &y, &w, &h, 0)) { TableInvalidate(tablePtr, x, y, w, h, mode); } } else if (mode & ROW) { /* get the position of the leftmost cell in the row */ if ((mode & INV_FILL) && row < tablePtr->topRow) { /* Invalidate whole table */ TableInvalidateAll(tablePtr, mode); } else if (TableCellVCoords(tablePtr, row, tablePtr->leftCol, &x, &y, &w, &h, 0)) { /* Invalidate from this row, maybe to end */ TableInvalidate(tablePtr, 0, y, Tk_Width(tablePtr->tkwin), (mode&INV_FILL)?Tk_Height(tablePtr->tkwin):h, mode); } } else if (mode & COL) { /* get the position of the topmost cell on the column */ if ((mode & INV_FILL) && col < tablePtr->leftCol) { /* Invalidate whole table */ TableInvalidateAll(tablePtr, mode); } else if (TableCellVCoords(tablePtr, tablePtr->topRow, col, &x, &y, &w, &h, 0)) { /* Invalidate from this column, maybe to end */ TableInvalidate(tablePtr, x, 0, (mode&INV_FILL)?Tk_Width(tablePtr->tkwin):w, Tk_Height(tablePtr->tkwin), mode); } } } /* *---------------------------------------------------------------------- * * TableGetGc -- * Gets a GC corresponding to the tag structure passed. * * Results: * Returns usable GC. * * Side effects: * None * *---------------------------------------------------------------------- */ static void TableGetGc(Display *display, Drawable d, TableTag *tagPtr, GC *tagGc) { XGCValues gcValues; gcValues.foreground = Tk_3DBorderColor(tagPtr->fg)->pixel; gcValues.background = Tk_3DBorderColor(tagPtr->bg)->pixel; gcValues.font = Tk_FontId(tagPtr->tkfont); if (*tagGc == NULL) { gcValues.graphics_exposures = False; *tagGc = XCreateGC(display, d, GCForeground|GCBackground|GCFont|GCGraphicsExposures, &gcValues); } else { XChangeGC(display, *tagGc, GCForeground|GCBackground|GCFont, &gcValues); } } #define TableFreeGc XFreeGC /* *-------------------------------------------------------------- * * TableUndisplay -- * This procedure removes the contents of a table window * that have been moved offscreen. * * Results: * Embedded windows can be unmapped. * * Side effects: * Information disappears from the screen. * *-------------------------------------------------------------- */ static void TableUndisplay(register Table *tablePtr) { register int *seen = tablePtr->seen; int row, col; /* We need to find out the true last cell, not considering spans */ tablePtr->flags |= AVOID_SPANS; TableGetLastCell(tablePtr, &row, &col); tablePtr->flags &= ~AVOID_SPANS; if (seen[0] != -1) { if (seen[0] < tablePtr->topRow) { /* Remove now hidden rows */ EmbWinUnmap(tablePtr, seen[0], MIN(seen[2],tablePtr->topRow-1), seen[1], seen[3]); /* Also account for the title area */ EmbWinUnmap(tablePtr, seen[0], MIN(seen[2],tablePtr->topRow-1), 0, tablePtr->titleCols-1); } if (seen[1] < tablePtr->leftCol) { /* Remove now hidden cols */ EmbWinUnmap(tablePtr, seen[0], seen[2], seen[1], MAX(seen[3],tablePtr->leftCol-1)); /* Also account for the title area */ EmbWinUnmap(tablePtr, 0, tablePtr->titleRows-1, seen[1], MAX(seen[3],tablePtr->leftCol-1)); } if (seen[2] > row) { /* Remove now off-screen rows */ EmbWinUnmap(tablePtr, MAX(seen[0],row+1), seen[2], seen[1], seen[3]); /* Also account for the title area */ EmbWinUnmap(tablePtr, MAX(seen[0],row+1), seen[2], 0, tablePtr->titleCols-1); } if (seen[3] > col) { /* Remove now off-screen cols */ EmbWinUnmap(tablePtr, seen[0], seen[2], MAX(seen[1],col+1), seen[3]); /* Also account for the title area */ EmbWinUnmap(tablePtr, 0, tablePtr->titleRows-1, MAX(seen[1],col+1), seen[3]); } } seen[0] = tablePtr->topRow; seen[1] = tablePtr->leftCol; seen[2] = row; seen[3] = col; } #if defined(MAC_TCL) || (defined(WIN32) && defined(TCL_THREADS)) || defined(MAC_OSX_TK) #define NO_XSETCLIP #endif /* *-------------------------------------------------------------- * * TableDisplay -- * This procedure redraws the contents of a table window. * The conditional code in this function is due to these factors: * o Lack of XSetClipRectangles on Macintosh * o Use of alternative routine for Windows * * Results: * None. * * Side effects: * Information appears on the screen. * *-------------------------------------------------------------- */ static void TableDisplay(ClientData clientdata) { register Table *tablePtr = (Table *) clientdata; Tk_Window tkwin = tablePtr->tkwin; Display *display = tablePtr->display; Drawable window; #ifdef NO_XSETCLIP Drawable clipWind; #elif !defined(WIN32) XRectangle clipRect; #endif int rowFrom, rowTo, colFrom, colTo, invalidX, invalidY, invalidWidth, invalidHeight, x, y, width, height, itemX, itemY, itemW, itemH, row, col, urow, ucol, hrow=0, hcol=0, cx, cy, cw, ch, borders, bd[6], numBytes, new, boundW, boundH, maxW, maxH, cellType, originX, originY, activeCell, shouldInvert, ipadx, ipady, padx, pady; GC tagGc = NULL, topGc, bottomGc; char *string = NULL; char buf[INDEX_BUFSIZE]; TableTag *tagPtr = NULL, *titlePtr, *selPtr, *activePtr, *flashPtr, *rowPtr, *colPtr; Tcl_HashEntry *entryPtr; static XPoint rect[3] = { {0, 0}, {0, 0}, {0, 0} }; Tcl_HashTable *colTagsCache = NULL; Tcl_HashTable *drawnCache = NULL; Tk_TextLayout textLayout = NULL; TableEmbWindow *ewPtr; tablePtr->flags &= ~REDRAW_PENDING; if ((tkwin == NULL) || !Tk_IsMapped(tkwin)) { return; } boundW = Tk_Width(tkwin) - tablePtr->highlightWidth; boundH = Tk_Height(tkwin) - tablePtr->highlightWidth; /* Constrain drawable to not include highlight borders */ invalidX = MAX(tablePtr->highlightWidth, tablePtr->invalidX); invalidY = MAX(tablePtr->highlightWidth, tablePtr->invalidY); invalidWidth = MIN(tablePtr->invalidWidth, MAX(1, boundW-invalidX)); invalidHeight = MIN(tablePtr->invalidHeight, MAX(1, boundH-invalidY)); ipadx = tablePtr->ipadX; ipady = tablePtr->ipadY; padx = tablePtr->padX; pady = tablePtr->padY; /* * if we are using the slow drawing mode with a pixmap * create the pixmap and adjust x && y for offset in pixmap */ if (tablePtr->drawMode == DRAW_MODE_SLOW) { window = Tk_GetPixmap(display, Tk_WindowId(tkwin), invalidWidth, invalidHeight, Tk_Depth(tkwin)); } else { window = Tk_WindowId(tkwin); } #ifdef NO_XSETCLIP clipWind = Tk_GetPixmap(display, window, invalidWidth, invalidHeight, Tk_Depth(tkwin)); #endif /* set up the permanent tag styles */ entryPtr = Tcl_FindHashEntry(tablePtr->tagTable, "title"); titlePtr = (TableTag *) Tcl_GetHashValue(entryPtr); entryPtr = Tcl_FindHashEntry(tablePtr->tagTable, "sel"); selPtr = (TableTag *) Tcl_GetHashValue(entryPtr); entryPtr = Tcl_FindHashEntry(tablePtr->tagTable, "active"); activePtr = (TableTag *) Tcl_GetHashValue(entryPtr); entryPtr = Tcl_FindHashEntry(tablePtr->tagTable, "flash"); flashPtr = (TableTag *) Tcl_GetHashValue(entryPtr); /* We need to find out the true cell span, not considering spans */ tablePtr->flags |= AVOID_SPANS; /* find out the cells represented by the invalid region */ TableWhatCell(tablePtr, invalidX, invalidY, &rowFrom, &colFrom); TableWhatCell(tablePtr, invalidX+invalidWidth-1, invalidY+invalidHeight-1, &rowTo, &colTo); tablePtr->flags &= ~AVOID_SPANS; #ifdef DEBUG tcl_dprintf(tablePtr->interp, "%d,%d => %d,%d", rowFrom+tablePtr->rowOffset, colFrom+tablePtr->colOffset, rowTo+tablePtr->rowOffset, colTo+tablePtr->colOffset); #endif /* * Initialize colTagsCache hash table to cache column tag names. */ colTagsCache = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(colTagsCache, TCL_ONE_WORD_KEYS); /* * Initialize drawnCache hash table to cache drawn cells. * This is necessary to prevent spanning cells being drawn multiple times. */ drawnCache = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(drawnCache, TCL_STRING_KEYS); /* * Create the tag here. This will actually create a JoinTag * That will handle the priority management of merging for us. * We only need one allocated, and we'll reset it for each cell. */ tagPtr = TableNewTag(tablePtr); /* Cycle through the cells and display them */ for (row = rowFrom; row <= rowTo; row++) { /* * are we in the 'dead zone' between the * title rows and the first displayed row */ if (row < tablePtr->topRow && row >= tablePtr->titleRows) { row = tablePtr->topRow; } /* Cache the row in user terms */ urow = row+tablePtr->rowOffset; /* Get the row tag once for all iterations of col */ rowPtr = FindRowColTag(tablePtr, urow, ROW); for (col = colFrom; col <= colTo; col++) { activeCell = 0; /* * Adjust to first viewable column if we are in the 'dead zone' * between the title cols and the first displayed column. */ if (col < tablePtr->leftCol && col >= tablePtr->titleCols) { col = tablePtr->leftCol; } /* * Get the coordinates for the cell before possible rearrangement * of row,col due to spanning cells */ cellType = TableCellCoords(tablePtr, row, col, &x, &y, &width, &height); if (cellType == CELL_HIDDEN) { /* * width,height holds the real start row,col of the span. * Put the use cell ref into a buffer for the hash lookups. */ TableMakeArrayIndex(width, height, buf); Tcl_CreateHashEntry(drawnCache, buf, &new); if (!new) { /* Not new in the entry, so it's already drawn */ continue; } hrow = row; hcol = col; row = width-tablePtr->rowOffset; col = height-tablePtr->colOffset; TableCellVCoords(tablePtr, row, col, &x, &y, &width, &height, 0); /* We have to adjust the coords back onto the visual display */ urow = row+tablePtr->rowOffset; rowPtr = FindRowColTag(tablePtr, urow, ROW); } /* Constrain drawn size to the visual boundaries */ if (width > boundW-x) { width = boundW-x; } if (height > boundH-y) { height = boundH-y; } /* Cache the col in user terms */ ucol = col+tablePtr->colOffset; /* put the use cell ref into a buffer for the hash lookups */ TableMakeArrayIndex(urow, ucol, buf); if (cellType != CELL_HIDDEN) { Tcl_CreateHashEntry(drawnCache, buf, &new); } /* * Make sure we start with a clean tag (set to table defaults). */ TableResetTag(tablePtr, tagPtr); /* * Check to see if we have an embedded window in this cell. */ entryPtr = Tcl_FindHashEntry(tablePtr->winTable, buf); if (entryPtr != NULL) { ewPtr = (TableEmbWindow *) Tcl_GetHashValue(entryPtr); if (ewPtr->tkwin != NULL) { /* Display embedded window instead of text */ /* if active, make it disabled to avoid * unnecessary editing */ if ((tablePtr->flags & HAS_ACTIVE) && row == tablePtr->activeRow && col == tablePtr->activeCol) { tablePtr->flags |= ACTIVE_DISABLED; } /* * The EmbWinDisplay function may modify values in * tagPtr, so reference those after this call. */ EmbWinDisplay(tablePtr, window, ewPtr, tagPtr, x, y, width, height); if (tablePtr->drawMode == DRAW_MODE_SLOW) { /* Correctly adjust x && y with the offset */ x -= invalidX; y -= invalidY; } Tk_Fill3DRectangle(tkwin, window, tagPtr->bg, x, y, width, height, 0, TK_RELIEF_FLAT); /* border width for cell should now be properly set */ borders = TableGetTagBorders(tagPtr, &bd[0], &bd[1], &bd[2], &bd[3]); bd[4] = (bd[0] + bd[1])/2; bd[5] = (bd[2] + bd[3])/2; goto DrawBorder; } } if (tablePtr->drawMode == DRAW_MODE_SLOW) { /* Correctly adjust x && y with the offset */ x -= invalidX; y -= invalidY; } shouldInvert = 0; /* * Get the combined tag structure for the cell. * First clear out a new tag structure that we will build in * then add tags as we realize they belong. * * Tags have their own priorities which TableMergeTag will * take into account when merging tags. */ /* * Merge colPtr if it exists * let's see if we have the value cached already * if not, run the findColTag routine and cache the value */ entryPtr = Tcl_CreateHashEntry(colTagsCache, (char *)ucol, &new); if (new) { colPtr = FindRowColTag(tablePtr, ucol, COL); Tcl_SetHashValue(entryPtr, colPtr); } else { colPtr = (TableTag *) Tcl_GetHashValue(entryPtr); } if (colPtr != (TableTag *) NULL) { TableMergeTag(tablePtr, tagPtr, colPtr); } /* Merge rowPtr if it exists */ if (rowPtr != (TableTag *) NULL) { TableMergeTag(tablePtr, tagPtr, rowPtr); } /* Am I in the titles */ if (row < tablePtr->titleRows || col < tablePtr->titleCols) { TableMergeTag(tablePtr, tagPtr, titlePtr); } /* Does this have a cell tag */ entryPtr = Tcl_FindHashEntry(tablePtr->cellStyles, buf); if (entryPtr != NULL) { TableMergeTag(tablePtr, tagPtr, (TableTag *) Tcl_GetHashValue(entryPtr)); } /* is this cell active? */ if ((tablePtr->flags & HAS_ACTIVE) && (tablePtr->state == STATE_NORMAL) && row == tablePtr->activeRow && col == tablePtr->activeCol) { if (tagPtr->state == STATE_DISABLED) { tablePtr->flags |= ACTIVE_DISABLED; } else { TableMergeTag(tablePtr, tagPtr, activePtr); activeCell = 1; tablePtr->flags &= ~ACTIVE_DISABLED; } } /* is this cell selected? */ if (Tcl_FindHashEntry(tablePtr->selCells, buf) != NULL) { if (tablePtr->invertSelected && !activeCell) { shouldInvert = 1; } else { TableMergeTag(tablePtr, tagPtr, selPtr); } } /* if flash mode is on, is this cell flashing? */ if (tablePtr->flashMode && Tcl_FindHashEntry(tablePtr->flashCells, buf) != NULL) { TableMergeTag(tablePtr, tagPtr, flashPtr); } if (shouldInvert) { TableInvertTag(tagPtr); } /* * Borders for cell should now be properly set */ borders = TableGetTagBorders(tagPtr, &bd[0], &bd[1], &bd[2], &bd[3]); bd[4] = (bd[0] + bd[1])/2; bd[5] = (bd[2] + bd[3])/2; /* * First fill in a blank rectangle. */ Tk_Fill3DRectangle(tkwin, window, tagPtr->bg, x, y, width, height, 0, TK_RELIEF_FLAT); /* * Correct the dimensions to enforce padding constraints */ width -= bd[0] + bd[1] + (2 * padx); height -= bd[2] + bd[3] + (2 * pady); /* * If an image is in the tag, draw it */ if (tagPtr->image != NULL) { Tk_SizeOfImage(tagPtr->image, &itemW, &itemH); /* Handle anchoring of image in cell space */ switch (tagPtr->anchor) { case TK_ANCHOR_NW: case TK_ANCHOR_W: case TK_ANCHOR_SW: /* western position */ originX = itemX = 0; break; case TK_ANCHOR_N: case TK_ANCHOR_S: case TK_ANCHOR_CENTER: /* centered position */ itemX = MAX(0, (itemW - width) / 2); originX = MAX(0, (width - itemW) / 2); break; default: /* eastern position */ itemX = MAX(0, itemW - width); originX = MAX(0, width - itemW); } switch (tagPtr->anchor) { case TK_ANCHOR_N: case TK_ANCHOR_NE: case TK_ANCHOR_NW: /* northern position */ originY = itemY = 0; break; case TK_ANCHOR_W: case TK_ANCHOR_E: case TK_ANCHOR_CENTER: /* centered position */ itemY = MAX(0, (itemH - height) / 2); originY = MAX(0, (height - itemH) / 2); break; default: /* southern position */ itemY = MAX(0, itemH - height); originY = MAX(0, height - itemH); } Tk_RedrawImage(tagPtr->image, itemX, itemY, MIN(itemW, width-originX), MIN(itemH, height-originY), window, x + originX + bd[0] + padx, y + originY + bd[2] + pady); /* * If we don't want to display the text as well, then jump. */ if (tagPtr->showtext == 0) { /* * Re-Correct the dimensions before border drawing */ width += bd[0] + bd[1] + (2 * padx); height += bd[2] + bd[3] + (2 * pady); goto DrawBorder; } } /* * Get the GC for this particular blend of tags. * This creates the GC if it never existed, otherwise it * modifies the one we have, so we only need the one */ TableGetGc(display, window, tagPtr, &tagGc); /* if this is the active cell, use the buffer */ if (activeCell) { string = tablePtr->activeBuf; } else { /* Is there a value in the cell? If so, draw it */ string = TableGetCellValue(tablePtr, urow, ucol); } #ifdef TCL_UTF_MAX /* * We have to use strlen here because otherwise it stops * at the first \x00 unicode char it finds (!= '\0'), * although there can be more to the string than that */ numBytes = Tcl_NumUtfChars(string, strlen(string)); #else numBytes = strlen(string); #endif /* If there is a string, show it */ if (activeCell || numBytes) { /* get the dimensions of the string */ textLayout = Tk_ComputeTextLayout(tagPtr->tkfont, string, numBytes, (tagPtr->wrap > 0) ? width : 0, tagPtr->justify, (tagPtr->multiline > 0) ? 0 : TK_IGNORE_NEWLINES, &itemW, &itemH); /* * Set the origin coordinates of the string to draw using * the anchor. origin represents the (x,y) coordinate of * the lower left corner of the text box, relative to the * internal (inside the border) window */ /* set the X origin first */ switch (tagPtr->anchor) { case TK_ANCHOR_NW: case TK_ANCHOR_W: case TK_ANCHOR_SW: /* western position */ originX = ipadx; break; case TK_ANCHOR_N: case TK_ANCHOR_S: case TK_ANCHOR_CENTER: /* centered position */ originX = (width - itemW) / 2; break; default: /* eastern position */ originX = width - itemW - ipadx; } /* then set the Y origin */ switch (tagPtr->anchor) { case TK_ANCHOR_N: case TK_ANCHOR_NE: case TK_ANCHOR_NW: /* northern position */ originY = ipady; break; case TK_ANCHOR_W: case TK_ANCHOR_E: case TK_ANCHOR_CENTER: /* centered position */ originY = (height - itemH) / 2; break; default: /* southern position */ originY = height - itemH - ipady; } /* * If this is the active cell and we are editing, * ensure that the cursor will be displayed */ if (activeCell) { Tk_CharBbox(textLayout, tablePtr->icursor, &cx, &cy, &cw, &ch); /* we have to fudge with maxW because of odd width * determination for newlines at the end of a line */ maxW = width - tablePtr->insertWidth - (cx + MIN(tablePtr->charWidth, cw)); maxH = height - (cy + ch); if (originX < bd[0] - cx) { /* cursor off cell to the left */ /* use western positioning to cet cursor at left * with slight variation to show some text */ originX = bd[0] - cx + MIN(cx, width - tablePtr->insertWidth); } else if (originX > maxW) { /* cursor off cell to the right */ /* use eastern positioning to cet cursor at right */ originX = maxW; } if (originY < bd[2] - cy) { /* cursor before top of cell */ /* use northern positioning to cet cursor at top */ originY = bd[2] - cy; } else if (originY > maxH) { /* cursor beyond bottom of cell */ /* use southern positioning to cet cursor at bottom */ originY = maxH; } tablePtr->activeTagPtr = tagPtr; tablePtr->activeX = originX; tablePtr->activeY = originY; } /* * Use a clip rectangle only if necessary as it means * updating the GC in the server which slows everything down. * We can't fudge the width or height, just in case the user * wanted empty pad space. */ if ((originX < 0) || (originY < 0) || (originX+itemW > width) || (originY+itemH > height)) { /* * The text wants to overflow the boundaries of the * displayed cell, so we must clip in some way */ #ifdef NO_XSETCLIP /* * This code is basically for the Macintosh. * Copy the the current contents of the cell into the * clipped window area. This keeps any fg/bg and image * data intact. */ XCopyArea(display, window, clipWind, tagGc, x, y, width + bd[0] + bd[1] + (2 * padx), height + bd[2] + bd[3] + (2 * pady), 0, 0); /* * Now draw into the cell space on the special window. * Don't use x,y base offset for clipWind. */ Tk_DrawTextLayout(display, clipWind, tagGc, textLayout, 0 + originX + bd[0] + padx, 0 + originY + bd[2] + pady, 0, -1); /* * Now copy back only the area that we want the * text to be drawn on. */ XCopyArea(display, clipWind, window, tagGc, bd[0] + padx, bd[2] + pady, width, height, x + bd[0] + padx, y + bd[2] + pady); #elif defined(WIN32) /* * This is evil, evil evil! but the XCopyArea * doesn't work in all cases - Michael Teske. * The general structure follows the comments below. */ TkWinDrawable *twdPtr = (TkWinDrawable *) window; HDC dc = GetDC(twdPtr->window.handle); HRGN clipR; clipR = CreateRectRgn(x + bd[0] + padx, y + bd[2] + pady, x + bd[0] + padx + width, y + bd[2] + pady + height); SelectClipRgn(dc, clipR); OffsetClipRgn(dc, 0, 0); Tk_DrawTextLayout(display, window, tagGc, textLayout, x + originX + bd[0] + padx, y + originY + bd[2] + pady, 0, -1); SelectClipRgn(dc, NULL); DeleteObject(clipR); #else /* * Use an X clipping rectangle. The clipping is the * rectangle just for the actual text space (to allow * for empty padding space). */ clipRect.x = x + bd[0] + padx; clipRect.y = y + bd[2] + pady; clipRect.width = width; clipRect.height = height; XSetClipRectangles(display, tagGc, 0, 0, &clipRect, 1, Unsorted); Tk_DrawTextLayout(display, window, tagGc, textLayout, x + originX + bd[0] + padx, y + originY + bd[2] + pady, 0, -1); XSetClipMask(display, tagGc, None); #endif } else { Tk_DrawTextLayout(display, window, tagGc, textLayout, x + originX + bd[0] + padx, y + originY + bd[2] + pady, 0, -1); } /* if this is the active cell draw the cursor if it's on. * this ignores clip rectangles. */ if (activeCell && (tablePtr->flags & CURSOR_ON) && (originY + cy + bd[2] + pady < height) && (originX + cx + bd[0] + padx - (tablePtr->insertWidth / 2) >= 0)) { /* make sure it will fit in the box */ maxW = MAX(0, originY + cy + bd[2] + pady); maxH = MIN(ch, height - maxW + bd[2] + pady); Tk_Fill3DRectangle(tkwin, window, tablePtr->insertBg, x + originX + cx + bd[0] + padx - (tablePtr->insertWidth/2), y + maxW, tablePtr->insertWidth, maxH, 0, TK_RELIEF_FLAT); } } /* * Re-Correct the dimensions before border drawing */ width += bd[0] + bd[1] + (2 * padx); height += bd[2] + bd[3] + (2 * pady); DrawBorder: /* Draw the 3d border on the pixmap correctly offset */ if (tablePtr->drawMode == DRAW_MODE_SINGLE) { topGc = Tk_3DBorderGC(tkwin, tagPtr->bg, TK_3D_DARK_GC); /* draw a line with single pixel width */ rect[0].x = x; rect[0].y = y + height - 1; rect[1].y = -height + 1; rect[2].x = width - 1; XDrawLines(display, window, topGc, rect, 3, CoordModePrevious); } else if (tablePtr->drawMode == DRAW_MODE_FAST) { /* * This depicts a full 1 pixel border. * * Choose the GCs to get the best approximation * to the desired drawing style. */ switch(tagPtr->relief) { case TK_RELIEF_FLAT: topGc = bottomGc = Tk_3DBorderGC(tkwin, tagPtr->bg, TK_3D_FLAT_GC); break; case TK_RELIEF_RAISED: case TK_RELIEF_RIDGE: topGc = Tk_3DBorderGC(tkwin, tagPtr->bg, TK_3D_LIGHT_GC); bottomGc = Tk_3DBorderGC(tkwin, tagPtr->bg, TK_3D_DARK_GC); break; default: /* TK_RELIEF_SUNKEN TK_RELIEF_GROOVE */ bottomGc = Tk_3DBorderGC(tkwin, tagPtr->bg, TK_3D_LIGHT_GC); topGc = Tk_3DBorderGC(tkwin, tagPtr->bg, TK_3D_DARK_GC); break; } /* draw a line with single pixel width */ rect[0].x = x + width - 1; rect[0].y = y; rect[1].y = height - 1; rect[2].x = -width + 1; XDrawLines(display, window, bottomGc, rect, 3, CoordModePrevious); rect[0].x = x; rect[0].y = y + height - 1; rect[1].y = -height + 1; rect[2].x = width - 1; XDrawLines(display, window, topGc, rect, 3, CoordModePrevious); } else { if (borders > 1) { if (bd[0]) { Tk_3DVerticalBevel(tkwin, window, tagPtr->bg, x, y, bd[0], height, 1 /* left side */, tagPtr->relief); } if (bd[1]) { Tk_3DVerticalBevel(tkwin, window, tagPtr->bg, x + width - bd[1], y, bd[1], height, 0 /* right side */, tagPtr->relief); } if ((borders == 4) && bd[2]) { Tk_3DHorizontalBevel(tkwin, window, tagPtr->bg, x, y, width, bd[2], 1, 1, 1 /* top */, tagPtr->relief); } if ((borders == 4) && bd[3]) { Tk_3DHorizontalBevel(tkwin, window, tagPtr->bg, x, y + height - bd[3], width, bd[3], 0, 0, 0 /* bottom */, tagPtr->relief); } } else if (borders == 1) { Tk_Draw3DRectangle(tkwin, window, tagPtr->bg, x, y, width, height, bd[0], tagPtr->relief); } } /* clean up the necessaries */ if (tagPtr == tablePtr->activeTagPtr) { /* * This means it was the activeCell with text displayed. * We buffer the active tag for the 'activate' command. */ tablePtr->activeTagPtr = TableNewTag(NULL); memcpy((VOID *) tablePtr->activeTagPtr, (VOID *) tagPtr, sizeof(TableTag)); } if (textLayout) { Tk_FreeTextLayout(textLayout); textLayout = NULL; } if (cellType == CELL_HIDDEN) { /* the last cell was a hidden one, * rework row stuff back to normal */ row = hrow; col = hcol; urow = row+tablePtr->rowOffset; rowPtr = FindRowColTag(tablePtr, urow, ROW); } } } ckfree((char *) tagPtr); #ifdef NO_XSETCLIP Tk_FreePixmap(display, clipWind); #endif /* Take care of removing embedded windows that are no longer in view */ TableUndisplay(tablePtr); /* copy over and delete the pixmap if we are in slow mode */ if (tablePtr->drawMode == DRAW_MODE_SLOW) { /* Get a default valued GC */ TableGetGc(display, window, &(tablePtr->defaultTag), &tagGc); XCopyArea(display, window, Tk_WindowId(tkwin), tagGc, 0, 0, invalidWidth, invalidHeight, invalidX, invalidY); Tk_FreePixmap(display, window); window = Tk_WindowId(tkwin); } /* * If we are at the end of the table, clear the area after the last * row/col. We discount spans here because we just need the coords * for the area that would be the last physical cell. */ tablePtr->flags |= AVOID_SPANS; TableCellCoords(tablePtr, tablePtr->rows-1, tablePtr->cols-1, &x, &y, &width, &height); tablePtr->flags &= ~AVOID_SPANS; /* This should occur before moving pixmap, but this simplifies things * * Could use Tk_Fill3DRectangle instead of XFillRectangle * for best compatibility, and XClearArea could be used on Unix * for best speed, so this is the compromise w/o #ifdef's */ if (x+width < invalidX+invalidWidth) { XFillRectangle(display, window, Tk_3DBorderGC(tkwin, tablePtr->defaultTag.bg, TK_3D_FLAT_GC), x+width, invalidY, invalidX+invalidWidth-x-width, invalidHeight); } if (y+height < invalidY+invalidHeight) { XFillRectangle(display, window, Tk_3DBorderGC(tkwin, tablePtr->defaultTag.bg, TK_3D_FLAT_GC), invalidX, y+height, invalidWidth, invalidY+invalidHeight-y-height); } if (tagGc != NULL) { TableFreeGc(display, tagGc); } TableRedrawHighlight(tablePtr); /* * Free the hash table used to cache evaluations. */ Tcl_DeleteHashTable(colTagsCache); ckfree((char *) (colTagsCache)); Tcl_DeleteHashTable(drawnCache); ckfree((char *) (drawnCache)); } /* *---------------------------------------------------------------------- * * TableInvalidate -- * Invalidates a rectangle and adds it to the total invalid rectangle * waiting to be redrawn. If the INV_FORCE flag bit is set, * it does an update instantly else waits until Tk is idle. * * Results: * Will schedule table (re)display. * * Side effects: * None * *---------------------------------------------------------------------- */ void TableInvalidate(Table * tablePtr, int x, int y, int w, int h, int flags) { Tk_Window tkwin = tablePtr->tkwin; int hl = tablePtr->highlightWidth; int height = Tk_Height(tkwin); int width = Tk_Width(tkwin); /* * Make sure that the window hasn't been destroyed already. * Avoid allocating 0 sized pixmaps which would be fatal, * and check if rectangle is even on the screen. */ if ((tkwin == NULL) || (w <= 0) || (h <= 0) || (x > width) || (y > height)) { return; } /* If not even mapped, wait for the remap to redraw all */ if (!Tk_IsMapped(tkwin)) { tablePtr->flags |= REDRAW_ON_MAP; return; } /* * If no pending updates exist, then replace the rectangle. * Otherwise find the bounding rectangle. */ if ((flags & INV_HIGHLIGHT) && (x < hl || y < hl || x+w >= width-hl || y+h >= height-hl)) { tablePtr->flags |= REDRAW_BORDER; } if (tablePtr->flags & REDRAW_PENDING) { tablePtr->invalidWidth = MAX(x + w, tablePtr->invalidX+tablePtr->invalidWidth); tablePtr->invalidHeight = MAX(y + h, tablePtr->invalidY+tablePtr->invalidHeight); if (tablePtr->invalidX > x) tablePtr->invalidX = x; if (tablePtr->invalidY > y) tablePtr->invalidY = y; tablePtr->invalidWidth -= tablePtr->invalidX; tablePtr->invalidHeight -= tablePtr->invalidY; /* Do we want to force this update out? */ if (flags & INV_FORCE) { Tcl_CancelIdleCall(TableDisplay, (ClientData) tablePtr); TableDisplay((ClientData) tablePtr); } } else { tablePtr->invalidX = x; tablePtr->invalidY = y; tablePtr->invalidWidth = w; tablePtr->invalidHeight = h; if (flags & INV_FORCE) { TableDisplay((ClientData) tablePtr); } else { tablePtr->flags |= REDRAW_PENDING; Tcl_DoWhenIdle(TableDisplay, (ClientData) tablePtr); } } } /* *---------------------------------------------------------------------- * * TableFlashEvent -- * Called when the flash timer goes off. * * Results: * Decrements all the entries in the hash table and invalidates * any cells that expire, deleting them from the table. If the * table is now empty, stops the timer, else reenables it. * * Side effects: * None. * *---------------------------------------------------------------------- */ static void TableFlashEvent(ClientData clientdata) { Table *tablePtr = (Table *) clientdata; Tcl_HashEntry *entryPtr; Tcl_HashSearch search; int entries, count, row, col; entries = 0; for (entryPtr = Tcl_FirstHashEntry(tablePtr->flashCells, &search); entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { count = (int) Tcl_GetHashValue(entryPtr); if (--count <= 0) { /* get the cell address and invalidate that region only */ TableParseArrayIndex(&row, &col, Tcl_GetHashKey(tablePtr->flashCells, entryPtr)); /* delete the entry from the table */ Tcl_DeleteHashEntry(entryPtr); TableRefresh(tablePtr, row-tablePtr->rowOffset, col-tablePtr->colOffset, CELL); } else { Tcl_SetHashValue(entryPtr, (ClientData) count); entries++; } } /* do I need to restart the timer */ if (entries && tablePtr->flashMode) { tablePtr->flashTimer = Tcl_CreateTimerHandler(250, TableFlashEvent, (ClientData) tablePtr); } else { tablePtr->flashTimer = 0; } } /* *---------------------------------------------------------------------- * * TableAddFlash -- * Adds a flash on cell row,col (real coords) with the default timeout * if flashing is enabled and flashtime > 0. * * Results: * Cell will flash. * * Side effects: * Will start flash timer if it didn't exist. * *---------------------------------------------------------------------- */ void TableAddFlash(Table *tablePtr, int row, int col) { char buf[INDEX_BUFSIZE]; int dummy; Tcl_HashEntry *entryPtr; if (!tablePtr->flashMode || tablePtr->flashTime < 1) { return; } /* create the array index in user coords */ TableMakeArrayIndex(row+tablePtr->rowOffset, col+tablePtr->colOffset, buf); /* add the flash to the hash table */ entryPtr = Tcl_CreateHashEntry(tablePtr->flashCells, buf, &dummy); Tcl_SetHashValue(entryPtr, tablePtr->flashTime); /* now set the timer if it's not already going and invalidate the area */ if (tablePtr->flashTimer == NULL) { tablePtr->flashTimer = Tcl_CreateTimerHandler(250, TableFlashEvent, (ClientData) tablePtr); } } /* *---------------------------------------------------------------------- * * TableSetActiveIndex -- * Sets the "active" index of the associated array to the current * value of the active buffer. * * Results: * None. * * Side effects: * Traces on the array can cause side effects. * *---------------------------------------------------------------------- */ void TableSetActiveIndex(register Table *tablePtr) { if (tablePtr->arrayVar) { tablePtr->flags |= SET_ACTIVE; Tcl_ObjSetVar2(tablePtr->interp, tablePtr->arrayVar, Tcl_NewStringObj("active",-1), Tcl_NewStringObj(tablePtr->activeBuf,-1), TCL_GLOBAL_ONLY); tablePtr->flags &= ~SET_ACTIVE; } } /* *---------------------------------------------------------------------- * * TableGetActiveBuf -- * Get the current selection into the buffer and mark it as unedited. * Set the position to the end of the string. * * Results: * None. * * Side effects: * tablePtr->activeBuf will change. * *---------------------------------------------------------------------- */ void TableGetActiveBuf(register Table *tablePtr) { char *data = ""; if (tablePtr->flags & HAS_ACTIVE) { data = TableGetCellValue(tablePtr, tablePtr->activeRow+tablePtr->rowOffset, tablePtr->activeCol+tablePtr->colOffset); } if (STREQ(tablePtr->activeBuf, data)) { /* this forced SetActiveIndex is necessary if we change array vars and * they happen to have these cells equal, we won't properly set the * active index for the new array var unless we do this here */ TableSetActiveIndex(tablePtr); return; } /* is the buffer long enough */ tablePtr->activeBuf = (char *)ckrealloc(tablePtr->activeBuf, strlen(data)+1); strcpy(tablePtr->activeBuf, data); TableGetIcursor(tablePtr, "end", (int *)0); tablePtr->flags &= ~TEXT_CHANGED; TableSetActiveIndex(tablePtr); } /* *---------------------------------------------------------------------- * * TableVarProc -- * This is the trace procedure associated with the Tcl array. No * validation will occur here because this only triggers when the * array value is directly set, and we can't maintain the old value. * * Results: * Invalidates changed cell. * * Side effects: * Creates/Updates entry in the cache if we are caching. * *---------------------------------------------------------------------- */ static char * TableVarProc(clientData, interp, name, index, flags) ClientData clientData; /* Information about table. */ Tcl_Interp *interp; /* Interpreter containing variable. */ Var name; /* Not used. */ char *index; /* Not used. */ int flags; /* Information about what happened. */ { Table *tablePtr = (Table *) clientData; int row, col, update = 1; /* This is redundant, as the name should always == arrayVar */ name = tablePtr->arrayVar; /* is this the whole var being destroyed or just one cell being deleted */ if ((flags & TCL_TRACE_UNSETS) && index == NULL) { /* if this isn't the interpreter being destroyed reinstate the trace */ if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) { Tcl_ObjSetVar2(interp, name, Tcl_NewStringObj(TEST_KEY,-1), Tcl_NewStringObj("",-1), TCL_GLOBAL_ONLY); /* Perltk not supported */ /* Tcl_UnsetVar2(interp, LangString(Tcl_GetVar(interp, name, TCL_GLOBAL_ONLY)), TEST_KEY, TCL_GLOBAL_ONLY); */ Tcl_ResetResult(interp); /* set a trace on the variable */ Lang_TraceVar(interp, name, TCL_TRACE_WRITES | TCL_TRACE_UNSETS | TCL_GLOBAL_ONLY, (Lang_VarTraceProc *)TableVarProc, (ClientData) tablePtr); /* only do the following if arrayVar is our data source */ if (tablePtr->dataSource & DATA_ARRAY) { /* clear the selection buffer */ TableGetActiveBuf(tablePtr); /* flush any cache */ Table_ClearHashTable(tablePtr->cache); Tcl_InitHashTable(tablePtr->cache, TCL_STRING_KEYS); /* and invalidate the table */ TableInvalidateAll(tablePtr, 0); } } return (char *)NULL; } /* only continue if arrayVar is our data source */ if (!(tablePtr->dataSource & DATA_ARRAY)) { return (char *)NULL; } /* get the cell address and invalidate that region only. * Make sure that it is a valid cell address. */ if (STREQ("active", index)) { if (tablePtr->flags & SET_ACTIVE) { /* If we are already setting the active cell, the update * will occur in other code */ update = 0; } else { /* modified TableGetActiveBuf */ CONST char *data = ""; row = tablePtr->activeRow; col = tablePtr->activeCol; if (tablePtr->flags & HAS_ACTIVE) data = Tcl_GetString(Tcl_ObjGetVar2(interp, name, Tcl_NewStringObj(index,-1), TCL_GLOBAL_ONLY)); if (!data) data = ""; if (STREQ(tablePtr->activeBuf, data)) { return (char *)NULL; } tablePtr->activeBuf = (char *)ckrealloc(tablePtr->activeBuf, strlen(data)+1); strcpy(tablePtr->activeBuf, data); /* set cursor to the last char */ TableGetIcursor(tablePtr, "end", (int *)0); tablePtr->flags |= TEXT_CHANGED; } } else if (TableParseArrayIndex(&row, &col, index) == 2) { char buf[INDEX_BUFSIZE]; /* Make sure it won't trigger on array(2,3extrastuff) */ TableMakeArrayIndex(row, col, buf); if (strcmp(buf, index)) { return (char *)NULL; } if (tablePtr->caching) { Tcl_HashEntry *entryPtr; int new; char *val, *data; entryPtr = Tcl_CreateHashEntry(tablePtr->cache, buf, &new); if (!new) { data = (char *) Tcl_GetHashValue(entryPtr); if (data) { ckfree(data); } } data = Tcl_GetString(Tcl_ObjGetVar2(interp, name, Tcl_NewStringObj(index,-1), TCL_GLOBAL_ONLY)); if (!data) data = ""; val = (char *)ckalloc(strlen(data)+1); strcpy(val, data); Tcl_SetHashValue(entryPtr, val); } /* convert index to real coords */ row -= tablePtr->rowOffset; col -= tablePtr->colOffset; /* did the active cell just update */ if (row == tablePtr->activeRow && col == tablePtr->activeCol) { TableGetActiveBuf(tablePtr); } /* Flash the cell */ TableAddFlash(tablePtr, row, col); } else { return (char *)NULL; } if (update) { TableRefresh(tablePtr, row, col, CELL); } return (char *)NULL; } /* *---------------------------------------------------------------------- * * TableGeometryRequest -- * This procedure is invoked to request a new geometry from Tk. * * Results: * None. * * Side effects: * Geometry information is updated and a new requested size is * registered for the widget. Internal border info is also set. * *---------------------------------------------------------------------- */ void TableGeometryRequest(tablePtr) register Table *tablePtr; { int x, y; /* Do the geometry request * If -width #cols was not specified or it is greater than the real * number of cols, use maxWidth as a lower bound, with the other lower * bound being the upper bound of the window's user-set width and the * value of -maxwidth set by the programmer * Vice versa for rows/height */ x = MIN((tablePtr->maxReqCols==0 || tablePtr->maxReqCols > tablePtr->cols)? tablePtr->maxWidth : tablePtr->colStarts[tablePtr->maxReqCols], tablePtr->maxReqWidth) + 2*tablePtr->highlightWidth; y = MIN((tablePtr->maxReqRows==0 || tablePtr->maxReqRows > tablePtr->rows)? tablePtr->maxHeight : tablePtr->rowStarts[tablePtr->maxReqRows], tablePtr->maxReqHeight) + 2*tablePtr->highlightWidth; Tk_GeometryRequest(tablePtr->tkwin, x, y); } /* *---------------------------------------------------------------------- * * TableAdjustActive -- * This procedure is called by AdjustParams and CMD_ACTIVATE to * move the active cell. * * Results: * Old and new active cell indices will be invalidated. * * Side effects: * If the old active cell index was edited, it will be saved. * The active buffer will be updated. * *---------------------------------------------------------------------- */ void TableAdjustActive(tablePtr) register Table *tablePtr; /* Widget record for table */ { if (tablePtr->flags & HAS_ACTIVE) { /* * Make sure the active cell has a reasonable real index */ CONSTRAIN(tablePtr->activeRow, 0, tablePtr->rows-1); CONSTRAIN(tablePtr->activeCol, 0, tablePtr->cols-1); } /* * Check the new value of active cell against the original, * Only invalidate if it changed. */ if (tablePtr->oldActRow == tablePtr->activeRow && tablePtr->oldActCol == tablePtr->activeCol) { return; } if (tablePtr->oldActRow >= 0 && tablePtr->oldActCol >= 0) { /* * Set the value of the old active cell to the active buffer * SetCellValue will check if the value actually changed */ if (tablePtr->flags & TEXT_CHANGED) { /* WARNING an outside trace will be triggered here and if it * calls something that causes TableAdjustParams to be called * again, we are in data consistency trouble */ /* HACK - turn TEXT_CHANGED off now to possibly avoid the * above data inconsistency problem. */ tablePtr->flags &= ~TEXT_CHANGED; TableSetCellValue(tablePtr, tablePtr->oldActRow + tablePtr->rowOffset, tablePtr->oldActCol + tablePtr->colOffset, tablePtr->activeBuf); } /* * Invalidate the old active cell */ TableRefresh(tablePtr, tablePtr->oldActRow, tablePtr->oldActCol, CELL); } /* * Store the new active cell value into the active buffer */ TableGetActiveBuf(tablePtr); /* * Invalidate the new active cell */ TableRefresh(tablePtr, tablePtr->activeRow, tablePtr->activeCol, CELL); /* * Cache the old active row/col for the next time this is called */ tablePtr->oldActRow = tablePtr->activeRow; tablePtr->oldActCol = tablePtr->activeCol; } /* *---------------------------------------------------------------------- * * TableAdjustParams -- * Calculate the row and column starts. Adjusts the topleft corner * variable to keep it within the screen range, out of the titles * and keep the screen full make sure the selected cell is in the * visible area checks to see if the top left cell has changed at * all and invalidates the table if it has. * * Results: * None. * * Side Effects: * Number of rows can change if -rowstretchmode == fill. * topRow && leftCol can change to fit display. * activeRow/Col can change to ensure it is a valid cell. * *---------------------------------------------------------------------- */ void TableAdjustParams(register Table *tablePtr) { int topRow, leftCol, row, col, total, i, value, x, y, width, height, w, h, hl, px, py, recalc, bd[4], diff, unpreset, lastUnpreset, pad, lastPad, numPixels, defColWidth, defRowHeight; Tcl_HashEntry *entryPtr; /* * Cache some values for many upcoming calculations */ hl = tablePtr->highlightWidth; w = Tk_Width(tablePtr->tkwin) - (2 * hl); h = Tk_Height(tablePtr->tkwin) - (2 * hl); TableGetTagBorders(&(tablePtr->defaultTag), &bd[0], &bd[1], &bd[2], &bd[3]); px = bd[0] + bd[1] + (2 * tablePtr->padX); py = bd[2] + bd[3] + (2 * tablePtr->padY); /* * Account for whether default dimensions are in chars (>0) or * pixels (<=0). Border and Pad space is added in here for convenience. * * When a value in pixels is specified, we take that exact amount, * not adding in padding. */ if (tablePtr->defColWidth > 0) { defColWidth = tablePtr->charWidth * tablePtr->defColWidth + px; } else { defColWidth = -(tablePtr->defColWidth); } if (tablePtr->defRowHeight > 0) { defRowHeight = tablePtr->charHeight * tablePtr->defRowHeight + py; } else { defRowHeight = -(tablePtr->defRowHeight); } /* * Set up the arrays to hold the col pixels and starts. * ckrealloc was fixed in 8.2.1 to handle NULLs, so we can't rely on it. */ if (tablePtr->colPixels) ckfree((char *) tablePtr->colPixels); tablePtr->colPixels = (int *) ckalloc(tablePtr->cols * sizeof(int)); if (tablePtr->colStarts) ckfree((char *) tablePtr->colStarts); tablePtr->colStarts = (int *) ckalloc((tablePtr->cols+1) * sizeof(int)); /* * Get all the preset columns and set their widths */ lastUnpreset = 0; numPixels = 0; unpreset = 0; for (i = 0; i < tablePtr->cols; i++) { entryPtr = Tcl_FindHashEntry(tablePtr->colWidths, (char *) i); if (entryPtr == NULL) { tablePtr->colPixels[i] = -1; unpreset++; lastUnpreset = i; } else { value = (int) Tcl_GetHashValue(entryPtr); if (value > 0) { tablePtr->colPixels[i] = value * tablePtr->charWidth + px; } else { /* * When a value in pixels is specified, we take that exact * amount, not adding in pad or border values. */ tablePtr->colPixels[i] = -value; } numPixels += tablePtr->colPixels[i]; } } /* * Work out how much to pad each col depending on the mode. */ diff = w - numPixels - (unpreset * defColWidth); total = 0; /* * Now do the padding and calculate the column starts. * Diff lower than 0 means we can't see the entire set of columns, * thus no special stretching will occur & we optimize the calculation. */ if (diff <= 0) { for (i = 0; i < tablePtr->cols; i++) { if (tablePtr->colPixels[i] == -1) { tablePtr->colPixels[i] = defColWidth; } tablePtr->colStarts[i] = total; total += tablePtr->colPixels[i]; } } else { switch (tablePtr->colStretch) { case STRETCH_MODE_NONE: pad = 0; lastPad = 0; break; case STRETCH_MODE_UNSET: if (unpreset == 0) { pad = 0; lastPad = 0; } else { pad = diff / unpreset; lastPad = diff - pad * (unpreset - 1); } break; case STRETCH_MODE_LAST: pad = 0; lastPad = diff; lastUnpreset = tablePtr->cols - 1; break; default: /* STRETCH_MODE_ALL, but also FILL for cols */ pad = diff / tablePtr->cols; /* force it to be applied to the last column too */ lastUnpreset = tablePtr->cols - 1; lastPad = diff - pad * lastUnpreset; } for (i = 0; i < tablePtr->cols; i++) { if (tablePtr->colPixels[i] == -1) { tablePtr->colPixels[i] = defColWidth + ((i == lastUnpreset) ? lastPad : pad); } else if (tablePtr->colStretch == STRETCH_MODE_ALL) { tablePtr->colPixels[i] += (i == lastUnpreset) ? lastPad : pad; } tablePtr->colStarts[i] = total; total += tablePtr->colPixels[i]; } } tablePtr->colStarts[i] = tablePtr->maxWidth = total; /* * The 'do' loop is only necessary for rows because of FILL mode */ recalc = 0; do { /* Set up the arrays to hold the row pixels and starts */ /* FIX - this can be moved outside 'do' if you check >row size */ if (tablePtr->rowPixels) ckfree((char *) tablePtr->rowPixels); tablePtr->rowPixels = (int *) ckalloc(tablePtr->rows * sizeof(int)); /* get all the preset rows and set their heights */ lastUnpreset = 0; numPixels = 0; unpreset = 0; for (i = 0; i < tablePtr->rows; i++) { entryPtr = Tcl_FindHashEntry(tablePtr->rowHeights, (char *) i); if (entryPtr == NULL) { tablePtr->rowPixels[i] = -1; unpreset++; lastUnpreset = i; } else { value = (int) Tcl_GetHashValue(entryPtr); if (value > 0) { tablePtr->rowPixels[i] = value * tablePtr->charHeight + py; } else { /* * When a value in pixels is specified, we take that exact * amount, not adding in pad or border values. */ tablePtr->rowPixels[i] = -value; } numPixels += tablePtr->rowPixels[i]; } } /* work out how much to pad each row depending on the mode */ diff = h - numPixels - (unpreset * defRowHeight); switch(tablePtr->rowStretch) { case STRETCH_MODE_NONE: pad = 0; lastPad = 0; break; case STRETCH_MODE_UNSET: if (unpreset == 0) { pad = 0; lastPad = 0; } else { pad = MAX(0,diff) / unpreset; lastPad = MAX(0,diff) - pad * (unpreset - 1); } break; case STRETCH_MODE_LAST: pad = 0; lastPad = MAX(0,diff); /* force it to be applied to the last column too */ lastUnpreset = tablePtr->rows - 1; break; case STRETCH_MODE_FILL: pad = 0; lastPad = diff; if (diff && !recalc) { tablePtr->rows += (diff/defRowHeight); if (diff < 0 && tablePtr->rows <= 0) { tablePtr->rows = 1; } lastUnpreset = tablePtr->rows - 1; recalc = 1; continue; } else { lastUnpreset = tablePtr->rows - 1; recalc = 0; } break; default: /* STRETCH_MODE_ALL */ pad = MAX(0,diff) / tablePtr->rows; /* force it to be applied to the last column too */ lastUnpreset = tablePtr->rows - 1; lastPad = MAX(0,diff) - pad * lastUnpreset; } } while (recalc); if (tablePtr->rowStarts) ckfree((char *) tablePtr->rowStarts); tablePtr->rowStarts = (int *) ckalloc((tablePtr->rows+1)*sizeof(int)); /* * Now do the padding and calculate the row starts */ total = 0; for (i = 0; i < tablePtr->rows; i++) { if (tablePtr->rowPixels[i] == -1) { tablePtr->rowPixels[i] = defRowHeight + ((i==lastUnpreset)?lastPad:pad); } else if (tablePtr->rowStretch == STRETCH_MODE_ALL) { tablePtr->rowPixels[i] += (i==lastUnpreset)?lastPad:pad; } /* calculate the start of each row */ tablePtr->rowStarts[i] = total; total += tablePtr->rowPixels[i]; } tablePtr->rowStarts[i] = tablePtr->maxHeight = total; /* * Make sure the top row and col have reasonable real indices */ CONSTRAIN(tablePtr->topRow, tablePtr->titleRows, tablePtr->rows-1); CONSTRAIN(tablePtr->leftCol, tablePtr->titleCols, tablePtr->cols-1); /* * If we don't have the info, don't bother to fix up the other parameters */ if (Tk_WindowId(tablePtr->tkwin) == None) { tablePtr->oldTopRow = tablePtr->oldLeftCol = -1; return; } topRow = tablePtr->topRow; leftCol = tablePtr->leftCol; w += hl; h += hl; /* * If we use this value of topRow, will we fill the window? * if not, decrease it until we will, or until it gets to titleRows * make sure we don't cut off the bottom row */ for (; topRow > tablePtr->titleRows; topRow--) { if ((tablePtr->maxHeight-(tablePtr->rowStarts[topRow-1] - tablePtr->rowStarts[tablePtr->titleRows])) > h) { break; } } /* * If we use this value of topCol, will we fill the window? * if not, decrease it until we will, or until it gets to titleCols * make sure we don't cut off the left column */ for (; leftCol > tablePtr->titleCols; leftCol--) { if ((tablePtr->maxWidth-(tablePtr->colStarts[leftCol-1] - tablePtr->colStarts[tablePtr->titleCols])) > w) { break; } } tablePtr->topRow = topRow; tablePtr->leftCol = leftCol; /* * Now work out where the bottom right is for scrollbar update and to test * for one last stretch. Avoid the confusion that spans could cause for * determining the last cell dimensions. */ tablePtr->flags |= AVOID_SPANS; TableGetLastCell(tablePtr, &row, &col); TableCellVCoords(tablePtr, row, col, &x, &y, &width, &height, 0); tablePtr->flags &= ~AVOID_SPANS; /* * Do we have scrollbars, if so, calculate and call the TCL functions In * order to get the scrollbar to be completely full when the whole screen * is shown and there are titles, we have to arrange for the scrollbar * range to be 0 -> rows-titleRows etc. This leads to the position * setting methods, toprow and leftcol, being relative to the titles, not * absolute row and column numbers. */ if (tablePtr->yScrollCmd != NULL || tablePtr->xScrollCmd != NULL) { Tcl_Interp *interp = tablePtr->interp; char buf[INDEX_BUFSIZE]; double first, last; /* * We must hold onto the interpreter because the data referred to at * tablePtr might be freed as a result of the call to Tcl_VarEval. */ Tcl_Preserve((ClientData) interp); /* Do we have a Y-scrollbar and rows to scroll? */ if (tablePtr->yScrollCmd != NULL) { if (row < tablePtr->titleRows) { first = 0; last = 1; } else { diff = tablePtr->rowStarts[tablePtr->titleRows]; last = (double) (tablePtr->rowStarts[tablePtr->rows]-diff); if (last <= 0.0) { first = 0; last = 1; } else { first = (tablePtr->rowStarts[topRow]-diff) / last; last = (height+tablePtr->rowStarts[row]-diff) / last; } } if ( LangDoCallback(interp,tablePtr->yScrollCmd, 0,2, " %g %g", first, last) != TCL_OK) { Tcl_AddErrorInfo(interp, "\n\t(vertical scrolling command executed by table)"); Tcl_BackgroundError(interp); } } /* Do we have a X-scrollbar and cols to scroll? */ if (tablePtr->xScrollCmd != NULL) { if (col < tablePtr->titleCols) { first = 0; last = 1; } else { diff = tablePtr->colStarts[tablePtr->titleCols]; last = (double) (tablePtr->colStarts[tablePtr->cols]-diff); if (last <= 0.0) { first = 0; last = 1; } else { first = (tablePtr->colStarts[leftCol]-diff) / last; last = (width+tablePtr->colStarts[col]-diff) / last; } } if ( LangDoCallback(interp,tablePtr->xScrollCmd, 0,2, " %g %g", first, last) != TCL_OK) { Tcl_AddErrorInfo(interp, "\n\t(horizontal scrolling command executed by table)"); Tcl_BackgroundError(interp); } } Tcl_Release((ClientData) interp); } /* * Adjust the last row/col to fill empty space if it is visible. * Do this after setting the scrollbars to not upset its calculations. */ if (row == tablePtr->rows-1 && tablePtr->rowStretch != STRETCH_MODE_NONE) { diff = h-(y+height); if (diff > 0) { tablePtr->rowPixels[tablePtr->rows-1] += diff; tablePtr->rowStarts[tablePtr->rows] += diff; } } if (col == tablePtr->cols-1 && tablePtr->colStretch != STRETCH_MODE_NONE) { diff = w-(x+width); if (diff > 0) { tablePtr->colPixels[tablePtr->cols-1] += diff; tablePtr->colStarts[tablePtr->cols] += diff; } } TableAdjustActive(tablePtr); /* * now check the new value of topleft cell against the originals, * If they changed, invalidate the area, else leave it alone */ if (tablePtr->topRow != tablePtr->oldTopRow || tablePtr->leftCol != tablePtr->oldLeftCol) { /* set the old top row/col for the next time this function is called */ tablePtr->oldTopRow = tablePtr->topRow; tablePtr->oldLeftCol = tablePtr->leftCol; /* only the upper corner title cells wouldn't change */ TableInvalidateAll(tablePtr, 0); } } /* *---------------------------------------------------------------------- * * TableCursorEvent -- * Toggle the cursor status. Equivalent to EntryBlinkProc. * * Results: * None. * * Side effects: * The cursor will be switched off/on. * *---------------------------------------------------------------------- */ static void TableCursorEvent(ClientData clientData) { register Table *tablePtr = (Table *) clientData; if (!(tablePtr->flags & HAS_FOCUS) || (tablePtr->insertOffTime == 0) || (tablePtr->flags & ACTIVE_DISABLED) || (tablePtr->state != STATE_NORMAL)) { return; } if (tablePtr->cursorTimer != NULL) { Tcl_DeleteTimerHandler(tablePtr->cursorTimer); } tablePtr->cursorTimer = Tcl_CreateTimerHandler((tablePtr->flags & CURSOR_ON) ? tablePtr->insertOffTime : tablePtr->insertOnTime, TableCursorEvent, (ClientData) tablePtr); /* Toggle the cursor */ tablePtr->flags ^= CURSOR_ON; /* invalidate the cell */ TableRefresh(tablePtr, tablePtr->activeRow, tablePtr->activeCol, CELL); } /* *---------------------------------------------------------------------- * * TableConfigCursor -- * Configures the timer depending on the state of the table. * Equivalent to EntryFocusProc. * * Results: * None. * * Side effects: * The cursor will be switched off/on. * *---------------------------------------------------------------------- */ void TableConfigCursor(register Table *tablePtr) { /* * To have a cursor, we have to have focus and allow edits */ if ((tablePtr->flags & HAS_FOCUS) && (tablePtr->state == STATE_NORMAL) && !(tablePtr->flags & ACTIVE_DISABLED)) { /* * Turn the cursor ON */ if (!(tablePtr->flags & CURSOR_ON)) { tablePtr->flags |= CURSOR_ON; /* * Only refresh when we toggled cursor */ TableRefresh(tablePtr, tablePtr->activeRow, tablePtr->activeCol, CELL); } /* set up the first timer */ if (tablePtr->insertOffTime != 0) { /* make sure nothing existed */ Tcl_DeleteTimerHandler(tablePtr->cursorTimer); tablePtr->cursorTimer = Tcl_CreateTimerHandler(tablePtr->insertOnTime, TableCursorEvent, (ClientData) tablePtr); } } else { /* * Turn the cursor OFF */ if ((tablePtr->flags & CURSOR_ON)) { tablePtr->flags &= ~CURSOR_ON; TableRefresh(tablePtr, tablePtr->activeRow, tablePtr->activeCol, CELL); } /* and disable the timer */ if (tablePtr->cursorTimer != NULL) { Tcl_DeleteTimerHandler(tablePtr->cursorTimer); } tablePtr->cursorTimer = NULL; } } /* *---------------------------------------------------------------------- * * TableFetchSelection -- * This procedure is called back by Tk when the selection is * requested by someone. It returns part or all of the selection * in a buffer provided by the caller. * * Results: * The return value is the number of non-NULL bytes stored * at buffer. Buffer is filled (or partially filled) with a * NULL-terminated string containing part or all of the selection, * as given by offset and maxBytes. * * Side effects: * None. * *---------------------------------------------------------------------- */ static int SelectionFetched = 0; /* Flag = 1 if a selection has been fetched before */ static int TableFetchSelection(clientData, offset, buffer, maxBytes) ClientData clientData; /* Information about table widget. */ int offset; /* Offset within selection of first * character to be returned. */ char *buffer; /* Location in which to place selection. */ int maxBytes; /* Maximum number of bytes to place at buffer, * not including terminating NULL. */ { register Table *tablePtr = (Table *) clientData; Tcl_Interp *interp = tablePtr->interp; char *data, *rowsep = tablePtr->rowSep, *colsep = tablePtr->colSep; /* We keep a static selection around so we don't have to remake the selection if we are getting the selection in chunks (i.e. offset != 0) */ static Tcl_DString selection; Tcl_HashEntry *entryPtr; Tcl_HashSearch search; int length, count, lastrow=0, needcs=0, r, c, listArgc, rslen=0, cslen=0; int numcols, numrows; Arg *listArgv; Arg value; /* if we are not exporting the selection || * we have no data source, return */ if (!tablePtr->exportSelection || (tablePtr->dataSource == DATA_NONE)) { return -1; } if( offset == 0){ /* First Time thru, get the selection, otherwise, just use the selection obtained before */ Tk_Cursor existingCursor; existingCursor = tablePtr->cursor; /* Set Cursor to wait, becuase this can take some time for large selections */ /* tablePtr->cursor = Tk_GetCursor(interp, tablePtr->tkwin, LangStringArg("watch")); */ Tk_DefineCursor(tablePtr->tkwin, Tk_AllocCursorFromObj(interp, tablePtr->tkwin, LangStringArg("watch"))); Tcl_DoOneEvent(TCL_DONT_WAIT); if( SelectionFetched){ /* If we have fetched a selection before, free it */ Tcl_DStringFree(&selection); } SelectionFetched = 1; /* First get a sorted list of the selected elements */ Tcl_DStringInit(&selection); for (entryPtr = Tcl_FirstHashEntry(tablePtr->selCells, &search); entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { Tcl_DStringAppendElement(&selection, Tcl_GetHashKey(tablePtr->selCells, entryPtr)); } value = TableCellSort(tablePtr, Tcl_DStringValue(&selection)); Tcl_DStringFree(&selection); if (value == NULL || Tcl_ListObjGetElements(interp, value, &listArgc, &listArgv) != TCL_OK) { Tk_DefineCursor(tablePtr->tkwin, existingCursor); /* Set Cursor Back */ return -1; } Tcl_DStringInit(&selection); rslen = (rowsep?(strlen(rowsep)):0); cslen = (colsep?(strlen(colsep)):0); numrows = numcols = 0; for (count = 0; count < listArgc; count++) { TableParseArrayIndex(&r, &c, Tcl_GetString(listArgv[count])); if (count) { if (lastrow != r) { lastrow = r; needcs = 0; if (rslen) { Tcl_DStringAppend(&selection, rowsep, rslen); /* perltk: Temporarily?? commented out, don't have a Tcl_DtringStartSublist } else { Tcl_DStringEndSublist(&selection); Tcl_DStringStartSublist(&selection); */ } ++numrows; } else { if (++needcs > numcols) numcols = needcs; } } else { lastrow = r; needcs = 0; /* perltk: Temporarily?? commented out, don't have a Tcl_DtringStartSublist if (!rslen) Tcl_DStringStartSublist(&selection); */ } data = TableGetCellValue(tablePtr, r, c); if (cslen) { if (needcs) { Tcl_DStringAppend(&selection, colsep, cslen); } Tcl_DStringAppend(&selection, data, -1); } else { Tcl_DStringAppendElement(&selection, data); } } /* perltk: Temporarily?? commented out, don't have a Tcl_DtringStartSublist if (!rslen && count) { Tcl_DStringEndSublist(&selection); } */ if (tablePtr->selCmd != NULL) { if ( LangDoCallback(interp, tablePtr->selCmd, 1, 4, "%d %d %s %d", numrows+1, numcols+1, Tcl_DStringValue(&selection), listArgc) == TCL_ERROR) { Tcl_AddErrorInfo(interp, "\n (error in table selection command)"); Tcl_BackgroundError(interp); Tk_DefineCursor(tablePtr->tkwin, existingCursor); /* Set Cursor Back */ Tcl_DStringFree(&selection); return -1; } else { Tcl_DStringFree(&selection); Tcl_DStringInit(&selection); Tcl_DStringAppendElement(&selection, Tcl_GetStringFromObj(Tcl_GetObjResult(interp),NULL)); } } Tk_DefineCursor(tablePtr->tkwin, existingCursor); /* Set Cursor Back */ } length = Tcl_DStringLength(&selection); if (length == 0){ return -1; } /* Copy the requested portion of the selection to the buffer. */ count = length - offset; if (count <= 0) { count = 0; } else { if (count > maxBytes) { count = maxBytes; } memcpy((VOID *) buffer, (VOID *) (Tcl_DStringValue(&selection) + offset), (size_t) count); } buffer[count] = '\0'; return count; } /* *---------------------------------------------------------------------- * * TableLostSelection -- * This procedure is called back by Tk when the selection is * grabbed away from a table widget. * * Results: * None. * * Side effects: * The existing selection is unhighlighted, and the window is * marked as not containing a selection. * *---------------------------------------------------------------------- */ void TableLostSelection(clientData) ClientData clientData; /* Information about table widget. */ { register Table *tablePtr = (Table *) clientData; if (tablePtr->exportSelection) { Tcl_HashEntry *entryPtr; Tcl_HashSearch search; int row, col; /* Same as SEL CLEAR ALL */ for (entryPtr = Tcl_FirstHashEntry(tablePtr->selCells, &search); entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { TableParseArrayIndex(&row, &col, Tcl_GetHashKey(tablePtr->selCells,entryPtr)); Tcl_DeleteHashEntry(entryPtr); TableRefresh(tablePtr, row-tablePtr->rowOffset, col-tablePtr->colOffset, CELL); } } } /* *---------------------------------------------------------------------- * * TableRestrictProc -- * A Tk_RestrictProc used by TableValidateChange to eliminate any * extra key input events in the event queue that * have a serial number no less than a given value. * * Results: * Returns either TK_DISCARD_EVENT or TK_DEFER_EVENT. * * Side effects: * None. * *---------------------------------------------------------------------- */ static Tk_RestrictAction TableRestrictProc(serial, eventPtr) ClientData serial; XEvent *eventPtr; { if ((eventPtr->type == KeyRelease || eventPtr->type == KeyPress) && ((eventPtr->xany.serial-(unsigned int)serial) > 0)) { return TK_DEFER_EVENT; } else { return TK_PROCESS_EVENT; } } /* *-------------------------------------------------------------- * * TableValidateChange -- * This procedure is invoked when any character is added or * removed from the table widget, or a set has triggered validation. * * Results: * TCL_OK if the validatecommand accepts the new string, * TCL_BREAK if the validatecommand rejects the new string, * TCL_ERROR if any problems occured with validatecommand. * * Side effects: * The insertion/deletion may be aborted, and the * validatecommand might turn itself off (if an error * or loop condition arises). * *-------------------------------------------------------------- */ int TableValidateChange(tablePtr, r, c, old, new, index) register Table *tablePtr; /* Table that needs validation. */ int r, c; /* row,col index of cell in user coords */ char *old; /* current value of cell */ char *new; /* potential new value of cell */ int index; /* index of insert/delete, -1 otherwise */ { register Tcl_Interp *interp = tablePtr->interp; int code, booln; /* perltk: Bool to booln to avoid problems with DEFINES*/ Tk_RestrictProc *rstrct; ClientData cdata; if (tablePtr->valCmd == NULL || tablePtr->validate == 0) { return TCL_OK; } /* Magic code to make this bit of code UI synchronous in the face of * possible new key events */ XSync(tablePtr->display, False); rstrct = Tk_RestrictEvents(TableRestrictProc, (ClientData) NextRequest(tablePtr->display), &cdata); /* * If we're already validating, then we're hitting a loop condition * Return and set validate to 0 to disallow further validations * and prevent current validation from finishing */ if (tablePtr->flags & VALIDATING) { tablePtr->validate = 0; return TCL_OK; } tablePtr->flags |= VALIDATING; code = LangDoCallback(tablePtr->interp, tablePtr->valCmd, 1, 5, "%d %d %s %s %d", r, c, old, new, index); if (code != TCL_OK && code != TCL_RETURN) { Tcl_AddErrorInfo(interp, "\n\t(in validation command executed by table)"); Tcl_BackgroundError(interp); code = TCL_ERROR; } else if (Tcl_GetBooleanFromObj(interp, Tcl_GetObjResult(interp), &booln) != TCL_OK) { Tcl_AddErrorInfo(interp, "\n\tboolean not returned by validation command"); Tcl_BackgroundError(interp); code = TCL_ERROR; } else { code = (booln) ? TCL_OK : TCL_BREAK; } Tcl_SetStringObj(Tcl_GetObjResult(interp), (char *) NULL, 0); /* * If ->validate has become VALIDATE_NONE during the validation, * it means that a loop condition almost occured. Do not allow * this validation result to finish. */ if (tablePtr->validate == 0) { code = TCL_ERROR; } /* If validate will return ERROR, then disallow further validations */ if (code == TCL_ERROR) { tablePtr->validate = 0; } Tk_RestrictEvents(rstrct, cdata, &cdata); tablePtr->flags &= ~VALIDATING; return code; } /* *-------------------------------------------------------------- * * ExpandPercents -- * Given a command and an event, produce a new command * by replacing % constructs in the original command * with information from the X event. * * Results: * The new expanded command is appended to the dynamic string * given by dsPtr. * * Side effects: * None. * *-------------------------------------------------------------- */ void ExpandPercents(tablePtr, before, r, c, old, new, index, dsPtr, cmdType) Table *tablePtr; /* Table that needs validation. */ char *before; /* Command containing percent * expressions to be replaced. */ int r, c; /* row,col index of cell */ char *old; /* current value of cell */ char *new; /* potential new value of cell */ int index; /* index of insert/delete */ Tcl_DString *dsPtr; /* Dynamic string in which to append * new command. */ int cmdType; /* type of command to make %-subs for */ { int length, spaceNeeded, cvtFlags; #ifdef TCL_UTF_MAX Tcl_UniChar ch; #else char ch; #endif char *string, buf[INDEX_BUFSIZE]; /* This returns the static value of the string as set in the array */ if (old == NULL && cmdType == CMD_VALIDATE) { old = TableGetCellValue(tablePtr, r, c); } while (1) { if (*before == '\0') { break; } /* * Find everything up to the next % character and append it * to the result string. */ string = before; #ifndef _LANG /* No need to convert '%', as it is in ascii range */ string = (char *) Tcl_UtfFindFirst(before, '%'); #else string = strchr(before, '%'); #endif if (string == (char *) NULL) { Tcl_DStringAppend(dsPtr, before, -1); break; } else if (string != before) { Tcl_DStringAppend(dsPtr, before, string-before); before = string; } /* * There's a percent sequence here. Process it. */ before++; /* skip over % */ if (*before != '\0') { #ifdef TCL_UTF_MAX before += Tcl_UtfToUniChar(before, &ch); #else ch = before[0]; before++; #endif } else { ch = '%'; } switch (ch) { case 'c': sprintf(buf, "%d", c); string = buf; break; case 'C': /* index of cell */ TableMakeArrayIndex(r, c, buf); string = buf; break; case 'r': sprintf(buf, "%d", r); string = buf; break; case 'i': /* index of cursor OR |number| of cells selected */ sprintf(buf, "%d", index); string = buf; break; case 's': /* Current cell value */ string = old; break; case 'S': /* Potential new value of cell */ string = (new?new:old); break; case 'W': /* widget name */ string = Tk_PathName(tablePtr->tkwin); break; default: #ifdef TCL_UTF_MAX length = Tcl_UniCharToUtf(ch, buf); #else buf[0] = ch; length = 1; #endif buf[length] = '\0'; string = buf; break; } /* perltk not supported */ /* spaceNeeded = Tcl_ScanElement(string, &cvtFlags); */ spaceNeeded = 0; length = Tcl_DStringLength(dsPtr); Tcl_DStringSetLength(dsPtr, length + spaceNeeded); /* perltk not supported */ /* spaceNeeded = Tcl_ConvertElement(string, Tcl_DStringValue(dsPtr) + length, cvtFlags | TCL_DONT_USE_BRACES); */ Tcl_DStringSetLength(dsPtr, length + spaceNeeded); } Tcl_DStringAppend(dsPtr, "", 1); } /* Function to call on loading the Table module */ #ifdef BUILD_Tktable # undef TCL_STORAGE_CLASS # define TCL_STORAGE_CLASS DLLEXPORT #endif #ifdef MAC_TCL #pragma export on #endif #if 0 /* perltk This not needed by perlTk */ EXTERN int Tktable_Init(interp) Tcl_Interp *interp; { /* This defines the static char initScript */ if ( #ifdef USE_TCL_STUBS Tcl_InitStubs(interp, "8.0", 0) #else Tcl_PkgRequire(interp, "Tcl", "8.0", 0) #endif == NULL) { return TCL_ERROR; } if ( #ifdef USE_TK_STUBS Tk_InitStubs(interp, "8.0", 0) #else # if (TK_MAJOR_VERSION == 8) && (TK_MINOR_VERSION == 0) /* We require 8.0 exact because of the Unicode in 8.1+ */ Tcl_PkgRequire(interp, "Tk", "8.0", 1) # else Tcl_PkgRequire(interp, "Tk", "8.0", 0) # endif #endif == NULL) { return TCL_ERROR; } if (Tcl_PkgProvide(interp, "Tktable", VERSION) != TCL_OK) { return TCL_ERROR; } Tcl_CreateObjCommand(interp, TBL_COMMAND, Tk_TableObjCmd, (ClientData) Tk_MainWindow(interp), (Tcl_CmdDeleteProc *) NULL); /* * The init script can't make certain calls in a safe interpreter, * so we always have to use the embedded runtime for it */ return Tcl_Eval(interp, Tcl_IsSafe(interp) ? tkTableSafeInitScript : tkTableInitScript); } EXTERN int Tktable_SafeInit(interp) Tcl_Interp *interp; { return Tktable_Init(interp); } #ifdef MAC_TCL #pragma export reset #endif #endif /* ifdef 0 */ #ifdef WIN32 /* *---------------------------------------------------------------------- * * DllEntryPoint -- * * This wrapper function is used by Windows to invoke the * initialization code for the DLL. If we are compiling * with Visual C++, this routine will be renamed to DllMain. * routine. * * Results: * Returns TRUE; * * Side effects: * None. * *---------------------------------------------------------------------- */ BOOL APIENTRY DllEntryPoint(hInst, reason, reserved) HINSTANCE hInst; /* Library instance handle. */ DWORD reason; /* Reason this function is being called. */ LPVOID reserved; /* Not used. */ { return TRUE; } #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable/tkTable.h�������������������������������������������������������0000644�0000000�0000000�00000063105�13745605157�017370� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * tkTable.h -- * * This is the header file for the module that implements * table widgets for the Tk toolkit. * * Copyright (c) 1997-2002 Jeffrey Hobbs * * See the file "license.txt" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tkTable.h,v 1.18 2004/02/08 03:09:45 cerney Exp $ */ #ifndef _TKTABLE_H_ #define _TKTABLE_H_ #include <string.h> #include <stdlib.h> #include <tk.h> #include "tkVMacro.h" #include "tkTableversion.h" #ifdef MAC_TCL # include <Xatom.h> #else # include <X11/Xatom.h> #endif /* MAC_TCL */ #if (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION == 0) /* Tcl8.0 stuff */ #define Tcl_GetString(objPtr) Tcl_GetStringFromObj(objPtr, (int *)NULL) #endif #define Arg Tcl_Obj* /* * Tcl/Tk 8.4 introduced better CONST-ness in the APIs, but we use CONST84 in * some cases for compatibility with earlier Tcl headers to prevent warnings. */ #ifndef CONST84 # define CONST84 #endif /* This EXTERN declaration is needed for Tcl < 8.0.3 */ #ifndef EXTERN # ifdef __cplusplus # define EXTERN extern "C" # else # define EXTERN extern # endif #endif #ifdef TCL_STORAGE_CLASS # undef TCL_STORAGE_CLASS #endif #ifdef BUILD_Tktable # define TCL_STORAGE_CLASS DLLEXPORT #else # define TCL_STORAGE_CLASS DLLIMPORT #endif #ifdef WIN32 # define WIN32_LEAN_AND_MEAN # include <windows.h> # undef WIN32_LEAN_AND_MEAN /* VC++ has an entry point called DllMain instead of DllEntryPoint */ # if defined(_MSC_VER) # define DllEntryPoint DllMain # endif #endif #if defined(WIN32) || defined(MAC_TCL) || defined(MAC_OSX_TK) /* XSync call defined in the internals for some reason */ # ifndef XSync # define XSync(display, bool) {display->request++;} # endif #endif /* defn of XSync */ #ifndef NORMAL_BG # ifdef WIN32 # define NORMAL_BG "SystemButtonFace" # define ACTIVE_BG NORMAL_BG # define SELECT_BG "SystemHighlight" # define SELECT_FG "SystemHighlightText" # define DISABLED "SystemDisabledText" # define HIGHLIGHT "SystemWindowFrame" # define DEF_TABLE_FONT "{MS Sans Serif} 8" # elif defined(MAC_TCL) || defined(MAC_OSX_TK) # define NORMAL_BG "systemWindowBody" # define ACTIVE_BG "#ececec" # define SELECT_BG "systemHighlight" # define SELECT_FG "systemHighlightText" # define DISABLED "#a3a3a3" # define HIGHLIGHT "Black" # define DEF_TABLE_FONT "Helvetica 12" # else # define NORMAL_BG "#d9d9d9" # define ACTIVE_BG "#fcfcfc" # define SELECT_BG "#c3c3c3" # define SELECT_FG "Black" # define DISABLED "#a3a3a3" # define HIGHLIGHT "Black" # define DEF_TABLE_FONT "Helvetica -12" # endif #endif /* NORMAL_BG */ #define MAX(A,B) (((A)>(B))?(A):(B)) #define MIN(A,B) (((A)>(B))?(B):(A)) #define BETWEEN(val,min,max) ( ((val)<(min)) ? (min) : \ ( ((val)>(max)) ? (max) : (val) ) ) #define CONSTRAIN(val,min,max) if ((val) < (min)) { (val) = (min); } \ else if ((val) > (max)) { (val) = (max); } #define STREQ(s1, s2) (strcmp((s1), (s2)) == 0) #define ARSIZE(A) (sizeof(A)/sizeof(*A)) #define INDEX_BUFSIZE 32 /* max size of buffer for indices */ #define TEST_KEY "#TEST KEY#" /* index for testing array existence */ /* * Assigned bits of "flags" fields of Table structures, and what those * bits mean: * * REDRAW_PENDING: Non-zero means a DoWhenIdle handler has * already been queued to redisplay the table. * REDRAW_BORDER: Non-zero means 3-D border must be redrawn * around window during redisplay. Normally * only text portion needs to be redrawn. * CURSOR_ON: Non-zero means insert cursor is displayed at * present. 0 means it isn't displayed. * TEXT_CHANGED: Non-zero means the active cell text is being edited. * HAS_FOCUS: Non-zero means this window has the input focus. * HAS_ACTIVE: Non-zero means the active cell is set. * HAS_ANCHOR: Non-zero means the anchor cell is set. * BROWSE_CMD: Non-zero means we're evaluating the -browsecommand. * VALIDATING: Non-zero means we are in a valCmd * SET_ACTIVE: About to set the active array element internally * ACTIVE_DISABLED: Non-zero means the active cell is -state disabled * OVER_BORDER: Non-zero means we are over a table cell border * REDRAW_ON_MAP: Forces a redraw on the unmap * AVOID_SPANS: prevent cell spans from being used * * FIX - consider adding UPDATE_SCROLLBAR a la entry */ #define REDRAW_PENDING (1L<<0) #define CURSOR_ON (1L<<1) #define HAS_FOCUS (1L<<2) #define TEXT_CHANGED (1L<<3) #define HAS_ACTIVE (1L<<4) #define HAS_ANCHOR (1L<<5) #define BROWSE_CMD (1L<<6) #define REDRAW_BORDER (1L<<7) #define VALIDATING (1L<<8) #define SET_ACTIVE (1L<<9) #define ACTIVE_DISABLED (1L<<10) #define OVER_BORDER (1L<<11) #define REDRAW_ON_MAP (1L<<12) #define AVOID_SPANS (1L<<13) /* Flags for TableInvalidate && TableRedraw */ #define ROW (1L<<0) #define COL (1L<<1) #define CELL (1L<<2) #define CELL_BAD (1<<0) #define CELL_OK (1<<1) #define CELL_SPAN (1<<2) #define CELL_HIDDEN (1<<3) #define CELL_VIEWABLE (CELL_OK|CELL_SPAN) #define INV_FILL (1L<<3) /* use for Redraw when the affected * row/col will affect neighbors */ #define INV_FORCE (1L<<4) #define INV_HIGHLIGHT (1L<<5) #define INV_NO_ERR_MSG (1L<<5) /* Don't leave an error message */ /* These alter how the selection set/clear commands behave */ #define SEL_ROW (1<<0) #define SEL_COL (1<<1) #define SEL_BOTH (1<<2) #define SEL_CELL (1<<3) #define SEL_NONE (1<<4) /* * Definitions for tablePtr->dataSource, by bit */ #define DATA_NONE 0 #define DATA_CACHE (1<<1) #define DATA_ARRAY (1<<2) #define DATA_COMMAND (1<<3) /* * Definitions for configuring -borderwidth */ #define BD_TABLE 0 #define BD_TABLE_TAG (1<<1) #define BD_TABLE_WIN (1<<2) /* * Possible state values for tags */ typedef enum { STATE_UNUSED, STATE_UNKNOWN, STATE_HIDDEN, STATE_NORMAL, STATE_DISABLED, STATE_ACTIVE, STATE_LAST } TableState; /* * Structure for use in parsing table commands/values. * Accessor functions defined in tkTableUtil.c */ typedef struct { char *name; /* name of the command/value */ int value; /* >0 because 0 represents an error or proc */ } Cmd_Struct; /* * The tag structure */ typedef struct { Tk_3DBorder bg; /* background color */ Tk_3DBorder fg; /* foreground color */ char * borderStr; /* border style */ int borders; /* number of borders specified (1, 2 or 4) */ int bd[4]; /* cell border width */ int relief; /* relief type */ Tk_Font tkfont; /* Information about text font, or NULL. */ Tk_Anchor anchor; /* default anchor point */ char * imageStr; /* name of image */ Tk_Image image; /* actual pointer to image, if any */ TableState state; /* state of the cell */ Tk_Justify justify; /* justification of text in the cell */ int multiline; /* wrapping style of multiline text */ int wrap; /* wrapping style of multiline text */ int showtext; /* whether to display text over image */ } TableTag; /* The widget structure for the table Widget */ typedef struct { /* basic information about the window and the interpreter */ Tk_Window tkwin; Display *display; Tcl_Interp *interp; Tcl_Command widgetCmd; /* Token for entry's widget command. */ /* * Configurable Options */ int autoClear; char *selectMode; /* single, browse, multiple, or extended */ int selectType; /* row, col, both, or cell */ int selectTitles; /* whether to do automatic title selection */ int rows, cols; /* number of rows and columns */ int defRowHeight; /* default row height in chars (positive) * or pixels (negative) */ int defColWidth; /* default column width in chars (positive) * or pixels (negative) */ int maxReqCols; /* the requested # cols to display */ int maxReqRows; /* the requested # rows to display */ int maxReqWidth; /* the maximum requested width in pixels */ int maxReqHeight; /* the maximum requested height in pixels */ Var arrayVar; /* name of traced array variable */ char *rowSep; /* separator string to place between * rows when getting selection */ char *colSep; /* separator string to place between * cols when getting selection */ TableTag defaultTag; /* the default tag colors/fonts etc */ LangCallback *yScrollCmd; /* the y-scroll command */ LangCallback *xScrollCmd; /* the x-scroll command */ LangCallback *browseCmd; /* the command that is called when the * active cell changes */ int caching; /* whether to cache values of table */ LangCallback *command; /* A command to eval when get/set occurs * for table values */ int useCmd; /* Signals whether to use command or the * array variable, will be 0 if command errs */ LangCallback *selCmd; /* the command that is called to when a * [selection get] call occurs for a table */ LangCallback *valCmd; /* Command prefix to use when invoking * validate command. NULL means don't * invoke commands. Malloc'ed. */ int validate; /* Non-zero means try to validate */ Tk_3DBorder insertBg; /* the cursor color */ Tk_Cursor cursor; /* the regular mouse pointer */ Tk_Cursor bdcursor; /* the mouse pointer when over borders */ #ifdef TITLE_CURSOR Tk_Cursor titleCursor; /* the mouse pointer when over titles */ #endif int exportSelection; /* Non-zero means tie internal table * to X selection. */ TableState state; /* Normal or disabled. Table is read-only * when disabled. */ int insertWidth; /* Total width of insert cursor. */ int insertBorderWidth; /* Width of 3-D border around insert cursor. */ int insertOnTime; /* Number of milliseconds cursor should spend * in "on" state for each blink. */ int insertOffTime; /* Number of milliseconds cursor should spend * in "off" state for each blink. */ int invertSelected; /* Whether to draw selected cells swapping * foreground and background */ int colStretch; /* The way to stretch columns if the window * is too large */ int rowStretch; /* The way to stretch rows if the window is * too large */ int colOffset; /* X index of leftmost col in the display */ int rowOffset; /* Y index of topmost row in the display */ int drawMode; /* The mode to use when redrawing */ int flashMode; /* Specifies whether flashing is enabled */ int flashTime; /* The number of ms to flash a cell for */ int resize; /* -resizeborders option for interactive * resizing of borders */ int sparse; /* Whether to use "sparse" arrays by * deleting empty array elements (default) */ LangCallback *rowTagCmd, *colTagCmd; /* script to eval for getting row/tag cmd */ int highlightWidth; /* Width in pixels of highlight to draw * around widget when it has the focus. * <= 0 means don't draw a highlight. */ XColor *highlightBgColorPtr;/* Color for drawing traversal highlight * area when highlight is off. */ XColor *highlightColorPtr; /* Color for drawing traversal highlight. */ char *takeFocus; /* Used only in Tcl to check if this * widget will accept focus */ int padX, padY; /* Extra space around text (pixels to leave * on each side). Ignored for bitmaps and * images. */ int ipadX, ipadY; /* Space to leave empty around cell borders. * This differs from pad* in that it is always * present for the cell (except windows). */ /* * Cached Information */ #ifdef TITLE_CURSOR Tk_Cursor *lastCursorPtr; /* pointer to last cursor defined. */ #endif int titleRows, titleCols; /* the number of rows|cols to use as a title */ /* these are kept in real coords */ int topRow, leftCol; /* The topleft cell to display excluding the * fixed title rows. This is just the * config request. The actual cell used may * be different to keep the screen full */ int anchorRow, anchorCol; /* the row,col of the anchor cell */ int activeRow, activeCol; /* the row,col of the active cell */ int oldTopRow, oldLeftCol; /* cached by TableAdjustParams */ int oldActRow, oldActCol; /* cached by TableAdjustParams */ int icursor; /* The index of the insertion cursor in the * active cell */ int flags; /* An or'ed combination of flags concerning * redraw/cursor etc. */ int dataSource; /* where our data comes from: * DATA_{NONE,CACHE,ARRAY,COMMAND} */ int maxWidth, maxHeight; /* max width|height required in pixels */ int charWidth, charHeight; /* size of a character in the default font */ int *colPixels, *rowPixels; /* Array of the pixel widths/heights */ int *colStarts, *rowStarts; /* Array of start pixels for rows|columns */ int scanMarkX, scanMarkY; /* Used by "scan" and "border" to mark */ int scanMarkRow, scanMarkCol;/* necessary information for dragto */ /* values in these are kept in user coords */ Tcl_HashTable *cache; /* value cache */ /* * colWidths and rowHeights are indexed from 0, so always adjust numbers * by the appropriate *Offset factor */ Tcl_HashTable *colWidths; /* hash table of non default column widths */ Tcl_HashTable *rowHeights; /* hash table of non default row heights */ Tcl_HashTable *spanTbl; /* table for spans */ Tcl_HashTable *spanAffTbl; /* table for cells affected by spans */ Tcl_HashTable *tagTable; /* table for style tags */ Tcl_HashTable *winTable; /* table for embedded windows */ Tcl_HashTable *rowStyles; /* table for row styles */ Tcl_HashTable *colStyles; /* table for col styles */ Tcl_HashTable *cellStyles; /* table for cell styles */ Tcl_HashTable *flashCells; /* table of flashing cells */ Tcl_HashTable *selCells; /* table of selected cells */ Tcl_TimerToken cursorTimer; /* timer token for the cursor blinking */ Tcl_TimerToken flashTimer; /* timer token for the cell flashing */ char *activeBuf; /* buffer where the selection is kept * for editing the active cell */ char **tagPrioNames; /* list of tag names in priority order */ TableTag **tagPrios; /* list of tag pointers in priority order */ TableTag *activeTagPtr; /* cache of active composite tag */ int activeX, activeY; /* cache offset of active layout in cell */ int tagPrioSize; /* size of tagPrios list */ int tagPrioMax; /* max allocated size of tagPrios list */ /* The invalid rectangle if there is an update pending */ int invalidX, invalidY, invalidWidth, invalidHeight; int seen[4]; /* see TableUndisplay */ #ifdef POSTSCRIPT /* Pointer to information used for generating Postscript for the canvas. * NULL means no Postscript is currently being generated. */ struct TkPostscriptInfo *psInfoPtr; #endif #ifdef PROCS Tcl_HashTable *inProc; /* cells where proc is being evaled */ int showProcs; /* whether to show embedded proc (1) or * its calculated value (0) */ int hasProcs; /* whether table has embedded procs or not */ #endif } Table; /* * HEADERS FOR EMBEDDED WINDOWS */ /* * A structure of the following type holds information for each window * embedded in a table widget. */ typedef struct TableEmbWindow { Table *tablePtr; /* Information about the overall table * widget. */ Tk_Window tkwin; /* Window for this segment. NULL means that * the window hasn't been created yet. */ Tcl_HashEntry *hPtr; /* entry into winTable */ LangCallback *create; /* Script to create window on-demand. * NULL means no such script. * Malloc-ed. */ Tk_3DBorder bg; /* background color */ char *borderStr; /* border style */ int borders; /* number of borders specified (1, 2 or 4) */ int bd[4]; /* border width for cell around window */ int relief; /* relief type */ int sticky; /* How to align window in space */ int padX, padY; /* Padding to leave around each side * of window, in pixels. */ int displayed; /* Non-zero means that the window has been * displayed on the screen recently. */ } TableEmbWindow; extern Tk_ConfigSpec tableSpecs[]; extern void EmbWinDisplay _ANSI_ARGS_((Table *tablePtr, Drawable window, TableEmbWindow *ewPtr, TableTag *tagPtr, int x, int y, int width, int height)); extern void EmbWinUnmap _ANSI_ARGS_((register Table *tablePtr, int rlo, int rhi, int clo, int chi)); extern void EmbWinDelete _ANSI_ARGS_((register Table *tablePtr, TableEmbWindow *ewPtr)); extern int Table_WinMove _ANSI_ARGS_((register Table *tablePtr, char *CONST srcPtr, char *CONST destPtr, int flags)); extern int Table_WinDelete _ANSI_ARGS_((register Table *tablePtr, char *CONST idxPtr)); extern int Table_WindowCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int TableValidateChange _ANSI_ARGS_((Table *tablePtr, int r, int c, char *oldVal, char *newVal, int idx)); extern void TableLostSelection _ANSI_ARGS_((ClientData clientData)); extern void TableSetActiveIndex _ANSI_ARGS_((register Table *tablePtr)); /* * HEADERS IN tkTableCmds.c */ extern int Table_ActivateCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_AdjustCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], int widthType)); extern int Table_BboxCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_BorderCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_ClearCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_CurselectionCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_CurvalueCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_GetCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_ScanCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_SeeCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_SelAnchorCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_SelClearCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_SelIncludesCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_SelSetCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_ViewCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); /* * HEADERS IN tkTableEdit.c */ extern int Table_EditCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern void TableDeleteChars _ANSI_ARGS_((register Table *tablePtr, int idx, int count)); extern void TableInsertChars _ANSI_ARGS_((register Table *tablePtr, int idx, char *string)); /* * HEADERS IN tkTableTag.c */ extern TableTag *TableNewTag _ANSI_ARGS_((Table *tablePtr)); extern void TableResetTag _ANSI_ARGS_((Table *tablePtr, TableTag *tagPtr)); extern void TableMergeTag _ANSI_ARGS_((Table *tablePtr, TableTag *baseTag, TableTag *addTag)); extern void TableInvertTag _ANSI_ARGS_((TableTag *baseTag)); extern int TableGetTagBorders _ANSI_ARGS_((TableTag *tagPtr, int *left, int *right, int *top, int *bottom)); extern void TableInitTags _ANSI_ARGS_((Table *tablePtr)); extern TableTag *FindRowColTag _ANSI_ARGS_((Table *tablePtr, int cell, int type)); extern void TableCleanupTag _ANSI_ARGS_((Table *tablePtr, TableTag *tagPtr)); extern int Table_TagCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); /* * HEADERS IN tkTableUtil.c */ extern void Table_ClearHashTable _ANSI_ARGS_((Tcl_HashTable *hashTblPtr)); extern int TableOptionBdSet _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, Arg value, char *widgRec, int offset)); extern Arg TableOptionBdGet _ANSI_ARGS_((ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)); extern int TableTagConfigureBd _ANSI_ARGS_((Table *tablePtr, TableTag *tagPtr, Arg oldValue, int nullOK)); extern int Cmd_OptionSet _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, Tk_Window unused, Arg value, char *widgRec, int offset)); extern Arg Cmd_OptionGet _ANSI_ARGS_((ClientData clientData, Tk_Window unused, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)); /* * HEADERS IN tkTableCell.c */ extern int TableTrueCell _ANSI_ARGS_((Table *tablePtr, int row, int col, int *trow, int *tcol)); extern int TableCellCoords _ANSI_ARGS_((Table *tablePtr, int row, int col, int *rx, int *ry, int *rw, int *rh)); extern int TableCellVCoords _ANSI_ARGS_((Table *tablePtr, int row, int col, int *rx, int *ry, int *rw, int *rh, int full)); extern void TableWhatCell _ANSI_ARGS_((register Table *tablePtr, int x, int y, int *row, int *col)); extern int TableAtBorder _ANSI_ARGS_((Table *tablePtr, int x, int y, int *row, int *col)); extern char * TableGetCellValue _ANSI_ARGS_((Table *tablePtr, int r, int c)); extern int TableSetCellValue _ANSI_ARGS_((Table *tablePtr, int r, int c, char *value)); extern int TableMoveCellValue _ANSI_ARGS_((Table *tablePtr, int fromr, int fromc, char *frombuf, int tor, int toc, char *tobuf, int outOfBounds)); extern int TableGetIcursor _ANSI_ARGS_((Table *tablePtr, char *arg, int *posn)); #define TableGetIcursorObj(tablePtr, objPtr, posnPtr) \ TableGetIcursor(tablePtr, Tcl_GetString(objPtr), posnPtr) extern int TableGetIndex _ANSI_ARGS_((register Table *tablePtr, char *str, int *row_p, int *col_p)); #define TableGetIndexObj(tablePtr, objPtr, rowPtr, colPtr) \ TableGetIndex(tablePtr, Tcl_GetString(objPtr), rowPtr, colPtr) extern int Table_SetCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_HiddenCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern int Table_SpanCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern void TableSpanSanCheck _ANSI_ARGS_((register Table *tablePtr)); /* * HEADERS IN TKTABLECELLSORT */ /* * We keep the old CellSort true because it is used for grabbing * the selection, so we really want them ordered */ extern Arg TableCellSort _ANSI_ARGS_((Table *tablePtr, char *str)); #ifdef NO_SORT_CELLS # define TableCellSortObj(interp, objPtr) (objPtr) #else extern Tcl_Obj* TableCellSortObj _ANSI_ARGS_((Tcl_Interp *interp, Tcl_Obj *listObjPtr)); #endif /* * HEADERS IN TKTABLEPS */ #ifdef POSTSCRIPT extern int Table_PostscriptCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); extern void Tcl_DStringAppendAll _ANSI_ARGS_(TCL_VARARGS(Tcl_DString *, arg1)); #endif /* * HEADERS IN TKTABLE */ EXTERN int Tktable_Init _ANSI_ARGS_((Tcl_Interp *interp)); EXTERN int Tktable_SafeInit _ANSI_ARGS_((Tcl_Interp *interp)); extern void TableGetActiveBuf _ANSI_ARGS_((register Table *tablePtr)); extern void ExpandPercents _ANSI_ARGS_((Table *tablePtr, char *before, int r, int c, char *oldVal, char *newVal, int idx, Tcl_DString *dsPtr, int cmdType)); extern void TableInvalidate _ANSI_ARGS_((Table *tablePtr, int x, int y, int width, int height, int force)); extern void TableRefresh _ANSI_ARGS_((register Table *tablePtr, int arg1, int arg2, int mode)); extern void TableGeometryRequest _ANSI_ARGS_((Table *tablePtr)); extern void TableAdjustActive _ANSI_ARGS_((register Table *tablePtr)); extern void TableAdjustParams _ANSI_ARGS_((register Table *tablePtr)); extern void TableConfigCursor _ANSI_ARGS_((register Table *tablePtr)); extern void TableAddFlash _ANSI_ARGS_((Table *tablePtr, int row, int col)); #define TableInvalidateAll(tablePtr, flags) \ TableInvalidate((tablePtr), 0, 0, Tk_Width((tablePtr)->tkwin),\ Tk_Height((tablePtr)->tkwin), (flags)) /* * Turn row/col into an index into the table */ #define TableMakeArrayIndex(r, c, i) sprintf((i), "%d,%d", (r), (c)) /* * Turn array index back into row/col * return the number of args parsed (should be two) */ #define TableParseArrayIndex(r, c, i) sscanf((i), "%d,%d", (r), (c)) /* * Macro for finding the last cell of the table */ #define TableGetLastCell(tablePtr, rowPtr, colPtr) \ TableWhatCell((tablePtr),\ Tk_Width((tablePtr)->tkwin)-(tablePtr)->highlightWidth-1,\ Tk_Height((tablePtr)->tkwin)-(tablePtr)->highlightWidth-1,\ (rowPtr), (colPtr)) EXTERN int Tk_TableObjCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); /* * end of header * reset TCL_STORAGE_CLASS to DLLIMPORT. */ #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT /* perltk tkTables replacement for TCL_unsetVar. deletes an element in a hash */ EXTERN void tkTableUnsetElement _ANSI_ARGS_((Var hashEntry, char * key)); #endif /* _TKTABLE_H_ */ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable/tkTableversion.h������������������������������������������������0000644�0000000�0000000�00000000317�13745605157�020772� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#if 0 TBL_MAJOR_VERSION = 2 TBL_MINOR_VERSION = 7 TBL_VERSION = $(TBL_MAJOR_VERSION).$(TBL_MINOR_VERSION) #endif #define TBL_MAJOR_VERSION 2 #define TBL_MINOR_VERSION 7 #define TBL_VERSION "2.7" �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable/mac_tkTable_prefix.h��������������������������������������������0000644�0000000�0000000�00000002340�13745605157�021557� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Macintosh Tcl must be compiled with certain compiler options to * ensure that it will work correctly. The following pragmas are * used to ensure that those options are set correctly. An error * will occur at compile time if they are not set correctly. */ #if !__option(enumsalwaysint) #error Tcl requires the Metrowerks setting "Enums always ints". #endif #if !defined(__POWERPC__) #if !__option(far_data) #error Tcl requires the Metrowerks setting "Far data". #endif #endif #if !defined(__POWERPC__) #if !__option(fourbyteints) #error Tcl requires the Metrowerks setting "4 byte ints". #endif #endif #if !defined(__POWERPC__) #if !__option(IEEEdoubles) #error Tcl requires the Metrowerks setting "8 byte doubles". #endif #endif /* * The define is used most everywhere to tell Tcl (or any Tcl * extensions) that we are compiling for the Macintosh platform. */ #define MAC_TCL /* * The following defines control the behavior of the Macintosh * Universal Headers. */ #define SystemSevenOrLater 1 #define STRICT_CONTROLS 1 #define STRICT_WINDOWS 1 #define TBL_COMMAND "table" #define TBL_RUNTIME "tkTable.tcl" #define TBL_RUNTIME_DIR "{}" #include "../generic/version.h" ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable/tkTableInitScript.h���������������������������������������������0000644�0000000�0000000�00000005265�13745605157�021404� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * tkTableInitScript.h -- * * This file contains common init script for tkTable * * Copyright (c) 1998 Jeffrey Hobbs * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. */ /* * The following string is the startup script executed when the table is * loaded. It looks on disk in several different directories for a script * "TBL_RUNTIME" (as defined in Makefile) that is compatible with this * version of tkTable. The sourced script has all key bindings defined. */ static char tkTableInitScript[] = "if {[info proc tkTableInit]==\"\"} {\n\ proc tkTableInit {} {\n\ global tk_library tcl_pkgPath errorInfo env\n\ rename tkTableInit {}\n\ set errors {}\n\ if {![info exists env(TK_TABLE_LIBRARY_FILE)]} {\n\ set env(TK_TABLE_LIBRARY_FILE) " TBL_RUNTIME "\n\ }\n\ if {[info exists env(TK_TABLE_LIBRARY)]} {\n\ lappend dirs $env(TK_TABLE_LIBRARY)\n\ }\n\ lappend dirs " TBL_RUNTIME_DIR "\n\ if {[info exists tcl_pkgPath]} {\n\ foreach i $tcl_pkgPath {\n\ lappend dirs [file join $i Tktable" VERSION "] \\\n\ [file join $i Tktable] $i\n\ }\n\ }\n\ lappend dirs $tk_library [pwd]\n\ foreach i $dirs {\n\ set try [file join $i $env(TK_TABLE_LIBRARY_FILE)]\n\ if {[file exists $try]} {\n\ if {![catch {uplevel #0 [list source $try]} msg]} {\n\ set env(TK_TABLE_LIBRARY) $i\n\ return\n\ } else {\n\ append errors \"$try: $msg\n$errorInfo\n\"\n\ }\n\ }\n\ }\n" #ifdef NO_EMBEDDED_RUNTIME " set msg \"Can't find a $env(TK_TABLE_LIBRARY_FILE) in the following directories: \n\"\n\ append msg \" $dirs\n\n$errors\n\n\"\n\ append msg \"This probably means that TkTable wasn't installed properly.\"\n\ return -code error $msg\n" #else " set env(TK_TABLE_LIBRARY) EMBEDDED_RUNTIME\n" # ifdef MAC_TCL " source -rsrc tkTable" # else " uplevel #0 {" # include "tkTable.tcl.h" " }" # endif #endif " }\n\ }\n\ tkTableInit"; /* * The init script can't make certain calls in a safe interpreter, * so we always have to use the embedded runtime for it */ static char tkTableSafeInitScript[] = "if {[info proc tkTableInit]==\"\"} {\n\ proc tkTableInit {} {\n\ set env(TK_TABLE_LIBRARY) EMBEDDED_RUNTIME\n" #ifdef NO_EMBEDDED_RUNTIME " append msg \"tkTable requires embedded runtime to be compiled for\"\n\ append msg \" use in safe interpreters\"\n\ return -code error $msg\n" #endif # ifdef MAC_TCL " source -rsrc tkTable" # else " uplevel #0 {" # include "tkTable.tcl.h" " }" # endif " }\n\ }\n\ tkTableInit"; �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable/tkTableCmds.c���������������������������������������������������0000644�0000000�0000000�00000115163�13745605157�020174� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * tkTableCmds.c -- * * This module implements general commands of a table widget, * based on the major/minor command structure. * * Copyright (c) 1998-2002 Jeffrey Hobbs * * See the file "license.txt" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * */ #include "tkVMacro.h" #include "tkTable.h" /* *-------------------------------------------------------------- * * Table_ActivateCmd -- * This procedure is invoked to process the activate method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_ActivateCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int result = TCL_OK; int row, col; if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "index"); return TCL_ERROR; } else if (TableGetIndexObj(tablePtr, objv[2], &row, &col) != TCL_OK) { return TCL_ERROR; } else { int x, y, w, dummy; char buf1[INDEX_BUFSIZE], buf2[INDEX_BUFSIZE]; /* convert to valid active index in real coords */ row -= tablePtr->rowOffset; col -= tablePtr->colOffset; /* we do this regardless, to avoid cell commit problems */ if ((tablePtr->flags & HAS_ACTIVE) && (tablePtr->flags & TEXT_CHANGED)) { tablePtr->flags &= ~TEXT_CHANGED; TableSetCellValue(tablePtr, tablePtr->activeRow+tablePtr->rowOffset, tablePtr->activeCol+tablePtr->colOffset, tablePtr->activeBuf); } if (row != tablePtr->activeRow || col != tablePtr->activeCol) { if (tablePtr->flags & HAS_ACTIVE) { TableMakeArrayIndex(tablePtr->activeRow+tablePtr->rowOffset, tablePtr->activeCol+tablePtr->colOffset, buf1); } else { buf1[0] = '\0'; } tablePtr->flags |= HAS_ACTIVE; tablePtr->flags &= ~ACTIVE_DISABLED; tablePtr->activeRow = row; tablePtr->activeCol = col; if (tablePtr->activeTagPtr != NULL) { ckfree((char *) (tablePtr->activeTagPtr)); tablePtr->activeTagPtr = NULL; } TableAdjustActive(tablePtr); TableConfigCursor(tablePtr); if (!(tablePtr->flags & BROWSE_CMD) && tablePtr->browseCmd != NULL) { tablePtr->flags |= BROWSE_CMD; row = tablePtr->activeRow+tablePtr->rowOffset; col = tablePtr->activeCol+tablePtr->colOffset; TableMakeArrayIndex(row, col, buf2); result = LangDoCallback(interp, tablePtr->browseCmd, 1, 2, "%s %s",buf1,buf2); if (result == TCL_OK || result == TCL_RETURN) { Tcl_ResetResult(interp); } tablePtr->flags &= ~BROWSE_CMD; } } else { char *p = Tcl_GetString(objv[2]); if ((tablePtr->activeTagPtr != NULL) && *p == '@' && !(tablePtr->flags & ACTIVE_DISABLED) && TableCellVCoords(tablePtr, row, col, &x, &y, &w, &dummy, 0)) { /* we are clicking into the same cell * If it was activated with @x,y indexing, * find the closest char */ Tk_TextLayout textLayout; TableTag *tagPtr = tablePtr->activeTagPtr; /* no error checking because GetIndex did it for us */ p++; x = strtol(p, &p, 0) - x - tablePtr->activeX; p++; y = strtol(p, &p, 0) - y - tablePtr->activeY; textLayout = Tk_ComputeTextLayout(tagPtr->tkfont, tablePtr->activeBuf, -1, (tagPtr->wrap) ? w : 0, tagPtr->justify, 0, &dummy, &dummy); tablePtr->icursor = Tk_PointToChar(textLayout, x, y); Tk_FreeTextLayout(textLayout); TableRefresh(tablePtr, row, col, CELL|INV_FORCE); } } tablePtr->flags |= HAS_ACTIVE; } return result; } /* *-------------------------------------------------------------- * * Table_AdjustCmd -- * This procedure is invoked to process the width/height method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_AdjustCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], int widthType) { /* widthType is a Flag = 1 if this is a col width change command, otherwise assumed to be a row height change command */ register Table *tablePtr = (Table *) clientData; Tcl_HashEntry *entryPtr; Tcl_HashSearch search; Tcl_HashTable *hashTablePtr; int i, dummy, value, posn, offset; char buf1[INDEX_BUFSIZE]; /* changes the width/height of certain selected columns */ if (objc != 3 && (objc & 1)) { Tcl_WrongNumArgs(interp, 2, objv, widthType ? "?col? ?width col width ...?" : "?row? ?height row height ...?"); return TCL_ERROR; } if (widthType) { hashTablePtr = tablePtr->colWidths; offset = tablePtr->colOffset; } else { hashTablePtr = tablePtr->rowHeights; offset = tablePtr->rowOffset; } if (objc == 2) { /* print out all the preset column widths or row heights */ entryPtr = Tcl_FirstHashEntry(hashTablePtr, &search); while (entryPtr != NULL) { posn = ((int) Tcl_GetHashKey(hashTablePtr, entryPtr)) + offset; value = (int) Tcl_GetHashValue(entryPtr); sprintf(buf1, "%d %d", posn, value); /* OBJECTIFY */ Tcl_AppendElement(interp, buf1); entryPtr = Tcl_NextHashEntry(&search); } } else if (objc == 3) { /* get the width/height of a particular row/col */ if (Tcl_GetIntFromObj(interp, objv[2], &posn) != TCL_OK) { return TCL_ERROR; } /* no range check is done, why bother? */ posn -= offset; entryPtr = Tcl_FindHashEntry(hashTablePtr, (char *) posn); if (entryPtr != NULL) { Tcl_SetIntObj(Tcl_GetObjResult(interp), (int) Tcl_GetHashValue(entryPtr)); } else { Tcl_SetIntObj(Tcl_GetObjResult(interp), widthType ? tablePtr->defColWidth : tablePtr->defRowHeight); } } else { for (i=2; i<objc; i++) { /* set new width|height here */ value = -999999; if (Tcl_GetIntFromObj(interp, objv[i++], &posn) != TCL_OK || (strcmp(Tcl_GetString(objv[i]), "default") && Tcl_GetIntFromObj(interp, objv[i], &value) != TCL_OK)) { return TCL_ERROR; } posn -= offset; if (value == -999999) { /* reset that field */ entryPtr = Tcl_FindHashEntry(hashTablePtr, (char *) posn); if (entryPtr != NULL) { Tcl_DeleteHashEntry(entryPtr); } } else { entryPtr = Tcl_CreateHashEntry(hashTablePtr, (char *) posn, &dummy); Tcl_SetHashValue(entryPtr, (ClientData) value); } } TableAdjustParams(tablePtr); /* rerequest geometry */ TableGeometryRequest(tablePtr); /* * Invalidate the whole window as TableAdjustParams * will only check to see if the top left cell has moved * FIX: should just move from lowest order visible cell * to edge of window */ TableInvalidateAll(tablePtr, 0); } return TCL_OK; } /* *-------------------------------------------------------------- * * Table_BboxCmd -- * This procedure is invoked to process the bbox method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_BboxCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int x, y, w, h, row, col, key; Tcl_Obj *resultPtr; /* Returns bounding box of cell(s) */ if (objc < 3 || objc > 4) { Tcl_WrongNumArgs(interp, 2, objv, "first ?last?"); return TCL_ERROR; } else if (TableGetIndexObj(tablePtr, objv[2], &row, &col) == TCL_ERROR || (objc == 4 && TableGetIndexObj(tablePtr, objv[3], &x, &y) == TCL_ERROR)) { return TCL_ERROR; } resultPtr = Tcl_GetObjResult(interp); if (objc == 3) { row -= tablePtr->rowOffset; col -= tablePtr->colOffset; if (TableCellVCoords(tablePtr, row, col, &x, &y, &w, &h, 0)) { Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewIntObj(x)); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewIntObj(y)); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewIntObj(w)); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewIntObj(h)); } return TCL_OK; } else { int r1, c1, r2, c2, minX = 99999, minY = 99999, maxX = 0, maxY = 0; row -= tablePtr->rowOffset; col -= tablePtr->colOffset; x -= tablePtr->rowOffset; y -= tablePtr->colOffset; r1 = MIN(row,x); r2 = MAX(row,x); c1 = MIN(col,y); c2 = MAX(col,y); key = 0; for (row = r1; row <= r2; row++) { for (col = c1; col <= c2; col++) { if (TableCellVCoords(tablePtr, row, col, &x, &y, &w, &h, 0)) { /* Get max bounding box */ if (x < minX) minX = x; if (y < minY) minY = y; if (x+w > maxX) maxX = x+w; if (y+h > maxY) maxY = y+h; key++; } } } if (key) { Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewIntObj(minX)); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewIntObj(minY)); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewIntObj(maxX-minX)); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewIntObj(maxY-minY)); } } return TCL_OK; } static CONST char *bdCmdNames[] = { "mark", "dragto", (char *)NULL }; enum bdCmd { BD_MARK, BD_DRAGTO }; /* *-------------------------------------------------------------- * * Table_BorderCmd -- * This procedure is invoked to process the bbox method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_BorderCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; Tcl_HashEntry *entryPtr; int x, y, w, h, row, col, key, dummy, value, cmdIndex; char *rc = NULL; Tcl_Obj *objPtr, *resultPtr; if (objc < 5 || objc > 6) { Tcl_WrongNumArgs(interp, 2, objv, "mark|dragto x y ?row|col?"); return TCL_ERROR; } if (Tcl_GetIndexFromObj(interp, objv[2], bdCmdNames, "option", 0, &cmdIndex) != TCL_OK || Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK || Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK) { return TCL_ERROR; } if (objc == 6) { rc = Tcl_GetStringFromObj(objv[5], &w); if ((w < 1) || (strncmp(rc, "row", w) && strncmp(rc, "col", w))) { Tcl_WrongNumArgs(interp, 2, objv, "mark|dragto x y ?row|col?"); return TCL_ERROR; } } resultPtr = Tcl_GetObjResult(interp); switch ((enum bdCmd) cmdIndex) { case BD_MARK: /* Use x && y to determine if we are over a border */ value = TableAtBorder(tablePtr, x, y, &row, &col); /* Cache the row && col for use in DRAGTO */ tablePtr->scanMarkRow = row; tablePtr->scanMarkCol = col; if (!value) { return TCL_OK; } TableCellCoords(tablePtr, row, col, &x, &y, &dummy, &dummy); tablePtr->scanMarkX = x; tablePtr->scanMarkY = y; if (objc == 5 || *rc == 'r') { if (row < 0) { objPtr = Tcl_NewStringObj("", 0); } else { objPtr = Tcl_NewIntObj(row+tablePtr->rowOffset); } Tcl_ListObjAppendElement(NULL, resultPtr, objPtr); } if (objc == 5 || *rc == 'c') { if (col < 0) { objPtr = Tcl_NewStringObj("", 0); } else { objPtr = Tcl_NewIntObj(col+tablePtr->colOffset); } Tcl_ListObjAppendElement(NULL, resultPtr, objPtr); } return TCL_OK; /* BORDER MARK */ case BD_DRAGTO: /* check to see if we want to resize any borders */ if (tablePtr->resize == SEL_NONE) { return TCL_OK; } row = tablePtr->scanMarkRow; col = tablePtr->scanMarkCol; TableCellCoords(tablePtr, row, col, &w, &h, &dummy, &dummy); key = 0; if (row >= 0 && (tablePtr->resize & SEL_ROW)) { /* row border was active, move it */ value = y-h; if (value < -1) value = -1; if (value != tablePtr->scanMarkY) { entryPtr = Tcl_CreateHashEntry(tablePtr->rowHeights, (char *) row, &dummy); /* -value means rowHeight will be interp'd as pixels, not lines */ Tcl_SetHashValue(entryPtr, (ClientData) MIN(0,-value)); tablePtr->scanMarkY = value; key++; } } if (col >= 0 && (tablePtr->resize & SEL_COL)) { /* col border was active, move it */ value = x-w; if (value < -1) value = -1; if (value != tablePtr->scanMarkX) { entryPtr = Tcl_CreateHashEntry(tablePtr->colWidths, (char *) col, &dummy); /* -value means colWidth will be interp'd as pixels, not chars */ Tcl_SetHashValue(entryPtr, (ClientData) MIN(0,-value)); tablePtr->scanMarkX = value; key++; } } /* Only if something changed do we want to update */ if (key) { TableAdjustParams(tablePtr); /* Only rerequest geometry if the basis is the #rows &| #cols */ if (tablePtr->maxReqCols || tablePtr->maxReqRows) TableGeometryRequest(tablePtr); TableInvalidateAll(tablePtr, 0); } return TCL_OK; /* BORDER DRAGTO */ } return TCL_OK; } /* clear subcommands */ static CONST char *clearNames[] = { "all", "cache", "sizes", "tags", (char *)NULL }; enum clearCommand { CLEAR_ALL, CLEAR_CACHE, CLEAR_SIZES, CLEAR_TAGS }; /* *-------------------------------------------------------------- * * Table_ClearCmd -- * This procedure is invoked to process the clear method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * Cached info can be lost. Returns valid Tcl result. * * Side effects: * Can cause redraw. * See the user documentation. * *-------------------------------------------------------------- */ int Table_ClearCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int cmdIndex, redraw = 0; if (objc < 3 || objc > 5) { Tcl_WrongNumArgs(interp, 2, objv, "option ?first? ?last?"); return TCL_ERROR; } if (Tcl_GetIndexFromObj(interp, objv[2], clearNames, "clear option", 0, &cmdIndex) != TCL_OK) { return TCL_ERROR; } if (objc == 3) { if (cmdIndex == CLEAR_TAGS || cmdIndex == CLEAR_ALL) { Tcl_DeleteHashTable(tablePtr->rowStyles); Tcl_DeleteHashTable(tablePtr->colStyles); Tcl_DeleteHashTable(tablePtr->cellStyles); Tcl_DeleteHashTable(tablePtr->flashCells); Tcl_DeleteHashTable(tablePtr->selCells); /* style hash tables */ Tcl_InitHashTable(tablePtr->rowStyles, TCL_ONE_WORD_KEYS); Tcl_InitHashTable(tablePtr->colStyles, TCL_ONE_WORD_KEYS); Tcl_InitHashTable(tablePtr->cellStyles, TCL_STRING_KEYS); /* special style hash tables */ Tcl_InitHashTable(tablePtr->flashCells, TCL_STRING_KEYS); Tcl_InitHashTable(tablePtr->selCells, TCL_STRING_KEYS); } if (cmdIndex == CLEAR_SIZES || cmdIndex == CLEAR_ALL) { Tcl_DeleteHashTable(tablePtr->colWidths); Tcl_DeleteHashTable(tablePtr->rowHeights); /* style hash tables */ Tcl_InitHashTable(tablePtr->colWidths, TCL_ONE_WORD_KEYS); Tcl_InitHashTable(tablePtr->rowHeights, TCL_ONE_WORD_KEYS); } if (cmdIndex == CLEAR_CACHE || cmdIndex == CLEAR_ALL) { Table_ClearHashTable(tablePtr->cache); Tcl_InitHashTable(tablePtr->cache, TCL_STRING_KEYS); /* If we were caching and we have no other data source, * invalidate all the cells */ if (tablePtr->dataSource == DATA_CACHE) { TableGetActiveBuf(tablePtr); } } redraw = 1; } else { int row, col, r1, r2, c1, c2; Tcl_HashEntry *entryPtr; char buf[INDEX_BUFSIZE], *value; if (TableGetIndexObj(tablePtr, objv[3], &row, &col) != TCL_OK || ((objc == 5) && TableGetIndexObj(tablePtr, objv[4], &r2, &c2) != TCL_OK)) { return TCL_ERROR; } if (objc == 4) { r1 = r2 = row; c1 = c2 = col; } else { r1 = MIN(row,r2); r2 = MAX(row,r2); c1 = MIN(col,c2); c2 = MAX(col,c2); } for (row = r1; row <= r2; row++) { /* Note that *Styles entries are user based (no offset) * while size entries are 0-based (real) */ if ((cmdIndex == CLEAR_TAGS || cmdIndex == CLEAR_ALL) && (entryPtr = Tcl_FindHashEntry(tablePtr->rowStyles, (char *) row))) { Tcl_DeleteHashEntry(entryPtr); redraw = 1; } if ((cmdIndex == CLEAR_SIZES || cmdIndex == CLEAR_ALL) && (entryPtr = Tcl_FindHashEntry(tablePtr->rowHeights, (char *) row-tablePtr->rowOffset))) { Tcl_DeleteHashEntry(entryPtr); redraw = 1; } for (col = c1; col <= c2; col++) { TableMakeArrayIndex(row, col, buf); if (cmdIndex == CLEAR_TAGS || cmdIndex == CLEAR_ALL) { if ((row == r1) && (entryPtr = Tcl_FindHashEntry(tablePtr->colStyles, (char *) col))) { Tcl_DeleteHashEntry(entryPtr); redraw = 1; } if ((entryPtr = Tcl_FindHashEntry(tablePtr->cellStyles, buf))) { Tcl_DeleteHashEntry(entryPtr); redraw = 1; } if ((entryPtr = Tcl_FindHashEntry(tablePtr->flashCells, buf))) { Tcl_DeleteHashEntry(entryPtr); redraw = 1; } if ((entryPtr = Tcl_FindHashEntry(tablePtr->selCells, buf))) { Tcl_DeleteHashEntry(entryPtr); redraw = 1; } } if ((cmdIndex == CLEAR_SIZES || cmdIndex == CLEAR_ALL) && row == r1 && (entryPtr = Tcl_FindHashEntry(tablePtr->colWidths, (char *) col-tablePtr->colOffset))) { Tcl_DeleteHashEntry(entryPtr); redraw = 1; } if ((cmdIndex == CLEAR_CACHE || cmdIndex == CLEAR_ALL) && (entryPtr = Tcl_FindHashEntry(tablePtr->cache, buf))) { value = (char *) Tcl_GetHashValue(entryPtr); if (value) { ckfree(value); } Tcl_DeleteHashEntry(entryPtr); /* if the cache is our data source, * we need to invalidate the cells changed */ if ((tablePtr->dataSource == DATA_CACHE) && (row-tablePtr->rowOffset == tablePtr->activeRow && col-tablePtr->colOffset == tablePtr->activeCol)) TableGetActiveBuf(tablePtr); redraw = 1; } } } } /* This could be more sensitive about what it updates, * but that can actually be a lot more costly in some cases */ if (redraw) { if (cmdIndex == CLEAR_SIZES || cmdIndex == CLEAR_ALL) { TableAdjustParams(tablePtr); /* rerequest geometry */ TableGeometryRequest(tablePtr); } TableInvalidateAll(tablePtr, 0); } return TCL_OK; } /* *-------------------------------------------------------------- * * Table_CurselectionCmd -- * This procedure is invoked to process the bbox method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_CurselectionCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; Tcl_HashEntry *entryPtr; Tcl_HashSearch search; char *value = NULL; int row, col; if (objc > 3) { Tcl_WrongNumArgs(interp, 2, objv, "?value?"); return TCL_ERROR; } if (objc == 3) { /* make sure there is a data source to accept a set value */ if ((tablePtr->state == STATE_DISABLED) || (tablePtr->dataSource == DATA_NONE)) { return TCL_OK; } value = Tcl_GetString(objv[2]); for (entryPtr = Tcl_FirstHashEntry(tablePtr->selCells, &search); entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { TableParseArrayIndex(&row, &col, Tcl_GetHashKey(tablePtr->selCells, entryPtr)); TableSetCellValue(tablePtr, row, col, value); row -= tablePtr->rowOffset; col -= tablePtr->colOffset; if (row == tablePtr->activeRow && col == tablePtr->activeCol) { TableGetActiveBuf(tablePtr); } TableRefresh(tablePtr, row, col, CELL); } } else { Tcl_Obj *objPtr = Tcl_NewObj(); for (entryPtr = Tcl_FirstHashEntry(tablePtr->selCells, &search); entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { value = Tcl_GetHashKey(tablePtr->selCells, entryPtr); Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj(value, -1)); } Tcl_SetObjResult(interp, TableCellSortObj(interp, objPtr)); } return TCL_OK; } /* *-------------------------------------------------------------- * * Table_CurvalueCmd -- * This procedure is invoked to process the curvalue method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_CurvalueCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; if (objc > 3) { Tcl_WrongNumArgs(interp, 2, objv, "?<value>?"); return TCL_ERROR; } else if (!(tablePtr->flags & HAS_ACTIVE)) { return TCL_OK; } if (objc == 3) { char *value; int len; value = Tcl_GetStringFromObj(objv[2], &len); if (STREQ(value, tablePtr->activeBuf)) { Tcl_SetObjResult(interp, objv[2]); return TCL_OK; } /* validate potential new active buffer contents * only accept if validation returns acceptance. */ if (tablePtr->validate && TableValidateChange(tablePtr, tablePtr->activeRow+tablePtr->rowOffset, tablePtr->activeCol+tablePtr->colOffset, tablePtr->activeBuf, value, tablePtr->icursor) != TCL_OK) { return TCL_OK; } tablePtr->activeBuf = (char *)ckrealloc(tablePtr->activeBuf, len+1); strcpy(tablePtr->activeBuf, value); /* mark the text as changed */ tablePtr->flags |= TEXT_CHANGED; TableSetActiveIndex(tablePtr); /* check for possible adjustment of icursor */ TableGetIcursor(tablePtr, "insert", (int *)0); TableRefresh(tablePtr, tablePtr->activeRow, tablePtr->activeCol, CELL); } Tcl_SetStringObj(Tcl_GetObjResult(interp), tablePtr->activeBuf, -1); return TCL_OK; } /* *-------------------------------------------------------------- * * Table_GetCmd -- * This procedure is invoked to process the bbox method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_GetCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int result = TCL_OK; int r1, c1, r2, c2, row, col; if (objc < 3 || objc > 4) { Tcl_WrongNumArgs(interp, 2, objv, "first ?last?"); result = TCL_ERROR; } else if (TableGetIndexObj(tablePtr, objv[2], &row, &col) == TCL_ERROR) { result = TCL_ERROR; } else if (objc == 3) { Tcl_SetObjResult(interp, Tcl_NewStringObj(TableGetCellValue(tablePtr, row, col), -1)); } else if (TableGetIndexObj(tablePtr, objv[3], &r2, &c2) == TCL_ERROR) { result = TCL_ERROR; } else { Tcl_Obj *objPtr = Tcl_NewObj(); r1 = MIN(row,r2); r2 = MAX(row,r2); c1 = MIN(col,c2); c2 = MAX(col,c2); for ( row = r1; row <= r2; row++ ) { for ( col = c1; col <= c2; col++ ) { Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj(TableGetCellValue(tablePtr, row, col), -1)); } } Tcl_SetObjResult(interp, objPtr); } return result; } /* *-------------------------------------------------------------- * * Table_ScanCmd -- * This procedure is invoked to process the scan method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_ScanCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int x, y, row, col, cmdIndex; if (objc != 5) { Tcl_WrongNumArgs(interp, 2, objv, "mark|dragto x y"); return TCL_ERROR; } else if (Tcl_GetIndexFromObj(interp, objv[2], bdCmdNames, "option", 0, &cmdIndex) != TCL_OK || Tcl_GetIntFromObj(interp, objv[3], &x) == TCL_ERROR || Tcl_GetIntFromObj(interp, objv[4], &y) == TCL_ERROR) { return TCL_ERROR; } switch ((enum bdCmd) cmdIndex) { case BD_MARK: TableWhatCell(tablePtr, x, y, &row, &col); tablePtr->scanMarkRow = row-tablePtr->topRow; tablePtr->scanMarkCol = col-tablePtr->leftCol; tablePtr->scanMarkX = x; tablePtr->scanMarkY = y; break; case BD_DRAGTO: { int oldTop = tablePtr->topRow, oldLeft = tablePtr->leftCol; y += (5*(y-tablePtr->scanMarkY)); x += (5*(x-tablePtr->scanMarkX)); TableWhatCell(tablePtr, x, y, &row, &col); /* maintain appropriate real index */ tablePtr->topRow = BETWEEN(row-tablePtr->scanMarkRow, tablePtr->titleRows, tablePtr->rows-1); tablePtr->leftCol = BETWEEN(col-tablePtr->scanMarkCol, tablePtr->titleCols, tablePtr->cols-1); /* Adjust the table if new top left */ if (oldTop != tablePtr->topRow || oldLeft != tablePtr->leftCol) { TableAdjustParams(tablePtr); } break; } } return TCL_OK; } /* *-------------------------------------------------------------- * * Table_SelAnchorCmd -- * This procedure is invoked to process the selection anchor method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_SelAnchorCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int row, col; if (objc != 4) { Tcl_WrongNumArgs(interp, 3, objv, "index"); return TCL_ERROR; } else if (TableGetIndexObj(tablePtr, objv[3], &row, &col) != TCL_OK) { return TCL_ERROR; } tablePtr->flags |= HAS_ANCHOR; /* maintain appropriate real index */ if (tablePtr->selectTitles) { tablePtr->anchorRow = BETWEEN(row-tablePtr->rowOffset, 0, tablePtr->rows-1); tablePtr->anchorCol = BETWEEN(col-tablePtr->colOffset, 0, tablePtr->cols-1); } else { tablePtr->anchorRow = BETWEEN(row-tablePtr->rowOffset, tablePtr->titleRows, tablePtr->rows-1); tablePtr->anchorCol = BETWEEN(col-tablePtr->colOffset, tablePtr->titleCols, tablePtr->cols-1); } return TCL_OK; } /* *-------------------------------------------------------------- * * Table_SelClearCmd -- * This procedure is invoked to process the selection clear method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_SelClearCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int result = TCL_OK; char buf1[INDEX_BUFSIZE]; int row, col, key, clo=0,chi=0,r1,c1,r2,c2; Tcl_HashEntry *entryPtr; if (objc < 4 || objc > 5) { Tcl_WrongNumArgs(interp, 3, objv, "all|<first> ?<last>?"); return TCL_ERROR; } if (STREQ(Tcl_GetString(objv[3]), "all")) { Tcl_HashSearch search; for(entryPtr = Tcl_FirstHashEntry(tablePtr->selCells, &search); entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { TableParseArrayIndex(&row, &col, Tcl_GetHashKey(tablePtr->selCells,entryPtr)); Tcl_DeleteHashEntry(entryPtr); TableRefresh(tablePtr, row-tablePtr->rowOffset, col-tablePtr->colOffset, CELL); } return TCL_OK; } if (TableGetIndexObj(tablePtr, objv[3], &row, &col) == TCL_ERROR || (objc==5 && TableGetIndexObj(tablePtr, objv[4], &r2, &c2) == TCL_ERROR)) { return TCL_ERROR; } key = 0; if (objc == 4) { r1 = r2 = row; c1 = c2 = col; } else { r1 = MIN(row,r2); r2 = MAX(row,r2); c1 = MIN(col,c2); c2 = MAX(col,c2); } switch (tablePtr->selectType) { case SEL_BOTH: clo = c1; chi = c2; c1 = tablePtr->colOffset; c2 = tablePtr->cols-1+c1; key = 1; goto CLEAR_CELLS; CLEAR_BOTH: key = 0; c1 = clo; c2 = chi; case SEL_COL: r1 = tablePtr->rowOffset; r2 = tablePtr->rows-1+r1; break; case SEL_ROW: c1 = tablePtr->colOffset; c2 = tablePtr->cols-1+c1; break; } /* row/col are in user index coords */ CLEAR_CELLS: for ( row = r1; row <= r2; row++ ) { for ( col = c1; col <= c2; col++ ) { TableMakeArrayIndex(row, col, buf1); entryPtr = Tcl_FindHashEntry(tablePtr->selCells, buf1); if (entryPtr != NULL) { Tcl_DeleteHashEntry(entryPtr); TableRefresh(tablePtr, row-tablePtr->rowOffset, col-tablePtr->colOffset, CELL); } } } if (key) goto CLEAR_BOTH; return result; } /* *-------------------------------------------------------------- * * Table_SelIncludesCmd -- * This procedure is invoked to process the selection includes method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_SelIncludesCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int row, col; if (objc != 4) { Tcl_WrongNumArgs(interp, 3, objv, "index"); return TCL_ERROR; } else if (TableGetIndexObj(tablePtr, objv[3], &row, &col) == TCL_ERROR) { return TCL_ERROR; } else { char buf[INDEX_BUFSIZE]; TableMakeArrayIndex(row, col, buf); Tcl_SetBooleanObj(Tcl_GetObjResult(interp), (Tcl_FindHashEntry(tablePtr->selCells, buf)!=NULL)); } return TCL_OK; } /* *-------------------------------------------------------------- * * Table_SelSetCmd -- * This procedure is invoked to process the selection set method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_SelSetCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int row, col, dummy, key; char buf1[INDEX_BUFSIZE]; Tcl_HashSearch search; Tcl_HashEntry *entryPtr; int clo=0, chi=0, r1, c1, r2, c2, firstRow, firstCol, lastRow, lastCol; if (objc < 4 || objc > 5) { Tcl_WrongNumArgs(interp, 3, objv, "first ?last?"); return TCL_ERROR; } if (TableGetIndexObj(tablePtr, objv[3], &row, &col) == TCL_ERROR || (objc==5 && TableGetIndexObj(tablePtr, objv[4], &r2, &c2) == TCL_ERROR)) { return TCL_ERROR; } key = 0; lastRow = tablePtr->rows-1+tablePtr->rowOffset; lastCol = tablePtr->cols-1+tablePtr->colOffset; if (tablePtr->selectTitles) { firstRow = tablePtr->rowOffset; firstCol = tablePtr->colOffset; } else { firstRow = tablePtr->titleRows+tablePtr->rowOffset; firstCol = tablePtr->titleCols+tablePtr->colOffset; } /* maintain appropriate user index */ CONSTRAIN(row, firstRow, lastRow); CONSTRAIN(col, firstCol, lastCol); if (objc == 4) { r1 = r2 = row; c1 = c2 = col; } else { CONSTRAIN(r2, firstRow, lastRow); CONSTRAIN(c2, firstCol, lastCol); r1 = MIN(row,r2); r2 = MAX(row,r2); c1 = MIN(col,c2); c2 = MAX(col,c2); } switch (tablePtr->selectType) { case SEL_BOTH: if (firstCol > lastCol) c2--; /* No selectable columns in table */ if (firstRow > lastRow) r2--; /* No selectable rows in table */ clo = c1; chi = c2; c1 = firstCol; c2 = lastCol; key = 1; goto SET_CELLS; SET_BOTH: key = 0; c1 = clo; c2 = chi; case SEL_COL: r1 = firstRow; r2 = lastRow; if (firstCol > lastCol) c2--; /* No selectable columns in table */ break; case SEL_ROW: c1 = firstCol; c2 = lastCol; if (firstRow>lastRow) r2--; /* No selectable rows in table */ break; } SET_CELLS: entryPtr = Tcl_FirstHashEntry(tablePtr->selCells, &search); for ( row = r1; row <= r2; row++ ) { for ( col = c1; col <= c2; col++ ) { TableMakeArrayIndex(row, col, buf1); if (Tcl_FindHashEntry(tablePtr->selCells, buf1) == NULL) { Tcl_CreateHashEntry(tablePtr->selCells, buf1, &dummy); TableRefresh(tablePtr, row-tablePtr->rowOffset, col-tablePtr->colOffset, CELL); } } } if (key) goto SET_BOTH; /* Adjust the table for top left, selection on screen etc */ TableAdjustParams(tablePtr); /* If the table was previously empty and we want to export the * selection, we should grab it now */ if (entryPtr == NULL && tablePtr->exportSelection) { Tk_OwnSelection(tablePtr->tkwin, XA_PRIMARY, TableLostSelection, (ClientData) tablePtr); } return TCL_OK; } /* *-------------------------------------------------------------- * * Table_ViewCmd -- * This procedure is invoked to process the x|yview method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_ViewCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int row, col, value; char *xy; /* Check xview or yview */ if (objc > 5) { Tcl_WrongNumArgs(interp, 2, objv, "?args?"); return TCL_ERROR; } xy = Tcl_GetString(objv[1]); if (objc == 2) { Tcl_Obj *resultPtr; int diff, x, y, w, h; double first, last; resultPtr = Tcl_GetObjResult(interp); TableGetLastCell(tablePtr, &row, &col); TableCellVCoords(tablePtr, row, col, &x, &y, &w, &h, 0); if (*xy == 'y') { if (row < tablePtr->titleRows) { first = 0; last = 1; } else { diff = tablePtr->rowStarts[tablePtr->titleRows]; last = (double) (tablePtr->rowStarts[tablePtr->rows]-diff); first = (tablePtr->rowStarts[tablePtr->topRow]-diff) / last; last = (h+tablePtr->rowStarts[row]-diff) / last; } } else { if (col < tablePtr->titleCols) { first = 0; last = 1; } else { diff = tablePtr->colStarts[tablePtr->titleCols]; last = (double) (tablePtr->colStarts[tablePtr->cols]-diff); first = (tablePtr->colStarts[tablePtr->leftCol]-diff) / last; last = (w+tablePtr->colStarts[col]-diff) / last; } } Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewDoubleObj(first)); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewDoubleObj(last)); } else { /* cache old topleft to see if it changes */ int oldTop = tablePtr->topRow, oldLeft = tablePtr->leftCol; if (objc == 3) { if (Tcl_GetIntFromObj(interp, objv[2], &value) != TCL_OK) { return TCL_ERROR; } if (*xy == 'y') { tablePtr->topRow = value + tablePtr->titleRows; } else { tablePtr->leftCol = value + tablePtr->titleCols; } } else { int result; double frac; #if (TK_MINOR_VERSION > 0) /* 8.1+ */ result = Tk_GetScrollInfoObj(interp, objc, objv, &frac, &value); #else int i; Arg * args = (Arg *) ckalloc((objc + 1) * sizeof(Arg)); for (i = 0; i < objc; i++) { args[i] = LangStringArg(Tcl_GetString(objv[i])); } args[i] = NULL; result = Tk_GetScrollInfo(interp, objc, args, &frac, &value); ckfree ((char * ) args); #endif switch (result) { case TK_SCROLL_ERROR: return TCL_ERROR; case TK_SCROLL_MOVETO: if (frac < 0) frac = 0; if (*xy == 'y') { tablePtr->topRow = (int)(frac*tablePtr->rows) +tablePtr->titleRows; } else { tablePtr->leftCol = (int)(frac*tablePtr->cols) +tablePtr->titleCols; } break; case TK_SCROLL_PAGES: TableGetLastCell(tablePtr, &row, &col); if (*xy == 'y') { tablePtr->topRow += value * (row-tablePtr->topRow+1); } else { tablePtr->leftCol += value * (col-tablePtr->leftCol+1); } break; case TK_SCROLL_UNITS: if (*xy == 'y') { tablePtr->topRow += value; } else { tablePtr->leftCol += value; } break; } } /* maintain appropriate real index */ CONSTRAIN(tablePtr->topRow, tablePtr->titleRows, tablePtr->rows-1); CONSTRAIN(tablePtr->leftCol, tablePtr->titleCols, tablePtr->cols-1); /* Do the table adjustment if topRow || leftCol changed */ if (oldTop != tablePtr->topRow || oldLeft != tablePtr->leftCol) { TableAdjustParams(tablePtr); } } return TCL_OK; } #if 0 /* *-------------------------------------------------------------- * * Table_Cmd -- * This procedure is invoked to process the CMD method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_Cmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int result = TCL_OK; return result; } #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable/makefile.vc�����������������������������������������������������0000644�0000000�0000000�00000011144�13745605157�017734� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Makefile.vc # # This makefile builds Tktable.dll, a table widget as a dynamically # loadable Tk extension. This makefile is suitable for use with # Microsoft Visual C++ 4-5. # TkTable assumes that Tcl/Tk has already been installed on Windows. # # This does not provide support for static builds on Windows # !include <ntwin32.mak> #Get version info (this is in Makefile and C format) !include "version.h" PROJECT = Tktable TBL_COMMAND = table TBL_RUNTIME = tkTable.tcl # Project directories -- these may need to be customized for your site # # ROOT -- location of the source files. # TMPDIR -- location for .obj files. # TOOLS32 -- location of VC++ compiler installation. # DESTDIR -- location of Tcl/Tk installation hierarchy # DESTDIRU -- same as above with "/" as path separator # ROOT = . TMPDIR = . TOOLS32 = C:\Progra~1\DevStudio\Vc DESTDIR = C:\Progra~1\Tcl DESTDIRU = C:/Progra~1/Tcl # Set your version of Tcl TCL_VERSION = 8.1 TK_VERSION = 8.1 TCL_LIB_V = 81 TK_LIB_V = 81 INST_RUNTIME = $(DESTDIR)\lib\tkTable$(TBL_VERSION) INST_RUNTIMEU = $(DESTDIRU)/lib/tkTable$(TBL_VERSION) # NO_EMBEDDED_RUNTIME means that the tkTable.tcl file will not be embedded # into the executable, thus the default tkTable.tcl library file will not # be available when the library is loaded. # If this is defined, the tkTable.tcl file must be available in a # predefined set of directories (see docs). #TBL_CFLAGS += -DNO_EMBEDDED_RUNTIME # comment the following line to compile with symbols NODEBUG=1 # Necessary for some partially-installed VC++ setups: #INCLUDE="$(TOOLS32)\include" #LIB="$(TOOLS32)\lib" # # Visual C++ tools # PATH=$(TOOLS32)\bin;$(PATH) cc32 = "$(TOOLS32)\bin\cl" -I"$(TOOLS32)\include" CP = copy RM = del ###################################################################### # Project specific targets ###################################################################### TBL_LIBDIR = $(ROOT)\..\lib # Assume that WISH is already INSTALLED TCLSH = $(DESTDIR)\bin\tclsh$(TCL_LIB_V) WISH = $(DESTDIR)\bin\wish$(TK_LIB_V) LIBS = $(DESTDIR)\lib\tcl$(TCL_LIB_V).lib $(DESTDIR)\lib\tk$(TK_LIB_V).lib INCLUDES = -I"$(TOOLS32)\include" -I"$(DESTDIR)\include" DEFINES = -DDLL_BUILD -DBUILD_tkTable $(TBL_CFLAGS) \ -DTBL_VERSION=\"$(TBL_VERSION)\" \ -DTBL_COMMAND=\"$(TBL_COMMAND)\" \ -DTBL_RUNTIME="\"$(TBL_RUNTIME)\"" \ -DTBL_RUNTIME_DIR="\"$(INST_RUNTIMEU)\"" # # Global makefile settings # DLLOBJS = $(TMPDIR)\tkTable.obj $(TMPDIR)\tkTableWin.obj $(TMPDIR)\tkTableTag.obj $(TMPDIR)\tkTableEdit.obj $(TMPDIR)\tkTableCell.obj $(TMPDIR)\tkTableCmds.obj $(TMPDIR)\cmd.obj # $(TMPDIR)\tkTablePs.obj DLL=$(PROJECT).dll # Targets all: pkgIndex.tcl test: pkgIndex.tcl @"$(WISH)" << lappend auto_path $(ROOT) set code [catch { package require $(PROJECT) pack [$(TBL_COMMAND) .t] } msg] if {$$code != 0} { tk_messageBox -type ok -message\ "$(PROJECT) failed to load and run: $$msg" } else { tk_messageBox -type ok -message\ "everything seems OK for 'package require $(PROJECT)'" } exit $$code << pkgIndex.tcl: $(DLL) "$(TCLSH)" << pkgIndex.tcl set out [open [lindex $$argv 0] w] puts $$out {if {[catch {package require Tcl $(TCL_VERSION)}]} return} puts -nonewline $$out {package ifneeded $(PROJECT) $(TBL_VERSION) } puts -nonewline $$out {"package require Tk $(TK_VERSION); } puts $$out {[list load [file join $$dir $(DLL)] $(PROJECT)]"} close $$out << $(DLLOBJS): tkTable.tcl.h $(DLL): $(DLLOBJS) $(link) $(linkdebug) $(dlllflags) $(LIBS) \ $(guilibsdll) -out:$(DLL) $(DLLOBJS) tkTable.tcl.h: $(TBL_LIBDIR)\tkTable.tcl "$(TCLSH)" << $(TBL_LIBDIR)\tkTable.tcl >$(TMPDIR)\tkTable.tcl.h set in [open [lindex $$argv 0] r] while {[gets $$in line] != -1} { switch -regexp -- $$line "^$$" - {^#} continue regsub -all {\\} $$line {\\\\} line regsub -all {"} $$line {\"} line puts "\"$$line\\n\"" } << # Implicit Targets .c.obj: $(cc32) $(cdebug) $(cflags) $(cvarsdll) \ $(INCLUDES) $(DEFINES) -Fo$(TMPDIR)\ $< install: if not exist "$(INST_RUNTIME)\" mkdir "$(INST_RUNTIME)" copy "$(TBL_LIBDIR)\tkTable.tcl" "$(INST_RUNTIME)" copy "$(DLL)" "$(INST_RUNTIME)" copy pkgIndex.tcl "$(INST_RUNTIME)" uninstall: -$(RM) "$(INST_RUNTIME)\tkTable.tcl" -$(RM) "$(INST_RUNTIME)\$(DLL)" -$(RM) "$(INST_RUNTIME)\pkgIndex.tcl" clean: -$(RM) $(TMPDIR)\*.obj 2>nul -$(RM) $(DLL) 2>nul -$(RM) $(PROJECT).lib 2>nul -$(RM) $(PROJECT).exp 2>nul -$(RM) pkgIndex.tcl 2>nul -$(RM) $(TMPDIR)\tkTable.tcl.h 2>nul ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable/tkTablePs.c�����������������������������������������������������0000644�0000000�0000000�00000123643�13745605157�017672� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * tkTablePs.c -- * * This module implements postscript output for table widgets. * Based off of Tk8.1a2 tkCanvPs.c. * * Copyright (c) 1991-1994 The Regents of the University of California. * Copyright (c) 1994-1997 Sun Microsystems, Inc. * changes 1998 Copyright (c) 1998 Jeffrey Hobbs * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * */ /* Currently generating postscript */ #define POSTSCRIPT #include "tkVMacro.h" #include "tkTable.h" /* This is for Tcl_DStringAppendAll */ #if defined(__STDC__) || defined(HAS_STDARG) #include <stdarg.h> #else #include <varargs.h> #endif #ifndef TCL_INTEGER_SPACE /* This appears in 8.1 */ #define TCL_INTEGER_SPACE 24 #endif /* * One of the following structures is created to keep track of Postscript * output being generated. It consists mostly of information provided on * the widget command line. */ typedef struct TkPostscriptInfo { int x, y, width, height; /* Area to print, in table pixel * coordinates. */ int x2, y2; /* x+width and y+height. */ char *pageXString; /* String value of "-pagex" option or NULL. */ char *pageYString; /* String value of "-pagey" option or NULL. */ double pageX, pageY; /* Postscript coordinates (in points) * corresponding to pageXString and * pageYString. Don't forget that y-values * grow upwards for Postscript! */ char *pageWidthString; /* Printed width of output. */ char *pageHeightString; /* Printed height of output. */ double scale; /* Scale factor for conversion: each pixel * maps into this many points. */ Tk_Anchor pageAnchor; /* How to anchor bbox on Postscript page. */ int rotate; /* Non-zero means output should be rotated * on page (landscape mode). */ Var fontVar; /* If non-NULL, gives name of global variable * containing font mapping information. * Malloc'ed. */ Var colorVar; /* If non-NULL, give name of global variable * containing color mapping information. * Malloc'ed. */ char *colorMode; /* Mode for handling colors: "monochrome", * "gray", or "color". Malloc'ed. */ int colorLevel; /* Numeric value corresponding to colorMode: * 0 for mono, 1 for gray, 2 for color. */ char *fileName; /* Name of file in which to write Postscript; * NULL means return Postscript info as * result. Malloc'ed. */ char *channelName; /* If -channel is specified, the name of * the channel to use. */ Tcl_Channel chan; /* Open channel corresponding to fileName. */ Tcl_HashTable fontTable; /* Hash table containing names of all font * families used in output. The hash table * values are not used. */ char *first, *last; /* table indices to start and end at */ } TkPostscriptInfo; /* * The table below provides a template that's used to process arguments * to the table "postscript" command and fill in TkPostscriptInfo * structures. */ static Tk_ConfigSpec configSpecs[] = { {TK_CONFIG_SCALARVAR, "-colormap", (char *) NULL, (char *) NULL, "", Tk_Offset(TkPostscriptInfo, colorVar), 0}, {TK_CONFIG_STRING, "-colormode", (char *) NULL, (char *) NULL, "", Tk_Offset(TkPostscriptInfo, colorMode), 0}, {TK_CONFIG_STRING, "-file", (char *) NULL, (char *) NULL, "", Tk_Offset(TkPostscriptInfo, fileName), 0}, {TK_CONFIG_STRING, "-channel", (char *) NULL, (char *) NULL, "", Tk_Offset(TkPostscriptInfo, channelName), 0}, {TK_CONFIG_STRING, "-first", (char *) NULL, (char *) NULL, "", Tk_Offset(TkPostscriptInfo, first), 0}, {TK_CONFIG_SCALARVAR, "-fontmap", (char *) NULL, (char *) NULL, "", Tk_Offset(TkPostscriptInfo, fontVar), 0}, {TK_CONFIG_PIXELS, "-height", (char *) NULL, (char *) NULL, "", Tk_Offset(TkPostscriptInfo, height), 0}, {TK_CONFIG_STRING, "-last", (char *) NULL, (char *) NULL, "", Tk_Offset(TkPostscriptInfo, last), 0}, {TK_CONFIG_ANCHOR, "-pageanchor", (char *) NULL, (char *) NULL, "", Tk_Offset(TkPostscriptInfo, pageAnchor), 0}, {TK_CONFIG_STRING, "-pageheight", (char *) NULL, (char *) NULL, "", Tk_Offset(TkPostscriptInfo, pageHeightString), 0}, {TK_CONFIG_STRING, "-pagewidth", (char *) NULL, (char *) NULL, "", Tk_Offset(TkPostscriptInfo, pageWidthString), 0}, {TK_CONFIG_STRING, "-pagex", (char *) NULL, (char *) NULL, "", Tk_Offset(TkPostscriptInfo, pageXString), 0}, {TK_CONFIG_STRING, "-pagey", (char *) NULL, (char *) NULL, "", Tk_Offset(TkPostscriptInfo, pageYString), 0}, {TK_CONFIG_BOOLEAN, "-rotate", (char *) NULL, (char *) NULL, "", Tk_Offset(TkPostscriptInfo, rotate), 0}, {TK_CONFIG_PIXELS, "-width", (char *) NULL, (char *) NULL, "", Tk_Offset(TkPostscriptInfo, width), 0}, {TK_CONFIG_PIXELS, "-x", (char *) NULL, (char *) NULL, "", Tk_Offset(TkPostscriptInfo, x), 0}, {TK_CONFIG_PIXELS, "-y", (char *) NULL, (char *) NULL, "", Tk_Offset(TkPostscriptInfo, y), 0}, {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL, (char *) NULL, 0, 0} }; /* * The prolog data. Generated by str2c from prolog.ps * This was split in small chunks by str2c because * some C compiler have limitations on the size of static strings. * (str2c is a small tcl script in tcl's tool directory (source release)) */ /* * This is a stripped down version of that found in tkCanvPs.c of Tk8.1a2. * Comments, and stuff pertaining to stipples and other unused entities * have been removed */ static CONST char * CONST prolog[]= { /* Start of part 1 */ "%%BeginProlog\n\ 50 dict begin\n\ \n\ % This is standard prolog for Postscript generated by Tk's table widget.\n\ % Based of standard prolog for Tk's canvas widget.\n\ \n\ % INITIALIZING VARIABLES\n\ \n\ /baseline 0 def\n\ /height 0 def\n\ /justify 0 def\n\ /cellHeight 0 def\n\ /cellWidth 0 def\n\ /spacing 0 def\n\ /strings 0 def\n\ /xoffset 0 def\n\ /yoffset 0 def\n\ /x 0 def\n\ /y 0 def\n\ \n\ % Define the array ISOLatin1Encoding, if it isn't already present.\n\ \n\ systemdict /ISOLatin1Encoding known not {\n\ /ISOLatin1Encoding [\n\ /space /space /space /space /space /space /space /space\n\ /space /space /space /space /space /space /space /space\n\ /space /space /space /space /space /space /space /space\n\ /space /space /space /space /space /space /space /space\n\ /space /exclam /quotedbl /numbersign /dollar /percent /ampersand\n\ /quoteright\n\ /parenleft /parenright /asterisk /plus /comma /minus /period /slash\n\ /zero /one /two /three /four /five /six /seven\n\ /eight /nine /colon /semicolon /less /equal /greater /question\n\ /at /A /B /C /D /E /F /G\n\ /H /I /J /K /L /M /N /O\n\ /P /Q /R /S /T /U /V /W\n\ /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore\n\ /quoteleft /a /b /c /d /e /f /g\n\ /h /i /j /k /l /m /n /o\n\ /p /q /r /s /t /u /v /w\n\ /x /y /z /braceleft /bar /braceright /asciitilde /space\n\ /space /space /space /space /space /space /space /space\n\ /space /space /space /space /space /space /space /space\n\ /dotlessi /grave /acute /circumflex /tilde /macron /breve /dotaccent\n\ /dieresis /space /ring /cedilla /space /hungarumlaut /ogonek /caron\n\ /space /exclamdown /cent /sterling /currency /yen /brokenbar /section\n\ /dieresis /copyright /ordfem", "inine /guillemotleft /logicalnot /hyphen\n\ /registered /macron\n\ /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph\n\ /periodcentered\n\ /cedillar /onesuperior /ordmasculine /guillemotright /onequarter\n\ /onehalf /threequarters /questiondown\n\ /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla\n\ /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex\n\ /Idieresis\n\ /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply\n\ /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn\n\ /germandbls\n\ /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla\n\ /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex\n\ /idieresis\n\ /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide\n\ /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn\n\ /ydieresis\n\ ] def\n\ } if\n", "\n\ % font ISOEncode font\n\ % This procedure changes the encoding of a font from the default\n\ % Postscript encoding to ISOLatin1. It's typically invoked just\n\ % before invoking \"setfont\". The body of this procedure comes from\n\ % Section 5.6.1 of the Postscript book.\n\ \n\ /ISOEncode {\n\ dup length dict begin\n\ {1 index /FID ne {def} {pop pop} ifelse} forall\n\ /Encoding ISOLatin1Encoding def\n\ currentdict\n\ end\n\ \n\ % I'm not sure why it's necessary to use \"definefont\" on this new\n\ % font, but it seems to be important; just use the name \"Temporary\"\n\ % for the font.\n\ \n\ /Temporary exch definefont\n\ } bind def\n\ \n\ % -- AdjustColor --\n\ % Given a color value already set for output by the caller, adjusts\n\ % that value to a grayscale or mono value if requested by the CL variable.\n\ \n\ /AdjustColor {\n\ setrgbcolor\n\ CL 2 lt {\n\ currentgray\n\ CL 0 eq {\n\ .5 lt {0} {1} ifelse\n\ } if\n\ setgray\n\ } if\n\ } bind def\n\ \n\ % pointSize fontName SetFont\n\ % The ISOEncode shouldn't be done to Symbol fonts...\n\ /SetFont {\n\ findfont exch scalefont ISOEncode setfont\n\ } def\n\ \n", "% x y strings spacing xoffset yoffset justify ... DrawText --\n\ % This procedure does all of the real work of drawing text. The\n\ % color and font must already have been set by the caller, and the\n\ % following arguments must be on the stack:\n\ %\n\ % x, y - Coordinates at which to draw text.\n\ % strings - An array of strings, one for each line of the text item,\n\ % in order from top to bottom.\n\ % spacing - Spacing between lines.\n\ % xoffset - Horizontal offset for text bbox relative to x and y: 0 for\n\ % nw/w/sw anchor, -0.5 for n/center/s, and -1.0 for ne/e/se.\n\ % yoffset - Vertical offset for text bbox relative to x and y: 0 for\n\ % nw/n/ne anchor, +0.5 for w/center/e, and +1.0 for sw/s/se.\n\ % justify - 0 for left justification, 0.5 for center, 1 for right justify.\n\ % cellWidth - width for this cell\n\ % cellHeight - height for this cell\n\ %\n\ % Also, when this procedure is invoked, the color and font must already\n\ % have been set for the text.\n\ \n", "/DrawCellText {\n\ /cellHeight exch def\n\ /cellWidth exch def\n\ /justify exch def\n\ /yoffset exch def\n\ /xoffset exch def\n\ /spacing exch def\n\ /strings exch def\n\ /y exch def\n\ /x exch def\n\ \n\ % Compute the baseline offset and the actual font height.\n\ \n\ 0 0 moveto (TXygqPZ) false charpath\n\ pathbbox dup /baseline exch def\n\ exch pop exch sub /height exch def pop\n\ newpath\n\ \n\ % Translate coordinates first so that the origin is at the upper-left\n\ % corner of the text's bounding box. Remember that x and y for\n\ % positioning are still on the stack.\n\ \n\ col0 x sub row0 y sub translate\n\ cellWidth xoffset mul\n\ strings length 1 sub spacing mul height add yoffset mul translate\n\ \n\ % Now use the baseline and justification information to translate so\n\ % that the origin is at the baseline and positioning point for the\n\ % first line of text.\n\ \n\ justify cellWidth mul baseline neg translate\n\ \n\ % Iterate over each of the lines to output it. For each line,\n\ % compute its width again so it can be properly justified, then\n\ % display it.\n\ \n\ strings {\n\ dup stringwidth pop\n\ justify neg mul 0 moveto\n\ show\n\ 0 spacing neg translate\n\ } forall\n\ } bind def\n\ \n", "%\n\ % x, y - Coordinates at which to draw text.\n\ % strings - An array of strings, one for each line of the text item,\n\ % in order from top to bottom.\n\ % spacing - Spacing between lines.\n\ % xoffset - Horizontal offset for text bbox relative to x and y: 0 for\n\ % nw/w/sw anchor, -0.5 for n/center/s, and -1.0 for ne/e/se.\n\ % yoffset - Vertical offset for text bbox relative to x and y: 0 for\n\ % nw/n/ne anchor, +0.5 for w/center/e, and +1.0 for sw/s/se.\n\ % justify - 0 for left justification, 0.5 for center, 1 for right justify.\n\ % cellWidth - width for this cell\n\ % cellHeight - height for this cell\n\ %\n\ % Also, when this procedure is invoked, the color and font must already\n\ % have been set for the text.\n\ \n\ /DrawCellTextOld {\n\ /cellHeight exch def\n\ /cellWidth exch def\n\ /justify exch def\n\ /yoffset exch def\n\ /xoffset exch def\n\ /spacing exch def\n\ /strings exch def\n\ \n\ % Compute the baseline offset and the actual font height.\n\ \n\ 0 0 moveto (TXygqPZ) false charpath\n\ pathbbox dup /baseline exch def\n\ exch pop exch sub /height exch def pop\n\ newpath\n\ \n\ % Translate coordinates first so that the origin is at the upper-left\n\ % corner of the text's bounding box. Remember that x and y for\n\ % positioning are still on the stack.\n\ \n\ translate\n\ cellWidth xoffset mul\n\ strings length 1 sub spacing mul height add yoffset mul translate\n\ \n\ % Now use the baseline and justification information to translate so\n\ % that the origin is at the baseline and positioning point for the\n\ % first line of text.\n\ \n\ justify cellWidth mul baseline neg translate\n\ \n\ % Iterate over each of the lines to output it. For each line,\n\ % compute its width again so it can be properly justified, then\n\ % display it.\n\ \n\ strings {\n\ dup stringwidth pop\n\ justify neg mul 0 moveto\n\ show\n\ 0 spacing neg translate\n\ } forall\n\ } bind def\n\ \n\ %%EndProlog\n\ ", /* End of part 5 */ NULL /* End of data marker */ }; /* * Forward declarations for procedures defined later in this file: */ static int GetPostscriptPoints _ANSI_ARGS_((Tcl_Interp *interp, char *string, double *doublePtr)); int Tk_TablePsFont _ANSI_ARGS_((Tcl_Interp *interp, Table *tablePtr, Tk_Font tkfont)); int Tk_TablePsColor _ANSI_ARGS_((Tcl_Interp *interp, Table *tablePtr, XColor *colorPtr)); static int TextToPostscript _ANSI_ARGS_((Tcl_Interp *interp, Table *tablePtr, TableTag *tagPtr, int tagX, int tagY, int width, int height, int row, int col, Tk_TextLayout textLayout)); /* * Tcl could really use some more convenience routines... * This is just Tcl_DStringAppend for multiple lines, including * the full text of each line */ void Tcl_DStringAppendAll TCL_VARARGS_DEF(Tcl_DString *, arg1) { va_list argList; Tcl_DString *dstringPtr; char *string; dstringPtr = TCL_VARARGS_START(Tcl_DString *, arg1, argList); while ((string = va_arg(argList, char *)) != NULL) { Tcl_DStringAppend(dstringPtr, string, -1); } va_end(argList); } /* *-------------------------------------------------------------- * * Table_PostscriptCmd -- * * This procedure is invoked to process the "postscript" options * of the widget command for table widgets. See the user * documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ /* ARGSUSED */ int Table_PostscriptCmd(clientData, interp, objc, objv) ClientData clientData; /* Information about table widget. */ Tcl_Interp *interp; /* Current interpreter. */ int objc; /* Number of argument objects. */ Tcl_Obj *CONST objv[]; { #ifdef _WIN32 /* * At the moment, it just doesn't like this code... */ return TCL_OK; #else register Table *tablePtr = (Table *) clientData; TkPostscriptInfo psInfo, *oldInfoPtr; int result; int row, col, firstRow, firstCol, lastRow, lastCol; /* dimensions of first and last cell to output */ int x0, y0, w0, h0, xn, yn, wn, hn; int x, y, w, h, i; #define STRING_LENGTH 400 char string[STRING_LENGTH+1], *p; Arg *args; size_t length; int deltaX = 0, deltaY = 0; /* Offset of lower-left corner of area to * be marked up, measured in table units * from the positioning point on the page * (reflects anchor position). Initial * values needed only to stop compiler * warnings. */ Tcl_HashSearch search; Tcl_HashEntry *hPtr; CONST char * CONST *chunk; Tk_TextLayout textLayout = NULL; char *value; int rowHeight, total, *colWidths, iW, iH; TableTag *tagPtr, *colPtr, *rowPtr, *titlePtr; Tcl_DString postscript, buffer; if (objc < 2) { Tcl_WrongNumArgs(interp, 2, objv, "?option value ...?"); return TCL_ERROR; } /* *---------------------------------------------------------------- * Initialize the data structure describing Postscript generation, * then process all the arguments to fill the data structure in. *---------------------------------------------------------------- */ Tcl_DStringInit(&postscript); Tcl_DStringInit(&buffer); oldInfoPtr = tablePtr->psInfoPtr; tablePtr->psInfoPtr = &psInfo; /* This is where in the window that we start printing from */ psInfo.x = 0; psInfo.y = 0; psInfo.width = -1; psInfo.height = -1; psInfo.pageXString = NULL; psInfo.pageYString = NULL; psInfo.pageX = 72*4.25; psInfo.pageY = 72*5.5; psInfo.pageWidthString = NULL; psInfo.pageHeightString = NULL; psInfo.scale = 1.0; psInfo.pageAnchor = TK_ANCHOR_CENTER; psInfo.rotate = 0; psInfo.fontVar = NULL; psInfo.colorVar = NULL; psInfo.colorMode = NULL; psInfo.colorLevel = 0; psInfo.fileName = NULL; psInfo.channelName = NULL; psInfo.chan = NULL; psInfo.first = NULL; psInfo.last = NULL; Tcl_InitHashTable(&psInfo.fontTable, TCL_STRING_KEYS); /* * The magic StringifyObjects */ args = (Arg *) ckalloc((objc + 1) * sizeof(Arg)); for (i = 0; i < objc; i++) args[i] = LangStringArg(Tcl_GetString(objv[i])); args[i] = NULL; result = Tk_ConfigureWidget(interp, tablePtr->tkwin, configSpecs, objc-2, args+2, (char *) &psInfo, TK_CONFIG_ARGV_ONLY); if (result != TCL_OK) { goto cleanup; } if (psInfo.first == NULL) { firstRow = 0; firstCol = 0; } else if (TableGetIndex(tablePtr, psInfo.first, &firstRow, &firstCol) != TCL_OK) { result = TCL_ERROR; goto cleanup; } if (psInfo.last == NULL) { lastRow = tablePtr->rows-1; lastCol = tablePtr->cols-1; } else if (TableGetIndex(tablePtr, psInfo.last, &lastRow, &lastCol) != TCL_OK) { result = TCL_ERROR; goto cleanup; } if (psInfo.fileName != NULL) { /* Check that -file and -channel are not both specified. */ if (psInfo.channelName != NULL) { Tcl_AppendResult(interp, "can't specify both -file", " and -channel", (char *) NULL); result = TCL_ERROR; goto cleanup; } /* * Check that we are not in a safe interpreter. If we are, disallow * the -file specification. */ if (Tcl_IsSafe(interp)) { Tcl_AppendResult(interp, "can't specify -file in a", " safe interpreter", (char *) NULL); result = TCL_ERROR; goto cleanup; } p = Tcl_TranslateFileName(interp, psInfo.fileName, &buffer); if (p == NULL) { result = TCL_ERROR; goto cleanup; } psInfo.chan = Tcl_OpenFileChannel(interp, p, "w", 0666); Tcl_DStringFree(&buffer); Tcl_DStringInit(&buffer); if (psInfo.chan == NULL) { result = TCL_ERROR; goto cleanup; } } if (psInfo.channelName != NULL) { int mode; /* * Check that the channel is found in this interpreter and that it * is open for writing. */ psInfo.chan = Tcl_GetChannel(interp, psInfo.channelName, &mode); if (psInfo.chan == (Tcl_Channel) NULL) { result = TCL_ERROR; goto cleanup; } if ((mode & TCL_WRITABLE) == 0) { Tcl_AppendResult(interp, "channel \"", psInfo.channelName, "\" wasn't opened for writing", (char *) NULL); result = TCL_ERROR; goto cleanup; } } if (psInfo.colorMode == NULL) { psInfo.colorLevel = 2; } else { length = strlen(psInfo.colorMode); if (strncmp(psInfo.colorMode, "monochrome", length) == 0) { psInfo.colorLevel = 0; } else if (strncmp(psInfo.colorMode, "gray", length) == 0) { psInfo.colorLevel = 1; } else if (strncmp(psInfo.colorMode, "color", length) == 0) { psInfo.colorLevel = 2; } else { Tcl_AppendResult(interp, "bad color mode \"", psInfo.colorMode, "\": must be monochrome, gray or color", (char *) NULL); goto cleanup; } } TableCellCoords(tablePtr, firstRow, firstCol, &x0, &y0, &w0, &h0); TableCellCoords(tablePtr, lastRow, lastCol, &xn, &yn, &wn, &hn); psInfo.x = x0; psInfo.y = y0; if (psInfo.width == -1) { psInfo.width = xn+wn; } if (psInfo.height == -1) { psInfo.height = yn+hn; } psInfo.x2 = psInfo.x + psInfo.width; psInfo.y2 = psInfo.y + psInfo.height; if (psInfo.pageXString != NULL) { if (GetPostscriptPoints(interp, psInfo.pageXString, &psInfo.pageX) != TCL_OK) { goto cleanup; } } if (psInfo.pageYString != NULL) { if (GetPostscriptPoints(interp, psInfo.pageYString, &psInfo.pageY) != TCL_OK) { goto cleanup; } } if (psInfo.pageWidthString != NULL) { if (GetPostscriptPoints(interp, psInfo.pageWidthString, &psInfo.scale) != TCL_OK) { goto cleanup; } psInfo.scale /= psInfo.width; } else if (psInfo.pageHeightString != NULL) { if (GetPostscriptPoints(interp, psInfo.pageHeightString, &psInfo.scale) != TCL_OK) { goto cleanup; } psInfo.scale /= psInfo.height; } else { psInfo.scale = (72.0/25.4)*WidthMMOfScreen(Tk_Screen(tablePtr->tkwin)) / WidthOfScreen(Tk_Screen(tablePtr->tkwin)); } switch (psInfo.pageAnchor) { case TK_ANCHOR_NW: case TK_ANCHOR_W: case TK_ANCHOR_SW: deltaX = 0; break; case TK_ANCHOR_N: case TK_ANCHOR_CENTER: case TK_ANCHOR_S: deltaX = -psInfo.width/2; break; case TK_ANCHOR_NE: case TK_ANCHOR_E: case TK_ANCHOR_SE: deltaX = -psInfo.width; break; } switch (psInfo.pageAnchor) { case TK_ANCHOR_NW: case TK_ANCHOR_N: case TK_ANCHOR_NE: deltaY = - psInfo.height; break; case TK_ANCHOR_W: case TK_ANCHOR_CENTER: case TK_ANCHOR_E: deltaY = -psInfo.height/2; break; case TK_ANCHOR_SW: case TK_ANCHOR_S: case TK_ANCHOR_SE: deltaY = 0; break; } /* *-------------------------------------------------------- * Make a PREPASS over all of the tags * to collect information about all the fonts in use, so that * we can output font information in the proper form required * by the Document Structuring Conventions. *-------------------------------------------------------- */ Tk_TablePsFont(interp, tablePtr, tablePtr->defaultTag.tkfont); Tcl_ResetResult(interp); for (hPtr = Tcl_FirstHashEntry(tablePtr->tagTable, &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { tagPtr = (TableTag *) Tcl_GetHashValue(hPtr); if (tagPtr->tkfont != NULL) { Tk_TablePsFont(interp, tablePtr, tagPtr->tkfont); } } Tcl_ResetResult(interp); /* *-------------------------------------------------------- * Generate the header and prolog for the Postscript. *-------------------------------------------------------- */ sprintf(string, " %d,%d => %d,%d\n", firstRow, firstCol, lastRow, lastCol); Tcl_DStringAppendAll(&postscript, "%!PS-Adobe-3.0 EPSF-3.0\n", "%%Creator: Tk Table Widget ", TBL_VERSION, "\n", "%%Title: Window ", Tk_PathName(tablePtr->tkwin), string, "%%BoundingBox: ", (char *) NULL); if (!psInfo.rotate) { sprintf(string, "%d %d %d %d\n", (int) (psInfo.pageX + psInfo.scale*deltaX), (int) (psInfo.pageY + psInfo.scale*deltaY), (int) (psInfo.pageX + psInfo.scale*(deltaX + psInfo.width) + 1.0), (int) (psInfo.pageY + psInfo.scale*(deltaY + psInfo.height) + 1.0)); } else { sprintf(string, "%d %d %d %d\n", (int) (psInfo.pageX - psInfo.scale*(deltaY + psInfo.height)), (int) (psInfo.pageY + psInfo.scale*deltaX), (int) (psInfo.pageX - psInfo.scale*deltaY + 1.0), (int) (psInfo.pageY + psInfo.scale*(deltaX + psInfo.width) + 1.0)); } Tcl_DStringAppendAll(&postscript, string, "%%Pages: 1\n%%DocumentData: Clean7Bit\n", "%%Orientation: ", psInfo.rotate?"Landscape\n":"Portrait\n", (char *) NULL); p = "%%DocumentNeededResources: font "; for (hPtr = Tcl_FirstHashEntry(&psInfo.fontTable, &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { sprintf(string, "%s%s\n", p, Tcl_GetHashKey(&psInfo.fontTable, hPtr)); Tcl_DStringAppend(&postscript, string, -1); p = "%%+ font "; } Tcl_DStringAppend(&postscript, "%%EndComments\n\n", -1); /* * Insert the prolog */ for (chunk=prolog; *chunk; chunk++) { Tcl_DStringAppend(&postscript, *chunk, -1); } if (psInfo.chan != NULL) { Tcl_Write(psInfo.chan, Tcl_DStringValue(&postscript), -1); Tcl_DStringFree(&postscript); Tcl_DStringInit(&postscript); } /* * Document setup: set the color level and include fonts. * This is where we start using &postscript */ sprintf(string, "/CL %d def\n", psInfo.colorLevel); Tcl_DStringAppendAll(&postscript, "%%BeginSetup\n", string, (char *) NULL); for (hPtr = Tcl_FirstHashEntry(&psInfo.fontTable, &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { sprintf(string, "%s%s\n", "%%IncludeResource: font ", Tcl_GetHashKey(&psInfo.fontTable, hPtr)); Tcl_DStringAppend(&postscript, string, -1); } Tcl_DStringAppend(&postscript, "%%EndSetup\n\n", -1); /* * Page setup: move to page positioning point, rotate if * needed, set scale factor, offset for proper anchor position, * and set clip region. */ sprintf(string, "%.1f %.1f translate\n", psInfo.pageX, psInfo.pageY); Tcl_DStringAppendAll(&postscript, "%%Page: 1 1\nsave\n", string, psInfo.rotate?"90 rotate\n":"", (char *) NULL); sprintf(string, "%.4g %.4g scale\n%d %d translate\n", psInfo.scale, psInfo.scale, deltaX - psInfo.x, deltaY); Tcl_DStringAppend(&postscript, string, -1); sprintf(string, "%d %.15g moveto %d %.15g lineto %d %.15g lineto %d %.15g", psInfo.x, (double) psInfo.y2-psInfo.y, psInfo.x2,(double) psInfo.y2-psInfo.y, psInfo.x2, 0.0, psInfo.x, 0.0); Tcl_DStringAppend(&postscript, string, -1); Tcl_DStringAppend(&postscript, " lineto closepath clip newpath\n", -1); if (psInfo.chan != NULL) { Tcl_Write(psInfo.chan, Tcl_DStringValue(&postscript), -1); Tcl_DStringFree(&postscript); Tcl_DStringInit(&postscript); } /* * Go through each cell, calculating full desired height */ result = TCL_OK; hPtr = Tcl_FindHashEntry(tablePtr->tagTable, "title"); titlePtr = (TableTag *) Tcl_GetHashValue(hPtr); total = 0; colWidths = (int *) ckalloc((lastCol-firstCol) * sizeof(int)); for (col = 0; col <= lastCol-firstCol; col++) colWidths[col] = 0; Tcl_DStringAppend(&buffer, "gsave\n", -1); for (row = firstRow; row <= lastRow; row++) { rowHeight = 0; rowPtr = FindRowColTag(tablePtr, row+tablePtr->rowOffset, ROW); for (col = firstCol; col <= lastCol; col++) { /* get the coordinates for the cell */ TableCellCoords(tablePtr, row, col, &x, &y, &w, &h); if ((x >= psInfo.x2) || (x+w < psInfo.x) || (y >= psInfo.y2) || (y+h < psInfo.y)) { continue; } if (row == tablePtr->activeRow && col == tablePtr->activeCol) { value = tablePtr->activeBuf; } else { value = TableGetCellValue(tablePtr, row+tablePtr->rowOffset, col+tablePtr->colOffset); } if (!strlen(value)) { continue; } /* Create the tag here */ tagPtr = TableNewTag(); /* First, merge in the default tag */ TableMergeTag(tagPtr, &(tablePtr->defaultTag)); colPtr = FindRowColTag(tablePtr, col+tablePtr->colOffset, COL); if (colPtr != (TableTag *) NULL) TableMergeTag(tagPtr, colPtr); if (rowPtr != (TableTag *) NULL) TableMergeTag(tagPtr, rowPtr); /* Am I in the titles */ if (row < tablePtr->topRow || col < tablePtr->leftCol) { TableMergeTag(tagPtr, titlePtr); } /* Does this have a cell tag */ TableMakeArrayIndex(row+tablePtr->rowOffset, col+tablePtr->colOffset, string); hPtr = Tcl_FindHashEntry(tablePtr->cellStyles, string); if (hPtr != NULL) { TableMergeTag(tagPtr, (TableTag *) Tcl_GetHashValue(hPtr)); } /* * the use of -1 instead of Tcl_NumUtfChars means we don't * pass NULLs to postscript */ textLayout = Tk_ComputeTextLayout(tagPtr->tkfont, value, -1, (tagPtr->wrap>0) ? w : 0, tagPtr->justify, (tagPtr->multiline>0) ? 0 : TK_IGNORE_NEWLINES, &iW, &iH); rowHeight = MAX(rowHeight, iH); colWidths[col-firstCol] = MAX(colWidths[col-firstCol], iW); result = TextToPostscript(interp, tablePtr, tagPtr, x, y, iW, iH, row, col, textLayout); Tk_FreeTextLayout(textLayout); if (result != TCL_OK) { char msg[64 + TCL_INTEGER_SPACE]; sprintf(msg, "\n (generating Postscript for cell %s)", string); Tcl_AddErrorInfo(interp, msg); goto cleanup; } Tcl_DStringAppend(&buffer, Tcl_GetResult(interp), -1); } sprintf(string, "/row%d %d def\n", row, tablePtr->psInfoPtr->y2 - total); Tcl_DStringAppend(&postscript, string, -1); total += rowHeight + 2*tablePtr->defaultTag.bd; } Tcl_DStringAppend(&buffer, "grestore\n", -1); sprintf(string, "/row%d %d def\n", row, tablePtr->psInfoPtr->y2 - total); Tcl_DStringAppend(&postscript, string, -1); total = tablePtr->defaultTag.bd; for (col = firstCol; col <= lastCol; col++) { sprintf(string, "/col%d %d def\n", col, total); Tcl_DStringAppend(&postscript, string, -1); total += colWidths[col-firstCol] + 2*tablePtr->defaultTag.bd; } sprintf(string, "/col%d %d def\n", col, total); Tcl_DStringAppend(&postscript, string, -1); Tcl_DStringAppend(&postscript, Tcl_DStringValue(&buffer), -1); /* * Output to channel at the end of it all * This should more incremental, but that can't be avoided in order * to post-define width/height of the cols/rows */ if (psInfo.chan != NULL) { Tcl_Write(psInfo.chan, Tcl_DStringValue(&postscript), -1); Tcl_DStringFree(&postscript); Tcl_DStringInit(&postscript); } /* *--------------------------------------------------------------------- * Output page-end information, such as commands to print the page * and document trailer stuff. *--------------------------------------------------------------------- */ Tcl_DStringAppend(&postscript, "restore showpage\n\n%%Trailer\nend\n%%EOF\n", -1); if (psInfo.chan != NULL) { Tcl_Write(psInfo.chan, Tcl_DStringValue(&postscript), -1); Tcl_DStringFree(&postscript); Tcl_DStringInit(&postscript); } /* * Clean up psInfo to release malloc'ed stuff. */ cleanup: ckfree((char *) args); Tcl_DStringResult(interp, &postscript); Tcl_DStringFree(&postscript); Tcl_DStringFree(&buffer); if (psInfo.first != NULL) { ckfree(psInfo.first); } if (psInfo.last != NULL) { ckfree(psInfo.last); } if (psInfo.pageXString != NULL) { ckfree(psInfo.pageXString); } if (psInfo.pageYString != NULL) { ckfree(psInfo.pageYString); } if (psInfo.pageWidthString != NULL) { ckfree(psInfo.pageWidthString); } if (psInfo.pageHeightString != NULL) { ckfree(psInfo.pageHeightString); } if (psInfo.fontVar != NULL) { LangFreeVar(psInfo.fontVar); } if (psInfo.colorVar != NULL) { LangFreeVar(psInfo.colorVar); } if (psInfo.colorMode != NULL) { ckfree(psInfo.colorMode); } if (psInfo.fileName != NULL) { ckfree(psInfo.fileName); } if ((psInfo.chan != NULL) && (psInfo.channelName == NULL)) { Tcl_Close(interp, psInfo.chan); } if (psInfo.channelName != NULL) { ckfree(psInfo.channelName); } Tcl_DeleteHashTable(&psInfo.fontTable); tablePtr->psInfoPtr = oldInfoPtr; return result; #endif } /* *-------------------------------------------------------------- * * Tk_TablePsColor -- * * This procedure is called by individual table items when * they want to set a color value for output. Given information * about an X color, this procedure will generate Postscript * commands to set up an appropriate color in Postscript. * * Results: * Returns a standard Tcl return value. If an error occurs * then an error message will be left in the interp's result. * If no error occurs, then additional Postscript will be * appended to the interp's result. * * Side effects: * None. * *-------------------------------------------------------------- */ int Tk_TablePsColor(interp, tablePtr, colorPtr) Tcl_Interp *interp; /* Interpreter for returning Postscript * or error message. */ Table *tablePtr; /* Information about table. */ XColor *colorPtr; /* Information about color. */ { TkPostscriptInfo *psInfoPtr = tablePtr->psInfoPtr; int tmp; double red, green, blue; char string[200]; /* * If there is a color map defined, then look up the color's name * in the map and use the Postscript commands found there, if there * are any. */ if (psInfoPtr->colorVar != NULL) { Arg cmdString; cmdString = Tcl_GetVar2(interp, psInfoPtr->colorVar, Tk_NameOfColor(colorPtr), 0); if (cmdString != NULL) { Tcl_AppendResult(interp, LangString(cmdString), "\n", (char *) NULL); return TCL_OK; } } /* * No color map entry for this color. Grab the color's intensities * and output Postscript commands for them. Special note: X uses * a range of 0-65535 for intensities, but most displays only use * a range of 0-255, which maps to (0, 256, 512, ... 65280) in the * X scale. This means that there's no way to get perfect white, * since the highest intensity is only 65280 out of 65535. To * work around this problem, rescale the X intensity to a 0-255 * scale and use that as the basis for the Postscript colors. This * scheme still won't work if the display only uses 4 bits per color, * but most diplays use at least 8 bits. */ tmp = colorPtr->red; red = ((double) (tmp >> 8))/255.0; tmp = colorPtr->green; green = ((double) (tmp >> 8))/255.0; tmp = colorPtr->blue; blue = ((double) (tmp >> 8))/255.0; sprintf(string, "%.3f %.3f %.3f AdjustColor\n", red, green, blue); Tcl_AppendResult(interp, string, (char *) NULL); return TCL_OK; } /* *-------------------------------------------------------------- * * Tk_TablePsFont -- * * This procedure is called by individual table items when * they want to output text. Given information about an X * font, this procedure will generate Postscript commands * to set up an appropriate font in Postscript. * * Results: * Returns a standard Tcl return value. If an error occurs * then an error message will be left in the interp's result. * If no error occurs, then additional Postscript will be * appended to the interp's result. * * Side effects: * The Postscript font name is entered into psInfoPtr->fontTable * if it wasn't already there. * *-------------------------------------------------------------- */ int Tk_TablePsFont(interp, tablePtr, tkfont) Tcl_Interp *interp; /* Interpreter for returning Postscript * or error message. */ Table *tablePtr; /* Information about table. */ Tk_Font tkfont; /* Information about font in which text * is to be printed. */ { TkPostscriptInfo *psInfoPtr = tablePtr->psInfoPtr; char *end; char pointString[TCL_INTEGER_SPACE]; Tcl_DString ds; int i, points; /* * First, look up the font's name in the font map, if there is one. * If there is an entry for this font, it consists of a list * containing font name and size. Use this information. */ Tcl_DStringInit(&ds); if (psInfoPtr->fontVar != NULL) { Arg list; Arg *objv; int objc; double size; char *name; name = Tk_NameOfFont(tkfont); list = Tcl_GetVar2(interp, psInfoPtr->fontVar, name, 0); if (list != NULL) { if (Tcl_ListObjGetElements(interp, list, &objc, &objv) != TCL_OK) { badMapEntry: Tcl_ResetResult(interp); Tcl_AppendResult(interp, "bad font map entry for \"", name, "\": \"", list, "\"", (char *) NULL); return TCL_ERROR; } if (objc != 2) { goto badMapEntry; } size = strtod(LangString(objv[1]), &end); if ((size <= 0) || (*end != 0)) { goto badMapEntry; } Tcl_DStringAppend(&ds, LangString(objv[0]), -1); points = (int) size; ckfree((char *) objv); goto findfont; } } points = Tk_PostscriptFontName(tkfont, &ds); findfont: sprintf(pointString, "%d", points); Tcl_AppendResult(interp, pointString, " /", Tcl_DStringValue(&ds), " SetFont\n", (char *) NULL); Tcl_CreateHashEntry(&psInfoPtr->fontTable, Tcl_DStringValue(&ds), &i); Tcl_DStringFree(&ds); return TCL_OK; } /* *-------------------------------------------------------------- * * GetPostscriptPoints -- * * Given a string, returns the number of Postscript points * corresponding to that string. * * Results: * The return value is a standard Tcl return result. If * TCL_OK is returned, then everything went well and the * screen distance is stored at *doublePtr; otherwise * TCL_ERROR is returned and an error message is left in * the interp's result. * * Side effects: * None. * *-------------------------------------------------------------- */ static int GetPostscriptPoints(interp, string, doublePtr) Tcl_Interp *interp; /* Use this for error reporting. */ char *string; /* String describing a screen distance. */ double *doublePtr; /* Place to store converted result. */ { char *end; double d; d = strtod(string, &end); if (end == string) { error: Tcl_AppendResult(interp, "bad distance \"", string, "\"", (char *) NULL); return TCL_ERROR; } #define UCHAR(c) ((unsigned char) (c)) while ((*end != '\0') && isspace(UCHAR(*end))) { end++; } switch (*end) { case 'c': d *= 72.0/2.54; end++; break; case 'i': d *= 72.0; end++; break; case 'm': d *= 72.0/25.4; end++; break; case 0: break; case 'p': end++; break; default: goto error; } while ((*end != '\0') && isspace(UCHAR(*end))) { end++; } if (*end != 0) { goto error; } *doublePtr = d; return TCL_OK; } /* *-------------------------------------------------------------- * * TextToPostscript -- * * This procedure is called to generate Postscript for * text items. * * Results: * The return value is a standard Tcl result. If an error * occurs in generating Postscript then an error message is * left in the interp's result, replacing whatever used * to be there. If no error occurs, then Postscript for the * item is appended to the result. * * Side effects: * None. * *-------------------------------------------------------------- */ static int TextToPostscript(interp, tablePtr, tagPtr, tagX, tagY, width, height, row, col, textLayout) Tcl_Interp *interp; /* Leave Postscript or error message here. */ Table *tablePtr; /* Information about overall canvas. */ TableTag *tagPtr; /* */ int tagX, tagY; /* */ int width, height; /* */ int row, col; /* */ Tk_TextLayout textLayout; /* */ { int x, y; Tk_FontMetrics fm; char *justify; char buffer[500]; Tk_3DBorder fg = tagPtr->fg; if (fg == NULL) { fg = tablePtr->defaultTag.fg; } if (Tk_TablePsFont(interp, tablePtr, tagPtr->tkfont) != TCL_OK) { return TCL_ERROR; } if (Tk_TablePsColor(interp, tablePtr, Tk_3DBorderColor(fg)) != TCL_OK) { return TCL_ERROR; } sprintf(buffer, "%% %.15g %.15g [\n", (tagX+width)/2.0, tablePtr->psInfoPtr->y2 - ((tagY+height)/2.0)); Tcl_AppendResult(interp, buffer, (char *) NULL); sprintf(buffer, "col%d row%d [\n", col, row); Tcl_AppendResult(interp, buffer, (char *) NULL); Tk_TextLayoutToPostscript(interp, textLayout); x = 0; y = 0; justify = NULL; /* lint. */ switch (tagPtr->anchor) { case TK_ANCHOR_NW: x = 0; y = 0; break; case TK_ANCHOR_N: x = 1; y = 0; break; case TK_ANCHOR_NE: x = 2; y = 0; break; case TK_ANCHOR_E: x = 2; y = 1; break; case TK_ANCHOR_SE: x = 2; y = 2; break; case TK_ANCHOR_S: x = 1; y = 2; break; case TK_ANCHOR_SW: x = 0; y = 2; break; case TK_ANCHOR_W: x = 0; y = 1; break; case TK_ANCHOR_CENTER: x = 1; y = 1; break; } switch (tagPtr->justify) { case TK_JUSTIFY_RIGHT: justify = "1"; break; case TK_JUSTIFY_CENTER: justify = "0.5";break; case TK_JUSTIFY_LEFT: justify = "0"; } Tk_GetFontMetrics(tagPtr->tkfont, &fm); sprintf(buffer, "] %d %g %g %s %d %d DrawCellText\n", fm.linespace, (x / -2.0), (y / 2.0), justify, width, height); Tcl_AppendResult(interp, buffer, (char *) NULL); return TCL_OK; } ���������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable/tkTableCellSort.c�����������������������������������������������0000644�0000000�0000000�00000007723�13745605157�021037� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * tkTableCell.c -- * * This module implements cell sort functions for table * widgets. The MergeSort algorithm and other aux sorting * functions were taken from tclCmdIL.c lsort command: * tclCmdIL.c -- * * This file contains the top-level command routines for most of * the Tcl built-in commands whose names begin with the letters * I through L. It contains only commands in the generic core * (i.e. those that don't depend much upon UNIX facilities). * * Copyright (c) 1987-1993 The Regents of the University of California. * Copyright (c) 1993-1997 Lucent Technologies. * Copyright (c) 1994-1997 Sun Microsystems, Inc. * Copyright (c) 1998-1999 by Scriptics Corporation. * * Copyright (c) 1998-2002 Jeffrey Hobbs * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * */ #include "tkTable.h" #ifndef UCHAR #define UCHAR(c) ((unsigned char) (c)) #endif /* *---------------------------------------------------------------------- * * TableSortCompareProc -- * This procedure is invoked by qsort to determine the proper * ordering between two elements. * * Results: * < 0 means first is "smaller" than "second", > 0 means "first" * is larger than "second", and 0 means they should be treated * as equal. * * Side effects: * None, unless a user-defined comparison command does something * weird. * *---------------------------------------------------------------------- */ static int TableSortCompareProc(first, second) CONST VOID *first, *second; /* Elements to be compared. */ { int r1, c1, r2, c2; char *firstString; char *secondString; firstString = Tcl_GetString( *((Arg*) first)); secondString = Tcl_GetString(*((Arg*) second)); /* This doesn't account for badly formed indices */ sscanf(firstString, "%d,%d", &r1, &c1); sscanf(secondString, "%d,%d", &r2, &c2); if (r1 > r2) { return 1; } else if (r1 < r2) { return -1; } else if (c1 > c2) { return 1; } else if (c1 < c2) { return -1; } return 0; } /* *---------------------------------------------------------------------- * * TableCellSort -- * Sort a list of table cell elements (of form row,col) * * Results: * Returns the sorted list of elements. Because Tcl_Merge allocs * the space for result, it must later be Tcl_Free'd by caller. * * Side effects: * Behaviour undefined for ill-formed input list of elements. * *---------------------------------------------------------------------- */ Arg TableCellSort(Table *tablePtr, char *str) { int listArgc; Arg *listArgv; Arg result; Arg argstr; argstr = LangStringArg(str); if (Tcl_ListObjGetElements(tablePtr->interp, argstr, &listArgc, &listArgv) != TCL_OK) { ckfree((char *) argstr); return LangStringArg(str); } qsort((VOID *) listArgv, (size_t) listArgc, sizeof (char *), TableSortCompareProc); result = Tcl_NewListObj(listArgc, listArgv); return result; } /* *---------------------------------------------------------------------- * * TableCellSortObj -- * Sorts a list of table cell elements (of form row,col) in place * * Results: * Sorts list of elements in place. * * Side effects: * Behaviour undefined for ill-formed input list of elements. * *---------------------------------------------------------------------- */ Tcl_Obj * TableCellSortObj(Tcl_Interp *interp, Tcl_Obj *listObjPtr) { int length, i; Tcl_Obj* result; Tcl_Obj *sortedObjPtr, **listObjPtrs; if (Tcl_ListObjGetElements(interp, listObjPtr, &length, &listObjPtrs) != TCL_OK) { return NULL; } if (length <= 0) { return listObjPtr; } qsort((VOID *) listObjPtrs, (size_t) length, sizeof (char *), TableSortCompareProc); result = Tcl_NewListObj(length, listObjPtrs); return result; } ���������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable/tkTableTag.c����������������������������������������������������0000644�0000000�0000000�00000121314�13745605157�020014� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * tkTableTag.c -- * * This module implements tags for table widgets. * * Copyright (c) 1998-2002 Jeffrey Hobbs * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tkTableTag.c,v 1.18 2004/02/08 03:09:46 cerney Exp $ */ #include "tkVMacro.h" #include "tkTable.h" static TableTag *TableTagGetEntry _ANSI_ARGS_((Table *tablePtr, char *name, int objc, char **argv)); static unsigned int TableTagGetPriority _ANSI_ARGS_((Table *tablePtr, TableTag *tagPtr)); static void TableImageProc _ANSI_ARGS_((ClientData clientData, int x, int y, int width, int height, int imageWidth, int imageHeight)); static int TableOptionReliefSet _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, Arg value, char *widgRec, int offset)); static Arg TableOptionReliefGet _ANSI_ARGS_((ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)); static CONST char *tagCmdNames[] = { "celltag", "cget", "coltag", "configure", "delete", "exists", "includes", "lower", "names", "raise", "rowtag", (char *) NULL }; enum tagCmd { TAG_CELLTAG, TAG_CGET, TAG_COLTAG, TAG_CONFIGURE, TAG_DELETE, TAG_EXISTS, TAG_INCLUDES, TAG_LOWER, TAG_NAMES, TAG_RAISE, TAG_ROWTAG }; static Cmd_Struct tagState_vals[]= { {"unknown", STATE_UNKNOWN}, {"normal", STATE_NORMAL}, {"disabled", STATE_DISABLED}, {"", 0 } }; static Tk_CustomOption tagStateOpt = { Cmd_OptionSet, Cmd_OptionGet, (ClientData) (&tagState_vals) }; static Tk_CustomOption tagBdOpt = { TableOptionBdSet, TableOptionBdGet, (ClientData) BD_TABLE_TAG }; static Tk_CustomOption tagReliefOpt = { TableOptionReliefSet, TableOptionReliefGet, (ClientData) NULL }; /* * The default specification for configuring tags * Done like this to make the command line parsing easy */ static Tk_ConfigSpec tagConfig[] = { {TK_CONFIG_ANCHOR, "-anchor", "anchor", "Anchor", "center", Tk_Offset(TableTag, anchor), TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK }, {TK_CONFIG_BORDER, "-background", "background", "Background", NULL, Tk_Offset(TableTag, bg), TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK }, {TK_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL, 0, 0}, {TK_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0}, {TK_CONFIG_CUSTOM, "-borderwidth", "borderWidth", "BorderWidth", "", 0 /* no offset */, TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK, &tagBdOpt }, {TK_CONFIG_BORDER, "-foreground", "foreground", "Foreground", NULL, Tk_Offset(TableTag, fg), TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK }, {TK_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL, (char *)NULL, 0, 0}, {TK_CONFIG_FONT, "-font", "font", "Font", NULL, Tk_Offset(TableTag, tkfont), TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK }, {TK_CONFIG_STRING, "-image", "image", "Image", NULL, Tk_Offset(TableTag, imageStr), TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK }, {TK_CONFIG_JUSTIFY, "-justify", "justify", "Justify", "left", Tk_Offset(TableTag, justify), TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK }, {TK_CONFIG_INT, "-multiline", "multiline", "Multiline", "-1", Tk_Offset(TableTag, multiline), TK_CONFIG_DONT_SET_DEFAULT }, {TK_CONFIG_CUSTOM, "-relief", "relief", "Relief", "flat", Tk_Offset(TableTag, relief), TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK, &tagReliefOpt }, {TK_CONFIG_INT, "-showtext", "showText", "ShowText", "-1", Tk_Offset(TableTag, showtext), TK_CONFIG_DONT_SET_DEFAULT }, {TK_CONFIG_CUSTOM, "-state", "state", "State", "unknown", Tk_Offset(TableTag, state), TK_CONFIG_DONT_SET_DEFAULT, &tagStateOpt }, {TK_CONFIG_INT, "-wrap", "wrap", "Wrap", "-1", Tk_Offset(TableTag, wrap), TK_CONFIG_DONT_SET_DEFAULT }, {TK_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; /* * The join tag structure is used to create a combined tag, so it * keeps priority info. */ typedef struct { TableTag tag; /* must be first */ unsigned int magic; unsigned int pbg, pfg, pborders, prelief, ptkfont, panchor, pimage; unsigned int pstate, pjustify, pmultiline, pwrap, pshowtext; } TableJoinTag; /* *---------------------------------------------------------------------- * * TableImageProc -- * Called when an image associated with a tag is changed. * * Results: * None. * * Side effects: * Invalidates the whole table. * This should only invalidate affected cells, but that info * is not managed... * *---------------------------------------------------------------------- */ static void TableImageProc(ClientData clientData, int x, int y, int width, int height, int imageWidth, int imageHeight) { TableInvalidateAll((Table *)clientData, 0); } /* *---------------------------------------------------------------------- * * TableNewTag -- * ckallocs space for a new tag structure and inits the structure. * * Results: * Returns a pointer to the new structure. Must be freed later. * * Side effects: * None. * *---------------------------------------------------------------------- */ TableTag * TableNewTag(Table *tablePtr) { TableTag *tagPtr; /* * If tablePtr is NULL, make a regular tag, otherwise make a join tag. */ if (tablePtr == NULL) { tagPtr = (TableTag *) ckalloc(sizeof(TableTag)); memset((VOID *) tagPtr, 0, sizeof(TableTag)); /* * Set the values that aren't 0/NULL by default */ tagPtr->anchor = (Tk_Anchor)-1; tagPtr->justify = (Tk_Justify)-1; tagPtr->multiline = -1; tagPtr->relief = -1; tagPtr->showtext = -1; tagPtr->state = STATE_UNKNOWN; tagPtr->wrap = -1; } else { TableJoinTag *jtagPtr = (TableJoinTag *) ckalloc(sizeof(TableJoinTag)); memset((VOID *) jtagPtr, 0, sizeof(TableJoinTag)); tagPtr = (TableTag *) jtagPtr; tagPtr->anchor = (Tk_Anchor)-1; tagPtr->justify = (Tk_Justify)-1; tagPtr->multiline = -1; tagPtr->relief = -1; tagPtr->showtext = -1; tagPtr->state = STATE_UNKNOWN; tagPtr->wrap = -1; jtagPtr->magic = 0x99ABCDEF; jtagPtr->pbg = -1; jtagPtr->pfg = -1; jtagPtr->pborders = -1; jtagPtr->prelief = -1; jtagPtr->ptkfont = -1; jtagPtr->panchor = -1; jtagPtr->pimage = -1; jtagPtr->pstate = -1; jtagPtr->pjustify = -1; jtagPtr->pmultiline = -1; jtagPtr->pwrap = -1; jtagPtr->pshowtext = -1; } return (TableTag *) tagPtr; } /* *---------------------------------------------------------------------- * * TableResetTag -- * This routine resets a given tag to the table defaults. * * Results: * Tag will have values changed. * * Side effects: * None. * *---------------------------------------------------------------------- */ void TableResetTag(Table *tablePtr, TableTag *tagPtr) { TableJoinTag *jtagPtr = (TableJoinTag *) tagPtr; if (jtagPtr->magic != 0x99ABCDEF) { panic("bad mojo in TableResetTag"); } memset((VOID *) jtagPtr, 0, sizeof(TableJoinTag)); tagPtr->anchor = (Tk_Anchor)-1; tagPtr->justify = (Tk_Justify)-1; tagPtr->multiline = -1; tagPtr->relief = -1; tagPtr->showtext = -1; tagPtr->state = STATE_UNKNOWN; tagPtr->wrap = -1; jtagPtr->magic = 0x99ABCDEF; jtagPtr->pbg = -1; jtagPtr->pfg = -1; jtagPtr->pborders = -1; jtagPtr->prelief = -1; jtagPtr->ptkfont = -1; jtagPtr->panchor = -1; jtagPtr->pimage = -1; jtagPtr->pstate = -1; jtagPtr->pjustify = -1; jtagPtr->pmultiline = -1; jtagPtr->pwrap = -1; jtagPtr->pshowtext = -1; /* * Merge in the default tag. */ memcpy((VOID *) jtagPtr, (VOID *) &(tablePtr->defaultTag), sizeof(TableTag)); } /* *---------------------------------------------------------------------- * * TableMergeTag -- * This routine merges two tags by adding any fields from the addTag * that are set to the baseTag. * * Results: * baseTag will inherit all set characteristics of addTag * (addTag thus has the priority). * * Side effects: * None. * *---------------------------------------------------------------------- */ void TableMergeTag(Table *tablePtr, TableTag *baseTag, TableTag *addTag) { TableJoinTag *jtagPtr = (TableJoinTag *) baseTag; unsigned int prio; if (jtagPtr->magic != 0x99ABCDEF) { panic("bad mojo in TableMergeTag"); } #ifndef NO_TAG_PRIORITIES /* * Find priority for the tag to merge */ prio = TableTagGetPriority(tablePtr, addTag); if ((addTag->anchor != -1) && (prio < jtagPtr->panchor)) { baseTag->anchor = addTag->anchor; jtagPtr->panchor = prio; } if ((addTag->bg != NULL) && (prio < jtagPtr->pbg)) { baseTag->bg = addTag->bg; jtagPtr->pbg = prio; } if ((addTag->fg != NULL) && (prio < jtagPtr->pfg)) { baseTag->fg = addTag->fg; jtagPtr->pfg = prio; } if ((addTag->tkfont != NULL) && (prio < jtagPtr->ptkfont)) { baseTag->tkfont = addTag->tkfont; jtagPtr->ptkfont = prio; } if ((addTag->imageStr != NULL) && (prio < jtagPtr->pimage)) { baseTag->imageStr = addTag->imageStr; baseTag->image = addTag->image; jtagPtr->pimage = prio; } if ((addTag->multiline >= 0) && (prio < jtagPtr->pmultiline)) { baseTag->multiline = addTag->multiline; jtagPtr->pmultiline = prio; } if ((addTag->relief != -1) && (prio < jtagPtr->prelief)) { baseTag->relief = addTag->relief; jtagPtr->prelief = prio; } if ((addTag->showtext >= 0) && (prio < jtagPtr->pshowtext)) { baseTag->showtext = addTag->showtext; jtagPtr->pshowtext = prio; } if ((addTag->state != STATE_UNKNOWN) && (prio < jtagPtr->pstate)) { baseTag->state = addTag->state; jtagPtr->pstate = prio; } if ((addTag->justify != -1) && (prio < jtagPtr->pjustify)) { baseTag->justify = addTag->justify; jtagPtr->pjustify = prio; } if ((addTag->wrap >= 0) && (prio < jtagPtr->pwrap)) { baseTag->wrap = addTag->wrap; jtagPtr->pwrap = prio; } if ((addTag->borders) && (prio < jtagPtr->pborders)) { baseTag->borderStr = addTag->borderStr; baseTag->borders = addTag->borders; baseTag->bd[0] = addTag->bd[0]; baseTag->bd[1] = addTag->bd[1]; baseTag->bd[2] = addTag->bd[2]; baseTag->bd[3] = addTag->bd[3]; jtagPtr->pborders = prio; } #else if (addTag->anchor != -1) baseTag->anchor = addTag->anchor; if (addTag->bg != NULL) baseTag->bg = addTag->bg; if (addTag->fg != NULL) baseTag->fg = addTag->fg; if (addTag->tkfont != NULL) baseTag->tkfont = addTag->tkfont; if (addTag->imageStr != NULL) { baseTag->imageStr = addTag->imageStr; baseTag->image = addTag->image; } if (addTag->multiline >= 0) baseTag->multiline = addTag->multiline; if (addTag->relief != -1) baseTag->relief = addTag->relief; if (addTag->showtext >= 0) baseTag->showtext = addTag->showtext; if (addTag->state != STATE_UNKNOWN) baseTag->state = addTag->state; if (addTag->justify != -1) baseTag->justify = addTag->justify; if (addTag->wrap >= 0) baseTag->wrap = addTag->wrap; if (addTag->borders) { baseTag->borderStr = addTag->borderStr; baseTag->borders = addTag->borders; baseTag->bd[0] = addTag->bd[0]; baseTag->bd[1] = addTag->bd[1]; baseTag->bd[2] = addTag->bd[2]; baseTag->bd[3] = addTag->bd[3]; } #endif } /* *---------------------------------------------------------------------- * * TableInvertTag -- * This routine swaps background and foreground for the selected tag. * * Results: * Inverts fg and bg of tag. * * Side effects: * None. * *---------------------------------------------------------------------- */ void TableInvertTag(TableTag *baseTag) { Tk_3DBorder tmpBg; tmpBg = baseTag->fg; baseTag->fg = baseTag->bg; baseTag->bg = tmpBg; } /* *---------------------------------------------------------------------- * * TableGetTagBorders -- * This routine gets the border values based on a tag. * * Results: * It returns the values in the int*'s (if not NULL), and the * total number of defined borders as a result. * * Side effects: * None. * *---------------------------------------------------------------------- */ int TableGetTagBorders(TableTag *tagPtr, int *left, int *right, int *top, int *bottom) { switch (tagPtr->borders) { case 0: if (left) { *left = 0; } if (right) { *right = 0; } if (top) { *top = 0; } if (bottom) { *bottom = 0; } break; case 1: if (left) { *left = tagPtr->bd[0]; } if (right) { *right = tagPtr->bd[0]; } if (top) { *top = tagPtr->bd[0]; } if (bottom) { *bottom = tagPtr->bd[0]; } break; case 2: if (left) { *left = tagPtr->bd[0]; } if (right) { *right = tagPtr->bd[1]; } if (top) { *top = 0; } if (bottom) { *bottom = 0; } break; case 4: if (left) { *left = tagPtr->bd[0]; } if (right) { *right = tagPtr->bd[1]; } if (top) { *top = tagPtr->bd[2]; } if (bottom) { *bottom = tagPtr->bd[3]; } break; default: panic("invalid border value '%d'\n", tagPtr->borders); break; } return tagPtr->borders; } /* *---------------------------------------------------------------------- * * TableTagGetEntry -- * Takes a name and optional args and creates a tag entry in the * table's tag table. * * Results: * A new tag entry will be created and returned. * * Side effects: * None. * *---------------------------------------------------------------------- */ static TableTag * TableTagGetEntry(Table *tablePtr, char *name, int objc, char **argv) { Tcl_HashEntry *entryPtr; TableTag *tagPtr = NULL; int new; entryPtr = Tcl_CreateHashEntry(tablePtr->tagTable, name, &new); if (new) { tagPtr = TableNewTag(NULL); Tcl_SetHashValue(entryPtr, (ClientData) tagPtr); if (tablePtr->tagPrioSize >= tablePtr->tagPrioMax) { int i; /* * Increase the priority list size in blocks of 10 */ tablePtr->tagPrioMax += 10; tablePtr->tagPrioNames = (char **) ckrealloc( (char *) tablePtr->tagPrioNames, sizeof(TableTag *) * tablePtr->tagPrioMax); tablePtr->tagPrios = (TableTag **) ckrealloc( (char *) tablePtr->tagPrios, sizeof(TableTag *) * tablePtr->tagPrioMax); for (i = tablePtr->tagPrioSize; i < tablePtr->tagPrioMax; i++) { tablePtr->tagPrioNames[i] = (char *) NULL; tablePtr->tagPrios[i] = (TableTag *) NULL; } } tablePtr->tagPrioNames[tablePtr->tagPrioSize] = (char *) Tcl_GetHashKey(tablePtr->tagTable, entryPtr); tablePtr->tagPrios[tablePtr->tagPrioSize] = tagPtr; tablePtr->tagPrioSize++; } else { tagPtr = (TableTag *) Tcl_GetHashValue(entryPtr); } if (objc) { Tk_ConfigureWidget(tablePtr->interp, tablePtr->tkwin, tagConfig, objc, argv, (char *)tagPtr, TK_CONFIG_ARGV_ONLY); } return tagPtr; } /* *---------------------------------------------------------------------- * * TableTagGetPriority -- * Get the priority value for a tag. * * Results: * returns the priority. * * Side effects: * None. * *---------------------------------------------------------------------- */ static unsigned int TableTagGetPriority(Table *tablePtr, TableTag *tagPtr) { unsigned int prio = 0; while (tagPtr != tablePtr->tagPrios[prio]) { prio++; } return prio; } /* *---------------------------------------------------------------------- * * TableInitTags -- * Creates the static table tags. * * Results: * active, sel, title and flash are created as tags. * * Side effects: * None. * *---------------------------------------------------------------------- */ void TableInitTags(Table *tablePtr) { Arg activeArgs[4]; Arg selArgs[6]; Arg titleArgs[8]; Arg flashArgs[2]; activeArgs[0]= LangStringArg("-bg"); activeArgs[1]= LangStringArg(ACTIVE_BG); activeArgs[2]=LangStringArg("-relief"); activeArgs[3]=LangStringArg("flat"); selArgs[0]= LangStringArg("-bg"); selArgs[1]=LangStringArg(SELECT_BG); selArgs[2]=LangStringArg("-fg"); selArgs[3]=LangStringArg(SELECT_FG); selArgs[4]=LangStringArg("-relief"); selArgs[5]=LangStringArg("sunken"); titleArgs[0]=LangStringArg("-bg"), titleArgs[1]=LangStringArg(DISABLED), titleArgs[2]=LangStringArg("-fg"), titleArgs[3]=LangStringArg("white"), titleArgs[4]=LangStringArg("-relief"), titleArgs[5]=LangStringArg("flat"), titleArgs[6]=LangStringArg("-state"), titleArgs[7]=LangStringArg("disabled"); flashArgs[0]= LangStringArg("-bg"); flashArgs[1]=LangStringArg("red"); /* * The order of creation is important to priority. */ TableTagGetEntry(tablePtr, "flash", ARSIZE(flashArgs), flashArgs); TableTagGetEntry(tablePtr, "active", ARSIZE(activeArgs), activeArgs); TableTagGetEntry(tablePtr, "sel", ARSIZE(selArgs), selArgs); TableTagGetEntry(tablePtr, "title", ARSIZE(titleArgs), titleArgs); } /* *---------------------------------------------------------------------- * * FindRowColTag -- * Finds a row/col tag based on the row/col styles and tagCommand. * * Results: * Returns tag associated with row/col cell, if any. * * Side effects: * Possible side effects from eval of tagCommand. * IMPORTANT: This plays with the interp result object, * so use of resultPtr in prior command may be invalid after * calling this function. * *---------------------------------------------------------------------- */ TableTag * FindRowColTag(Table *tablePtr, int cell, int mode) { Tcl_HashEntry *entryPtr; TableTag *tagPtr = NULL; /* kill(0,2); */ entryPtr = Tcl_FindHashEntry((mode == ROW) ? tablePtr->rowStyles : tablePtr->colStyles, (char *) cell); if (entryPtr == NULL) { LangCallback *cmd = (mode == ROW) ? tablePtr->rowTagCmd : tablePtr->colTagCmd; if (cmd) { register Tcl_Interp *interp = tablePtr->interp; char buf[INDEX_BUFSIZE]; /* * Since no specific row/col tag exists, eval the given command * with row/col appended */ sprintf(buf, " %d", cell); Tcl_Preserve((ClientData) interp); if ( LangDoCallback(interp, cmd, 1, 1, " %d", cell) == TCL_OK) { CONST char *name = Tcl_GetStringFromObj(Tcl_GetObjResult(interp),NULL); if (name && *name) { /* * If a result was returned, check to see if it is * a valid tag. */ entryPtr = Tcl_FindHashEntry(tablePtr->tagTable, name); } } Tcl_Release((ClientData) interp); Tcl_ResetResult(interp); } } if (entryPtr != NULL) { /* * This can be either the one in row|colStyles, * or that returned by eval'ing the row|colTagCmd */ tagPtr = (TableTag *) Tcl_GetHashValue(entryPtr); } return tagPtr; } /* *---------------------------------------------------------------------- * * TableCleanupTag -- * Releases the resources used by a tag before it is freed up. * * Results: * None. * * Side effects: * The tag is no longer valid. * *---------------------------------------------------------------------- */ void TableCleanupTag(Table *tablePtr, TableTag *tagPtr) { /* * Free resources that the optionSpec doesn't specifically know about */ if (tagPtr->image) { Tk_FreeImage(tagPtr->image); } Tk_FreeOptions(tagConfig, (char *) tagPtr, tablePtr->display, 0); } /* *-------------------------------------------------------------- * * Table_TagCmd -- * This procedure is invoked to process the tag method * that corresponds to a widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_TagCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *)clientData; int result = TCL_OK, cmdIndex, i, newEntry, value, len; int row, col, tagPrio, refresh = 0; TableTag *tagPtr, *tag2Ptr; Tcl_HashEntry *entryPtr, *scanPtr; Tcl_HashTable *hashTblPtr; Tcl_HashSearch search; Tk_Image image; Tcl_Obj *objPtr, *resultPtr; char buf[INDEX_BUFSIZE], *keybuf, *tagname; if (objc < 3) { Tcl_WrongNumArgs(interp, 2, objv, "option ?arg arg ...?"); return TCL_ERROR; } result = Tcl_GetIndexFromObj(interp, objv[2], tagCmdNames, "tag option", 0, &cmdIndex); if (result != TCL_OK) { return result; } /* * Before using this object, make sure there aren't any calls that * could have changed the interp result, thus freeing the object. */ resultPtr = Tcl_GetObjResult(interp); switch ((enum tagCmd) cmdIndex) { case TAG_CELLTAG: /* add named tag to a (group of) cell(s) */ if (objc < 4) { Tcl_WrongNumArgs(interp, 3, objv, "tag ?arg arg ...?"); return TCL_ERROR; } tagname = Tcl_GetStringFromObj(objv[3], &len); if (len == 0) { /* * An empty string was specified, so just delete the tag. */ tagPtr = NULL; } else { /* * Get the pointer to the tag structure. If it doesn't * exist, it will be created. */ tagPtr = TableTagGetEntry(tablePtr, tagname, 0, NULL); } if (objc == 4) { /* * The user just wants the cells with this tag returned. * Handle specially tags named: active, flash, sel, title */ if ((tablePtr->flags & HAS_ACTIVE) && STREQ(tagname, "active")) { TableMakeArrayIndex( tablePtr->activeRow+tablePtr->rowOffset, tablePtr->activeCol+tablePtr->colOffset, buf); Tcl_SetStringObj(resultPtr, buf, -1); } else if ((tablePtr->flashMode && STREQ(tagname, "flash")) || STREQ(tagname, "sel")) { hashTblPtr = (*tagname == 's') ? tablePtr->selCells : tablePtr->flashCells; for (scanPtr = Tcl_FirstHashEntry(hashTblPtr, &search); scanPtr != NULL; scanPtr = Tcl_NextHashEntry(&search)) { keybuf = (char *) Tcl_GetHashKey(hashTblPtr, scanPtr); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewStringObj(keybuf, -1)); } } else if (STREQ(tagname, "title") && (tablePtr->titleRows || tablePtr->titleCols)) { for (row = tablePtr->rowOffset; row < tablePtr->rowOffset+tablePtr->rows; row++) { for (col = tablePtr->colOffset; col < tablePtr->colOffset+tablePtr->titleCols; col++) { TableMakeArrayIndex(row, col, buf); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewStringObj(buf, -1)); } } for (row = tablePtr->rowOffset; row < tablePtr->rowOffset+tablePtr->titleRows; row++) { for (col = tablePtr->colOffset+tablePtr->titleCols; col < tablePtr->colOffset+tablePtr->cols; col++) { TableMakeArrayIndex(row, col, buf); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewStringObj(buf, -1)); } } } else { /* * Check this tag pointer amongst all tagged cells */ for (scanPtr = Tcl_FirstHashEntry(tablePtr->cellStyles, &search); scanPtr != NULL; scanPtr = Tcl_NextHashEntry(&search)) { if ((TableTag *) Tcl_GetHashValue(scanPtr) == tagPtr) { keybuf = (char *) Tcl_GetHashKey( tablePtr->cellStyles, scanPtr); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewStringObj(keybuf, -1)); } } } return TCL_OK; } /* * Loop through the arguments and fill in the hash table */ for (i = 4; i < objc; i++) { /* * Try and parse the index */ if (TableGetIndexObj(tablePtr, objv[i], &row, &col) != TCL_OK) { return TCL_ERROR; } /* * Get the hash key ready */ TableMakeArrayIndex(row, col, buf); if (tagPtr == NULL) { /* * This is a deletion */ entryPtr = Tcl_FindHashEntry(tablePtr->cellStyles, buf); if (entryPtr != NULL) { Tcl_DeleteHashEntry(entryPtr); refresh = 1; } } else { /* * Add a key to the hash table and set it to point to the * Tag structure if it wasn't the same as an existing one */ entryPtr = Tcl_CreateHashEntry(tablePtr->cellStyles, buf, &newEntry); if (newEntry || (tagPtr != (TableTag *) Tcl_GetHashValue(entryPtr))) { Tcl_SetHashValue(entryPtr, (ClientData) tagPtr); refresh = 1; } } /* * Now invalidate this cell for redraw */ if (refresh) { TableRefresh(tablePtr, row-tablePtr->rowOffset, col-tablePtr->colOffset, CELL); } } return TCL_OK; case TAG_COLTAG: case TAG_ROWTAG: { /* tag a row or a column */ int forRows = (cmdIndex == TAG_ROWTAG); if (objc < 4) { Tcl_WrongNumArgs(interp, 3, objv, "tag ?arg arg ..?"); return TCL_ERROR; } tagname = Tcl_GetStringFromObj(objv[3], &len); if (len == 0) { /* * Empty string, so we want to delete this element */ tagPtr = NULL; } else { /* * Get the pointer to the tag structure. If it doesn't * exist, it will be created. */ tagPtr = TableTagGetEntry(tablePtr, tagname, 0, NULL); } /* * Choose the correct hash table based on args */ hashTblPtr = forRows ? tablePtr->rowStyles : tablePtr->colStyles; if (objc == 4) { /* the user just wants the tagged cells to be returned */ /* Special handling for tags: active, flash, sel, title */ if ((tablePtr->flags & HAS_ACTIVE) && strcmp(tagname, "active") == 0) { Tcl_SetIntObj(resultPtr, (forRows ? tablePtr->activeRow+tablePtr->rowOffset : tablePtr->activeCol+tablePtr->colOffset)); } else if ((tablePtr->flashMode && STREQ(tagname, "flash")) || STREQ(tagname, "sel")) { Tcl_HashTable *cacheTblPtr; cacheTblPtr = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(cacheTblPtr, TCL_ONE_WORD_KEYS); hashTblPtr = (*tagname == 's') ? tablePtr->selCells : tablePtr->flashCells; for (scanPtr = Tcl_FirstHashEntry(hashTblPtr, &search); scanPtr != NULL; scanPtr = Tcl_NextHashEntry(&search)) { TableParseArrayIndex(&row, &col, Tcl_GetHashKey(hashTblPtr, scanPtr)); value = forRows ? row : col; entryPtr = Tcl_CreateHashEntry(cacheTblPtr, (char *)value, &newEntry); if (newEntry) { Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewIntObj(value)); } } Tcl_DeleteHashTable(cacheTblPtr); ckfree((char *) (cacheTblPtr)); } else if (STREQ(tagname, "title") && (forRows?tablePtr->titleRows:tablePtr->titleCols)) { if (forRows) { for (row = tablePtr->rowOffset; row < tablePtr->rowOffset+tablePtr->titleRows; row++) { Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewIntObj(row)); } } else { for (col = tablePtr->colOffset; col < tablePtr->colOffset+tablePtr->titleCols; col++) { Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewIntObj(col)); } } } else { for (scanPtr = Tcl_FirstHashEntry(hashTblPtr, &search); scanPtr != NULL; scanPtr = Tcl_NextHashEntry(&search)) { /* is this the tag pointer on this row */ if ((TableTag *) Tcl_GetHashValue(scanPtr) == tagPtr) { objPtr = Tcl_NewIntObj( (int) Tcl_GetHashKey(hashTblPtr, scanPtr)); Tcl_ListObjAppendElement(NULL, resultPtr, objPtr); } } } return TCL_OK; } /* * Loop through the arguments and fill in the hash table */ for (i = 4; i < objc; i++) { /* * Try and parse the index */ if (Tcl_GetIntFromObj(interp, objv[i], &value) != TCL_OK) { return TCL_ERROR; } if (tagPtr == NULL) { /* * This is a deletion */ entryPtr = Tcl_FindHashEntry(hashTblPtr, (char *)value); if (entryPtr != NULL) { Tcl_DeleteHashEntry(entryPtr); refresh = 1; } } else { /* * Add a key to the hash table and set it to point to the * Tag structure if it wasn't the same as an existing one */ entryPtr = Tcl_CreateHashEntry(hashTblPtr, (char *) value, &newEntry); if (newEntry || (tagPtr != (TableTag *) Tcl_GetHashValue(entryPtr))) { Tcl_SetHashValue(entryPtr, (ClientData) tagPtr); refresh = 1; } } /* and invalidate the row or column affected */ if (refresh) { if (cmdIndex == TAG_ROWTAG) { TableRefresh(tablePtr, value-tablePtr->rowOffset, 0, ROW); } else { TableRefresh(tablePtr, 0, value-tablePtr->colOffset, COL); } } } return TCL_OK; /* COLTAG && ROWTAG */ } case TAG_CGET: if (objc != 5) { Tcl_WrongNumArgs(interp, 3, objv, "tagName option"); return TCL_ERROR; } tagname = Tcl_GetString(objv[3]); entryPtr = Tcl_FindHashEntry(tablePtr->tagTable, tagname); if (entryPtr == NULL) { goto invalidtag; } else { tagPtr = (TableTag *) Tcl_GetHashValue (entryPtr); result = Tk_ConfigureValue(interp, tablePtr->tkwin, tagConfig, (char *) tagPtr, Tcl_GetString(objv[4]), 0); /* * This is a work-around to fix a bug in Tk_ConfigureValue * that would set interp->result to NULL for -borderwidth * which has no associated tag offset value. This was fixed * in 8.3.5 and 8.4b1. [Bug #522882] */ if (Tcl_GetObjResult(interp) == NULL) { interp->result = ""; } } return result; /* CGET */ case TAG_CONFIGURE: if (objc < 4) { Tcl_WrongNumArgs(interp, 3, objv, "tagName ?arg arg ...?"); return TCL_ERROR; } /* * Get the pointer to the tag structure. If it doesn't * exist, it will be created. */ tagPtr = TableTagGetEntry(tablePtr, Tcl_GetString(objv[3]), 0, NULL); /* * If there were less than 6 args, we return the configuration * (for all or just one option), even for new tags */ if (objc < 6) { result = Tk_ConfigureInfo(interp, tablePtr->tkwin, tagConfig, (char *) tagPtr, (objc == 5) ? Tcl_GetString(objv[4]) : NULL, 0); } else { Arg *args; /* Stringify */ args = (Arg *) ckalloc((objc + 1) * sizeof(Arg)); for (i = 0; i < objc; i++) args[i] = LangStringArg(Tcl_GetString(objv[i])); args[objc] = NULL; result = Tk_ConfigureWidget(interp, tablePtr->tkwin, tagConfig, objc-4, args+4, (char *) tagPtr, TK_CONFIG_ARGV_ONLY); ckfree((char *) args); if (result == TCL_ERROR) { return TCL_ERROR; } /* * Handle change of image name */ if (tagPtr->imageStr) { image = Tk_GetImage(interp, tablePtr->tkwin, tagPtr->imageStr, TableImageProc, (ClientData)tablePtr); if (image == NULL) { result = TCL_ERROR; } } else { image = NULL; } if (tagPtr->image) { Tk_FreeImage(tagPtr->image); } tagPtr->image = image; /* * We reconfigured, so invalidate the table to redraw */ TableInvalidateAll(tablePtr, 0); } return result; case TAG_DELETE: /* delete a tag */ if (objc < 4) { Tcl_WrongNumArgs(interp, 3, objv, "tagName ?tagName ...?"); return TCL_ERROR; } /* run through the remaining arguments */ for (i = 3; i < objc; i++) { tagname = Tcl_GetString(objv[i]); /* cannot delete the title tag */ if (STREQ(tagname, "title") || STREQ(tagname, "sel") || STREQ(tagname, "flash") || STREQ(tagname, "active")) { Tcl_AppendStringsToObj(resultPtr, "cannot delete ", tagname, " tag", (char *) NULL); return TCL_ERROR; } entryPtr = Tcl_FindHashEntry(tablePtr->tagTable, tagname); if (entryPtr != NULL) { /* get the tag pointer */ tagPtr = (TableTag *) Tcl_GetHashValue(entryPtr); /* delete all references to this tag in rows */ scanPtr = Tcl_FirstHashEntry(tablePtr->rowStyles, &search); for (; scanPtr != NULL; scanPtr = Tcl_NextHashEntry(&search)) { if ((TableTag *)Tcl_GetHashValue(scanPtr) == tagPtr) { Tcl_DeleteHashEntry(scanPtr); refresh = 1; } } /* delete all references to this tag in cols */ scanPtr = Tcl_FirstHashEntry(tablePtr->colStyles, &search); for (; scanPtr != NULL; scanPtr = Tcl_NextHashEntry(&search)) { if ((TableTag *)Tcl_GetHashValue(scanPtr) == tagPtr) { Tcl_DeleteHashEntry(scanPtr); refresh = 1; } } /* delete all references to this tag in cells */ scanPtr = Tcl_FirstHashEntry(tablePtr->cellStyles, &search); for (; scanPtr != NULL; scanPtr = Tcl_NextHashEntry(&search)) { if ((TableTag *)Tcl_GetHashValue(scanPtr) == tagPtr) { Tcl_DeleteHashEntry(scanPtr); refresh = 1; } } /* * Remove the tag from the prio list and collapse * the rest of the tags. We could check for shrinking * the prio list as well. */ for (i = 0; i < tablePtr->tagPrioSize; i++) { if (tablePtr->tagPrios[i] == tagPtr) break; } for ( ; i < tablePtr->tagPrioSize; i++) { tablePtr->tagPrioNames[i] = tablePtr->tagPrioNames[i+1]; tablePtr->tagPrios[i] = tablePtr->tagPrios[i+1]; } tablePtr->tagPrioSize--; /* Release the tag structure */ TableCleanupTag(tablePtr, tagPtr); ckfree((char *) tagPtr); /* And free the hash table entry */ Tcl_DeleteHashEntry(entryPtr); } } /* since we deleted a tag, redraw the screen */ if (refresh) { TableInvalidateAll(tablePtr, 0); } return result; case TAG_EXISTS: if (objc != 4) { Tcl_WrongNumArgs(interp, 3, objv, "tagName"); return TCL_ERROR; } Tcl_SetBooleanObj(resultPtr, (Tcl_FindHashEntry(tablePtr->tagTable, Tcl_GetString(objv[3])) != NULL)); return TCL_OK; case TAG_INCLUDES: /* does a tag contain a index ? */ if (objc != 5) { Tcl_WrongNumArgs(interp, 3, objv, "tag index"); return TCL_ERROR; } tagname = Tcl_GetString(objv[3]); /* check to see if the tag actually exists */ entryPtr = Tcl_FindHashEntry(tablePtr->tagTable, tagname); if (entryPtr == NULL) { /* Unknown tag, just return 0 */ Tcl_SetBooleanObj(resultPtr, 0); return TCL_OK; } /* parse index */ if (TableGetIndexObj(tablePtr, objv[4], &row, &col) != TCL_OK) { return TCL_ERROR; } /* create hash key */ TableMakeArrayIndex(row, col, buf); if (STREQ(tagname, "active")) { result = (tablePtr->activeRow+tablePtr->rowOffset==row && tablePtr->activeCol+tablePtr->colOffset==col); } else if (STREQ(tagname, "flash")) { result = (tablePtr->flashMode && (Tcl_FindHashEntry(tablePtr->flashCells, buf) != NULL)); } else if (STREQ(tagname, "sel")) { result = (Tcl_FindHashEntry(tablePtr->selCells, buf) != NULL); } else if (STREQ(tagname, "title")) { result = (row < tablePtr->titleRows+tablePtr->rowOffset || col < tablePtr->titleCols+tablePtr->colOffset); } else { /* get the pointer to the tag structure */ tagPtr = (TableTag *) Tcl_GetHashValue(entryPtr); scanPtr = Tcl_FindHashEntry(tablePtr->cellStyles, buf); /* * Look to see if there is a cell, row, or col tag * for this cell */ result = ((scanPtr && (tagPtr == (TableTag *) Tcl_GetHashValue(scanPtr))) || (tagPtr == FindRowColTag(tablePtr, row, ROW)) || (tagPtr == FindRowColTag(tablePtr, col, COL))); } /* * Because we may call FindRowColTag above, we can't use * the resultPtr, but this is almost equivalent, and is SAFE */ Tcl_SetObjResult(interp, Tcl_NewIntObj(result)); return TCL_OK; case TAG_NAMES: /* * Print out the tag names in priority order */ if (objc < 3 || objc > 4) { Tcl_WrongNumArgs(interp, 3, objv, "?pattern?"); return TCL_ERROR; } tagname = (objc == 4) ? Tcl_GetString(objv[3]) : NULL; for (i = 0; i < tablePtr->tagPrioSize; i++) { keybuf = tablePtr->tagPrioNames[i]; if (objc == 3 || Tcl_StringMatch(keybuf, tagname)) { objPtr = Tcl_NewStringObj(keybuf, -1); Tcl_ListObjAppendElement(NULL, resultPtr, objPtr); } } return TCL_OK; case TAG_LOWER: case TAG_RAISE: /* * Change priority of the named tag */ if (objc != 4 && objc != 5) { Tcl_WrongNumArgs(interp, 3, objv, (cmdIndex == TAG_LOWER) ? "tagName ?belowThis?" : "tagName ?aboveThis?"); return TCL_ERROR; } tagname = Tcl_GetString(objv[3]); /* check to see if the tag actually exists */ entryPtr = Tcl_FindHashEntry(tablePtr->tagTable, tagname); if (entryPtr == NULL) { goto invalidtag; } tagPtr = (TableTag *) Tcl_GetHashValue(entryPtr); tagPrio = TableTagGetPriority(tablePtr, tagPtr); keybuf = tablePtr->tagPrioNames[tagPrio]; /* * In the RAISE case, the priority is one higher (-1) because * we want the named tag to move above the other in priority. */ if (objc == 5) { tagname = Tcl_GetString(objv[4]); entryPtr = Tcl_FindHashEntry(tablePtr->tagTable, tagname); if (entryPtr == NULL) { goto invalidtag; } tag2Ptr = (TableTag *) Tcl_GetHashValue(entryPtr); if (cmdIndex == TAG_LOWER) { value = TableTagGetPriority(tablePtr, tag2Ptr); } else { value = TableTagGetPriority(tablePtr, tag2Ptr) - 1; } } else { if (cmdIndex == TAG_LOWER) { /* * Lower this tag's priority to the bottom. */ value = tablePtr->tagPrioSize - 1; } else { /* * Raise this tag's priority to the top. */ value = -1; } } if (value < tagPrio) { /* * Move tag up in priority. */ for (i = tagPrio; i > value; i--) { tablePtr->tagPrioNames[i] = tablePtr->tagPrioNames[i-1]; tablePtr->tagPrios[i] = tablePtr->tagPrios[i-1]; } i++; tablePtr->tagPrioNames[i] = keybuf; tablePtr->tagPrios[i] = tagPtr; refresh = 1; } else if (value > tagPrio) { /* * Move tag down in priority. */ for (i = tagPrio; i < value; i++) { tablePtr->tagPrioNames[i] = tablePtr->tagPrioNames[i+1]; tablePtr->tagPrios[i] = tablePtr->tagPrios[i+1]; } tablePtr->tagPrioNames[i] = keybuf; tablePtr->tagPrios[i] = tagPtr; refresh = 1; } /* since we deleted a tag, redraw the screen */ if (refresh) { TableInvalidateAll(tablePtr, 0); } return TCL_OK; } return TCL_OK; invalidtag: /* * When jumping here, ensure the invalid 'tagname' is set already. */ Tcl_AppendStringsToObj(resultPtr, "invalid tag name \"", tagname, "\"", (char *) NULL); return TCL_ERROR; } /* *---------------------------------------------------------------------- * * TableOptionReliefSet -- * * This routine configures the borderwidth value for a tag. * * Results: * A standard Tcl result. * * Side effects: * It may adjust the tag struct values of relief[0..4] and borders. * *---------------------------------------------------------------------- */ static int TableOptionReliefSet(clientData, interp, tkwin, value, widgRec, offset) ClientData clientData; /* Type of struct being set. */ Tcl_Interp *interp; /* Used for reporting errors. */ Tk_Window tkwin; /* Window containing table widget. */ Arg value; /* Value of option. */ char *widgRec; /* Pointer to record for item. */ int offset; /* Offset into item. */ { TableTag *tagPtr = (TableTag *) widgRec; if (STREQ(Tcl_GetString(value),"")) { tagPtr->relief = -1; } else { return Tk_GetRelief(interp, Tcl_GetString(value), &(tagPtr->relief)); } return TCL_OK; } /* *---------------------------------------------------------------------- * * TableOptionReliefGet -- * * Results: * Value of the tag's -relief option. * * Side effects: * None. * *---------------------------------------------------------------------- */ static Arg TableOptionReliefGet(clientData, tkwin, widgRec, offset, freeProcPtr) ClientData clientData; /* Type of struct being set. */ Tk_Window tkwin; /* Window containing canvas widget. */ char *widgRec; /* Pointer to record for item. */ int offset; /* Offset into item. */ Tcl_FreeProc **freeProcPtr; /* Pointer to variable to fill in with * information about how to reclaim * storage for return string. */ { return LangStringArg( Tk_NameOfRelief(((TableTag *) widgRec)->relief)); } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable/confdefs.h������������������������������������������������������0000644�0000000�0000000�00000000002�13745605157�017554� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable/config.log������������������������������������������������������0000644�0000000�0000000�00000000270�13742524721�017565� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. configure:565: checking for a BSD compatible install ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable/tkAppInit.c�����������������������������������������������������0000644�0000000�0000000�00000007356�13745605157�017706� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * tkAppInit.c -- * * Provides a default version of the Tcl_AppInit procedure for * use in wish and similar Tk-based applications. * * Copyright (c) 1993 The Regents of the University of California. * Copyright (c) 1994-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * SCCS: @(#) tkAppInit.c 1.24 98/01/13 17:21:40 */ #include "tk.h" #include "locale.h" /* * The following variable is a special hack that is needed in order for * Sun shared libraries to be used for Tcl. */ extern int matherr(); int *tclDummyMathPtr = (int *) matherr; EXTERN int Tktable_Init _ANSI_ARGS_((Tcl_Interp *interp)); #ifdef TK_TEST EXTERN int Tcltest_Init _ANSI_ARGS_((Tcl_Interp *interp)); EXTERN int Tktest_Init _ANSI_ARGS_((Tcl_Interp *interp)); #endif /* TK_TEST */ /* *---------------------------------------------------------------------- * * main -- * * This is the main program for the application. * * Results: * None: Tk_Main never returns here, so this procedure never * returns either. * * Side effects: * Whatever the application does. * *---------------------------------------------------------------------- */ int main(argc, argv) int argc; /* Number of command-line arguments. */ char **argv; /* Values of command-line arguments. */ { Tk_Main(argc, argv, Tcl_AppInit); return 0; /* Needed only to prevent compiler warning. */ } /* *---------------------------------------------------------------------- * * Tcl_AppInit -- * * This procedure performs application-specific initialization. * Most applications, especially those that incorporate additional * packages, will have their own version of this procedure. * * Results: * Returns a standard Tcl completion code, and leaves an error * message in interp->result if an error occurs. * * Side effects: * Depends on the startup script. * *---------------------------------------------------------------------- */ int Tcl_AppInit(interp) Tcl_Interp *interp; /* Interpreter for application. */ { if (Tcl_Init(interp) == TCL_ERROR) { return TCL_ERROR; } if (Tk_Init(interp) == TCL_ERROR) { return TCL_ERROR; } Tcl_StaticPackage(interp, "Tk", Tk_Init, (Tcl_PackageInitProc *) NULL); #ifdef TK_TEST if (Tcltest_Init(interp) == TCL_ERROR) { return TCL_ERROR; } Tcl_StaticPackage(interp, "Tcltest", Tcltest_Init, (Tcl_PackageInitProc *) NULL); if (Tktest_Init(interp) == TCL_ERROR) { return TCL_ERROR; } Tcl_StaticPackage(interp, "Tktest", Tktest_Init, (Tcl_PackageInitProc *) NULL); #endif /* TK_TEST */ /* * Call the init procedures for included packages. Each call should * look like this: * * if (Mod_Init(interp) == TCL_ERROR) { * return TCL_ERROR; * } * * where "Mod" is the name of the module. */ if (Tktable_Init(interp) == TCL_ERROR) { return TCL_ERROR; } Tcl_StaticPackage(interp, "Tktable", Tktable_Init, Tktable_SafeInit); /* * Call Tcl_CreateCommand for application-specific commands, if * they weren't already created by the init procedures called above. */ /* * Specify a user-specific startup file to invoke if the application * is run interactively. Typically the startup file is "~/.apprc" * where "app" is the name of the application. If this line is deleted * then no user-specific startup file will be run under any conditions. */ Tcl_SetVar(interp, "tcl_rcFileName", "~/.wishrc", TCL_GLOBAL_ONLY); return TCL_OK; } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable/tkTableCell.c���������������������������������������������������0000644�0000000�0000000�00000125743�13745605157�020172� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * tkTableCell.c -- * * This module implements cell oriented functions for table * widgets. * * Copyright (c) 1998-2000 Jeffrey Hobbs * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tkTableCell.c,v 1.17 2004/02/08 03:09:46 cerney Exp $ */ #include "tkVMacro.h" #include "tkTable.h" static int TableSortCompareProc _ANSI_ARGS_((CONST VOID *first, CONST VOID *second)); /* *---------------------------------------------------------------------- * * TableTrueCell -- * Takes a row,col pair in user coords and returns the true * cell that it relates to, either dimension bounded, or a * span cell if it was hidden. * * Results: * The true row, col in user coords are placed in the pointers. * If the value changed for some reasons, 0 is returned (it was not * the /true/ cell). * * Side effects: * None. * *---------------------------------------------------------------------- */ int TableTrueCell(Table *tablePtr, int r, int c, int *row, int *col) { *row = r; *col = c; /* * We check spans before constraints, because we don't want to * constrain and then think we ended up in a span */ if (tablePtr->spanAffTbl && !(tablePtr->flags & AVOID_SPANS)) { char buf[INDEX_BUFSIZE]; Tcl_HashEntry *entryPtr; TableMakeArrayIndex(r, c, buf); entryPtr = Tcl_FindHashEntry(tablePtr->spanAffTbl, buf); if ((entryPtr != NULL) && ((char *)Tcl_GetHashValue(entryPtr) != NULL)) { /* * This cell is covered by another spanning cell. * We need to return the coords for that spanning cell. */ TableParseArrayIndex(row, col, (char *)Tcl_GetHashValue(entryPtr)); return 0; } } *row = BETWEEN(r, tablePtr->rowOffset, tablePtr->rows-1+tablePtr->rowOffset); *col = BETWEEN(c, tablePtr->colOffset, tablePtr->cols-1+tablePtr->colOffset); return ((*row == r) && (*col == c)); } /* *---------------------------------------------------------------------- * * TableCellCoords -- * Takes a row,col pair in real coords and finds it position * on the virtual screen. * * Results: * The virtual x, y, width, and height of the cell * are placed in the pointers. * * Side effects: * None. * *---------------------------------------------------------------------- */ int TableCellCoords(Table *tablePtr, int row, int col, int *x, int *y, int *w, int *h) { register int hl = tablePtr->highlightWidth; int result = CELL_OK; if (tablePtr->rows <= 0 || tablePtr->cols <= 0) { *w = *h = *x = *y = 0; return CELL_BAD; } /* * Real coords required, always should be passed acceptable values, * but this is a possible seg fault otherwise */ CONSTRAIN(row, 0, tablePtr->rows-1); CONSTRAIN(col, 0, tablePtr->cols-1); *w = tablePtr->colPixels[col]; *h = tablePtr->rowPixels[row]; /* * Adjust for sizes of spanning cells * and ensure that this cell isn't "hidden" */ if (tablePtr->spanAffTbl && !(tablePtr->flags & AVOID_SPANS)) { char buf[INDEX_BUFSIZE]; Tcl_HashEntry *entryPtr; TableMakeArrayIndex(row+tablePtr->rowOffset, col+tablePtr->colOffset, buf); entryPtr = Tcl_FindHashEntry(tablePtr->spanAffTbl, buf); if (entryPtr != NULL) { int rs, cs; char *cell; cell = (char *) Tcl_GetHashValue(entryPtr); if (cell != NULL) { /* This cell is covered by another spanning cell */ /* We need to return the coords for that cell */ TableParseArrayIndex(&rs, &cs, cell); *w = rs; *h = cs; result = CELL_HIDDEN; goto setxy; } /* Get the actual span values out of spanTbl */ entryPtr = Tcl_FindHashEntry(tablePtr->spanTbl, buf); cell = (char *) Tcl_GetHashValue(entryPtr); TableParseArrayIndex(&rs, &cs, cell); if (rs > 0) { /* * Make sure we don't overflow our space */ if (row < tablePtr->titleRows) { rs = MIN(tablePtr->titleRows-1, row+rs); } else { rs = MIN(tablePtr->rows-1, row+rs); } *h = tablePtr->rowStarts[rs+1]-tablePtr->rowStarts[row]; result = CELL_SPAN; } else if (rs <= 0) { /* currently negative spans are not supported */ } if (cs > 0) { /* * Make sure we don't overflow our space */ if (col < tablePtr->titleCols) { cs = MIN(tablePtr->titleCols-1, col+cs); } else { cs = MIN(tablePtr->cols-1, col+cs); } *w = tablePtr->colStarts[cs+1]-tablePtr->colStarts[col]; result = CELL_SPAN; } else if (cs <= 0) { /* currently negative spans are not supported */ } } } setxy: *x = hl + tablePtr->colStarts[col]; if (col >= tablePtr->titleCols) { *x -= tablePtr->colStarts[tablePtr->leftCol] - tablePtr->colStarts[tablePtr->titleCols]; } *y = hl + tablePtr->rowStarts[row]; if (row >= tablePtr->titleRows) { *y -= tablePtr->rowStarts[tablePtr->topRow] - tablePtr->rowStarts[tablePtr->titleRows]; } return result; } /* *---------------------------------------------------------------------- * * TableCellVCoords -- * Takes a row,col pair in real coords and finds it position * on the actual screen. The full arg specifies whether * only 100% visible cells should be considered visible. * * Results: * The x, y, width, and height of the cell are placed in the pointers, * depending upon visibility of the cell. * Returns 0 for hidden and 1 for visible cells. * * Side effects: * None. * *---------------------------------------------------------------------- */ int TableCellVCoords(Table *tablePtr, int row, int col, int *rx, int *ry, int *rw, int *rh, int full) { int x, y, w, h, w0, h0, cellType, hl = tablePtr->highlightWidth; if (tablePtr->tkwin == NULL) return 0; /* * Necessary to use separate vars in case dummies are passed in */ cellType = TableCellCoords(tablePtr, row, col, &x, &y, &w, &h); *rx = x; *ry = y; *rw = w; *rh = h; if (cellType == CELL_OK) { if ((row < tablePtr->topRow && row >= tablePtr->titleRows) || (col < tablePtr->leftCol && col >= tablePtr->titleCols)) { /* * A non-spanning cell hiding in "dead" space * between title areas and visible cells */ return 0; } } else if (cellType == CELL_SPAN) { /* * we might need to treat full better is CELL_SPAN but primary * cell is visible */ int topX = tablePtr->colStarts[tablePtr->titleCols]+hl; int topY = tablePtr->rowStarts[tablePtr->titleRows]+hl; if ((col < tablePtr->leftCol) && (col >= tablePtr->titleCols)) { if (full || (x+w < topX)) { return 0; } else { w -= topX-x; x = topX; } } if ((row < tablePtr->topRow) && (row >= tablePtr->titleRows)) { if (full || (y+h < topY)) { return 0; } else { h -= topY-y; y = topY; } } /* * re-set these according to changed coords */ *rx = x; *ry = y; *rw = w; *rh = h; } else { /* * If it is a hidden cell, then w,h is the row,col in user coords * of the cell that spans over this one */ return 0; } /* * At this point, we know it is on the screen, * but not if we can see 100% of it (if we care) */ if (full) { w0 = w; h0 = h; } else { /* * if we don't care about seeing the whole thing, then * make sure we at least see a pixel worth */ w0 = h0 = 1; } /* * Is the cell visible? */ if ((x < hl) || (y < hl) || ((x+w0) > (Tk_Width(tablePtr->tkwin)-hl)) || ((y+h0) > (Tk_Height(tablePtr->tkwin)-hl))) { /* definitely off the screen */ return 0; } else { /* if it was full, then w,h are already be properly constrained */ if (!full) { *rw = MIN(w, Tk_Width(tablePtr->tkwin)-hl-x); *rh = MIN(h, Tk_Height(tablePtr->tkwin)-hl-y); } return 1; } } /* *---------------------------------------------------------------------- * * TableWhatCell -- * Takes a x,y screen coordinate and determines what cell contains. * that point. This will return cells that are beyond the right/bottom * edge of the viewable screen. * * Results: * The row,col of the cell are placed in the pointers. * * Side effects: * None. * *---------------------------------------------------------------------- */ void TableWhatCell(register Table *tablePtr, int x, int y, int *row, int *col) { int i; x = MAX(0, x); y = MAX(0, y); /* Adjust for table's global highlightthickness border */ x -= tablePtr->highlightWidth; y -= tablePtr->highlightWidth; /* Adjust the x coord if not in the column titles to change display coords * into internal coords */ x += (x < tablePtr->colStarts[tablePtr->titleCols]) ? 0 : tablePtr->colStarts[tablePtr->leftCol] - tablePtr->colStarts[tablePtr->titleCols]; y += (y < tablePtr->rowStarts[tablePtr->titleRows]) ? 0 : tablePtr->rowStarts[tablePtr->topRow] - tablePtr->rowStarts[tablePtr->titleRows]; x = MIN(x, tablePtr->maxWidth-1); y = MIN(y, tablePtr->maxHeight-1); for (i = 1; x >= tablePtr->colStarts[i]; i++); *col = i - 1; for (i = 1; y >= tablePtr->rowStarts[i]; i++); *row = i - 1; if (tablePtr->spanAffTbl && !(tablePtr->flags & AVOID_SPANS)) { char buf[INDEX_BUFSIZE]; Tcl_HashEntry *entryPtr; /* We now correct the returned cell if this was "hidden" */ TableMakeArrayIndex(*row+tablePtr->rowOffset, *col+tablePtr->colOffset, buf); entryPtr = Tcl_FindHashEntry(tablePtr->spanAffTbl, buf); if ((entryPtr != NULL) && /* We have to make sure this was not already hidden * that's an error */ ((char *)Tcl_GetHashValue(entryPtr) != NULL)) { /* this is a "hidden" cell */ TableParseArrayIndex(row, col, (char *)Tcl_GetHashValue(entryPtr)); *row -= tablePtr->rowOffset; *col -= tablePtr->colOffset; } } } /* *---------------------------------------------------------------------- * * TableAtBorder -- * Takes a x,y screen coordinate and determines if that point is * over a border. * * Results: * The left/top row,col corresponding to that point are placed in * the pointers. The number of borders (+1 for row, +1 for col) * hit is returned. * * Side effects: * None. * *---------------------------------------------------------------------- */ int TableAtBorder(Table * tablePtr, int x, int y, int *row, int *col) { int i, brow, bcol, borders = 2, bd[6]; TableGetTagBorders(&(tablePtr->defaultTag), &bd[0], &bd[1], &bd[2], &bd[3]); bd[4] = (bd[0] + bd[1])/2; bd[5] = (bd[2] + bd[3])/2; /* * Constrain x && y appropriately, and adjust x if it is not in the * column titles to change display coords into internal coords. */ x = MAX(0, x); y = MAX(0, y); x -= tablePtr->highlightWidth; y -= tablePtr->highlightWidth; x += (x < tablePtr->colStarts[tablePtr->titleCols]) ? 0 : tablePtr->colStarts[tablePtr->leftCol] - tablePtr->colStarts[tablePtr->titleCols]; x = MIN(x, tablePtr->maxWidth - 1); for (i = 1; (i <= tablePtr->cols) && (x + (bd[0] + bd[1])) >= tablePtr->colStarts[i]; i++); if (x > tablePtr->colStarts[--i] + bd[4]) { borders--; *col = -1; bcol = (i < tablePtr->leftCol && i >= tablePtr->titleCols) ? tablePtr->titleCols-1 : i-1; } else { bcol = *col = (i < tablePtr->leftCol && i >= tablePtr->titleCols) ? tablePtr->titleCols-1 : i-1; } y += (y < tablePtr->rowStarts[tablePtr->titleRows]) ? 0 : tablePtr->rowStarts[tablePtr->topRow] - tablePtr->rowStarts[tablePtr->titleRows]; y = MIN(y, tablePtr->maxHeight - 1); for (i = 1; i <= tablePtr->rows && (y + (bd[2] + bd[3])) >= tablePtr->rowStarts[i]; i++); if (y > tablePtr->rowStarts[--i]+bd[5]) { borders--; *row = -1; brow = (i < tablePtr->topRow && i >= tablePtr->titleRows) ? tablePtr->titleRows-1 : i-1; } else { brow = *row = (i < tablePtr->topRow && i >= tablePtr->titleRows) ? tablePtr->titleRows-1 : i-1; } /* * We have to account for spanning cells, which may hide cells. * In that case, we have to decrement our border count. */ if (tablePtr->spanAffTbl && !(tablePtr->flags & AVOID_SPANS) && borders) { Tcl_HashEntry *entryPtr1, *entryPtr2 ; char buf1[INDEX_BUFSIZE], buf2[INDEX_BUFSIZE]; char *val; if (*row != -1) { TableMakeArrayIndex(brow+tablePtr->rowOffset, bcol+tablePtr->colOffset+1, buf1); TableMakeArrayIndex(brow+tablePtr->rowOffset+1, bcol+tablePtr->colOffset+1, buf2); entryPtr1 = Tcl_FindHashEntry(tablePtr->spanAffTbl, buf1); entryPtr2 = Tcl_FindHashEntry(tablePtr->spanAffTbl, buf2); if (entryPtr1 != NULL && entryPtr2 != NULL) { if ((val = (char *) Tcl_GetHashValue(entryPtr1)) != NULL) { strcpy(buf1, val); } if ((val = (char *) Tcl_GetHashValue(entryPtr2)) != NULL) { strcpy(buf2, val); } if (strcmp(buf1, buf2) == 0) { borders--; *row = -1; } } } if (*col != -1) { TableMakeArrayIndex(brow+tablePtr->rowOffset+1, bcol+tablePtr->colOffset, buf1); TableMakeArrayIndex(brow+tablePtr->rowOffset+1, bcol+tablePtr->colOffset+1, buf2); entryPtr1 = Tcl_FindHashEntry(tablePtr->spanAffTbl, buf1); entryPtr2 = Tcl_FindHashEntry(tablePtr->spanAffTbl, buf2); if (entryPtr1 != NULL && entryPtr2 != NULL) { if ((val = (char *) Tcl_GetHashValue(entryPtr1)) != NULL) { strcpy(buf1, val); } if ((val = (char *) Tcl_GetHashValue(entryPtr2)) != NULL) { strcpy(buf2, val); } if (strcmp(buf1, buf2) == 0) { borders--; *col = -1; } } } } return borders; } /* *---------------------------------------------------------------------- * * TableGetCellValue -- * Takes a row,col pair in user coords and returns the value for * that cell. This varies depending on what data source the * user has selected. * * Results: * The value of the cell is returned. The return value is VOLATILE * (do not free). * * Side effects: * The value will be cached if caching is turned on. * *---------------------------------------------------------------------- */ char * TableGetCellValue(Table *tablePtr, int r, int c) { register Tcl_Interp *interp = tablePtr->interp; char *result = NULL; char buf[INDEX_BUFSIZE]; Tcl_HashEntry *entryPtr = NULL; int new = 1; TableMakeArrayIndex(r, c, buf); if (tablePtr->caching) { /* * If we are caching, let's see if we have the value cached */ entryPtr = Tcl_CreateHashEntry(tablePtr->cache, buf, &new); if (!new) { result = (char *) Tcl_GetHashValue(entryPtr); if (result == NULL) { result = ""; } goto VALUE; } } if (tablePtr->command && tablePtr->useCmd) { if (LangDoCallback(interp, tablePtr->command, 1, 3, "%d %d %d",0,r,c) == TCL_ERROR) { tablePtr->useCmd = 0; tablePtr->dataSource &= ~DATA_COMMAND; if (tablePtr->arrayVar) tablePtr->dataSource |= DATA_ARRAY; Tcl_AddErrorInfo(interp, "\n\t(in -command evaled by table)"); Tcl_BackgroundError(interp); TableInvalidateAll(tablePtr, 0); } else { result = (char *) Tcl_GetStringFromObj(Tcl_GetObjResult(interp),NULL); } /* Tcl_FreeResult(interp); not support for perl/tk */ } else if (tablePtr->arrayVar) { result = Tcl_GetString(Tcl_ObjGetVar2(interp, tablePtr->arrayVar, Tcl_NewStringObj(buf,-1), TCL_GLOBAL_ONLY)); } if (result == NULL) result = ""; if (tablePtr->caching && entryPtr != NULL) { /* * If we are caching, make sure we cache the returned value * * entryPtr will have been set from above, but check to make sure * someone didn't change caching during -command evaluation. */ char *val; val = (char *)ckalloc(strlen(result)+1); strcpy(val, result); Tcl_SetHashValue(entryPtr, val); } VALUE: #ifdef PROCS if (result != NULL) { /* Do we have procs, are we showing their value, is this a proc? */ if (tablePtr->hasProcs && !tablePtr->showProcs && *result == '=' && !(r-tablePtr->rowOffset == tablePtr->activeRow && c-tablePtr->colOffset == tablePtr->activeCol)) { Tcl_DString script; /* provides a rough mutex on preventing proc loops */ entryPtr = Tcl_CreateHashEntry(tablePtr->inProc, buf, &new); if (!new) { Tcl_SetHashValue(entryPtr, 1); Tcl_AddErrorInfo(interp, "\n\t(loop hit in proc evaled by table)"); return result; } Tcl_SetHashValue(entryPtr, 0); Tcl_DStringInit(&script); ExpandPercents(tablePtr, result+1, r, c, result+1, (char *)NULL, 0, &script, 0); if (Tcl_GlobalEval(interp, Tcl_DStringValue(&script)) != TCL_OK || Tcl_GetHashValue(entryPtr) == 1) { Tcl_AddErrorInfo(interp, "\n\tin proc evaled by table:\n"); Tcl_AddErrorInfo(interp, Tcl_DStringValue(&script)); Tcl_BackgroundError(interp); } else { result = Tcl_GetResult(interp); } /* Tcl_FreeResult(interp); Not Supported for perl/tk */ Tcl_DStringFree(&script); Tcl_DeleteHashEntry(entryPtr); } } #endif return (result?result:""); } /* *---------------------------------------------------------------------- * * TableSetCellValue -- * Takes a row,col pair in user coords and saves the given value for * that cell. This varies depending on what data source the * user has selected. * * Results: * Returns TCL_ERROR or TCL_OK, depending on whether an error * occured during set (ie: during evaluation of -command). * * Side effects: * If the value is NULL (empty string), it will be unset from * an array rather than set to the empty string. * *---------------------------------------------------------------------- */ int TableSetCellValue(Table *tablePtr, int r, int c, char *value) { register Tcl_Interp *interp = tablePtr->interp; char buf[INDEX_BUFSIZE]; int code = TCL_OK, flash = 0; TableMakeArrayIndex(r, c, buf); if (tablePtr->state == STATE_DISABLED) { return TCL_OK; } if (tablePtr->command && tablePtr->useCmd) { if (LangDoCallback(interp, tablePtr->command, 1, 4, "%d %d %d %_",1,r,c, LangStringArg(value)) == TCL_ERROR) { /* An error resulted. Prevent further triggering of the command * and set up the error message. */ tablePtr->useCmd = 0; tablePtr->dataSource &= ~DATA_COMMAND; if (tablePtr->arrayVar) tablePtr->dataSource |= DATA_ARRAY; Tcl_AddErrorInfo(interp, "\n\t(in command executed by table)"); Tcl_BackgroundError(interp); code = TCL_ERROR; } else { flash = 1; } Tcl_SetResult(interp, (char *) NULL, TCL_STATIC); } else if (tablePtr->arrayVar) { /* Warning: checking for \0 as the first char could invalidate * allowing it as a valid first char */ if ((value == NULL || *value == '\0') && tablePtr->sparse) { /* perltk not supported */ /* Tcl_UnsetVar2(interp, LangString(Tcl_GetVar(interp, tablePtr->arrayVar, TCL_GLOBAL_ONLY)), buf, TCL_GLOBAL_ONLY); */ /* Replaced with This (defined in tkTable.xs) */ tkTableUnsetElement(tablePtr->arrayVar, buf); } else if (Tcl_ObjSetVar2(interp, tablePtr->arrayVar, Tcl_NewStringObj(buf,-1), Tcl_NewStringObj(value,-1), TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) { code = TCL_ERROR; } } if (code == TCL_ERROR) { return TCL_ERROR; } if (tablePtr->caching) { Tcl_HashEntry *entryPtr; int new; char *val; entryPtr = Tcl_CreateHashEntry(tablePtr->cache, buf, &new); if (!new) { val = (char *) Tcl_GetHashValue(entryPtr); if (val) ckfree(val); } val = (char *)ckalloc(strlen(value)+1); strcpy(val, value); Tcl_SetHashValue(entryPtr, val); flash = 1; } /* We do this conditionally because the var array already has * it's own check to flash */ if (flash && tablePtr->flashMode) { r -= tablePtr->rowOffset; c -= tablePtr->colOffset; TableAddFlash(tablePtr, r, c); TableRefresh(tablePtr, r, c, CELL); } return TCL_OK; } /* *---------------------------------------------------------------------- * * TableMoveCellValue -- * To move cells faster on delete/insert line or col when cache is on * and variable, command is off. * To avoid another call to TableMakeArrayIndex(r, c, buf), * we optionally provide the buffers. * outOfBounds means we will just set the cell value to "" * * Results: * Returns TCL_ERROR or TCL_OK, depending on whether an error * occured during set (ie: during evaluation of -command). * * Side effects: * If the value is NULL (empty string), it will be unset from * an array rather than set to the empty string. * *---------------------------------------------------------------------- */ int TableMoveCellValue(Table *tablePtr, int fromr, int fromc, char *frombuf, int tor, int toc, char *tobuf, int outOfBounds) { int new; char *result = NULL; Tcl_Interp *interp = tablePtr->interp; if (outOfBounds) { return TableSetCellValue(tablePtr, tor, toc, ""); } if (tablePtr->caching && (!(tablePtr->command && tablePtr->useCmd))) { Tcl_HashEntry *entryPtr; /* * if we are caching, let's see if we have the value cached */ entryPtr = Tcl_CreateHashEntry(tablePtr->cache, frombuf, &new); if (!new) { char *val; result = (char *) Tcl_GetHashValue(entryPtr); /* * we set tho old value to NULL */ Tcl_SetHashValue(entryPtr, NULL); /* * set the destination to the source pointer without new mallocing! */ entryPtr = Tcl_CreateHashEntry(tablePtr->cache, tobuf, &new); /* * free old value */ if (!new) { val = (char *) Tcl_GetHashValue(entryPtr); if (val) ckfree(val); } Tcl_SetHashValue(entryPtr, result); if (tablePtr->arrayVar) { /* * first, delete from var. */ /* perltk not supported */ /*Tcl_UnsetVar2(interp, tablePtr->arrayVar, frombuf, TCL_GLOBAL_ONLY); */ /* Replaced with This (defined in tkTable.xs) */ tkTableUnsetElement(tablePtr->arrayVar, frombuf); /* * Warning: checking for \0 as the first char could invalidate * allowing it as a valid first char */ if (Tcl_ObjSetVar2(interp, tablePtr->arrayVar, Tcl_NewStringObj(tobuf,-1), Tcl_NewStringObj(result, -1), TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) { return TCL_ERROR; } } return TCL_OK; } } /* * We have to do it the old way */ return TableSetCellValue(tablePtr, tor, toc, TableGetCellValue(tablePtr, fromr, fromc)); } /* *---------------------------------------------------------------------- * * TableGetIcursor -- * Parses the argument as an index into the active cell string. * Recognises 'end', 'insert' or an integer. Constrains it to the * size of the buffer. This acts like a "SetIcursor" when *posn is NULL. * * Results: * If (posn != NULL), then it gets the cursor position. * * Side effects: * Can move cursor position. * *---------------------------------------------------------------------- */ int TableGetIcursor(Table *tablePtr, char *arg, int *posn) { int tmp, len; len = strlen(tablePtr->activeBuf); #ifdef TCL_UTF_MAX /* Need to base it off strlen to account for \x00 (Unicode null) */ len = Tcl_NumUtfChars(tablePtr->activeBuf, len); #endif /* ensure icursor didn't get out of sync */ if (tablePtr->icursor > len) tablePtr->icursor = len; /* is this end */ if (strcmp(arg, "end") == 0) { tmp = len; } else if (strcmp(arg, "insert") == 0) { tmp = tablePtr->icursor; } else { if (Tcl_GetIntFromObj(tablePtr->interp, LangStringArg(arg), &tmp) != TCL_OK) { return TCL_ERROR; } CONSTRAIN(tmp, 0, len); } if (posn) { *posn = tmp; } else { tablePtr->icursor = tmp; } return TCL_OK; } /* *-------------------------------------------------------------- * * TableGetIndex -- * Parse an index into a table and return either its value * or an error. * * Results: * A standard Tcl result. If all went well, then *row,*col is * filled in with the index corresponding to string. If an * error occurs then an error message is left in interp result. * The index returned is in user coords. * * Side effects: * Sets row,col index to an appropriately constrained user index. * *-------------------------------------------------------------- */ int TableGetIndex(tablePtr, str, row_p, col_p) register Table *tablePtr; /* Table for which the index is being * specified. */ char *str; /* Symbolic specification of cell in table. */ int *row_p; /* Where to store converted row. */ int *col_p; /* Where to store converted col. */ { int r, c, len = strlen(str); char dummy; /* * Note that all of these values will be adjusted by row/ColOffset */ if (str[0] == '@') { /* @x,y coordinate */ int x, y; if (sscanf(str+1, "%d,%d%c", &x, &y, &dummy) != 2) { /* Make sure it won't work for "2,3extrastuff" */ goto IndexError; } TableWhatCell(tablePtr, x, y, &r, &c); r += tablePtr->rowOffset; c += tablePtr->colOffset; } else if (*str == '-' || isdigit(str[0])) { if (sscanf(str, "%d,%d%c", &r, &c, &dummy) != 2) { /* Make sure it won't work for "2,3extrastuff" */ goto IndexError; } /* ensure appropriate user index */ CONSTRAIN(r, tablePtr->rowOffset, tablePtr->rows-1+tablePtr->rowOffset); CONSTRAIN(c, tablePtr->colOffset, tablePtr->cols-1+tablePtr->colOffset); } else if (len > 1 && strncmp(str, "active", len) == 0 ) { /* active */ if (tablePtr->flags & HAS_ACTIVE) { r = tablePtr->activeRow+tablePtr->rowOffset; c = tablePtr->activeCol+tablePtr->colOffset; } else { Tcl_SetStringObj(Tcl_GetObjResult(tablePtr->interp), "no \"active\" cell in table", -1); return TCL_ERROR; } } else if (len > 1 && strncmp(str, "anchor", len) == 0) { /* anchor */ if (tablePtr->flags & HAS_ANCHOR) { r = tablePtr->anchorRow+tablePtr->rowOffset; c = tablePtr->anchorCol+tablePtr->colOffset; } else { Tcl_SetStringObj(Tcl_GetObjResult(tablePtr->interp), "no \"anchor\" cell in table", -1); return TCL_ERROR; } } else if (strncmp(str, "end", len) == 0) { /* end */ r = tablePtr->rows-1+tablePtr->rowOffset; c = tablePtr->cols-1+tablePtr->colOffset; } else if (strncmp(str, "origin", len) == 0) { /* origin */ r = tablePtr->titleRows+tablePtr->rowOffset; c = tablePtr->titleCols+tablePtr->colOffset; } else if (strncmp(str, "topleft", len) == 0) { /* topleft */ r = tablePtr->topRow+tablePtr->rowOffset; c = tablePtr->leftCol+tablePtr->colOffset; } else if (strncmp(str, "bottomright", len) == 0) { /* bottomright */ /* * FIX: Should this avoid spans, or consider them in the bottomright? tablePtr->flags |= AVOID_SPANS; tablePtr->flags &= ~AVOID_SPANS; */ TableGetLastCell(tablePtr, &r, &c); r += tablePtr->rowOffset; c += tablePtr->colOffset; } else { IndexError: Tcl_AppendStringsToObj(Tcl_GetObjResult(tablePtr->interp), "bad table index \"", str, "\": must be active, anchor, end, ", "origin, topleft, bottomright, @x,y, or <row>,<col>", (char *)NULL); return TCL_ERROR; } /* Note: values are expected to be properly constrained * as a user index by this point */ if (row_p) *row_p = r; if (col_p) *col_p = c; return TCL_OK; } /* *-------------------------------------------------------------- * * Table_SetCmd -- * This procedure is invoked to process the set method * that corresponds to a widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_SetCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *)clientData; int row, col, len, i, j, max; char *str; /* sets any number of tags/indices to a given value */ if (objc < 3) { CMD_SET_USAGE: Tcl_WrongNumArgs(interp, 2, objv, "?row|col? index ?value? ?index value ...?"); return TCL_ERROR; } /* make sure there is a data source to accept set */ if (tablePtr->dataSource == DATA_NONE) { return TCL_OK; } str = Tcl_GetStringFromObj(objv[2], &len); if (strncmp(str, "row", len) == 0 || strncmp(str, "col", len) == 0) { Tcl_Obj *resultPtr = Tcl_GetObjResult(interp); /* set row index list ?index list ...? */ if (objc < 4) { goto CMD_SET_USAGE; } else if (objc == 4) { if (TableGetIndexObj(tablePtr, objv[3], &row, &col) != TCL_OK) { return TCL_ERROR; } if (*str == 'r') { max = tablePtr->cols+tablePtr->colOffset; for (i=col; i<max; i++) { str = TableGetCellValue(tablePtr, row, i); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewStringObj(str, -1)); } } else { max = tablePtr->rows+tablePtr->rowOffset; for (i=row; i<max; i++) { str = TableGetCellValue(tablePtr, i, col); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewStringObj(str, -1)); } } } else if (tablePtr->state == STATE_NORMAL) { int listc; Tcl_Obj **listv; /* make sure there are an even number of index/list pairs */ if (objc & 0) { goto CMD_SET_USAGE; } for (i = 3; i < objc-1; i += 2) { if ((TableGetIndexObj(tablePtr, objv[i], &row, &col) != TCL_OK) || (Tcl_ListObjGetElements(interp, objv[i+1], &listc, &listv) != TCL_OK)) { return TCL_ERROR; } if (*str == 'r') { max = col+MIN(tablePtr->cols+tablePtr->colOffset-col, listc); for (j = col; j < max; j++) { if (TableSetCellValue(tablePtr, row, j, Tcl_GetString(listv[j-col])) != TCL_OK) { return TCL_ERROR; } if (row-tablePtr->rowOffset == tablePtr->activeRow && j-tablePtr->colOffset == tablePtr->activeCol) { TableGetActiveBuf(tablePtr); } TableRefresh(tablePtr, row-tablePtr->rowOffset, j-tablePtr->colOffset, CELL); } } else { max = row+MIN(tablePtr->rows+tablePtr->rowOffset-row, listc); for (j = row; j < max; j++) { if (TableSetCellValue(tablePtr, j, col, Tcl_GetString(listv[j-row])) != TCL_OK) { return TCL_ERROR; } if (j-tablePtr->rowOffset == tablePtr->activeRow && col-tablePtr->colOffset == tablePtr->activeCol) { TableGetActiveBuf(tablePtr); } TableRefresh(tablePtr, j-tablePtr->rowOffset, col-tablePtr->colOffset, CELL); } } } } } else if (objc == 3) { /* set index */ if (TableGetIndexObj(tablePtr, objv[2], &row, &col) != TCL_OK) { return TCL_ERROR; } else { /* * Cannot use Tcl_GetObjResult here because TableGetCellValue * can corrupt the resultPtr. */ Tcl_SetObjResult(interp, Tcl_NewStringObj( TableGetCellValue(tablePtr, row, col),-1)); } } else { /* set index val ?index val ...? */ /* make sure there are an even number of index/value pairs */ if (objc & 1) { goto CMD_SET_USAGE; } for (i = 2; i < objc-1; i += 2) { if ((TableGetIndexObj(tablePtr, objv[i], &row, &col) != TCL_OK) || (TableSetCellValue(tablePtr, row, col, Tcl_GetString(objv[i+1])) != TCL_OK)) { return TCL_ERROR; } row -= tablePtr->rowOffset; col -= tablePtr->colOffset; if (row == tablePtr->activeRow && col == tablePtr->activeCol) { TableGetActiveBuf(tablePtr); } TableRefresh(tablePtr, row, col, CELL); } } return TCL_OK; } /* *-------------------------------------------------------------- * * Table_SpanSet -- * Takes row,col in user coords and sets a span on the * cell if possible * * Results: * A standard Tcl result * * Side effects: * The span can be constrained * *-------------------------------------------------------------- */ static int Table_SpanSet(register Table *tablePtr, int urow, int ucol, int rs, int cs) { Tcl_Interp *interp = tablePtr->interp; int i, j, new, ors, ocs, result = TCL_OK; int row, col; Tcl_HashEntry *entryPtr; Tcl_HashSearch search; char *dbuf, buf[INDEX_BUFSIZE], cell[INDEX_BUFSIZE], span[INDEX_BUFSIZE]; row = urow - tablePtr->rowOffset; col = ucol - tablePtr->colOffset; TableMakeArrayIndex(urow, ucol, cell); if (tablePtr->spanTbl == NULL) { tablePtr->spanTbl = (Tcl_HashTable *)ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(tablePtr->spanTbl, TCL_STRING_KEYS); tablePtr->spanAffTbl = (Tcl_HashTable *)ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(tablePtr->spanAffTbl, TCL_STRING_KEYS); } /* first check in the affected cells table */ if ((entryPtr=Tcl_FindHashEntry(tablePtr->spanAffTbl, cell)) != NULL) { /* We have to make sure this was not already hidden * that's an error */ if ((char *)Tcl_GetHashValue(entryPtr) != NULL) { Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "cannot set spanning on hidden cell ", cell, (char *) NULL); return TCL_ERROR; } } /* do constraints on the spans * title cells must not expand beyond the titles * other cells can't expand negatively into title area */ if ((row < tablePtr->titleRows) && (row + rs >= tablePtr->titleRows)) { rs = tablePtr->titleRows - row - 1; } if ((col < tablePtr->titleCols) && (col + cs >= tablePtr->titleCols)) { cs = tablePtr->titleCols - col - 1; } rs = MAX(0, rs); cs = MAX(0, cs); /* then work in the span cells table */ if ((entryPtr = Tcl_FindHashEntry(tablePtr->spanTbl, cell)) != NULL) { /* We have to readjust for what was there first */ TableParseArrayIndex(&ors, &ocs, (char *)Tcl_GetHashValue(entryPtr)); ckfree((char *) Tcl_GetHashValue(entryPtr)); Tcl_DeleteHashEntry(entryPtr); for (i = urow; i <= urow+ors; i++) { for (j = ucol; j <= ucol+ocs; j++) { TableMakeArrayIndex(i, j, buf); entryPtr = Tcl_FindHashEntry(tablePtr->spanAffTbl, buf); if (entryPtr != NULL) { Tcl_DeleteHashEntry(entryPtr); } TableRefresh(tablePtr, i-tablePtr->rowOffset, j-tablePtr->colOffset, CELL); } } } else { ors = ocs = 0; } /* calc to make sure that span is OK */ for (i = urow; i <= urow+rs; i++) { for (j = ucol; j <= ucol+cs; j++) { TableMakeArrayIndex(i, j, buf); entryPtr = Tcl_FindHashEntry(tablePtr->spanAffTbl, buf); if (entryPtr != NULL) { /* Something already spans here */ Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "cannot overlap already spanned cell ", buf, (char *) NULL); result = TCL_ERROR; rs = ors; cs = ocs; break; } } if (result == TCL_ERROR) break; } /* 0,0 span means set to unspanned again */ if (rs == 0 && cs == 0) { entryPtr = Tcl_FindHashEntry(tablePtr->spanTbl, cell); if (entryPtr != NULL) { ckfree((char *) Tcl_GetHashValue(entryPtr)); Tcl_DeleteHashEntry(entryPtr); } entryPtr = Tcl_FindHashEntry(tablePtr->spanAffTbl, cell); if (entryPtr != NULL) { Tcl_DeleteHashEntry(entryPtr); } if (Tcl_FirstHashEntry(tablePtr->spanTbl, &search) == NULL) { /* There are no more spans, so delete tables to improve * performance of TableCellCoords */ Tcl_DeleteHashTable(tablePtr->spanTbl); ckfree((char *) (tablePtr->spanTbl)); Tcl_DeleteHashTable(tablePtr->spanAffTbl); ckfree((char *) (tablePtr->spanAffTbl)); tablePtr->spanTbl = NULL; tablePtr->spanAffTbl = NULL; } return result; } /* Make sure there is no extra stuff */ TableMakeArrayIndex(rs, cs, span); /* Set affected cell table to a NULL value */ entryPtr = Tcl_CreateHashEntry(tablePtr->spanAffTbl, cell, &new); Tcl_SetHashValue(entryPtr, (char *) NULL); /* set the spanning cells table with span value */ entryPtr = Tcl_CreateHashEntry(tablePtr->spanTbl, cell, &new); dbuf = (char *)ckalloc(strlen(span)+1); strcpy(dbuf, span); Tcl_SetHashValue(entryPtr, dbuf); dbuf = Tcl_GetHashKey(tablePtr->spanTbl, entryPtr); /* Set other affected cells */ EmbWinUnmap(tablePtr, row, row + rs, col, col + cs); for (i = urow; i <= urow+rs; i++) { for (j = ucol; j <= ucol+cs; j++) { TableMakeArrayIndex(i, j, buf); entryPtr = Tcl_CreateHashEntry(tablePtr->spanAffTbl, buf, &new); if (!(i == urow && j == ucol)) { Tcl_SetHashValue(entryPtr, (char *) dbuf); } } } TableRefresh(tablePtr, row, col, CELL); return result; } /* *-------------------------------------------------------------- * * Table_SpanCmd -- * This procedure is invoked to process the span method * that corresponds to a widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_SpanCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int rs, cs, row, col, i; Tcl_HashEntry *entryPtr; Tcl_Obj *objPtr, *resultPtr; if (objc < 2 || (objc > 4 && (objc&1))) { Tcl_WrongNumArgs(interp, 2, objv, "?index? ?rows,cols index rows,cols ...?"); return TCL_ERROR; } resultPtr = Tcl_GetObjResult(interp); if (objc == 2) { if (tablePtr->spanTbl) { Tcl_HashSearch search; for (entryPtr = Tcl_FirstHashEntry(tablePtr->spanTbl, &search); entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { objPtr = Tcl_NewStringObj(Tcl_GetHashKey(tablePtr->spanTbl, entryPtr), -1); Tcl_ListObjAppendElement(NULL, resultPtr, objPtr); objPtr = Tcl_NewStringObj((char *) Tcl_GetHashValue(entryPtr), -1); Tcl_ListObjAppendElement(NULL, resultPtr, objPtr); } } return TCL_OK; } else if (objc == 3) { if (TableGetIndexObj(tablePtr, objv[2], &row, &col) == TCL_ERROR) { return TCL_ERROR; } /* Just return the spanning values of the one cell */ if (tablePtr->spanTbl && (entryPtr = Tcl_FindHashEntry(tablePtr->spanTbl, Tcl_GetString(objv[2]))) != NULL) { Tcl_SetStringObj(resultPtr, (char *)Tcl_GetHashValue(entryPtr), -1); } return TCL_OK; } else { for (i = 2; i < objc-1; i += 2) { if (TableGetIndexObj(tablePtr, objv[i], &row, &col) == TCL_ERROR || (TableParseArrayIndex(&rs, &cs, Tcl_GetString(objv[i+1])) != 2) || Table_SpanSet(tablePtr, row, col, rs, cs) == TCL_ERROR) { return TCL_ERROR; } } } return TCL_OK; } /* *-------------------------------------------------------------- * * Table_HiddenCmd -- * This procedure is invoked to process the hidden method * that corresponds to a widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_HiddenCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int i, row, col; Tcl_HashEntry *entryPtr; char *span; if (objc < 2) { Tcl_WrongNumArgs(interp, 2, objv, "?index? ?index ...?"); return TCL_ERROR; } if (tablePtr->spanTbl == NULL) { /* Avoid the whole thing if we have no spans */ if (objc > 3) { Tcl_SetBooleanObj(Tcl_GetObjResult(interp), 0); } return TCL_OK; } if (objc == 2) { /* return all "hidden" cells */ Tcl_DString cells; Tcl_HashSearch search; Tcl_DStringInit(&cells); for (entryPtr = Tcl_FirstHashEntry(tablePtr->spanAffTbl, &search); entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { if ((span = (char *) Tcl_GetHashValue(entryPtr)) == NULL) { /* this is actually a spanning cell */ continue; } Tcl_DStringAppendElement(&cells, Tcl_GetHashKey(tablePtr->spanAffTbl, entryPtr)); } span = Tcl_GetString(TableCellSort(tablePtr, Tcl_DStringValue(&cells))); if (span != NULL) { Tcl_SetResult(interp, span, TCL_DYNAMIC); } Tcl_DStringFree(&cells); return TCL_OK; } if (objc == 3) { if (TableGetIndexObj(tablePtr, objv[2], &row, &col) != TCL_OK) { return TCL_ERROR; } /* Just return the spanning values of the one cell */ entryPtr = Tcl_FindHashEntry(tablePtr->spanAffTbl, Tcl_GetString(objv[2])); if (entryPtr != NULL && (span = (char *)Tcl_GetHashValue(entryPtr)) != NULL) { /* this is a hidden cell */ Tcl_SetStringObj(Tcl_GetObjResult(interp), span, -1); } return TCL_OK; } for (i = 2; i < objc; i++) { if (TableGetIndexObj(tablePtr, objv[i], &row, &col) == TCL_ERROR) { return TCL_ERROR; } entryPtr = Tcl_FindHashEntry(tablePtr->spanAffTbl, Tcl_GetString(objv[i])); if (entryPtr != NULL && (char *)Tcl_GetHashValue(entryPtr) != NULL) { /* this is a hidden cell */ continue; } /* We only reach here if it doesn't satisfy "hidden" criteria */ Tcl_SetBooleanObj(Tcl_GetObjResult(interp), 0); return TCL_OK; } Tcl_SetBooleanObj(Tcl_GetObjResult(interp), 1); return TCL_OK; } /* *-------------------------------------------------------------- * * TableSpanSanCheck -- * This procedure is invoked by TableConfigure to make sure * that spans are kept sane according to the docs. * See the user documentation for details on what it does. * * Results: * void. * * Side effects: * Spans in title areas can be reconstrained. * *-------------------------------------------------------------- */ void TableSpanSanCheck(register Table *tablePtr) { int rs, cs, row, col, reset; Tcl_HashEntry *entryPtr; Tcl_HashSearch search; if (tablePtr->spanTbl == NULL) { return; } for (entryPtr = Tcl_FirstHashEntry(tablePtr->spanTbl, &search); entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { reset = 0; TableParseArrayIndex(&row, &col, Tcl_GetHashKey(tablePtr->spanTbl, entryPtr)); TableParseArrayIndex(&rs, &cs, (char *) Tcl_GetHashValue(entryPtr)); if ((row-tablePtr->rowOffset < tablePtr->titleRows) && (row-tablePtr->rowOffset+rs >= tablePtr->titleRows)) { rs = tablePtr->titleRows-(row-tablePtr->rowOffset)-1; reset = 1; } if ((col-tablePtr->colOffset < tablePtr->titleCols) && (col-tablePtr->colOffset+cs >= tablePtr->titleCols)) { cs = tablePtr->titleCols-(col-tablePtr->colOffset)-1; reset = 1; } if (reset) { Table_SpanSet(tablePtr, row, col, rs, cs); } } } �����������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable/mm.h������������������������������������������������������������0000644�0000000�0000000�00000007276�13745605157�016422� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * mm.h -- * * This is the header file for the module that implements * command structure lookups. * * Copyright (c) 1997,1998 Jeffrey Hobbs * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * */ #ifndef _MM_H_ #define _MM_H_ #include <string.h> #include <stdlib.h> #include <tk.h> /* Make sure this syncs with Makefile.in */ #define MM_MAJOR_VERSION 1 #define MM_MINOR_VERSION 0 #define MM_RELEASE_SERIAL 0 #define MM_VERSION "1.0" #define MM_PATCH_LEVEL "1.0.0" /* Now we start defining package specific stuff */ #define MM_ERROR 0 #define MM_VALUE (1<<0) #define MM_PROC (1<<1) #define MM_OBJPROC (1<<2) #define MM_SUBPROC (1<<3) #define MM_LAST ((char *) NULL) #define MM_OVERWRITE (1<<0) #define MM_MERGE (1<<1) /* structure for use in parsing general major/minor commands */ typedef struct { char *name; /* name of the command/value */ Tcl_CmdProc *proc; /* >0 because 0 represents an error or proc */ int type; /* whether it is proc or just value */ ClientData data; /* optional clientData arg */ } MajorMinor_Cmd; extern int MM_GetProcExact _ANSI_ARGS_((const MajorMinor_Cmd *cmds, const char *name, Tcl_CmdProc **proc)); extern void MM_GetError _ANSI_ARGS_((Tcl_Interp *interp, const MajorMinor_Cmd *cmds, const char *arg)); extern int MM_GetProc _ANSI_ARGS_((Tcl_Interp *interp, MajorMinor_Cmd *cmds, const char *arg, MajorMinor_Cmd **cmd)); extern int MM_HandleArgs _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, MajorMinor_Cmd *cmds, int argc, char **argv)); extern int MM_HandleCmds _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv)); extern MajorMinor_Cmd *MM_InitCmds _ANSI_ARGS_((Tcl_Interp *interp, char *name, MajorMinor_Cmd *cmds, ClientData clientData, int flags)); extern int MM_InsertCmd _ANSI_ARGS_((Tcl_Interp *interp, MajorMinor_Cmd *cmds, const char *name, Tcl_CmdProc **proc, int type)); extern int MM_RemoveCmd _ANSI_ARGS_((Tcl_Interp *interp, MajorMinor_Cmd *cmds, const char *name)); EXTERN int Majmin_Init _ANSI_ARGS_((Tcl_Interp *interp)); EXTERN int Majmin_SafeInit _ANSI_ARGS_((Tcl_Interp *interp)); EXTERN int Tcl_MajminCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv)); /* structure for use in parsing table commands/values */ typedef struct { char *name; /* name of the command/value */ int value; /* >0 because 0 represents an error or proc */ } Cmd_Struct; extern char * Cmd_GetName _ANSI_ARGS_((const Cmd_Struct *cmds, int val)); extern int Cmd_GetValue _ANSI_ARGS_((const Cmd_Struct *cmds, Arg arg)); extern void Cmd_GetError _ANSI_ARGS_((Tcl_Interp *interp, const Cmd_Struct *cmds, Arg arg)); extern int Cmd_Parse _ANSI_ARGS_((Tcl_Interp *interp, Cmd_Struct *cmds, const char *arg)); extern int Cmd_OptionSet _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, Tk_Window unused, Arg value, char *widgRec, int offset)); extern Arg Cmd_OptionGet _ANSI_ARGS_((ClientData clientData, Tk_Window unused, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)); extern int Cmd_BitSet _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, Tk_Window unused, Arg value, char *widgRec, int offset)); extern char * Cmd_BitGet _ANSI_ARGS_((ClientData clientData, Tk_Window unused, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)); #endif /* _MM_H_ */ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable/mac_tkTable.r���������������������������������������������������0000644�0000000�0000000�00000002504�13745605157�020216� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include <Types.r> #include <SysTypes.r> #include "../generic/version.h" resource 'vers' (1) { TBL_MAJOR_VERSION, TBL_MINOR_VERSION, final, 0x00, verUS, TBL_VERSION, "tkTable " TBL_VERSION " by Jeffrey Hobbs\n" "Macintosh Port by Chuck Houpt" }; resource 'vers' (2) { TBL_MAJOR_VERSION, TBL_MINOR_VERSION, final, 0x00, verUS, TBL_VERSION, "tkTable " TBL_VERSION " © 1997-2000" }; /* * The -16397 string will be displayed by Finder when a user * tries to open the shared library. The string should * give the user a little detail about the library's capabilities * and enough information to install the library in the correct location. * A similar string should be placed in all shared libraries. */ resource 'STR ' (-16397, purgeable) { "tkTable Library\n\n" "This library provides the ability to create tables " " from Tcl/Tk programs. To work properly, it " "should be placed in the ÔTool Command LanguageŐ folder " "within the Extensions folder." }; read 'TEXT' (3000, "tkTable", purgeable, preload) "tkTable.tcl"; /* * We now load the Tk library into the resource fork of the library. */ data 'TEXT' (4000, "pkgIndex", purgeable, preload) { "package ifneeded Tktable " TBL_VERSION " " "\"package require Tk; [list load [file join $dir Tktable.shlb] Tktable]\"" }; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable/Makefile.in�����������������������������������������������������0000644�0000000�0000000�00000012641�13745605157�017675� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# version info in Makefile and C format include @srcdir@/version.h # This sets the name that tkTable will define for itself when loaded # If you change this, then the demos won't work, but it might be necessary # for those with another built-in "table" command TBL_COMMAND = table TBL_RUNTIME = tkTable.tcl SRCDIR = @srcdir@ TOPDIR = @srcdir@/.. LIBDIR = $(TOPDIR)/lib DOCDIR = $(TOPDIR)/doc PACKAGE = Tktable OBJS = tkTable.o tkTableWin.o tkTableTag.o tkTableEdit.o \ tkTableCell.o tkTableCmds.o cmd.o ## PostScript is on the drawing board #OBJS += tkTablePs.o MANS = tkTable.n #------------------------------------------------- prefix = @prefix@ exec_prefix = @exec_prefix@ TCL_VERSION = @TCL_VERSION@ TK_VERSION = @TK_VERSION@ WISH = wish$(TK_VERSION) TCL_SRC_DIR = @TCL_SRC_DIR@ TK_SRC_DIR = @TK_SRC_DIR@ TCL_BUILD_LIB_SPEC = @TCL_BUILD_LIB_SPEC@ TK_BUILD_LIB_SPEC = @TK_BUILD_LIB_SPEC@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TK_LIB_SPEC = @TK_LIB_SPEC@ TCL_LIBS = @TCL_LIBS@ TK_LIBS = @TK_LIBS@ TBL_CFLAGS = -O ## NO_EMBEDDED_RUNTIME means that the tkTable.tcl file will not be embedded ## into the executable, thus the default tkTable.tcl library file will not ## be available when the library is loaded. ## If this is defined, the tkTable.tcl file must be available in a ## predefined set of directories (see docs). #TBL_CFLAGS += -DNO_EMBEDDED_RUNTIME ## USE_EXIT_HANDLER is necessary for 8.1 before b3 and 8.0 ## It is a work-around for the improper unloading of DLLs when exiting #TBL_CFLAGS += -DUSE_EXIT_HANDLER ## Experimental, not documented, not complete... #TBL_CFLAGS += -DPROCS ## I use this for helping hunt down the slightest error #TBL_CFLAGS += -DDEBUG -g -Wall -Wno-implicit -Wshadow \ -Wpointer-arith -Wmissing-prototypes \ -Wmissing-declarations -Wnested-externs -Winline INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ CC = @CC@ RM = rm -f RANLIB = @TCL_RANLIB@ SHLIB_CFLAGS = @TCL_SHLIB_CFLAGS@ SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ SHLIB_LD = @TCL_SHLIB_LD@ TCL_PREFIX = @TCL_PREFIX@ ## HP cc sometimes requires -Aa for proper ansi compilation TCL_CFLAGS = $(TBL_CFLAGS) @TCL_DEFS@ @TCL_CFLAGS@ TCL_LD_FLAGS = @TCL_LD_FLAGS@ TK_LD_SEARCH_FLAGS = @TK_LD_SEARCH_FLAGS@ TK_XINCLUDES = @TK_XINCLUDES@ LIB_RUNTIME_DIR = @libdir@ INCLUDES = -I@includedir@ $(TK_XINCLUDES)\ -I$(TCL_SRC_DIR)/generic\ -I$(TK_SRC_DIR)/generic DLL = $(PACKAGE)$(SHLIB_SUFFIX) STATIC_LIB = $(PACKAGE).a PACKAGEDIR = $(PACKAGE)$(TBL_VERSION) STATIC_EXEC = tablewish DLLDIR = ${exec_prefix}/lib/$(PACKAGEDIR) RUNDIR = ${prefix}/lib/$(PACKAGEDIR) CFLAGS = -I. -I$(SRCDIR) $(TCL_CFLAGS) $(SHLIB_CFLAGS) $(INCLUDES)\ -DTBL_VERSION=\"$(TBL_VERSION)\"\ -DTBL_COMMAND=\"$(TBL_COMMAND)\"\ -DTBL_RUNTIME=\"$(TBL_RUNTIME)\"\ -DTBL_RUNTIME_DIR=\"$(RUNDIR)\" MAN_INSTALL_DIR = @mandir@/mann #COMPRESS = tar cvf $(PACKAGEDIR).tar $(PACKAGEDIR); compress $(PACKAGEDIR).tar COMPRESS = gtar zcvf $(PACKAGEDIR).tar.gz $(PACKAGEDIR) all: $(DLL) pkgIndex.tcl $(DLL): $(OBJS) $(SHLIB_LD) -o $@ $(OBJS) static $(STATIC_LIB): $(OBJS) pkgIndex.tcl $(RM) $(STATIC_LIB) ar cr $(STATIC_LIB) $(OBJS) $(RANLIB) $(STATIC_LIB) tkTable.o: $(SRCDIR)/tkTable.h $(SRCDIR)/tkTable.c \ $(SRCDIR)/tkTableInitScript.h tkTable.tcl.h tkTableCmds.o: $(SRCDIR)/tkTable.h $(SRCDIR)/tkTableCmds.c tkTableCell.o: $(SRCDIR)/tkTable.h $(SRCDIR)/tkTableCell.c tkTablePs.o: $(SRCDIR)/tkTable.h $(SRCDIR)/tkTablePs.c tkTableTag.o: $(SRCDIR)/tkTable.h $(SRCDIR)/tkTableTag.c tkTableWin.o: $(SRCDIR)/tkTable.h $(SRCDIR)/tkTableWin.c .c.o: $(CC) $(CFLAGS) $(CPPFLAGS) -c $(SRCDIR)/$*.c pkgIndex.tcl: (\ echo 'if {[catch {package require Tcl $(TCL_VERSION)}]} return';\ echo 'package ifneeded $(PACKAGE) $(TBL_VERSION)\ "package require Tk $(TK_VERSION);\ [list load [file join $$dir $(DLL).$(TBL_VERSION)] $(PACKAGE)]"'\ ) > pkgIndex.tcl install: all if test ! -d "$(DLLDIR)"; then mkdir "$(DLLDIR)"; fi if test ! -d "$(RUNDIR)"; then mkdir "$(RUNDIR)"; fi $(INSTALL_PROGRAM) $(DLL) "$(DLLDIR)/$(DLL).$(TBL_VERSION)" $(INSTALL_DATA) pkgIndex.tcl "$(DLLDIR)/pkgIndex.tcl" $(INSTALL_DATA) $(LIBDIR)/tkTable.tcl "$(RUNDIR)/tkTable.tcl" $(INSTALL_DATA) $(DOCDIR)/$(MANS) $(MAN_INSTALL_DIR)/ # Leaves behind created directories uninstall: $(RM) "$(DLLDIR)/$(DLL).$(TBL_VERSION)" "$(DLLDIR)/pkgIndex.tcl" "$(RUNDIR)/tkTable.tcl" $(MAN_INSTALL_DIR)/$(MANS) test: all $(WISH) $(TOPDIR)/demos/basic.tcl clean: $(RM) $(OBJS) $(DLL) $(STATIC_LIB) $(STATIC_EXEC) core pkgIndex.tcl tkTable.tcl.h distclean: clean $(RM) Makefile config.cache config.log config.status tkTable.tcl.h: $(LIBDIR)/tkTable.tcl sed -e '/^$\#/d' -e '/^$$/d' -e 's/\"/\\"/g' -e 's/^/"/' -e 's/$$/\\n"/' <$(LIBDIR)/tkTable.tcl > $@ || { $(RM) $@; exit 1; } tablewish: tkAppInit.o $(OBJS) wish: tkAppInit.o $(OBJS) $(CC) $(TK_LD_SEARCH_FLAGS) -o $(STATIC_EXEC) tkAppInit.o $(OBJS) \ $(LIBS) $(TK_BUILD_LIB_SPEC) $(TK_LIB_SPEC) $(TCL_BUILD_LIB_SPEC) $(TCL_LIB_SPEC) $(TK_LIBS) $(TCL_LIBS) distrib-clean: rm -rf ../../$(PACKAGEDIR) ../../$(PACKAGEDIR).tar.* distrib: $(RM) $(DOCDIR)/tkTable.html nroff -man $(DOCDIR)/tkTable.n | rman -f HTML > $(DOCDIR)/tkTable.html (cd ../..; \ cp -r tkTable $(PACKAGEDIR); \ cd $(PACKAGEDIR)/src; \ make distclean >&1 > /dev/null; \ cd ../..; $(COMPRESS); \ ) �����������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable/mac_tkTable.mcp�������������������������������������������������0000644�0000000�0000000�00000334060�13742524721�020533� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cool�����(�¨Č�©đ��@������������CodeWarrior Project�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������m��€��Nů��P���m�˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙�������!°ŕ�������������"���!ˇĐ���)���!ˇ0���8�����*t���G����������T���!˘���a����ç¸���o��� �������s��� �������‚��� !˘P���”��� �ăČ���¤��� �������¶����������Č���!˘€���×����ďŕ���ä���˙p���ň���ë�����ů�����Ž�� ���!ˇĐ�����������)���������6���îČ<��F���!˘Đ��S������H��[��������n���������|���������Ś����@��–��������Ż������Â��� """"��Ú���!��€��ô���"������#���������$���(��!���%�wi��0���&ë����?���'������X���(��¦0��j���)��� ��|���*8086�����+�¶ô ��”���,˙˙÷H�� ���-�����ą���.�����Ń���/µň\��ę���05ĘŔ�����1��đ�����2������-���3������E���4������^���5������v���6������‰���7�¶ô@��ś���8˙˙÷��®���9���%��Ŕ���:���"��Ó���;���)��ć���<���*��ř���=���-�� ���>���0�����?���3��3���@���6��G���A������_���B������w���C������Ź���D������§���E������ą���F������Ĺ���G������Ď���H������Ý���I������ě���J������ú���K������ ���L���������M������3���N������N���O������d���P������Ś���Q������Ł���R������­���S������ą���T������Ă���U������Ě���V������Ř���W������ă���X������ó���Y���������Z���������[������#���\������0���]������<���^������H���_������W���`������e���a������w���b���������c������’���d������¤���e������µ���f������Ę���g������ĺ���h������ü���i���������j������+���k������9���l������?���m������M���n������Y���o������f���p������s���q���������r������ś���s�������������������������������������������������������������������������������������������������������������������������������������������������������������������s���€��¦������s�PortSetPBitsPortS������������������������ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ��� ��'���˙����˙����˙����˙�������������������������������������������������������������JavaClasses.zip����������������ZIP JAVA������������������������������� ��� ��+��������������� �������������������������������� �����mac_tkTable_prefix.h�������������������������������������������������������������������� ��� ��� ������ ��� ���������������������������������������������������������������� Merge Out������������������������������������������������������????APPL���DLGXckidProjWSPC��������˙����˙����˙����˙�������������������������&���JavaClasses.jar����������������ZIP MWZP������������������������������������������������������������������������������������������������������������������������������Tktable.PPC.shlbBUG PPC��������TclLshlb�����������������������������������������������������������������������������������������������������������������????���������������������� ������� MacHeaders.h�������������������������������������������������������������������������������������������������������������������������������������������������������@���B������,���.���L���K���P���M���N���5���1���3���9���6���"���O���I���J���T���e���`���_���)��� ���+���#���*������H���E������ ��� ���-���/���!������� ���<���k���Z���D������;���:������������F���G���0���2���4���8���7������j���p������?������&������>��� ������=������h������g������X������Y���f���'���(��������������� ������A���C���������������U���c���W���V���d���R���^���]���\���Q���i���S���a���b���[���l���q���m���n���o���$���%���r����������������������������������������������������������JavaClasses.jar����������������ZIP MWZP���������� �� ���� Tktable.shlb���������������������������������������������������TclLshlb���DLGXckidProjWSPC����������JavaClasses.zip����������������ZIP JAVA�����MacOS Toolbox DEBUG 68K\���������������������������������������????APPL��€XŔ������������������������������������������������������������������????���������U {��������������€���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JavaClasses.zip����������������ZIP JAVA�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MSIEInternet Explorer����������������������������������������������Iexplore.exe��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������TclMacInitializeFragment�����������������������������������__sta�_start���������������������������������������������������������TclMacTerminateFragment������������������������������������������������������������������������ NONAME.EXE����������������������@���������������U {�������������˙����˙����˙����˙���������������������������������������������������������������������������������������������������������������������������������������������� ��������������������������������������������������������������������������a.out���������������������������@���������������U {��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MSIEInternet Explorer����������������������������������������������Iexplore.exe������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ ��������������������������������������������������������������������������a.out���������������������������@���������������U {������������������������������tktable2.20����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ��������������������������������������������������������������������������a.out���������������������������@���������������U {����������������������±Ů(��T~���������������� ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������__start������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MSIEInternet Explorer����������������������������������������������Iexplore.exe�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������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��ť��ž��ź�� ��™��ś��ˇ��˘��Ł����›��¤��Ą��¦��§��¨��©��Ş��«��¬��­��®��Ż��°��±��š��˛��ł��´��µ���B���C���D���E���>���A���F���G���H���=���@���I���J���K���L���M���N���O���P���Q���R���S���T���U���V���?���W���X���Y���Z���$���%���&���'��� ���#���(���)���*������"���+���,���-���.���/���0���1���2���3���4���5���6���7���8���!���9���:���;���<���ś���ť���ž���ź������›��� ���ˇ���˘���—���š���Ł���¤���Ą���¦���§���¨���©���Ş���«���¬���­���™���ł���´���µ���¶���Ż���˛���·���¸���ą���®���±���ş���»���Ľ���˝���ľ���ż���Ŕ���Á���Â���Ă���Ä���°���~������€������z���}���‚������„���y���|���…���†���‡������‰���Š���‹���Ś���Ť���Ž���Ź������‘���’���{���“���”���•���–��������������������� ��� ��� ���������� ��� ������������������������������������������������������`���a���b���c���\���_���d���e���f���[���^���g���h���i���j���k���l���m���n���o���p���q���r���s���t���]���u���v���w���x��Ů��Ú��Ű��Ü��Ő��Ř��Ý��Ţ��ß��Ô��×��ŕ��á��â��ă��ä��ĺ��ć��ç��č��é��ę��ë��ě��í��Ö��î��ď��đ��ń���Ę���Ë���Ě���Í���Ć��J���É���Î���Ď���Đ���Ĺ���Č��K���Ń��L��M��N���Ň���Ó���Ô���Ő���Ö���×���Ř���Ů���Ú���Ű���Ç��O��P��Q��R���á���â���ă���ä���Ý��8���ŕ���ĺ���ć���ç���Ü���ß��9���č��:��;��<���é���ę���ë���ě���í���î���ď���đ���ń���ň���Ţ��=��>��?��@���ř���ů���ú���ű���ô��A���÷���ü���ý���ţ���ó���ö��B���˙��C��D��E��������������������� ���ő��F��G��H��I��&��'��(��)��"��%��*��+��,��!��$��-��.��/��0��1��2��3��4��5��6��7��#���������� ��S���������� �� ��T����U��V��W�������������������� �� ��X��Y��Z��[����€����‚��{��~����„��…��z��}��†��ň��‡����‰��ô��Š��‹��Ś��Ť��Ž��Ź����‘��’��“��|��”��•��–��—��»��Ľ��˝��ľ��·��ş��ż��Ŕ��Á��¶��ą��Â��ó��Ă��Ä��Ĺ��ő��Ć��Ç��Č��É��Ę��Ë��Ě��Í��Î��Ď��¸��Đ��Ń��Ň��Ó�����R��S��T��U��N��l��Q��V��W��X��M��P��Y��Z��[��\��]��^��_��`��a��b��c��d��e��O��f��g��h��i��5��6��7��8��1��j��4��9��:��;��0��3��<��=��>��?��@��A��B��C��D��E��F��G��H��2��I��J��K��L������������k���������������� ��!��"��#��$��%��&��'��(��)��*��+����,��-��.��/��ű��ü��ý��ţ��÷��ú��˙�������ö��ů���������������� �� �� �� �� ����ř������������������������������������������������������������������������������������������^���������������`±Đż/˙˙Ľő���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������] ���������������a±Ů&ő��Ď���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������_ ���������������f±Ů&ő��hM��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� NONAME.EXE����������������������@���������������U {�������������������������������������������������b������������������€�������������j������������������€�������������k��������������������������������k���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ����������������������������������������������������������������������������������????���������a.out����������������������������������������������������������????APPL��€XŔ������������������������������������������������������������������????���������U {��������������€����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PC�������������������������������������������������Basic Toolbox Multi�First Segment�:a.out�Lib Import 68K�MPW Import 68K�Balloon Help�MW C/C++ 68K�MW Pascal 68K�Rez�PEF Import 68K�Basic Toolbox 68k�:Toolbox68k.out�Basci Toolbox PPC�Basic Toolbox PPC�Lib Import PPC�MW C/C++ PPC�MW Pascal PPC�PPCAsm�XCOFF Import PPC�PEF Import PPC�:ToolboxPPC.out�SillyBalls.c�SillyBalls.rsrc�InterfaceLib�MathLib�MSL RuntimePPC.Lib�MSL C.PPC.Lib�MSL C++.PPC.Lib�MacOS.lib�MathLib68K Fa(4i/8d).Lib�MSL Runtime68K.Lib�MSL C.68K Fa(4i_8d).Lib�MSL C++.68K Fa(4i_8d).Lib�Basic Toolbox FAT�:Merge Out�:ToolboxFAT.out�Toolbox68k.out�ToolboxPPC.out�MathLib68K Fa(4i_8d).Lib�MSL SIOUX.68K.Lib�MSL SIOUX.PPC.Lib�:Toolbox68k�:ToolboxPPC�:ToolboxFAT�:Basic Toolbox DEBUG 68k�Basic Toolbox DEBUG 68k�:Basic Toolbox DEBUG PPC�Basic Toolbox DEBUG PPC�MacOS Toolbox 68K�:MacOS Toolbox DEBUG 68K�MacOS Toolbox DEBUG 68K�:MacOS Toolbox DEBUG PPC�MacOS Toolbox DEBUG PPC�:MacOS Toolbox 68K�:MacOS Toolbox PPC�MacOS Toolbox PPC�MacOS Toolbox FAT�:MacOS Toolbox FAT�GameCode Converter�Flex Preprocessor�Bison Preprocessor�MSL C.68K (2i).Lib�MSL C++.68K (2i).Lib�MathLib68K (2i).Lib�68K Debug MacOS Toolbox�PPC Debug MacOS Toolbox�68K Final MacOS Toolbox�PPC Final MacOS Toolbox�FAT MacOS Toolbox�Application�Libraries�Mac Libraries�ANSI Libraries�:SillyBalls.c�:SillyBalls.rsrc�:Bin:MSL C.PPC.Lib�:Bin:MSL C++.PPC.Lib�:MacOS Common:InterfaceLib�:MacOS Common:MathLib�:Runtime:Runtime PPC:MSL RuntimePPC.Lib�:Bin:MSL SIOUX.PPC.Lib�tkTable.c�tkAppInit.c�tkTable.h�:tkTable�Tcl8.0.shlb�Tk8.0.shlb�tclMacLibrary.c�MSL RuntimePPC.DLL�MSL ShLibRuntime.Lib�dummy.c�Tktable.shlb�Tktable PPC�Tktable Fat�Tktable CFM68k�:Tktable.shlb�:Tktable.PPC.shlb�Tktable.PPC.shlb�tkTable.r�Tcl8.0CFM68K.shlb�Tk8.0CFM68K.shlb�:Tktable.CFM68k.shlb�MSL ShLibRuntimeCFM68K.Lib�MSL MWRuntimeLibCFM68K�MSL C.CFM68K Fa(4i_8d).Lib�Tktable.CFM68k.shlb�mac_tkTable.r�cmd.c�tkTableCell.c�tkTablePs.c�tkTableTag.c�tkTableWin.c�mac_tkTable_prefix.h�tkTableInitScript.h�version.h����������������������������������������������������������������������������������������������MacOS PPC Linker��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tktable PPC�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������:��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������__start�������������������������������������������������������������������������������������������������������������������������� �� �� �� �� �� �� �� �� �� �� �� �� �� ��! ��" ��# ��$ ��& ��'����� ���@����::���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙�����:::Tcl/Tk Folder:tcl8.0:�:�8.0:����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙@����:::Tcl/Tk Folder:tk8.0:�:�8.0:�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙@����:Extensions:Tool Command Language:�ol Command Language:����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙�����:MacOS Support:Headers:Universal Headers:������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙@����:Metrowerks Standard Library:MSL C:������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙@����:Metrowerks Standard Library:MSL C++:����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙@����:MacOS Support:MacHeaders:���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙@����:MacOS Support:Libraries:����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙@�� ��:MacOS Support:��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙@��� �����mac_tkTable_prefix.h���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������reg���$����������E���illD���i���5¸ ���‹���Get���¬���tMou���Ě���tDia���ń���dDia����� Dial��0��� ialo��S��� wDia��v��� ialo��‘��� xt I��˛���vent��Ň���elec��ó���alog�����alog��5���Dial��Y���Item��}���topA��ť���eAle��Â���onAl��á���dAle��ý���lert�����xt E��>���dGe��_���etDI��‚���Text��˘���t Mo��Á���gDe��á���urce��ó��� urge�����!��€��4���"nded��V���#ist���v���$5ň°��•���%������ł���&������Ö���'������ó���(���������)��� ��2���*_cas��S���+5ă0��l���,�ĺŔ��‹���-�reg��©���.������Č���/illD��â���05¸ �����1Get��(���2tMou��J���3tDia��h���4dDia��‹���5Dial��¨���6ialo��Â���7wDia��ŕ���8ialo��˙���9xt I�����:vent��?���;elec��]���<alog��z���=alog�����>Dial��ş���?Item��Ů���@topA��ű���A��€�����BonAl��:���CdAle��X���Dlert��{���Ext E�����FdGe��¶���GetDI��×���HText��ř���It Mo�� ���JgDe�� 0���Kurce�� N���Lurge�� m���M����� ‡���N����� «���O����� Í���P��� �� ď���Q����� ���R����� 0���S����� M���T����� g���U����� …���V����� ¤���W����� Ă���X Get�� ä���Y���� ���Zc To�� ���[lti��� =���\gmen�� _���]�Lib�� ~���^68K���  ���_rt 6�� Ŕ���`on H�� ß���a��€�� ý���bPasc�� ���cez�P�� =���dt 68�� [���e!Żč�� |���f!Żđ�� ť���g!Żđ�� ¶���h!Żđ�� Ő���i!°��� ó���j!°Ř�� ���k!°Č�� ,���l!°Č�� P���m!°Č�� r���n!°Č�� ”���o!°Č�� ˛���p!°Č�� Ő���q!°Č�� ň���r!°Č�� ���s!°Č��*���t!°Ř��I���u!°Ř��h���v!°H��‰���w6~p��§���x�eÜ��Ä���ycall��â���zBŕCŕ�����{HŕIŕ��#���|NŕOŕ��E���}TŕUŕ��e���~Zŕ[ŕ��„���`ŕaŕ��˘���€fŕgŕ��Ĺ�����€��â���‚nded������ist���!���„Targ��B���…ct D��[���†Sett��z���‡ Set�����eSaf��·���‰��� ��Ń���Š_cas��ő���‹5ă0�����Ś�ĺŔ��9���Ť�reg��W���Ž������z���ŹillD��—���5¸ ��±���‘Get��Ď���’tMou��î���“tDia�� ���”dDia��.���•Dial��L���–ialo��i���—wDia��‡���ialo��Ż���™xt I��Ô���švent��ü���›elec��"���śalog��G���ťalog��k���žDial��”���źItem��·��� topA��Ű���ˇ���������˘������)���Ł������H���¤������m���Ą������—���¦������ż���§������ç���¨������ ���©������4���Ş������W���«������w���¬������›���­������Ŕ���®������ĺ���Ż������ ���°������2���±������Z���˛������€���ł������Ą���´������É���µ������ň���¶���������·������9���¸������`���ą������‡���ş������¦���»������Ë���Ľ������ő���˝���������ľ������E���ż������i���Ŕ������’���Á������µ���Â������Ő���Ă������ů���Ä���������Ĺ������C���Ć������e���Ç������„���Č������¦���É������Ć���Ę������ĺ���Ë���������Ě������&���Í������C���Î������a���Ď������‚���Đ������Ł���Ń������Ľ���Ň������Ű���Ó������˙���Ô������!���Ő������C���Ö������a���×������„���Ř������ˇ���Ů������»���Ú������Ů���Ű������ř���Ü���������Ý������?���Ţ������d���ß������Ś���ŕ������˛���á������×���â������ű���ă������$���ä������G���ĺ������k���ć������’���ç������ą���č������Ř���é������ý���ę������'���ë������O���ě������w���í������›���î������Ä���ď������ç���đ���������ń������+���ň������P���ó������u���ô������ť���ő������Â���ö������ę���÷������ ���ř������ 5���ů������ Y���ú������ ‚���ű������ Ą���ü������ É���ý������ đ���ţ������!���˙������!6���������![��������!…��������!­��������!Ő��������!ů��������""��������"E��������"e��������"‰�� ������"®�� ������"Ó�� ������"ő�� ������#�� ������#6��������#V��������#u��������#“��������#¶��������#Ó��������#ń��������$��������$3��������$L��������$k��������$Ź��������$±��������$Ó��������$ń��������%��������%1��������%K��������%i�� ������%��!������%§��"������%É��#������%č��$������& ��%������&*��&������&I��'������&g��(������&Š��)������&§��*������&Ĺ��+������&ć��,������'��-������' ��.������'?��/������'c��0������'…��1������'§��2������'Ĺ��3������'č��4������(��5������(��6������(=��7������(\��8������({��9������(ź��:������(Â��;������(ć��<������) ��=������)+��>������)R��?������)v��@������)™��A������)˝��B������)á��C������*��D������*(��E������*M��F������*m��G������*”��H������*¸��I������*Ű��J������*˙��K������+��L������+:��M������+X��N������+w��O������+‘��P������+˛��Q������+Đ��R������+í��S������, ��T������,)��U������,F��V������,d��W������,��X������,ť��Y������,ľ��Z������,Ü��[������,ů��\������-��]������-?��^������-d��_������-Ś��`������-˛��a������-×��b������-ű��c������.$��d������.G��e������.k��f������.’��g������.ą��h������.Ř��i������.ý��j������/!��k������/F��l������/f��m������/��n������/¸��o������/ŕ��p������0��q������0-��r������0P��s������0p��t������0”��u������0ą��v������0Ţ��w������1��x������1)��y������1L��z������1p��{������1��|������1˝��}������1ĺ��~������2 ��������20��€������2T��������2}��‚������2 ��������2Ä��„������2ë��…������3��†������31��‡������3V��������3z��‰������3ź��Š������3ż��‹������3é��Ś������4��Ť������49��Ž������4]��Ź������4†��������4©��‘������4É��’������4í��“������5��”������57��•������5^��–������5‚��—������5Ą��������5É��™������5ń��š������6��›������6>��ś������6d��ť������6‰��ž������6­��ź������6Ö�� ������6ů��ˇ������7��˘������7D��Ł������7k��¤������7Š��Ą������7Ż��¦������7Ó��§������7ř��¨������8��©������8B��Ş������8j��«������8’��¬������8¶��­������8ß��®������9��Ż������9"��°������9F��±������9k��˛������9��ł������9·��´������9Ű��µ������9ţ��¶������:"��·������:J��¸������:o��ą������:—��ş������:˝��»������:â��Ľ������;��˝������;/��ľ������;R��ż������;v��Ŕ������;ť��Á������;Ä��Â������;ă��Ă������<��Ä������<,��Ĺ������<Q��Ć������<q��Ç������<›��Č������<Ă��É������<ë��Ę������=��Ë������=8��Ě������=[��Í������={��Î������=ź��Ď������=Ä��Đ������=é��Ń������>��Ň������>4��Ó������>W��Ô������>{��Ő������>ť��Ö������>Ľ��×������>Ţ��Ř������>ţ��Ů������?��Ú������?;��Ű������?^��Ü������?{��Ý������?™��Ţ������?ş��ß������?Ű��ŕ������?ô��á������@��â������@1��ă������@P��ä������@j��ĺ������@Ž��ć������@°��ç������@Ň��č������@đ��é������A��ę������A0��ë������AJ��ě������Ah��í������A‡��î������A¦��ď������AÇ��đ������Aĺ��ń������B��ň������B ��ó������BF��ô������Bl��ő������B”��ö������BĽ��÷������BŮ��ř������Bó��ů������C��ú������C+��ű������CE��ü������C^��ý������C|��ţ������C”��˙������C­���������CÉ��������Cĺ��������Ců��������D��������D.��������DG��������Da��������D~��������Dť�� ������D¶�� ������DÔ�� ������Dě�� ������E�� ������E��������E4��������EN��������Ej��������E��������E›��������E´��������EĐ��������Eé��������F��������F��������F8��������FP��������Fm��������F„��������Fś��������F·��������FŇ��������Fĺ�� ������Fţ��!������G��"������G0��#������GI��$������Ge��%������G��&������G›��'������G¸��(������GĎ��)������Gă��*������Gű��+������H��,������H-��-������HH��.������H`��/������Hw��0������HŹ��1������H«��2������HÄ��3������Hŕ��4������Hú��5������I��6������I+��7������IH��8������I_��9������Iw��:������I’��;������I­��<������IŔ��=������IŮ��>������Ió��?������J ��@������J$��A������J@��B������J^��C������Jv��D������J“��E������JŞ��F������Jľ��G������JÖ��H������Jď��I������K��J������K#��K������K;��L������KR��M������Kj��N������K‰��O������KĄ��P������KÄ��Q������Ká��R������Ký��S������L��T������L8��U������LR��V������Lm��W������L‹��X������L©��Y������Lż��Z������LŰ��[������Lř��\������M��]������M/��^������MN��_������Mo��`������MŠ��a������MŞ��b������MÄ��c������MŰ��d������Mö��e������N��f������N.��g������NL��h������Ng��i������N��j������Nś��k������Nş��l������NŘ��m���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MSIEInternet Explorer����������������������������������������������Iexplore.exe���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/ uJIT�“Ň@�������“Ú �����:u��9u“ĎP�Řx¸Z´���J� MENU��bTarg���†STR#��’PPob���¶RidL���Âaete���ÎSTR ���Úpref���ćFlag���ňTMPL���ţvers� Drop��"h����������i� ���_����j����Ł�����€����ř����,˙˙�� ����.�( �Q����-�5�������€�@��˛�����€�J�� ®�������T��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������P��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'CODE' 'DATA' 'PICT'���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������@����::���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙�����:����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙@������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������__start�������������������������������������������������������������������������������������������������������������������������������a.out��������������������������????APPL��€��€���@��XŔ�������������������������������������������������������������������������������������������������????�����������������������������������������������������������������������������������������������������������������������������������������������������Tktable.CFM68k.shlb 68K����������������������������������������TclLshlb������������������������������������������������������������������������????���������U {������������������������������ �����mac_tkTable_prefix.h�������������������������������JavaClasses.jar����������������ZIP MWZP�������� Merge Out������������������������������������������������������????APPL���DLGXckidProjWSPC�����TclMacInitializeFragment�����������������������������������__sta�_start���������������������������������������������������������TclMacTerminateFragment��������������������������������������� NONAME.EXE����������������������@���������������U {���������� ��Basic Toolbox Multi:Custom Keywords�Basic Toolbox Multi:Access Paths�Basic Toolbox Multi:Target Settings�Basic Toolbox Multi:File Mappings�Basic Toolbox Multi:Build Extras�Basic Toolbox Multi:68K CodeGen�Basic Toolbox Multi:68K Disassembler�Basic Toolbox Multi:68K Linker�Basic Toolbox Multi:68K Project�Basic Toolbox Multi:C/C++ Compiler�Basic Toolbox Multi:C/C++ Warnings�Basic Toolbox Multi:CFM68K�Basic Toolbox Multi:IR Optimizer�Basic Toolbox Multi:Java Output�Basic Toolbox Multi:Java Project�Basic Toolbox Multi:Java VM�Basic Toolbox Multi:MacOS Merge Panel�Basic Toolbox Multi:Pascal Compiler�Basic Toolbox Multi:Pascal Warnings�Basic Toolbox Multi:PPC CodeGen�Basic Toolbox Multi:PPC Disassembler�Basic Toolbox Multi:PPC Linker�Basic Toolbox Multi:PPC PEF�Basic Toolbox Multi:PPC Project�Basic Toolbox Multi:PPCAsm Panel�Basic Toolbox Multi:Rez Compiler�Basic Toolbox Multi:WinRC Compiler�Basic Toolbox Multi:x86 CodeGen�Basic Toolbox Multi:x86 Linker�Basic Toolbox Multi:x86 Project�Project File List�Basic Toolbox 68k:Custom Keywords�Basic Toolbox 68k:Access Paths�Basic Toolbox 68k:Target Settings�Basic Toolbox 68k:File Mappings�Basic Toolbox 68k:Build Extras�Basic Toolbox 68k:68K CodeGen�Basic Toolbox 68k:68K Disassembler�Basic Toolbox 68k:68K Linker�Basic Toolbox 68k:68K Project�Basic Toolbox 68k:C/C++ Compiler�Basic Toolbox 68k:C/C++ Warnings�Basic Toolbox 68k:CFM68K�Basic Toolbox 68k:IR Optimizer�Basic Toolbox 68k:Java Output�Basic Toolbox 68k:Java Project�Basic Toolbox 68k:Java VM�Basic Toolbox 68k:MacOS Merge Panel�Basic Toolbox 68k:Pascal Compiler�Basic Toolbox 68k:Pascal Warnings�Basic Toolbox 68k:PPC CodeGen�Basic Toolbox 68k:PPC Disassembler�Basic Toolbox 68k:PPC Linker�Basic Toolbox 68k:PPC PEF�Basic Toolbox 68k:PPC Project�Basic Toolbox 68k:PPCAsm Panel�Basic Toolbox 68k:Rez Compiler�Basic Toolbox 68k:WinRC Compiler�Basic Toolbox 68k:x86 CodeGen�Basic Toolbox 68k:x86 Linker�Basic Toolbox 68k:x86 Project�Basci Toolbox PPC:Custom Keywords�Basci Toolbox PPC:Access Paths�Basci Toolbox PPC:Target Settings�Basci Toolbox PPC:File Mappings�Basci Toolbox PPC:Build Extras�Basci Toolbox PPC:68K CodeGen�Basci Toolbox PPC:68K Disassembler�Basci Toolbox PPC:68K Linker�Basci Toolbox PPC:68K Project�Basci Toolbox PPC:C/C++ Compiler�Basci Toolbox PPC:C/C++ Warnings�Basci Toolbox PPC:CFM68K�Basci Toolbox PPC:IR Optimizer�Basci Toolbox PPC:Java Output�Basci Toolbox PPC:Java Project�Basci Toolbox PPC:Java VM�Basci Toolbox PPC:MacOS Merge Panel�Basci Toolbox PPC:Pascal Compiler�Basci Toolbox PPC:Pascal Warnings�Basci Toolbox PPC:PPC CodeGen�Basci Toolbox PPC:PPC Disassembler�Basci Toolbox PPC:PPC Linker�Basci Toolbox PPC:PPC PEF�Basci Toolbox PPC:PPC Project�Basci Toolbox PPC:PPCAsm Panel�Basci Toolbox PPC:Rez Compiler�Basci Toolbox PPC:WinRC Compiler�Basci Toolbox PPC:x86 CodeGen�Basci Toolbox PPC:x86 Linker�Basci Toolbox PPC:x86 Project�Basic Toolbox PPC:Custom Keywords�Basic Toolbox PPC:Access Paths�Basic Toolbox PPC:Target Settings�Basic Toolbox PPC:File Mappings�Basic Toolbox PPC:Build Extras�Basic Toolbox PPC:68K CodeGen�Basic Toolbox PPC:68K Disassembler�Basic Toolbox PPC:68K Linker�Basic Toolbox PPC:68K Project�Basic Toolbox PPC:C/C++ Compiler�Basic Toolbox PPC:C/C++ Warnings�Basic Toolbox PPC:CFM68K�Basic Toolbox PPC:IR Optimizer�Basic Toolbox PPC:Java Output�Basic Toolbox PPC:Java Project�Basic Toolbox PPC:Java VM�Basic Toolbox PPC:MacOS Merge Panel�Basic Toolbox PPC:Pascal Compiler�Basic Toolbox PPC:Pascal Warnings�Basic Toolbox PPC:PPC CodeGen�Basic Toolbox PPC:PPC Disassembler�Basic Toolbox PPC:PPC Linker�Basic Toolbox PPC:PPC PEF�Basic Toolbox PPC:PPC Project�Basic Toolbox PPC:PPCAsm Panel�Basic Toolbox PPC:Rez Compiler�Basic Toolbox PPC:WinRC Compiler�Basic Toolbox PPC:x86 CodeGen�Basic Toolbox PPC:x86 Linker�Basic Toolbox PPC:x86 Project�Basic Toolbox FAT:Custom Keywords�Basic Toolbox FAT:Access Paths�Basic Toolbox FAT:Target Settings�Basic Toolbox FAT:File Mappings�Basic Toolbox FAT:Build Extras�Basic Toolbox FAT:68K CodeGen�Basic Toolbox FAT:68K Disassembler�Basic Toolbox FAT:68K Linker�Basic Toolbox FAT:68K Project�Basic Toolbox FAT:C/C++ Compiler�Basic Toolbox FAT:C/C++ Warnings�Basic Toolbox FAT:CFM68K�Basic Toolbox FAT:IR Optimizer�Basic Toolbox FAT:Java Output�Basic Toolbox FAT:Java Project�Basic Toolbox FAT:Java VM�Basic Toolbox FAT:MacOS Merge Panel�Basic Toolbox FAT:Pascal Compiler�Basic Toolbox FAT:Pascal Warnings�Basic Toolbox FAT:PPC CodeGen�Basic Toolbox FAT:PPC Disassembler�Basic Toolbox FAT:PPC Linker�Basic Toolbox FAT:PPC PEF�Basic Toolbox FAT:PPC Project�Basic Toolbox FAT:PPCAsm Panel�Basic Toolbox FAT:Rez Compiler�Basic Toolbox FAT:WinRC Compiler�Basic Toolbox FAT:x86 CodeGen�Basic Toolbox FAT:x86 Linker�Basic Toolbox FAT:x86 Project�Basic Toolbox DEBUG 68k:Custom Keywords�Basic Toolbox DEBUG 68k:Access Paths�Basic Toolbox DEBUG 68k:Target Settings�Basic Toolbox DEBUG 68k:File Mappings�Basic Toolbox DEBUG 68k:Build Extras�Basic Toolbox DEBUG 68k:68K CodeGen�Basic Toolbox DEBUG 68k:68K Disassembler�Basic Toolbox DEBUG 68k:68K Linker�Basic Toolbox DEBUG 68k:68K Project�Basic Toolbox DEBUG 68k:C/C++ Compiler�Basic Toolbox DEBUG 68k:C/C++ Warnings�Basic Toolbox DEBUG 68k:CFM68K�Basic Toolbox DEBUG 68k:IR Optimizer�Basic Toolbox DEBUG 68k:MacOS Merge Panel�Basic Toolbox DEBUG 68k:Pascal Compiler�Basic Toolbox DEBUG 68k:Pascal Warnings�Basic Toolbox DEBUG 68k:PPC CodeGen�Basic Toolbox DEBUG 68k:PPC Disassembler�Basic Toolbox DEBUG 68k:PPC Linker�Basic Toolbox DEBUG 68k:PPC PEF�Basic Toolbox DEBUG 68k:PPC Project�Basic Toolbox DEBUG 68k:PPCAsm Panel�Basic Toolbox DEBUG 68k:Rez Compiler�Basic Toolbox DEBUG PPC:Custom Keywords�Basic Toolbox DEBUG PPC:Access Paths�Basic Toolbox DEBUG PPC:Target Settings�Basic Toolbox DEBUG PPC:File Mappings�Basic Toolbox DEBUG PPC:Build Extras�Basic Toolbox DEBUG PPC:68K CodeGen�Basic Toolbox DEBUG PPC:68K Disassembler�Basic Toolbox DEBUG PPC:68K Linker�Basic Toolbox DEBUG PPC:68K Project�Basic Toolbox DEBUG PPC:C/C++ Compiler�Basic Toolbox DEBUG PPC:C/C++ Warnings�Basic Toolbox DEBUG PPC:CFM68K�Basic Toolbox DEBUG PPC:IR Optimizer�Basic Toolbox DEBUG PPC:MacOS Merge Panel�Basic Toolbox DEBUG PPC:Pascal Compiler�Basic Toolbox DEBUG PPC:Pascal Warnings�Basic Toolbox DEBUG PPC:PPC CodeGen�Basic Toolbox DEBUG PPC:PPC Disassembler�Basic Toolbox DEBUG PPC:PPC Linker�Basic Toolbox DEBUG PPC:PPC PEF�Basic Toolbox DEBUG PPC:PPC Project�Basic Toolbox DEBUG PPC:PPCAsm Panel�Basic Toolbox DEBUG PPC:Rez Compiler�MacOS Toolbox 68K:Custom Keywords�MacOS Toolbox 68K:Access Paths�MacOS Toolbox 68K:Target Settings�MacOS Toolbox 68K:File Mappings�MacOS Toolbox 68K:Build Extras�MacOS Toolbox 68K:68K CodeGen�MacOS Toolbox 68K:68K Disassembler�MacOS Toolbox 68K:68K Linker�MacOS Toolbox 68K:68K Project�MacOS Toolbox 68K:C/C++ Compiler�MacOS Toolbox 68K:C/C++ Warnings�MacOS Toolbox 68K:CFM68K�MacOS Toolbox 68K:IR Optimizer�MacOS Toolbox 68K:MacOS Merge Panel�MacOS Toolbox 68K:Pascal Compiler�MacOS Toolbox 68K:Pascal Warnings�MacOS Toolbox 68K:PPC CodeGen�MacOS Toolbox 68K:PPC Disassembler�MacOS Toolbox 68K:PPC Linker�MacOS Toolbox 68K:PPC PEF�MacOS Toolbox 68K:PPC Project�MacOS Toolbox 68K:PPCAsm Panel�MacOS Toolbox 68K:Rez Compiler�MacOS Toolbox DEBUG 68K:Custom Keywords�MacOS Toolbox DEBUG 68K:Access Paths�MacOS Toolbox DEBUG 68K:Target Settings�MacOS Toolbox DEBUG 68K:File Mappings�MacOS Toolbox DEBUG 68K:Build Extras�MacOS Toolbox DEBUG 68K:68K CodeGen�MacOS Toolbox DEBUG 68K:68K Disassembler�MacOS Toolbox DEBUG 68K:68K Linker�MacOS Toolbox DEBUG 68K:68K Project�MacOS Toolbox DEBUG 68K:C/C++ Compiler�MacOS Toolbox DEBUG 68K:C/C++ Warnings�MacOS Toolbox DEBUG 68K:CFM68K�MacOS Toolbox DEBUG 68K:IR Optimizer�MacOS Toolbox DEBUG 68K:MacOS Merge Panel�MacOS Toolbox DEBUG 68K:Pascal Compiler�MacOS Toolbox DEBUG 68K:Pascal Warnings�MacOS Toolbox DEBUG 68K:PPC CodeGen�MacOS Toolbox DEBUG 68K:PPC Disassembler�MacOS Toolbox DEBUG 68K:PPC Linker�MacOS Toolbox DEBUG 68K:PPC PEF�MacOS Toolbox DEBUG 68K:PPC Project�MacOS Toolbox DEBUG 68K:PPCAsm Panel�MacOS Toolbox DEBUG 68K:Rez Compiler�MacOS Toolbox DEBUG PPC:Custom Keywords�MacOS Toolbox DEBUG PPC:Access Paths�MacOS Toolbox DEBUG PPC:Target Settings�MacOS Toolbox DEBUG PPC:File Mappings�MacOS Toolbox DEBUG PPC:Build Extras�MacOS Toolbox DEBUG PPC:68K CodeGen�MacOS Toolbox DEBUG PPC:68K Disassembler�MacOS Toolbox DEBUG PPC:68K Linker�MacOS Toolbox DEBUG PPC:68K Project�MacOS Toolbox DEBUG PPC:C/C++ Compiler�MacOS Toolbox DEBUG PPC:C/C++ Warnings�MacOS Toolbox DEBUG PPC:CFM68K�MacOS Toolbox DEBUG PPC:IR Optimizer�MacOS Toolbox DEBUG PPC:MacOS Merge Panel�MacOS Toolbox DEBUG PPC:Pascal Compiler�MacOS Toolbox DEBUG PPC:Pascal Warnings�MacOS Toolbox DEBUG PPC:PPC CodeGen�MacOS Toolbox DEBUG PPC:PPC Disassembler�MacOS Toolbox DEBUG PPC:PPC Linker�MacOS Toolbox DEBUG PPC:PPC PEF�MacOS Toolbox DEBUG PPC:PPC Project�MacOS Toolbox DEBUG PPC:PPCAsm Panel�MacOS Toolbox DEBUG PPC:Rez Compiler�MacOS Toolbox PPC:Custom Keywords�MacOS Toolbox PPC:Access Paths�MacOS Toolbox PPC:Target Settings�MacOS Toolbox PPC:File Mappings�MacOS Toolbox PPC:Build Extras�MacOS Toolbox PPC:68K CodeGen�MacOS Toolbox PPC:68K Disassembler�MacOS Toolbox PPC:68K Linker�MacOS Toolbox PPC:68K Project�MacOS Toolbox PPC:C/C++ Compiler�MacOS Toolbox PPC:C/C++ Warnings�MacOS Toolbox PPC:CFM68K�MacOS Toolbox PPC:IR Optimizer�MacOS Toolbox PPC:MacOS Merge Panel�MacOS Toolbox PPC:Pascal Compiler�MacOS Toolbox PPC:Pascal Warnings�MacOS Toolbox PPC:PPC CodeGen�MacOS Toolbox PPC:PPC Disassembler�MacOS Toolbox PPC:PPC Linker�MacOS Toolbox PPC:PPC PEF�MacOS Toolbox PPC:PPC Project�MacOS Toolbox PPC:PPCAsm Panel�MacOS Toolbox PPC:Rez Compiler�MacOS Toolbox FAT:Custom Keywords�MacOS Toolbox FAT:Access Paths�MacOS Toolbox FAT:Target Settings�MacOS Toolbox FAT:File Mappings�MacOS Toolbox FAT:Build Extras�MacOS Toolbox FAT:68K CodeGen�MacOS Toolbox FAT:68K Disassembler�MacOS Toolbox FAT:68K Linker�MacOS Toolbox FAT:68K Project�MacOS Toolbox FAT:C/C++ Compiler�MacOS Toolbox FAT:C/C++ Warnings�MacOS Toolbox FAT:CFM68K�MacOS Toolbox FAT:IR Optimizer�MacOS Toolbox FAT:MacOS Merge Panel�MacOS Toolbox FAT:Pascal Compiler�MacOS Toolbox FAT:Pascal Warnings�MacOS Toolbox FAT:PPC CodeGen�MacOS Toolbox FAT:PPC Disassembler�MacOS Toolbox FAT:PPC Linker�MacOS Toolbox FAT:PPC PEF�MacOS Toolbox FAT:PPC Project�MacOS Toolbox FAT:PPCAsm Panel�MacOS Toolbox FAT:Rez Compiler�MacOS Toolbox DEBUG 68K:Bison Panel�MacOS Toolbox DEBUG 68K:Flex Panel�MacOS Toolbox DEBUG 68K:Java Output�MacOS Toolbox DEBUG 68K:Java Project�MacOS Toolbox DEBUG 68K:Java VM�MacOS Toolbox DEBUG 68K:WinRC Compiler�MacOS Toolbox DEBUG 68K:x86 CodeGen�MacOS Toolbox DEBUG 68K:x86 Linker�MacOS Toolbox DEBUG 68K:x86 Project�MacOS Toolbox DEBUG PPC:Bison Panel�MacOS Toolbox DEBUG PPC:Flex Panel�MacOS Toolbox DEBUG PPC:Java Output�MacOS Toolbox DEBUG PPC:Java Project�MacOS Toolbox DEBUG PPC:Java VM�MacOS Toolbox DEBUG PPC:WinRC Compiler�MacOS Toolbox DEBUG PPC:x86 CodeGen�MacOS Toolbox DEBUG PPC:x86 Linker�MacOS Toolbox DEBUG PPC:x86 Project�MacOS Toolbox 68K:Bison Panel�MacOS Toolbox 68K:Flex Panel�MacOS Toolbox 68K:Java Output�MacOS Toolbox 68K:Java Project�MacOS Toolbox 68K:Java VM�MacOS Toolbox 68K:WinRC Compiler�MacOS Toolbox 68K:x86 CodeGen�MacOS Toolbox 68K:x86 Linker�MacOS Toolbox 68K:x86 Project�MacOS Toolbox PPC:Bison Panel�MacOS Toolbox PPC:Flex Panel�MacOS Toolbox PPC:Java Output�MacOS Toolbox PPC:Java Project�MacOS Toolbox PPC:Java VM�MacOS Toolbox PPC:WinRC Compiler�MacOS Toolbox PPC:x86 CodeGen�MacOS Toolbox PPC:x86 Linker�MacOS Toolbox PPC:x86 Project�68K Debug MacOS Toolbox:Custom Keywords�68K Debug MacOS Toolbox:Access Paths�68K Debug MacOS Toolbox:Target Settings�68K Debug MacOS Toolbox:File Mappings�68K Debug MacOS Toolbox:Build Extras�68K Debug MacOS Toolbox:68K CodeGen�68K Debug MacOS Toolbox:68K Disassembler�68K Debug MacOS Toolbox:68K Linker�68K Debug MacOS Toolbox:68K Project�68K Debug MacOS Toolbox:C/C++ Compiler�68K Debug MacOS Toolbox:C/C++ Warnings�68K Debug MacOS Toolbox:CFM68K�68K Debug MacOS Toolbox:IR Optimizer�68K Debug MacOS Toolbox:Java Output�68K Debug MacOS Toolbox:Java Project�68K Debug MacOS Toolbox:Java VM�68K Debug MacOS Toolbox:MacOS Merge Panel�68K Debug MacOS Toolbox:Pascal Compiler�68K Debug MacOS Toolbox:Pascal Warnings�68K Debug MacOS Toolbox:PPC CodeGen�68K Debug MacOS Toolbox:PPC Disassembler�68K Debug MacOS Toolbox:PPC Linker�68K Debug MacOS Toolbox:PPC PEF�68K Debug MacOS Toolbox:PPC Project�68K Debug MacOS Toolbox:PPCAsm Panel�68K Debug MacOS Toolbox:Rez Compiler�68K Debug MacOS Toolbox:WinRC Compiler�68K Debug MacOS Toolbox:x86 CodeGen�68K Debug MacOS Toolbox:x86 Linker�68K Debug MacOS Toolbox:x86 Project�PPC Debug MacOS Toolbox:Custom Keywords�PPC Debug MacOS Toolbox:Access Paths�PPC Debug MacOS Toolbox:Target Settings�PPC Debug MacOS Toolbox:File Mappings�PPC Debug MacOS Toolbox:Build Extras�PPC Debug MacOS Toolbox:68K CodeGen�PPC Debug MacOS Toolbox:68K Disassembler�PPC Debug MacOS Toolbox:68K Linker�PPC Debug MacOS Toolbox:68K Project�PPC Debug MacOS Toolbox:C/C++ Compiler�PPC Debug MacOS Toolbox:C/C++ Warnings�PPC Debug MacOS Toolbox:CFM68K�PPC Debug MacOS Toolbox:IR Optimizer�PPC Debug MacOS Toolbox:Java Output�PPC Debug MacOS Toolbox:Java Project�PPC Debug MacOS Toolbox:Java VM�PPC Debug MacOS Toolbox:MacOS Merge Panel�PPC Debug MacOS Toolbox:Pascal Compiler�PPC Debug MacOS Toolbox:Pascal Warnings�PPC Debug MacOS Toolbox:PPC CodeGen�PPC Debug MacOS Toolbox:PPC Disassembler�PPC Debug MacOS Toolbox:PPC Linker�PPC Debug MacOS Toolbox:PPC PEF�PPC Debug MacOS Toolbox:PPC Project�PPC Debug MacOS Toolbox:PPCAsm Panel�PPC Debug MacOS Toolbox:Rez Compiler�PPC Debug MacOS Toolbox:WinRC Compiler�PPC Debug MacOS Toolbox:x86 CodeGen�PPC Debug MacOS Toolbox:x86 Linker�PPC Debug MacOS Toolbox:x86 Project�68K Final MacOS Toolbox:Custom Keywords�68K Final MacOS Toolbox:Access Paths�68K Final MacOS Toolbox:Target Settings�68K Final MacOS Toolbox:File Mappings�68K Final MacOS Toolbox:Build Extras�68K Final MacOS Toolbox:68K CodeGen�68K Final MacOS Toolbox:68K Disassembler�68K Final MacOS Toolbox:68K Linker�68K Final MacOS Toolbox:68K Project�68K Final MacOS Toolbox:C/C++ Compiler�68K Final MacOS Toolbox:C/C++ Warnings�68K Final MacOS Toolbox:CFM68K�68K Final MacOS Toolbox:IR Optimizer�68K Final MacOS Toolbox:Java Output�68K Final MacOS Toolbox:Java Project�68K Final MacOS Toolbox:Java VM�68K Final MacOS Toolbox:MacOS Merge Panel�68K Final MacOS Toolbox:Pascal Compiler�68K Final MacOS Toolbox:Pascal Warnings�68K Final MacOS Toolbox:PPC CodeGen�68K Final MacOS Toolbox:PPC Disassembler�68K Final MacOS Toolbox:PPC Linker�68K Final MacOS Toolbox:PPC PEF�68K Final MacOS Toolbox:PPC Project�68K Final MacOS Toolbox:PPCAsm Panel�68K Final MacOS Toolbox:Rez Compiler�68K Final MacOS Toolbox:WinRC Compiler�68K Final MacOS Toolbox:x86 CodeGen�68K Final MacOS Toolbox:x86 Linker�68K Final MacOS Toolbox:x86 Project�PPC Final MacOS Toolbox:Custom Keywords�PPC Final MacOS Toolbox:Access Paths�PPC Final MacOS Toolbox:Target Settings�PPC Final MacOS Toolbox:File Mappings�PPC Final MacOS Toolbox:Build Extras�PPC Final MacOS Toolbox:68K CodeGen�PPC Final MacOS Toolbox:68K Disassembler�PPC Final MacOS Toolbox:68K Linker�PPC Final MacOS Toolbox:68K Project�PPC Final MacOS Toolbox:C/C++ Compiler�PPC Final MacOS Toolbox:C/C++ Warnings�PPC Final MacOS Toolbox:CFM68K�PPC Final MacOS Toolbox:IR Optimizer�PPC Final MacOS Toolbox:Java Output�PPC Final MacOS Toolbox:Java Project�PPC Final MacOS Toolbox:Java VM�PPC Final MacOS Toolbox:MacOS Merge Panel�PPC Final MacOS Toolbox:Pascal Compiler�PPC Final MacOS Toolbox:Pascal Warnings�PPC Final MacOS Toolbox:PPC CodeGen�PPC Final MacOS Toolbox:PPC Disassembler�PPC Final MacOS Toolbox:PPC Linker�PPC Final MacOS Toolbox:PPC PEF�PPC Final MacOS Toolbox:PPC Project�PPC Final MacOS Toolbox:PPCAsm Panel�PPC Final MacOS Toolbox:Rez Compiler�PPC Final MacOS Toolbox:WinRC Compiler�PPC Final MacOS Toolbox:x86 CodeGen�PPC Final MacOS Toolbox:x86 Linker�PPC Final MacOS Toolbox:x86 Project�FAT MacOS Toolbox:Custom Keywords�FAT MacOS Toolbox:Access Paths�FAT MacOS Toolbox:Target Settings�FAT MacOS Toolbox:File Mappings�FAT MacOS Toolbox:Build Extras�FAT MacOS Toolbox:68K CodeGen�FAT MacOS Toolbox:68K Disassembler�FAT MacOS Toolbox:68K Linker�FAT MacOS Toolbox:68K Project�FAT MacOS Toolbox:C/C++ Compiler�FAT MacOS Toolbox:C/C++ Warnings�FAT MacOS Toolbox:CFM68K�FAT MacOS Toolbox:IR Optimizer�FAT MacOS Toolbox:Java Output�FAT MacOS Toolbox:Java Project�FAT MacOS Toolbox:Java VM�FAT MacOS Toolbox:MacOS Merge Panel�FAT MacOS Toolbox:Pascal Compiler�FAT MacOS Toolbox:Pascal Warnings�FAT MacOS Toolbox:PPC CodeGen�FAT MacOS Toolbox:PPC Disassembler�FAT MacOS Toolbox:PPC Linker�FAT MacOS Toolbox:PPC PEF�FAT MacOS Toolbox:PPC Project�FAT MacOS Toolbox:PPCAsm Panel�FAT MacOS Toolbox:Rez Compiler�FAT MacOS Toolbox:WinRC Compiler�FAT MacOS Toolbox:x86 CodeGen�FAT MacOS Toolbox:x86 Linker�FAT MacOS Toolbox:x86 Project�PPC Debug MacOS Toolbox:Java Language�PPC Final MacOS Toolbox:Java Language�PPC Debug MacOS Toolbox:JavaDoc Project�PPC Final MacOS Toolbox:JavaDoc Project�Tktable.shlb:Custom Keywords�Tktable.shlb:Access Paths�Tktable.shlb:Target Settings�Tktable.shlb:File Mappings�Tktable.shlb:Build Extras�Tktable.shlb:68K CodeGen�Tktable.shlb:68K Disassembler�Tktable.shlb:68K Linker�Tktable.shlb:68K Project�Tktable.shlb:C/C++ Compiler�Tktable.shlb:C/C++ Warnings�Tktable.shlb:CFM68K�Tktable.shlb:IR Optimizer�Tktable.shlb:Java Language�Tktable.shlb:Java Output�Tktable.shlb:Java Project�Tktable.shlb:JavaDoc Project�Tktable.shlb:MacOS Merge Panel�Tktable.shlb:PPC CodeGen�Tktable.shlb:PPC Disassembler�Tktable.shlb:PPC Linker�Tktable.shlb:PPC PEF�Tktable.shlb:PPC Project�Tktable.shlb:PPCAsm Panel�Tktable.shlb:Rez Compiler�Tktable.shlb:WinRC Compiler�Tktable.shlb:x86 CodeGen�Tktable.shlb:x86 Linker�Tktable.shlb:x86 Project�Tktable PPC:Custom Keywords�Tktable PPC:Access Paths�Tktable PPC:Target Settings�Tktable PPC:File Mappings�Tktable PPC:Build Extras�Tktable PPC:68K CodeGen�Tktable PPC:68K Disassembler�Tktable PPC:68K Linker�Tktable PPC:68K Project�Tktable PPC:C/C++ Compiler�Tktable PPC:C/C++ Warnings�Tktable PPC:CFM68K�Tktable PPC:IR Optimizer�Tktable PPC:Java Language�Tktable PPC:Java Output�Tktable PPC:Java Project�Tktable PPC:JavaDoc Project�Tktable PPC:MacOS Merge Panel�Tktable PPC:PPC CodeGen�Tktable PPC:PPC Disassembler�Tktable PPC:PPC Linker�Tktable PPC:PPC PEF�Tktable PPC:PPC Project�Tktable PPC:PPCAsm Panel�Tktable PPC:Rez Compiler�Tktable PPC:WinRC Compiler�Tktable PPC:x86 CodeGen�Tktable PPC:x86 Linker�Tktable PPC:x86 Project�Tktable Fat:Custom Keywords�Tktable Fat:Access Paths�Tktable Fat:Target Settings�Tktable Fat:File Mappings�Tktable Fat:Build Extras�Tktable Fat:68K CodeGen�Tktable Fat:68K Disassembler�Tktable Fat:68K Linker�Tktable Fat:68K Project�Tktable Fat:C/C++ Compiler�Tktable Fat:C/C++ Warnings�Tktable Fat:CFM68K�Tktable Fat:IR Optimizer�Tktable Fat:Java Language�Tktable Fat:Java Output�Tktable Fat:Java Project�Tktable Fat:JavaDoc Project�Tktable Fat:MacOS Merge Panel�Tktable Fat:PPC CodeGen�Tktable Fat:PPC Disassembler�Tktable Fat:PPC Linker�Tktable Fat:PPC PEF�Tktable Fat:PPC Project�Tktable Fat:PPCAsm Panel�Tktable Fat:Rez Compiler�Tktable Fat:WinRC Compiler�Tktable Fat:x86 CodeGen�Tktable Fat:x86 Linker�Tktable Fat:x86 Project�Tktable CFM68k:Custom Keywords�Tktable CFM68k:Access Paths�Tktable CFM68k:Target Settings�Tktable CFM68k:File Mappings�Tktable CFM68k:Build Extras�Tktable CFM68k:68K CodeGen�Tktable CFM68k:68K Disassembler�Tktable CFM68k:68K Linker�Tktable CFM68k:68K Project�Tktable CFM68k:C/C++ Compiler�Tktable CFM68k:C/C++ Warnings�Tktable CFM68k:CFM68K�Tktable CFM68k:IR Optimizer�Tktable CFM68k:Java Language�Tktable CFM68k:Java Output�Tktable CFM68k:Java Project�Tktable CFM68k:JavaDoc Project�Tktable CFM68k:MacOS Merge Panel�Tktable CFM68k:PPC CodeGen�Tktable CFM68k:PPC Disassembler�Tktable CFM68k:PPC Linker�Tktable CFM68k:PPC PEF�Tktable CFM68k:PPC Project�Tktable CFM68k:PPCAsm Panel�Tktable CFM68k:Rez Compiler�Tktable CFM68k:WinRC Compiler�Tktable CFM68k:x86 CodeGen�Tktable CFM68k:x86 Linker�Tktable CFM68k:x86 Project�Tktable Fat:Beyond HTML Panel�Tktable PPC:Beyond HTML Panel�Tktable CFM68k:Beyond HTML Panel��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������None�����������������������������MMPr����������������������������������������������������������������@���TEXT.l������������������������������Flex Preprocessor���������������€���TEXT.y������������������������������Bison Preprocessor��������������€���Java Linker����������������������APPL����������������������������������������������������������������`���Appl����������������������������������������������������������������`���COŚk��������������������������������MW Java�����������������������������Clss��������������������������������MW Java�����������������������������Jjrf.jrf���������������������������������������������������������������MWCD����������������������������������������������������������������`���RSRC����������������������������������������������������������������`���TEXT.bh�����������������������������Balloon Help������������������������TEXT.gc�����������������������������GameCode Converter��������������@���TEXT.html���������������������������������������������������������������TEXT.java���������������������������MW Java�����������������������������TEXT.l������������������������������Flex Preprocessor���������������€���TEXT.mf�����������������������������������������������������������������TEXT.r������������������������������Rez���������������������������������TEXT.y������������������������������Bison Preprocessor��������������€���ZIP ��������������������������������MW Java�������������������������@���ZipF��������������������������������MW Java�����������������������������docu����������������������������������������������������������������`���rsrc����������������������������������������������������������������`�������.class��������������������������MW Java���������������������������������.jar������������������������������������������������������������@�������.zip����������������������������MW Java�����������������������������MacOS 68K Linker����������������� APPL����������������������������������������������������������������`���Appl����������������������������������������������������������������`���MMLB��������������������������������Lib Import 68K����������������������MPLF��������������������������������Lib Import 68K����������������������MWCD����������������������������������������������������������������`���OBJ ��������������������������������MPW Import 68K����������������������PLob����������������������������������������������������������������`���RSRC����������������������������������������������������������������`���TEXT.bh�����������������������������Balloon Help������������������������TEXT.c������������������������������MW C/C++ 68K������������������������TEXT.c++����������������������������MW C/C++ 68K������������������������TEXT.cc�����������������������������MW C/C++ 68K������������������������TEXT.cp�����������������������������MW C/C++ 68K������������������������TEXT.cpp����������������������������MW C/C++ 68K������������������������TEXT.exp����������������������������������������������������������������TEXT.gc�����������������������������GameCode Converter��������������@���TEXT.h������������������������������MW C/C++ 68K�����������������������TEXT.l������������������������������Flex Preprocessor���������������€���TEXT.p������������������������������MW Pascal 68K�����������������������TEXT.pas����������������������������MW Pascal 68K�����������������������TEXT.pch����������������������������MW C/C++ 68K��������������������€���TEXT.pch++��������������������������MW C/C++ 68K��������������������€���TEXT.ppu����������������������������MW Pascal 68K�������������������€���TEXT.r������������������������������Rez���������������������������������TEXT.seg����������������������������������������������������������������TEXT.y������������������������������Bison Preprocessor��������������€���docu����������������������������������������������������������������`���rsrc����������������������������������������������������������������`���shlb��������������������������������PEF Import 68K����������������������stub��������������������������������PEF Import 68K��������������������������.doc������������������������������������������������������������P�������.rsrc�����������������������������������������������������������`���MacOS Merge���������������������� APPL����������������������������������������������������������������`���Appl����������������������������������������������������������������`���RSRC����������������������������������������������������������������`���TEXT.bh�����������������������������Balloon Help������������������������TEXT.gc�����������������������������GameCode Converter��������������@���TEXT.l������������������������������Flex Preprocessor���������������€���TEXT.r������������������������������Rez���������������������������������TEXT.y������������������������������Bison Preprocessor��������������€���rsrc����������������������������������������������������������������`���shlb��������������������������������������������������������������������MacOS PPC Linker�����������������APPL����������������������������������������������������������������`���Appl����������������������������������������������������������������`���MMLB��������������������������������Lib Import PPC����������������������MPLF��������������������������������Lib Import PPC����������������������MWCD����������������������������������������������������������������`���RSRC����������������������������������������������������������������`���TEXT.bh�����������������������������Balloon Help������������������������TEXT.c������������������������������MW C/C++ PPC������������������������TEXT.c++����������������������������MW C/C++ PPC������������������������TEXT.cc�����������������������������MW C/C++ PPC������������������������TEXT.cp�����������������������������MW C/C++ PPC������������������������TEXT.cpp����������������������������MW C/C++ PPC������������������������TEXT.exp����������������������������������������������������������������TEXT.gc�����������������������������GameCode Converter��������������@���TEXT.h������������������������������MW C/C++ PPC�����������������������TEXT.l������������������������������Flex Preprocessor���������������€���TEXT.p������������������������������MW Pascal PPC�����������������������TEXT.pas����������������������������MW Pascal PPC�����������������������TEXT.pch����������������������������MW C/C++ PPC��������������������€���TEXT.pch++��������������������������MW C/C++ PPC��������������������€���TEXT.ppu����������������������������MW Pascal PPC�������������������€���TEXT.r������������������������������Rez���������������������������������TEXT.s������������������������������PPCAsm������������������������������TEXT.y������������������������������Bison Preprocessor��������������€���XCOF��������������������������������XCOFF Import PPC��������������������docu����������������������������������������������������������������`���rsrc����������������������������������������������������������������`���shlb��������������������������������PEF Import PPC����������������������stub��������������������������������PEF Import PPC��������������������������.doc������������������������������������������������������������P���MC Linker������������������������CLUS����������������������������������������������������������������@���MMLB��������������������������������Lib Import 68K����������������������MPLF��������������������������������Lib Import 68K����������������������OBJ ��������������������������������MPW Import 68K����������������������TEXT.c������������������������������MW C/C++ 68K������������������������TEXT.c++����������������������������MW C/C++ 68K������������������������TEXT.cc�����������������������������MW C/C++ 68K������������������������TEXT.cls����������������������������MC Class Compiler���������������€���TEXT.cp�����������������������������MW C/C++ 68K������������������������TEXT.cpp����������������������������MW C/C++ 68K������������������������TEXT.def����������������������������������������������������������������TEXT.doc���������������������������������������������������������������TEXT.h������������������������������������������������������������������TEXT.p������������������������������MW Pascal 68K�����������������������TEXT.pas����������������������������MW Pascal 68K�����������������������TEXT.pch����������������������������MW C/C++ 68K��������������������€���TEXT.pch++��������������������������MW C/C++ 68K��������������������€���TEXT.ts�����������������������������������������������������������������Win32 x86 Linker�����������������TEXT.c������������������������������MW C/C++ x86������������������������TEXT.c++����������������������������MW C/C++ x86������������������������TEXT.cc�����������������������������MW C/C++ x86������������������������TEXT.cp�����������������������������MW C/C++ x86������������������������TEXT.cpp����������������������������MW C/C++ x86������������������������TEXT.def����������������������������������������������������������������TEXT.gc�����������������������������GameCode Converter��������������@���TEXT.h������������������������������MW C/C++ x86�����������������������TEXT.l������������������������������Flex Preprocessor���������������€���TEXT.p������������������������������MW Pascal x86�����������������������TEXT.pas����������������������������MW Pascal x86�����������������������TEXT.pch����������������������������MW C/C++ x86��������������������€���TEXT.pch++��������������������������MW C/C++ x86��������������������€���TEXT.ppu����������������������������MW Pascal x86�������������������€���TEXT.rc�����������������������������MW WinRC����������������������������TEXT.res����������������������������WinRes Import�����������������������TEXT.y������������������������������Bison Preprocessor��������������€�������.doc������������������������������������������������������������P�������.lib����������������������������Lib Import x86��������������������������.obj����������������������������Obj Import x86����������������������MW JavaDoc Linker���������������� COŚk��������������������������������MW JavaDoc��������������������������Clss��������������������������������MW JavaDoc��������������������������RSRC��������������������������������Rez�����������������������������`���TEXT.bh�����������������������������Balloon Help������������������������TEXT.html��������������������������������������������������������������TEXT.java���������������������������MW JavaDoc��������������������������TEXT.r������������������������������Rez���������������������������������ZIP ��������������������������������MW JavaDoc����������������������@���ZipF��������������������������������MW JavaDoc��������������������������rsrc��������������������������������Rez�����������������������������`�������.class��������������������������MW JavaDoc������������������������������.zip����������������������������MW JavaDoc�����������������������������MacOS Merge�nker��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tktable Fat�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������:�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������None�����������������������������MMPr����������������������������������������������������������������@���Java Linker����������������������APPL����������������������������������������������������������������`���Appl����������������������������������������������������������������`���COŚk��������������������������������MW Java�����������������������������Clss��������������������������������MW Java�����������������������������Jjrf.jrf���������������������������������������������������������������MWCD����������������������������������������������������������������`���RSRC����������������������������������������������������������������`���TEXT.bh�����������������������������Balloon Help������������������������TEXT.html��������������������������������������������������������������TEXT.java���������������������������MW Java�����������������������������TEXT.mf�����������������������������������������������������������������TEXT.r������������������������������Rez���������������������������������ZIP ��������������������������������MW Java�����������������������������ZipF��������������������������������MW Java�����������������������������docu����������������������������������������������������������������`���rsrc����������������������������������������������������������������`�������.class��������������������������MW Java���������������������������������.jar����������������������������MW Java���������������������������������.java���������������������������MW Java���������������������������������.zip����������������������������MW Java�����������������������������MacOS 68K Linker�����������������APPL����������������������������������������������������������������`���Appl����������������������������������������������������������������`���MMLB��������������������������������Lib Import 68K����������������������MPLF��������������������������������Lib Import 68K����������������������MWCD����������������������������������������������������������������`���OBJ ��������������������������������MPW Import 68K����������������������PLob����������������������������������������������������������������`���RSRC����������������������������������������������������������������`���TEXT.bh�����������������������������Balloon Help������������������������TEXT.c������������������������������MW C/C++ 68K������������������������TEXT.c++����������������������������MW C/C++ 68K������������������������TEXT.cc�����������������������������MW C/C++ 68K������������������������TEXT.cp�����������������������������MW C/C++ 68K������������������������TEXT.cpp����������������������������MW C/C++ 68K������������������������TEXT.exp����������������������������������������������������������������TEXT.h������������������������������MW C/C++ 68K�����������������������TEXT.pch����������������������������MW C/C++ 68K��������������������€���TEXT.pch++��������������������������MW C/C++ 68K��������������������€���TEXT.r������������������������������Rez���������������������������������TEXT.seg����������������������������������������������������������������docu����������������������������������������������������������������`���rsrc����������������������������������������������������������������`���shlb��������������������������������PEF Import 68K����������������������stub��������������������������������PEF Import 68K��������������������������.doc������������������������������������������������������������P�������.rsrc�����������������������������������������������������������`���MacOS Merge����������������������APPL����������������������������������������������������������������`���Appl����������������������������������������������������������������`���RSRC����������������������������������������������������������������`���TEXT.bh�����������������������������Balloon Help������������������������TEXT.r������������������������������Rez���������������������������������rsrc����������������������������������������������������������������`���shlb��������������������������������������������������������������������MacOS PPC Linker�����������������APPL����������������������������������������������������������������`���Appl����������������������������������������������������������������`���MMLB��������������������������������Lib Import PPC����������������������MPLF��������������������������������Lib Import PPC����������������������MWCD����������������������������������������������������������������`���RSRC����������������������������������������������������������������`���TEXT.bh�����������������������������Balloon Help������������������������TEXT.c������������������������������MW C/C++ PPC������������������������TEXT.c++����������������������������MW C/C++ PPC������������������������TEXT.cc�����������������������������MW C/C++ PPC������������������������TEXT.cp�����������������������������MW C/C++ PPC������������������������TEXT.cpp����������������������������MW C/C++ PPC������������������������TEXT.exp����������������������������������������������������������������TEXT.h������������������������������MW C/C++ PPC�����������������������TEXT.pch����������������������������MW C/C++ PPC��������������������€���TEXT.pch++��������������������������MW C/C++ PPC��������������������€���TEXT.r������������������������������Rez���������������������������������TEXT.s������������������������������PPCAsm������������������������������XCOF��������������������������������XCOFF Import PPC��������������������docu����������������������������������������������������������������`���rsrc����������������������������������������������������������������`���shlb��������������������������������PEF Import PPC����������������������stub��������������������������������PEF Import PPC��������������������������.doc������������������������������������������������������������P���MW JavaDoc Linker���������������� COŚk��������������������������������MW JavaDoc��������������������������Clss��������������������������������MW JavaDoc��������������������������RSRC��������������������������������Rez�����������������������������`���TEXT.bh�����������������������������Balloon Help������������������������TEXT.html��������������������������������������������������������������TEXT.java���������������������������MW JavaDoc��������������������������TEXT.r������������������������������Rez���������������������������������ZIP ��������������������������������MW JavaDoc����������������������@���ZipF��������������������������������MW JavaDoc��������������������������rsrc��������������������������������Rez�����������������������������`�������.class��������������������������MW JavaDoc������������������������������.zip����������������������������MW JavaDoc��������������������������Win32 x86 Linker�����������������TEXT.c������������������������������MW C/C++ x86������������������������TEXT.c++����������������������������MW C/C++ x86������������������������TEXT.cc�����������������������������MW C/C++ x86������������������������TEXT.cp�����������������������������MW C/C++ x86������������������������TEXT.cpp����������������������������MW C/C++ x86������������������������TEXT.def����������������������������������������������������������������TEXT.h������������������������������MW C/C++ x86�����������������������TEXT.pch����������������������������MW C/C++ x86��������������������€���TEXT.pch++��������������������������MW C/C++ x86��������������������€���TEXT.rc�����������������������������MW WinRC����������������������������TEXT.res����������������������������WinRes Import���������������������������.doc������������������������������������������������������������P�������.lib����������������������������Lib Import x86��������������������������.obj����������������������������Obj Import x86���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������DFLTInternet Explorer����������������������������������������������Internet Explorer����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������000DFLT����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������P��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'CODE' 'DATA' 'PICT'������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ ���@����::���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙�����:::Tcl/Tk Folder:tcl8.0:�:�8.0:����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙@����:::Tcl/Tk Folder:tk8.0:�:�8.0:�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙@����:Extensions:Tool Command Language:�ol Command Language:����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙�����:MacOS Support:Headers:Universal Headers:������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙@����:Metrowerks Standard Library:MSL C:������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙@����:Metrowerks Standard Library:MSL C++:����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙@����:MacOS Support:MacHeaders:���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙@����:MacOS Support:Libraries:����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙@�� ��:MacOS Support:��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������˙˙˙˙@�����MacOS 68K Linker��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tktable CFM68k����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������:���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� �tktable2.20����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������TclMacInitializeFragment�����������������������������������������_start���������������������������������������������������������TclMacTerminateFragment����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MSIEInternet Explorer����������������������������������������������Iexplore.exe���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/ uJIT�“Ň@�������“Ú �����:u��9u“ĎP�Řx¸Z´���J� MENU��bTarg���†STR#��’PPob���¶RidL���Âaete���ÎSTR ���Úpref���ćFlag���ňTMPL���ţvers� Drop��"h����������i� ���_����j����Ł�����€����ř����,˙˙�� ����.�( �Q����-�5�������€�@��˛�����€�J�� ®�������T��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tktable.PPC.shlbBUG PPC��������TclLshlb�����������������������������������������������������������������������������������������������������������������????��������P��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'CODE' 'DATA' 'PICT'����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ROOT������������FILE ��#FILE ��'GRUP�������Sources��� FILE ��$FILE ��FILE �� FILE ��FILE ��FILE �� FILE ��"FILE ��!FILE��FILE ��GRUP������� Tktable Libraries���FILE��FILE��GRUP������� Tcl/Tk Libraries���FILE ��FILE ��FILE ��FILE ��GRUP������� Mac Libraries���FILE ��FILE ��FILE ��FILE ��&FILE �� FILE ��FILE ��FILE ��o{o{o{o{o{o{o{o{o{o{o{o{o{o{o{o{������������� ��������������������� ��� ������ ��� ����������������������������������������������������������������� ��# ��$ ��& ��%��U {���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� �������������������������������� �� ���R�������������������������� �����T��������������������������� �����V�������������������������� �����W�������������������������� �����X�������������������������� �����Z�������������������������� �����Y�������������������������� ������������������������������� �����k�������������������������� �����l�������������������������� �����m�������������������������� �� ���o�������������������������� ��!���p�������������������������� ��"���n�������������������������� ��#���q��������������������������� ��$���r��������������������������� ��&����������������������������� ��'���s�������������������������������������˙˙˙˙����������������������������������˙˙˙˙����������������������������������˙˙˙˙����������������������������������˙˙˙˙��������������������������e?îŹ d0˙˙˙˙���@�·f������������·aĐ�·e`«�� � ˙˙˙˙�������îßŕ�·aĐë�� ���0˙˙ö|��˙˙˙˙���������������€�� îŃ,�·e k�P˙˙˙˙����������·aĐ������������������˙˙˙˙������ßŕ�·eĐ������� �·fp�������˙˙˙˙�·eĐ������đ�·h@������������·eĐ��˙˙˙˙����������������������ßŕ�·f0����°˙˙˙˙��������·eĐ�·fp�������·h@��˙˙˙˙ut���·fp������������������������������������������������������������������������������������� ����������������������������������������������������������������������� �������������������������������� �� ���R�������������������������� �����T��������������������������� �����d�������������������������� �����e�������������������������� �����g�������������������������� �����h�������������������������� �� ���i�������������������������� ��!���k�������������������������� ��"���l�������������������������� ��#���m�������������������������� ��%���o�������������������������� ��&���p�������������������������� ��'���X�������������������������� ��(���n�������������������������� ��)���q��������������������������� ��*���r��������������������������� ��+���s�������������������������������������˙˙˙˙����������������������������������˙˙˙˙����������������������������������˙˙˙˙����������������������������������˙˙˙˙����������������������������������˙˙˙˙��������������������������e?îŹ d0˙˙˙˙���@�·f������������·aĐ�·e`«�� � ˙˙˙˙�������îßŕ�·aĐë�� ���0˙˙ö|��˙˙˙˙���������������€�� îŃ,�·e k�P˙˙˙˙����������·aĐ������������������˙˙˙˙������ßŕ�·eĐ������� �·fp�������˙˙˙˙�·eĐ������đ�·h@������������·eĐ��˙˙˙˙����������������������ßŕ�·f0����°˙˙˙˙��������·eĐ�·fp�������·h@��˙˙˙˙ut���·fp���������������� �� �� ��! �� �� �� �� �� �� ��" ��# ��% ��& ��' ��( ��) ��* ��+��None�����������������������������MMPr����������������������������������������������������������������@���TEXT.l������������������������������Flex Preprocessor���������������€���TEXT.y������������������������������Bison Preprocessor��������������€���Java Linker����������������������APPL����������������������������������������������������������������`���Appl����������������������������������������������������������������`���COŚk��������������������������������MW Java�����������������������������Clss��������������������������������MW Java�����������������������������Jjrf.jrf���������������������������������������������������������������MWCD����������������������������������������������������������������`���RSRC����������������������������������������������������������������`���TEXT.bh�����������������������������Balloon Help������������������������TEXT.gc�����������������������������GameCode Converter��������������@���TEXT.html���������������������������������������������������������������TEXT.java���������������������������MW Java�����������������������������TEXT.l������������������������������Flex Preprocessor���������������€���TEXT.mf�����������������������������������������������������������������TEXT.r������������������������������Rez���������������������������������TEXT.y������������������������������Bison Preprocessor��������������€���ZIP ��������������������������������MW Java�������������������������@���ZipF��������������������������������MW Java�����������������������������docu����������������������������������������������������������������`���rsrc����������������������������������������������������������������`�������.class��������������������������MW Java���������������������������������.jar������������������������������������������������������������@�������.zip����������������������������MW Java�����������������������������MacOS 68K Linker����������������� APPL����������������������������������������������������������������`���Appl����������������������������������������������������������������`���MMLB��������������������������������Lib Import 68K����������������������MPLF��������������������������������Lib Import 68K����������������������MWCD����������������������������������������������������������������`���OBJ ��������������������������������MPW Import 68K����������������������PLob����������������������������������������������������������������`���RSRC����������������������������������������������������������������`���TEXT.bh�����������������������������Balloon Help������������������������TEXT.c������������������������������MW C/C++ 68K������������������������TEXT.c++����������������������������MW C/C++ 68K������������������������TEXT.cc�����������������������������MW C/C++ 68K������������������������TEXT.cp�����������������������������MW C/C++ 68K������������������������TEXT.cpp����������������������������MW C/C++ 68K������������������������TEXT.exp����������������������������������������������������������������TEXT.gc�����������������������������GameCode Converter��������������@���TEXT.h������������������������������MW C/C++ 68K�����������������������TEXT.l������������������������������Flex Preprocessor���������������€���TEXT.p������������������������������MW Pascal 68K�����������������������TEXT.pas����������������������������MW Pascal 68K�����������������������TEXT.pch����������������������������MW C/C++ 68K��������������������€���TEXT.pch++��������������������������MW C/C++ 68K��������������������€���TEXT.ppu����������������������������MW Pascal 68K�������������������€���TEXT.r������������������������������Rez���������������������������������TEXT.seg����������������������������������������������������������������TEXT.y������������������������������Bison Preprocessor��������������€���docu����������������������������������������������������������������`���rsrc����������������������������������������������������������������`���shlb��������������������������������PEF Import 68K����������������������stub��������������������������������PEF Import 68K��������������������������.doc������������������������������������������������������������P�������.rsrc�����������������������������������������������������������`���MacOS Merge���������������������� APPL����������������������������������������������������������������`���Appl����������������������������������������������������������������`���RSRC����������������������������������������������������������������`���TEXT.bh�����������������������������Balloon Help������������������������TEXT.gc�����������������������������GameCode Converter��������������@���TEXT.l������������������������������Flex Preprocessor���������������€���TEXT.r������������������������������Rez���������������������������������TEXT.y������������������������������Bison Preprocessor��������������€���rsrc����������������������������������������������������������������`���shlb��������������������������������������������������������������������MacOS PPC Linker�����������������APPL����������������������������������������������������������������`���Appl����������������������������������������������������������������`���MMLB��������������������������������Lib Import PPC����������������������MPLF��������������������������������Lib Import PPC����������������������MWCD����������������������������������������������������������������`���RSRC����������������������������������������������������������������`���TEXT.bh�����������������������������Balloon Help������������������������TEXT.c������������������������������MW C/C++ PPC������������������������TEXT.c++����������������������������MW C/C++ PPC������������������������TEXT.cc�����������������������������MW C/C++ PPC������������������������TEXT.cp�����������������������������MW C/C++ PPC������������������������TEXT.cpp����������������������������MW C/C++ PPC������������������������TEXT.exp����������������������������������������������������������������TEXT.gc�����������������������������GameCode Converter��������������@���TEXT.h������������������������������MW C/C++ PPC�����������������������TEXT.l������������������������������Flex Preprocessor���������������€���TEXT.p������������������������������MW Pascal PPC�����������������������TEXT.pas����������������������������MW Pascal PPC�����������������������TEXT.pch����������������������������MW C/C++ PPC��������������������€���TEXT.pch++��������������������������MW C/C++ PPC��������������������€���TEXT.ppu����������������������������MW Pascal PPC�������������������€���TEXT.r������������������������������Rez���������������������������������TEXT.s������������������������������PPCAsm������������������������������TEXT.y������������������������������Bison Preprocessor��������������€���XCOF��������������������������������XCOFF Import PPC��������������������docu����������������������������������������������������������������`���rsrc����������������������������������������������������������������`���shlb��������������������������������PEF Import PPC����������������������stub��������������������������������PEF Import PPC��������������������������.doc������������������������������������������������������������P���MC Linker������������������������CLUS����������������������������������������������������������������@���MMLB��������������������������������Lib Import 68K����������������������MPLF��������������������������������Lib Import 68K����������������������OBJ ��������������������������������MPW Import 68K����������������������TEXT.c������������������������������MW C/C++ 68K������������������������TEXT.c++����������������������������MW C/C++ 68K������������������������TEXT.cc�����������������������������MW C/C++ 68K������������������������TEXT.cls����������������������������MC Class Compiler���������������€���TEXT.cp�����������������������������MW C/C++ 68K������������������������TEXT.cpp����������������������������MW C/C++ 68K������������������������TEXT.def����������������������������������������������������������������TEXT.doc���������������������������������������������������������������TEXT.h������������������������������������������������������������������TEXT.p������������������������������MW Pascal 68K�����������������������TEXT.pas����������������������������MW Pascal 68K�����������������������TEXT.pch����������������������������MW C/C++ 68K��������������������€���TEXT.pch++��������������������������MW C/C++ 68K��������������������€���TEXT.ts�����������������������������������������������������������������Win32 x86 Linker�����������������TEXT.c������������������������������MW C/C++ x86������������������������TEXT.c++����������������������������MW C/C++ x86������������������������TEXT.cc�����������������������������MW C/C++ x86������������������������TEXT.cp�����������������������������MW C/C++ x86������������������������TEXT.cpp����������������������������MW C/C++ x86������������������������TEXT.def����������������������������������������������������������������TEXT.gc�����������������������������GameCode Converter��������������@���TEXT.h������������������������������MW C/C++ x86�����������������������TEXT.l������������������������������Flex Preprocessor���������������€���TEXT.p������������������������������MW Pascal x86�����������������������TEXT.pas����������������������������MW Pascal x86�����������������������TEXT.pch����������������������������MW C/C++ x86��������������������€���TEXT.pch++��������������������������MW C/C++ x86��������������������€���TEXT.ppu����������������������������MW Pascal x86�������������������€���TEXT.rc�����������������������������MW WinRC����������������������������TEXT.res����������������������������WinRes Import�����������������������TEXT.y������������������������������Bison Preprocessor��������������€�������.doc������������������������������������������������������������P�������.lib����������������������������Lib Import x86��������������������������.obj����������������������������Obj Import x86����������������������MW JavaDoc Linker���������������� COŚk��������������������������������MW JavaDoc��������������������������Clss��������������������������������MW JavaDoc��������������������������RSRC��������������������������������Rez�����������������������������`���TEXT.bh�����������������������������Balloon Help������������������������TEXT.html��������������������������������������������������������������TEXT.java���������������������������MW JavaDoc��������������������������TEXT.r������������������������������Rez���������������������������������ZIP ��������������������������������MW JavaDoc����������������������@���ZipF��������������������������������MW JavaDoc��������������������������rsrc��������������������������������Rez�����������������������������`�������.class��������������������������MW JavaDoc������������������������������.zip����������������������������MW JavaDoc����������������������������›��P�mstr��������������g���mstl��������������)D�� �mstn��������������(���(msti��������������AŢ���mstr��č����������P���mstl��č���������� 3���mstn��č����������P���(msti��č���������� Ž��,mpsi��č����������3D��Lmtgl��č���������qZ��€PLst�Qn���������á���.pref�›•���-��������Ipref�5đ���.������ -���pref����/������Ţ���$pref����:��������� pref�\���;������ ���’pref�•u���<������ž���Jpref�Ęs���=������é���.pref�˘ĺ���i������$ű��Ipref�ç���j������ /���pref�Š���k������ň���$pref�ä���v������č��� pref�Úń���w������˛���’pref�-���x������ D���Jpref�–e���y������Ţ���.pref�܆���‡��������Ipref�Ćź���������Ě���pref�˝‰���‰������ ���$pref�&���”������ #��� pref�ĘŐ���•������_���’pref�ěË���–������ń���Jpref�iá���—������€���pref�N˛��9��������� pref�Ő��:������ ]���pref�BL��B������ ť��� pref�ńs��C������ ]���pref�·F��K������ e��� pref�"`��L������ ���pref�©��T������g��� pref�ő™��U������Ę���pref�M ��Š������ e���8pref�LÜÎ��Ś������ş��� pref�MŠŕ��Ť������Ç���pref�MŻA��Ć������A¦���8pref�Lëí��Č������¶��� pref�Mń��É������9ţ���mtpl�������������Î���€mtps������������� Á��� mtsl�������������”���mtpi�������������N��� mtlo������������� ]��� mtsl��� ���������tŞ���mtpl��� ���������� Á���€mtps��� ����������Z���mtpi��� ����������P´���Lmtlo��� ����������j���pref�zU��������Q���°pref�–��������IŢ�� pref�·ú��������ë��*lpref�˛T��������x���pref�Ď•��������„���pref�y,��������ś��� pref�}ü��������¦���pref�zÓ�����������Ćpref�Ţđ�������� }���:pref�\��������Đ��� pref�Äi��������"ş��Úpref�{�������� ��� pref�î›�� ������Ő��pref�8¤��!������ á���2pref�˛S��"������…��Ppref�€Č��#������Šn��şpref�őé��$������ A���bpref�Çz��%������ A���pref�O»��&������ ��� pref�šF��'������`���Äpref�®��(������;��pref�t—��)������ ©���¨pref� Ţ��*������ ���.pref�†n��+������Ź(�� pref�С��,������$���"pref�-&��-������ ·��� pref�Vu��.������>ţ���’pref�C7��/������F���Jpref���0������ ­���pref�·„��1������‘4��0pref�°ó��2�����Š�� pref�…D��3�����–��2pref�ó��4������¤���pref�Żď��5������ Ç���pref�»a��6������ A��� pref�O~��7������ K���pref�G&��8������?¦���Ćpref�r[��9������ q���:pref�ý@��:������ «��� pref�č��;������•d��Úpref�n��<������ á��� pref�@��=������@l��pref�ţI��>������3���2pref�ĽŐ��?�����9Č��Ppref�­��@�����?��şpref�1y��A������w���bpref�{Ö��B������ í���pref�pú��C������ ·��� pref�Ş–��D������Oę���Ępref�®‡��E������eě��pref�†‰��F������—>���¨pref�đR��G������$”���.pref�âź��H�����CŇ�� pref�´÷��I������Q���"pref� e��J������Ă��� pref�¸L��K������—ć���’pref�ôu��L������9���Jpref�›N��M������g���mstp�������������Ş��� mtsl��� ���������z<���mtpl��� ���������rÚ���€mtps��� ���������� 1���mtpi��� ���������<���Hmtlo��� �������������pref�"Ĺ“��N�����EŢ��°pref�"+#��O�����ZŽ�� pref�"j��P�����„��*lpref�"]Ł��Q������´���pref�"u:��R������s���pref�""‘��S������ Ł��� pref�"\É��T������Í���pref�"Ťç��U������x���Ćpref�"6Ş��V������e°���:pref�!ç ��W������ Q��� pref�"`W��X�����`š��Úpref�!ő“��Y������Ş��� pref�"D��Z�����bt��pref�"“™��[������™x���2pref�"/d��\�����c†��Ppref�"FG��]�����hÖ��şpref�!úâ��^������™Ş���bpref�"!Ô��_������‹���pref�!˙m��`������ź��� pref�"M��a������š ���Äpref�"4��b�����m��pref�"Ťí��c�����n¦���¨pref�!âg��d������$Â���.pref�!ç§��e�����oN�� pref�"Ž{��f������9Ú���"pref�"- ��g������$đ��� pref�"‚��h�����yŞ���’pref�",Z��i������šĐ���Jpref�"˝€��j�����s~���dpref��š��k�����sâ���dpref��a–��l�����tF���dpref��I‹��m������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable/config.cache����������������������������������������������������0000644�0000000�0000000�00000000000�13742524721�020036� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable/configure.in����������������������������������������������������0000644�0000000�0000000�00000002705�13745605157�020141� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������AC_INIT(tkTable.c) if test "${prefix}" = "NONE"; then prefix=/usr/local echo "setting prefix to: ${prefix}" fi if test "${exec_prefix}" = "NONE"; then exec_prefix=$prefix echo "setting exec-prefix to: ${exec_prefix}" fi AC_PROG_INSTALL AC_ARG_WITH(tcl, [ --with-tcl=<directory> directory containing tclConfig.sh], [tcl_prefix=$withval], [tcl_prefix=${exec_prefix}/lib]) AC_ARG_WITH(tk, [ --with-tk=<directory> directory containing tkConfig.sh], [tk_prefix=$withval], [tk_prefix=${exec_prefix}/lib]) file=${tcl_prefix}/tclConfig.sh . $file file=${tk_prefix}/tkConfig.sh . $file CC=$TCL_CC AC_SUBST(CC) AC_SUBST(INSTALL) AC_SUBST(INSTALL_PROGRAM) AC_SUBST(INSTALL_DATA) AC_SUBST(TCL_SHLIB_CFLAGS) AC_SUBST(TCL_SHLIB_LD) AC_SUBST(TCL_SHLIB_SUFFIX) AC_SUBST(TCL_VERSION) AC_SUBST(TCL_RANLIB) AC_SUBST(TCL_XINCLUDES) AC_SUBST(TCL_PREFIX) AC_SUBST(TCL_EXEC_PREFIX) AC_SUBST(TCL_CFLAGS) AC_SUBST(TCL_DEFS) AC_SUBST(TCL_LIB_SPEC) AC_SUBST(TCL_LIBS) AC_SUBST(TCL_LD_FLAGS) AC_SUBST(TCL_COMPAT_OBJS) AC_SUBST(TCL_LD_SEARCH_FLAGS) AC_SUBST(TCL_SRC_DIR) AC_SUBST(TCL_BUILD_LIB_SPEC) AC_SUBST(prefix) AC_SUBST(exec_prefix) AC_SUBST(TK_VERSION) AC_SUBST(TK_XINCLUDES) AC_SUBST(TK_PREFIX) AC_SUBST(TK_EXEC_PREFIX) AC_SUBST(TK_DEFS) AC_SUBST(TK_LIBS) AC_SUBST(TK_LIB_SPEC) AC_SUBST(TK_LD_SEARCH_FLAGS) AC_SUBST(TK_SRC_DIR) AC_SUBST(TK_BUILD_LIB_SPEC) AC_OUTPUT(Makefile) �����������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable/tkTableWin.c����������������������������������������������������0000644�0000000�0000000�00000070625�13745605157�020046� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * tkTableWin.c -- * * This module implements embedded windows for table widgets. * Much of this code is adapted from tkGrid.c and tkTextWind.c. * * Copyright (c) 1998-2002 Jeffrey Hobbs * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tkTableWin.c,v 1.10 2004/02/08 03:09:47 cerney Exp $ */ #include "tkVMacro.h" #include "tkTable.h" static int StickyParseProc _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, Arg value, char *widgRec, int offset)); Arg StickyPrintProc _ANSI_ARGS_((ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)); static void EmbWinLostSlaveProc _ANSI_ARGS_((ClientData clientData, Tk_Window tkwin)); static void EmbWinRequestProc _ANSI_ARGS_((ClientData clientData, Tk_Window tkwin)); static void EmbWinCleanup _ANSI_ARGS_((Table *tablePtr, TableEmbWindow *ewPtr)); static int EmbWinConfigure _ANSI_ARGS_((Table *tablePtr, TableEmbWindow *ewPtr, int objc, Tcl_Obj *CONST objv[])); static void EmbWinStructureProc _ANSI_ARGS_((ClientData clientData, XEvent *eventPtr)); static void EmbWinUnmapNow _ANSI_ARGS_((Tk_Window ewTkwin, Tk_Window tkwin)); static Tk_GeomMgr tableGeomType = { "table", /* name */ EmbWinRequestProc, /* requestProc */ EmbWinLostSlaveProc, /* lostSlaveProc */ }; /* windows subcommands */ static CONST char *winCmdNames[] = { "cget", "configure", "delete", "move", "names", (char *) NULL }; enum winCommand { WIN_CGET, WIN_CONFIGURE, WIN_DELETE, WIN_MOVE, WIN_NAMES }; /* Flag values for "sticky"ness The 16 combinations subsume the packer's * notion of anchor and fill. * * STICK_NORTH This window sticks to the top of its cavity. * STICK_EAST This window sticks to the right edge of its cavity. * STICK_SOUTH This window sticks to the bottom of its cavity. * STICK_WEST This window sticks to the left edge of its cavity. */ #define STICK_NORTH (1<<0) #define STICK_EAST (1<<1) #define STICK_SOUTH (1<<2) #define STICK_WEST (1<<3) /* * The default specification for configuring embedded windows * Done like this to make the command line parsing easy */ static Tk_CustomOption stickyOption = { StickyParseProc, StickyPrintProc, (ClientData) NULL }; static Tk_CustomOption tagBdOpt = { TableOptionBdSet, TableOptionBdGet, (ClientData) BD_TABLE_WIN }; static Tk_ConfigSpec winConfigSpecs[] = { {TK_CONFIG_BORDER, "-background", "background", "Background", NULL, Tk_Offset(TableEmbWindow, bg), TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK }, {TK_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL, 0, 0}, {TK_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0}, {TK_CONFIG_CUSTOM, "-borderwidth", "borderWidth", "BorderWidth", "", 0 /* no offset */, TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK, &tagBdOpt }, {TK_CONFIG_STRING, "-create", (char *)NULL, (char *)NULL, (char *)NULL, Tk_Offset(TableEmbWindow, create), TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK }, {TK_CONFIG_PIXELS, "-padx", (char *)NULL, (char *)NULL, (char *)NULL, Tk_Offset(TableEmbWindow, padX), TK_CONFIG_DONT_SET_DEFAULT }, {TK_CONFIG_PIXELS, "-pady", (char *)NULL, (char *)NULL, (char *)NULL, Tk_Offset(TableEmbWindow, padY), TK_CONFIG_DONT_SET_DEFAULT }, {TK_CONFIG_CUSTOM, "-sticky", (char *)NULL, (char *)NULL, (char *)NULL, Tk_Offset(TableEmbWindow, sticky), TK_CONFIG_DONT_SET_DEFAULT, &stickyOption}, {TK_CONFIG_RELIEF, "-relief", "relief", "Relief", NULL, Tk_Offset(TableEmbWindow, relief), 0 }, {TK_CONFIG_WINDOW, "-window", (char *)NULL, (char *)NULL, (char *)NULL, Tk_Offset(TableEmbWindow, tkwin), TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK }, {TK_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0 } }; /* *---------------------------------------------------------------------- * * StickyPrintProc -- * Converts the internal boolean combination of "sticky" bits onto * a TCL string element containing zero or more of n, s, e, or w. * * Results: * A string is placed into the "result" pointer. * * Side effects: * none. * *---------------------------------------------------------------------- */ Arg StickyPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr) ClientData clientData; /* Ignored. */ Tk_Window tkwin; /* Window for text widget. */ char *widgRec; /* Pointer to TkTextEmbWindow * structure. */ int offset; /* Ignored. */ Tcl_FreeProc **freeProcPtr; /* Pointer to variable to fill in with * information about how to reclaim * storage for return string. */ { int flags = ((TableEmbWindow *) widgRec)->sticky; int count = 0; char *result = (char *) ckalloc(5*sizeof(char)); if (flags&STICK_NORTH) result[count++] = 'n'; if (flags&STICK_EAST) result[count++] = 'e'; if (flags&STICK_SOUTH) result[count++] = 's'; if (flags&STICK_WEST) result[count++] = 'w'; *freeProcPtr = TCL_DYNAMIC; result[count] = '\0'; return LangStringArg(result); } /* *---------------------------------------------------------------------- * * StringParseProc -- * Converts an ascii string representing a widgets stickyness * into the boolean result. * * Results: * The boolean combination of the "sticky" bits is retuned. If an * error occurs, such as an invalid character, -1 is returned instead. * * Side effects: * none * *---------------------------------------------------------------------- */ static int StickyParseProc(clientData, interp, tkwin, value, widgRec, offset) ClientData clientData; /* Not used.*/ Tcl_Interp *interp; /* Used for reporting errors. */ Tk_Window tkwin; /* Window for text widget. */ Arg value; /* Value of option. */ char *widgRec; /* Pointer to TkTextEmbWindow * structure. */ int offset; /* Offset into item (ignored). */ { register TableEmbWindow *ewPtr = (TableEmbWindow *) widgRec; int sticky = 0; char c; char * valuestring = Tcl_GetString(value); while ((c = *valuestring++) != '\0') { switch (c) { case 'n': case 'N': sticky |= STICK_NORTH; break; case 'e': case 'E': sticky |= STICK_EAST; break; case 's': case 'S': sticky |= STICK_SOUTH; break; case 'w': case 'W': sticky |= STICK_WEST; break; case ' ': case ',': case '\t': case '\r': case '\n': break; default: Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "bad sticky value \"", --valuestring, "\": must contain n, s, e or w", (char *) NULL); return TCL_ERROR; } } ewPtr->sticky = sticky; return TCL_OK; } /* * ckallocs space for a new embedded window structure and clears the structure * returns the pointer to the new structure */ static TableEmbWindow * TableNewEmbWindow(Table *tablePtr) { TableEmbWindow *ewPtr = (TableEmbWindow *) ckalloc(sizeof(TableEmbWindow)); memset((VOID *) ewPtr, 0, sizeof(TableEmbWindow)); /* * Set the values that aren't 0/NULL by default */ ewPtr->tablePtr = tablePtr; ewPtr->relief = -1; ewPtr->padX = -1; ewPtr->padY = -1; return ewPtr; } /* *---------------------------------------------------------------------- * * EmbWinCleanup -- * Releases resources used by an embedded window before it is freed up. * * Results: * Window will no longer be valid. * * Side effects: * None. * *---------------------------------------------------------------------- */ static void EmbWinCleanup(Table *tablePtr, TableEmbWindow *ewPtr) { Tk_FreeOptions(winConfigSpecs, (char *) ewPtr, tablePtr->display, 0); } /* *-------------------------------------------------------------- * * EmbWinDisplay -- * * This procedure is invoked by TableDisplay for * mapping windows into cells. * * Results: * Displays or moves window on table screen. * * Side effects: * None. * *-------------------------------------------------------------- */ void EmbWinDisplay(Table *tablePtr, Drawable window, TableEmbWindow *ewPtr, TableTag *tagPtr, int x, int y, int width, int height) { Tk_Window tkwin = tablePtr->tkwin; Tk_Window ewTkwin = ewPtr->tkwin; int diffx=0; /* Cavity width - slave width. */ int diffy=0; /* Cavity hight - slave height. */ int sticky = ewPtr->sticky; int padx, pady; if (ewPtr->bg) tagPtr->bg = ewPtr->bg; if (ewPtr->relief != -1) tagPtr->relief = ewPtr->relief; if (ewPtr->borders) { tagPtr->borderStr = ewPtr->borderStr; tagPtr->borders = ewPtr->borders; tagPtr->bd[0] = ewPtr->bd[0]; tagPtr->bd[1] = ewPtr->bd[1]; tagPtr->bd[2] = ewPtr->bd[2]; tagPtr->bd[3] = ewPtr->bd[3]; } padx = (ewPtr->padX < 0) ? tablePtr->padX : ewPtr->padX; pady = (ewPtr->padY < 0) ? tablePtr->padY : ewPtr->padY; x += padx; width -= padx*2; y += pady; height -= pady*2; if (width > Tk_ReqWidth(ewPtr->tkwin)) { diffx = width - Tk_ReqWidth(ewPtr->tkwin); width = Tk_ReqWidth(ewPtr->tkwin); } if (height > Tk_ReqHeight(ewPtr->tkwin)) { diffy = height - Tk_ReqHeight(ewPtr->tkwin); height = Tk_ReqHeight(ewPtr->tkwin); } if (sticky&STICK_EAST && sticky&STICK_WEST) { width += diffx; } if (sticky&STICK_NORTH && sticky&STICK_SOUTH) { height += diffy; } if (!(sticky&STICK_WEST)) { x += (sticky&STICK_EAST) ? diffx : diffx/2; } if (!(sticky&STICK_NORTH)) { y += (sticky&STICK_SOUTH) ? diffy : diffy/2; } /* * If we fall below a specific minimum width/height requirement, * we just unmap the window */ if (width < 4 || height < 4) { if (ewPtr->displayed) { EmbWinUnmapNow(ewTkwin, tkwin); } return; } if (tkwin == Tk_Parent(ewTkwin)) { if ((x != Tk_X(ewTkwin)) || (y != Tk_Y(ewTkwin)) || (width != Tk_Width(ewTkwin)) || (height != Tk_Height(ewTkwin))) { Tk_MoveResizeWindow(ewTkwin, x, y, width, height); } Tk_MapWindow(ewTkwin); } else { Tk_MaintainGeometry(ewTkwin, tkwin, x, y, width, height); } ewPtr->displayed = 1; } /* *-------------------------------------------------------------- * * EmbWinUnmapNow -- * Handles unmapping the window depending on parent. * tkwin should be tablePtr->tkwin. * ewTkwin should be ewPtr->tkwin. * * Results: * Removes the window. * * Side effects: * None. * *-------------------------------------------------------------- */ static void EmbWinUnmapNow(Tk_Window ewTkwin, Tk_Window tkwin) { if (tkwin != Tk_Parent(ewTkwin)) { Tk_UnmaintainGeometry(ewTkwin, tkwin); } Tk_UnmapWindow(ewTkwin); } /* *-------------------------------------------------------------- * * EmbWinUnmap -- * This procedure is invoked by TableAdjustParams for * unmapping windows managed moved offscreen. * rlo, ... should be in real coords. * * Results: * None. * * Side effects: * Unmaps embedded windows. * *-------------------------------------------------------------- */ void EmbWinUnmap(Table *tablePtr, int rlo, int rhi, int clo, int chi) { register TableEmbWindow *ewPtr; Tcl_HashEntry *entryPtr; int row, col, trow, tcol; char buf[INDEX_BUFSIZE]; /* * Transform numbers from real to user user coords */ rlo += tablePtr->rowOffset; rhi += tablePtr->rowOffset; clo += tablePtr->colOffset; chi += tablePtr->colOffset; for (row = rlo; row <= rhi; row++) { for (col = clo; col <= chi; col++) { TableTrueCell(tablePtr, row, col, &trow, &tcol); TableMakeArrayIndex(trow, tcol, buf); entryPtr = Tcl_FindHashEntry(tablePtr->winTable, buf); if (entryPtr != NULL) { ewPtr = (TableEmbWindow *) Tcl_GetHashValue(entryPtr); if (ewPtr->displayed) { ewPtr->displayed = 0; if (ewPtr->tkwin != NULL && tablePtr->tkwin != NULL) { EmbWinUnmapNow(ewPtr->tkwin, tablePtr->tkwin); } } } } } } /* *-------------------------------------------------------------- * * EmbWinRequestProc -- * This procedure is invoked by Tk_GeometryRequest for * windows managed by the Table. * * Results: * None. * * Side effects: * Arranges for tkwin, and all its managed siblings, to * be re-arranged at the next idle point. * *-------------------------------------------------------------- */ static void EmbWinRequestProc(clientData, tkwin) ClientData clientData; /* Table's information about * window that got new preferred * geometry. */ Tk_Window tkwin; /* Other Tk-related information * about the window. */ { register TableEmbWindow *ewPtr = (TableEmbWindow *) clientData; /* * Resize depends on the sticky */ if (ewPtr->displayed && ewPtr->hPtr != NULL) { Table *tablePtr = ewPtr->tablePtr; int row, col, x, y, width, height; TableParseArrayIndex(&row, &col, Tcl_GetHashKey(tablePtr->winTable, ewPtr->hPtr)); if (TableCellVCoords(tablePtr, row-tablePtr->rowOffset, col-tablePtr->colOffset, &x, &y, &width, &height, 0)) { TableInvalidate(tablePtr, x, y, width, height, 0); } } } static void EmbWinRemove(TableEmbWindow *ewPtr) { Table *tablePtr = ewPtr->tablePtr; if (ewPtr->tkwin != NULL) { Tk_DeleteEventHandler(ewPtr->tkwin, StructureNotifyMask, EmbWinStructureProc, (ClientData) ewPtr); ewPtr->tkwin = NULL; } ewPtr->displayed = 0; if (tablePtr->tkwin != NULL) { int row, col, x, y, width, height; TableParseArrayIndex(&row, &col, Tcl_GetHashKey(tablePtr->winTable, ewPtr->hPtr)); /* this will cause windows removed from the table to actually * cause the associated embdedded window hash data to be removed */ Tcl_DeleteHashEntry(ewPtr->hPtr); if (TableCellVCoords(tablePtr, row-tablePtr->rowOffset, col-tablePtr->colOffset, &x, &y, &width, &height, 0)) TableInvalidate(tablePtr, x, y, width, height, 1); } /* this will cause windows removed from the table to actually * cause the associated embdedded window hash data to be removed */ EmbWinCleanup(tablePtr, ewPtr); ckfree((char *) ewPtr); } /* *-------------------------------------------------------------- * * EmbWinLostSlaveProc -- * This procedure is invoked by Tk whenever some other geometry * claims control over a slave that used to be managed by us. * * Results: * None. * * Side effects: * Forgets all table-related information about the slave. * *-------------------------------------------------------------- */ static void EmbWinLostSlaveProc(clientData, tkwin) ClientData clientData; /* Table structure for slave window that * was stolen away. */ Tk_Window tkwin; /* Tk's handle for the slave window. */ { register TableEmbWindow *ewPtr = (TableEmbWindow *) clientData; #if 0 Tcl_CancelIdleCall(EmbWinDelayedUnmap, (ClientData) ewPtr); #endif EmbWinUnmapNow(tkwin, ewPtr->tablePtr->tkwin); EmbWinRemove(ewPtr); } /* *-------------------------------------------------------------- * * EmbWinStructureProc -- * This procedure is invoked by the Tk event loop whenever * StructureNotify events occur for a window that's embedded * in a table widget. This procedure's only purpose is to * clean up when windows are deleted. * * Results: * None. * * Side effects: * The window is disassociated from the window segment, and * the portion of the table is redisplayed. * *-------------------------------------------------------------- */ static void EmbWinStructureProc(clientData, eventPtr) ClientData clientData; /* Pointer to record describing window item. */ XEvent *eventPtr; /* Describes what just happened. */ { register TableEmbWindow *ewPtr = (TableEmbWindow *) clientData; if (eventPtr->type != DestroyNotify) { return; } EmbWinRemove(ewPtr); } /* *-------------------------------------------------------------- * * EmbWinDelete -- * This procedure is invoked by ... whenever * an embedded window is being deleted. * * Results: * None. * * Side effects: * The embedded window is deleted, if it exists, and any resources * associated with it are released. * *-------------------------------------------------------------- */ void EmbWinDelete(register Table *tablePtr, TableEmbWindow *ewPtr) { Tcl_HashEntry *entryPtr = ewPtr->hPtr; if (ewPtr->tkwin != NULL) { Tk_Window tkwin = ewPtr->tkwin; /* * Delete the event handler for the window before destroying * the window, so that EmbWinStructureProc doesn't get called * (we'll already do everything that it would have done, and * it will just get confused). */ ewPtr->tkwin = NULL; Tk_DeleteEventHandler(tkwin, StructureNotifyMask, EmbWinStructureProc, (ClientData) ewPtr); Tk_DestroyWindow(tkwin); } if (tablePtr->tkwin != NULL && entryPtr != NULL) { int row, col, x, y, width, height; TableParseArrayIndex(&row, &col, Tcl_GetHashKey(tablePtr->winTable, entryPtr)); Tcl_DeleteHashEntry(entryPtr); if (TableCellVCoords(tablePtr, row-tablePtr->rowOffset, col-tablePtr->colOffset, &x, &y, &width, &height, 0)) TableInvalidate(tablePtr, x, y, width, height, 0); } #if 0 Tcl_CancelIdleCall(EmbWinDelayedUnmap, (ClientData) ewPtr); #endif EmbWinCleanup(tablePtr, ewPtr); ckfree((char *) ewPtr); } /* *-------------------------------------------------------------- * * EmbWinConfigure -- * This procedure is called to handle configuration options * for an embedded window. * * Results: * The return value is a standard Tcl result. If TCL_ERROR is * returned, then the interp's result contains an error message.. * * Side effects: * Configuration information for the embedded window changes, * such as alignment, stretching, or name of the embedded * window. * *-------------------------------------------------------------- */ static int EmbWinConfigure(tablePtr, ewPtr, objc, objv) Table *tablePtr; /* Information about table widget that * contains embedded window. */ TableEmbWindow *ewPtr; /* Embedded window to be configured. */ int objc; /* Number of objs in objv. */ Tcl_Obj *CONST objv[]; /* Obj type options. */ { Tcl_Interp *interp = tablePtr->interp; Tk_Window oldWindow; int i, result; Arg *args; oldWindow = ewPtr->tkwin; /* Stringify */ args = (Arg *) ckalloc((objc + 1) * sizeof(Arg)); for (i = 0; i < objc; i++) args[i] = LangStringArg(Tcl_GetString(objv[i])); args[i] = NULL; result = Tk_ConfigureWidget(interp, tablePtr->tkwin, winConfigSpecs, objc, args, (char *) ewPtr, TK_CONFIG_ARGV_ONLY); ckfree((char *) args); if (result != TCL_OK) { return TCL_ERROR; } if (oldWindow != ewPtr->tkwin) { ewPtr->displayed = 0; if (oldWindow != NULL) { Tk_DeleteEventHandler(oldWindow, StructureNotifyMask, EmbWinStructureProc, (ClientData) ewPtr); Tk_ManageGeometry(oldWindow, (Tk_GeomMgr *) NULL, (ClientData) NULL); EmbWinUnmapNow(oldWindow, tablePtr->tkwin); } if (ewPtr->tkwin != NULL) { Tk_Window ancestor, parent; /* * Make sure that the table is either the parent of the * embedded window or a descendant of that parent. Also, * don't allow a top-level window to be managed inside * a table. */ parent = Tk_Parent(ewPtr->tkwin); for (ancestor = tablePtr->tkwin; ; ancestor = Tk_Parent(ancestor)) { if (ancestor == parent) { break; } if (Tk_IsTopLevel(ancestor)) { badMaster: Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "can't embed ", Tk_PathName(ewPtr->tkwin), " in ", Tk_PathName(tablePtr->tkwin), (char *)NULL); ewPtr->tkwin = NULL; return TCL_ERROR; } } if (Tk_IsTopLevel(ewPtr->tkwin) || (ewPtr->tkwin == tablePtr->tkwin)) { goto badMaster; } /* * Take over geometry management for the window, plus create * an event handler to find out when it is deleted. */ Tk_ManageGeometry(ewPtr->tkwin, &tableGeomType, (ClientData)ewPtr); Tk_CreateEventHandler(ewPtr->tkwin, StructureNotifyMask, EmbWinStructureProc, (ClientData) ewPtr); } } return TCL_OK; } /* *-------------------------------------------------------------- * * Table_WinMove -- * This procedure is invoked by ... whenever * an embedded window is being moved. * * Results: * A standard Tcl result. * * Side effects: * If an embedded window is in the dest cell, it is deleted. * *-------------------------------------------------------------- */ int Table_WinMove(register Table *tablePtr, char *CONST srcPtr, char *CONST destPtr, int flags) { int srow, scol, row, col, new; Tcl_HashEntry *entryPtr; TableEmbWindow *ewPtr; if (TableGetIndex(tablePtr, srcPtr, &srow, &scol) != TCL_OK || TableGetIndex(tablePtr, destPtr, &row, &col) != TCL_OK) { return TCL_ERROR; } entryPtr = Tcl_FindHashEntry(tablePtr->winTable, srcPtr); if (entryPtr == NULL) { if (flags & INV_NO_ERR_MSG) { return TCL_OK; } else { Tcl_AppendStringsToObj(Tcl_GetObjResult(tablePtr->interp), "no window at index \"", srcPtr, "\"", (char *) NULL); return TCL_ERROR; } } /* avoid moving it to the same location */ if (srow == row && scol == col) { return TCL_OK; } /* get the window pointer */ ewPtr = (TableEmbWindow *) Tcl_GetHashValue(entryPtr); /* and free the old hash table entry */ Tcl_DeleteHashEntry(entryPtr); entryPtr = Tcl_CreateHashEntry(tablePtr->winTable, destPtr, &new); if (!new) { /* window already there - just delete it */ TableEmbWindow *ewPtrDel; ewPtrDel = (TableEmbWindow *) Tcl_GetHashValue(entryPtr); /* This prevents the deletion of it's own entry, since we need it */ ewPtrDel->hPtr = NULL; EmbWinDelete(tablePtr, ewPtrDel); } /* set the new entry's value */ Tcl_SetHashValue(entryPtr, (ClientData) ewPtr); ewPtr->hPtr = entryPtr; if (flags & INV_FORCE) { int x, y, w, h; /* Invalidate old cell */ if (TableCellVCoords(tablePtr, srow-tablePtr->rowOffset, scol-tablePtr->colOffset, &x, &y, &w, &h, 0)) { TableInvalidate(tablePtr, x, y, w, h, 0); } /* Invalidate new cell */ if (TableCellVCoords(tablePtr, row-tablePtr->rowOffset, col-tablePtr->colOffset, &x, &y, &w, &h, 0)) { TableInvalidate(tablePtr, x, y, w, h, 0); } } return TCL_OK; } /* *-------------------------------------------------------------- * * Table_WinDelete -- * This procedure is invoked by ... whenever * an embedded window is being delete. * * Results: * A standard Tcl result. * * Side effects: * Window info will be deleted. * *-------------------------------------------------------------- */ int Table_WinDelete(register Table *tablePtr, char *CONST idxPtr) { Tcl_HashEntry *entryPtr; entryPtr = Tcl_FindHashEntry(tablePtr->winTable, idxPtr); if (entryPtr != NULL) { /* get the window pointer & clean up data associated with it */ EmbWinDelete(tablePtr, (TableEmbWindow *) Tcl_GetHashValue(entryPtr)); } return TCL_OK; } /* *-------------------------------------------------------------- * * Table_WindowCmd -- * This procedure is invoked to process the window method * that corresponds to a widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_WindowCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *)clientData; int result = TCL_OK, cmdIndex, row, col, x, y, width, height, i, new; TableEmbWindow *ewPtr; Tcl_HashEntry *entryPtr; Tcl_HashSearch search; char buf[INDEX_BUFSIZE], *keybuf, *winname; if (objc < 3) { Tcl_WrongNumArgs(interp, 2, objv, "option ?arg arg ...?"); return TCL_ERROR; } /* parse the next argument */ if (Tcl_GetIndexFromObj(interp, objv[2], winCmdNames, "option", 0, &cmdIndex) != TCL_OK) { return TCL_ERROR; } switch ((enum winCommand) cmdIndex) { case WIN_CGET: if (objc != 5) { Tcl_WrongNumArgs(interp, 3, objv, "index option"); return TCL_ERROR; } entryPtr = Tcl_FindHashEntry(tablePtr->winTable, Tcl_GetString(objv[3])); if (entryPtr == NULL) { Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "no window at index \"", Tcl_GetString(objv[3]), "\"", (char *)NULL); return TCL_ERROR; } else { ewPtr = (TableEmbWindow *) Tcl_GetHashValue(entryPtr); result = Tk_ConfigureValue(interp, tablePtr->tkwin, winConfigSpecs, (char *) ewPtr, Tcl_GetString(objv[4]), 0); } return result; /* CGET */ case WIN_CONFIGURE: if (objc < 4) { Tcl_WrongNumArgs(interp, 3, objv, "index ?arg arg ...?"); return TCL_ERROR; } if (TableGetIndexObj(tablePtr, objv[3], &row, &col) == TCL_ERROR) { return TCL_ERROR; } TableMakeArrayIndex(row, col, buf); entryPtr = Tcl_CreateHashEntry(tablePtr->winTable, buf, &new); if (new) { /* create the structure */ ewPtr = TableNewEmbWindow(tablePtr); /* insert it into the table */ Tcl_SetHashValue(entryPtr, (ClientData) ewPtr); ewPtr->hPtr = entryPtr; /* configure the window structure */ result = EmbWinConfigure(tablePtr, ewPtr, objc-4, objv+4); if (result == TCL_ERROR) { /* release the structure */ EmbWinCleanup(tablePtr, ewPtr); ckfree((char *) ewPtr); /* and free the hash table entry */ Tcl_DeleteHashEntry(entryPtr); } } else { /* window exists, do a reconfig if we have enough args */ /* get the window pointer from the table */ ewPtr = (TableEmbWindow *) Tcl_GetHashValue(entryPtr); /* 5 args means that there are values to replace */ if (objc > 5) { /* and do a reconfigure */ result = EmbWinConfigure(tablePtr, ewPtr, objc-4, objv+4); } } if (result == TCL_ERROR) { return TCL_ERROR; } /* * If there were less than 6 args, we need * to do a printout of the config, even for new windows */ if (objc < 6) { result = Tk_ConfigureInfo(interp, tablePtr->tkwin, winConfigSpecs, (char *) ewPtr, (objc == 5)? Tcl_GetString(objv[4]) : NULL, 0); } else { /* Otherwise we reconfigured so invalidate * the table for a redraw */ if (TableCellVCoords(tablePtr, row-tablePtr->rowOffset, col-tablePtr->colOffset, &x, &y, &width, &height, 0)) { TableInvalidate(tablePtr, x, y, width, height, 1); } } return result; /* CONFIGURE */ case WIN_DELETE: if (objc < 4) { Tcl_WrongNumArgs(interp, 3, objv, "index ?index ...?"); return TCL_ERROR; } for (i = 3; i < objc; i++) { Table_WinDelete(tablePtr, Tcl_GetString(objv[i])); } break; case WIN_MOVE: if (objc != 5) { Tcl_WrongNumArgs(interp, 3, objv, "srcIndex destIndex"); return TCL_ERROR; } result = Table_WinMove(tablePtr, Tcl_GetString(objv[3]), Tcl_GetString(objv[4]), INV_FORCE); break; case WIN_NAMES: { Tcl_Obj *objPtr = Tcl_NewObj(); /* just print out the window names */ if (objc < 3 || objc > 4) { Tcl_WrongNumArgs(interp, 3, objv, "?pattern?"); return TCL_ERROR; } winname = (objc == 4) ? Tcl_GetString(objv[3]) : NULL; entryPtr = Tcl_FirstHashEntry(tablePtr->winTable, &search); while (entryPtr != NULL) { keybuf = Tcl_GetHashKey(tablePtr->winTable, entryPtr); if (objc == 3 || Tcl_StringMatch(keybuf, winname) ) { Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj(keybuf, -1)); } entryPtr = Tcl_NextHashEntry(&search); } Tcl_SetResult(interp, Tcl_GetString(TableCellSort(tablePtr, Tcl_GetStringFromObj(Tcl_GetObjResult(interp),NULL))), TCL_DYNAMIC); break; } } return TCL_OK; } �����������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable/tkTableEdit.c���������������������������������������������������0000644�0000000�0000000�00000052101�13745605157�020163� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * tkTableEdit.c -- * * This module implements editing functions of a table widget. * * Copyright (c) 1998-2000 Jeffrey Hobbs * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tkTableEdit.c,v 1.6 2004/02/08 03:09:46 cerney Exp $ */ #include "tkVMacro.h" #include "tkTable.h" static void TableModifyRC _ANSI_ARGS_((register Table *tablePtr, int doRows, int movetag, Tcl_HashTable *tagTblPtr, Tcl_HashTable *dimTblPtr, int offset, int from, int to, int lo, int hi, int outOfBounds)); /* insert/delete subcommands */ static CONST char *modCmdNames[] = { "active", "cols", "rows", (char *)NULL }; enum modCmd { MOD_ACTIVE, MOD_COLS, MOD_ROWS }; /* insert/delete row/col switches */ static CONST char *rcCmdNames[] = { "-keeptitles", "-holddimensions", "-holdselection", "-holdtags", "-holdwindows", "--", (char *) NULL }; enum rcCmd { OPT_TITLES, OPT_DIMS, OPT_SEL, OPT_TAGS, OPT_WINS, OPT_LAST }; #define HOLD_TITLES 1<<0 #define HOLD_DIMS 1<<1 #define HOLD_TAGS 1<<2 #define HOLD_WINS 1<<3 #define HOLD_SEL 1<<4 /* *-------------------------------------------------------------- * * Table_EditCmd -- * This procedure is invoked to process the insert/delete method * that corresponds to a table widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ int Table_EditCmd(ClientData clientData, register Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { register Table *tablePtr = (Table *) clientData; int doInsert, cmdIndex, first, last; if (objc < 4) { Tcl_WrongNumArgs(interp, 2, objv, "option ?switches? arg ?arg?"); return TCL_ERROR; } if (Tcl_GetIndexFromObj(interp, objv[2], modCmdNames, "option", 0, &cmdIndex) != TCL_OK) { return TCL_ERROR; } doInsert = (*(Tcl_GetString(objv[1])) == 'i'); switch ((enum modCmd) cmdIndex) { case MOD_ACTIVE: if (doInsert) { /* INSERT */ if (objc != 5) { Tcl_WrongNumArgs(interp, 3, objv, "index string"); return TCL_ERROR; } if (TableGetIcursorObj(tablePtr, objv[3], &first) != TCL_OK) { return TCL_ERROR; } else if ((tablePtr->flags & HAS_ACTIVE) && !(tablePtr->flags & ACTIVE_DISABLED) && tablePtr->state == STATE_NORMAL) { TableInsertChars(tablePtr, first, Tcl_GetString(objv[4])); } } else { /* DELETE */ if (objc > 5) { Tcl_WrongNumArgs(interp, 3, objv, "first ?last?"); return TCL_ERROR; } if (TableGetIcursorObj(tablePtr, objv[3], &first) != TCL_OK) { return TCL_ERROR; } if (objc == 4) { last = first+1; } else if (TableGetIcursorObj(tablePtr, objv[4], &last) != TCL_OK) { return TCL_ERROR; } if ((last >= first) && (tablePtr->flags & HAS_ACTIVE) && !(tablePtr->flags & ACTIVE_DISABLED) && tablePtr->state == STATE_NORMAL) { TableDeleteChars(tablePtr, first, last-first); } } break; /* EDIT ACTIVE */ case MOD_COLS: case MOD_ROWS: { /* * ROW/COL INSERTION/DELETION * FIX: This doesn't handle spans */ int i, lo, hi, argsLeft, offset, minkeyoff, doRows; int maxrow, maxcol, maxkey, minkey, flags, count, *dimPtr; Tcl_HashTable *tagTblPtr, *dimTblPtr; Tcl_HashSearch search; doRows = (cmdIndex == MOD_ROWS); flags = 0; for (i = 3; i < objc; i++) { if (*(Tcl_GetString(objv[i])) != '-') { break; } if (Tcl_GetIndexFromObj(interp, objv[i], rcCmdNames, "switch", 0, &cmdIndex) != TCL_OK) { return TCL_ERROR; } if (cmdIndex == OPT_LAST) { i++; break; } switch (cmdIndex) { case OPT_TITLES: flags |= HOLD_TITLES; break; case OPT_DIMS: flags |= HOLD_DIMS; break; case OPT_SEL: flags |= HOLD_SEL; break; case OPT_TAGS: flags |= HOLD_TAGS; break; case OPT_WINS: flags |= HOLD_WINS; break; } } argsLeft = objc - i; if (argsLeft < 1 || argsLeft > 2) { Tcl_WrongNumArgs(interp, 3, objv, "?switches? index ?count?"); return TCL_ERROR; } count = 1; maxcol = tablePtr->cols-1+tablePtr->colOffset; maxrow = tablePtr->rows-1+tablePtr->rowOffset; if (strcmp(Tcl_GetString(objv[i]), "end") == 0) { /* allow "end" to be specified as an index */ first = (doRows) ? maxrow : maxcol; } else if (Tcl_GetIntFromObj(interp, objv[i], &first) != TCL_OK) { return TCL_ERROR; } if (argsLeft == 2 && Tcl_GetIntFromObj(interp, objv[++i], &count) != TCL_OK) { return TCL_ERROR; } if (count == 0 || (tablePtr->state == STATE_DISABLED)) { return TCL_OK; } if (doRows) { maxkey = maxrow; minkey = tablePtr->rowOffset; minkeyoff = tablePtr->rowOffset+tablePtr->titleRows; offset = tablePtr->rowOffset; tagTblPtr = tablePtr->rowStyles; dimTblPtr = tablePtr->rowHeights; dimPtr = &(tablePtr->rows); lo = tablePtr->colOffset + ((flags & HOLD_TITLES) ? tablePtr->titleCols : 0); hi = maxcol; } else { maxkey = maxcol; minkey = tablePtr->colOffset; minkeyoff = tablePtr->colOffset+tablePtr->titleCols; offset = tablePtr->colOffset; tagTblPtr = tablePtr->colStyles; dimTblPtr = tablePtr->colWidths; dimPtr = &(tablePtr->cols); lo = tablePtr->rowOffset + ((flags & HOLD_TITLES) ? tablePtr->titleRows : 0); hi = maxrow; } /* constrain the starting index */ if (first > maxkey) { first = maxkey; } else if (first < minkey) { first = minkey; } if (doInsert) { /* +count means insert after index, * -count means insert before index */ if (count < 0) { count = -count; } else { first++; } if ((flags & HOLD_TITLES) && (first < minkeyoff)) { count -= minkeyoff-first; if (count <= 0) { return TCL_OK; } first = minkeyoff; } if (!(flags & HOLD_DIMS)) { maxkey += count; *dimPtr += count; } /* * We need to call TableAdjustParams before TableModifyRC to * ensure that side effect code like var traces that might get * called will access the correct new dimensions. */ if (*dimPtr < 1) { *dimPtr = 1; } TableAdjustParams(tablePtr); for (i = maxkey; i >= first; i--) { /* move row/col style && width/height here */ TableModifyRC(tablePtr, doRows, flags, tagTblPtr, dimTblPtr, offset, i, i-count, lo, hi, ((i-count) < first)); } if (!(flags & HOLD_WINS)) { /* * This may be a little severe, but it does unmap the * windows that need to be unmapped, and those that should * stay do remap correctly. [Bug #551325] */ if (doRows) { EmbWinUnmap(tablePtr, first - tablePtr->rowOffset, maxkey - tablePtr->rowOffset, lo - tablePtr->colOffset, hi - tablePtr->colOffset); } else { EmbWinUnmap(tablePtr, lo - tablePtr->rowOffset, hi - tablePtr->rowOffset, first - tablePtr->colOffset, maxkey - tablePtr->colOffset); } } } else { /* (index = i && count = 1) == (index = i && count = -1) */ if (count < 0) { /* if the count is negative, make sure that the col count will * delete no greater than the original index */ if (first+count < minkey) { if (first-minkey < abs(count)) { /* * In this case, the user is asking to delete more rows * than exist before the minkey, so we have to shrink * the count down to the existing rows up to index. */ count = first-minkey; } else { count += first-minkey; } first = minkey; } else { first += count; count = -count; } } if ((flags & HOLD_TITLES) && (first <= minkeyoff)) { count -= minkeyoff-first; if (count <= 0) { return TCL_OK; } first = minkeyoff; } if (count > maxkey-first+1) { count = maxkey-first+1; } if (!(flags & HOLD_DIMS)) { *dimPtr -= count; } /* * We need to call TableAdjustParams before TableModifyRC to * ensure that side effect code like var traces that might get * called will access the correct new dimensions. */ if (*dimPtr < 1) { *dimPtr = 1; } TableAdjustParams(tablePtr); for (i = first; i <= maxkey; i++) { TableModifyRC(tablePtr, doRows, flags, tagTblPtr, dimTblPtr, offset, i, i+count, lo, hi, ((i+count) > maxkey)); } } if (!(flags & HOLD_SEL) && Tcl_FirstHashEntry(tablePtr->selCells, &search) != NULL) { /* clear selection - forceful, but effective */ Tcl_DeleteHashTable(tablePtr->selCells); Tcl_InitHashTable(tablePtr->selCells, TCL_STRING_KEYS); } /* * Make sure that the modified dimension is actually legal * after removing all that stuff. */ if (*dimPtr < 1) { *dimPtr = 1; TableAdjustParams(tablePtr); } /* change the geometry */ TableGeometryRequest(tablePtr); /* FIX: * This has to handle when the previous rows/cols resize because * of the *stretchmode. InvalidateAll does that, but could be * more efficient. */ TableInvalidateAll(tablePtr, 0); break; } } return TCL_OK; } /* *---------------------------------------------------------------------- * * TableDeleteChars -- * Remove one or more characters from an table widget. * * Results: * None. * * Side effects: * Memory gets freed, the table gets modified and (eventually) * redisplayed. * *---------------------------------------------------------------------- */ void TableDeleteChars(tablePtr, index, count) register Table *tablePtr; /* Table widget to modify. */ int index; /* Index of first character to delete. */ int count; /* How many characters to delete. */ { #ifdef TCL_UTF_MAX int byteIndex, byteCount, newByteCount, numBytes, numChars; char *new, *string; string = tablePtr->activeBuf; numBytes = strlen(string); numChars = Tcl_NumUtfChars(string, numBytes); if ((index + count) > numChars) { count = numChars - index; } if (count <= 0) { return; } byteIndex = Tcl_UtfAtIndex(string, index) - string; byteCount = Tcl_UtfAtIndex(string + byteIndex, count) - (string + byteIndex); newByteCount = numBytes + 1 - byteCount; new = (char *) ckalloc((unsigned) newByteCount); memcpy(new, string, (size_t) byteIndex); strcpy(new + byteIndex, string + byteIndex + byteCount); #else int oldlen; char *new; /* this gets the length of the string, as well as ensuring that * the cursor isn't beyond the end char */ TableGetIcursor(tablePtr, "end", &oldlen); if ((index+count) > oldlen) count = oldlen-index; if (count <= 0) return; new = (char *) ckalloc((unsigned)(oldlen-count+1)); strncpy(new, tablePtr->activeBuf, (size_t) index); strcpy(new+index, tablePtr->activeBuf+index+count); /* make sure this string is null terminated */ new[oldlen-count] = '\0'; #endif /* This prevents deletes on BREAK or validation error. */ if (tablePtr->validate && TableValidateChange(tablePtr, tablePtr->activeRow+tablePtr->rowOffset, tablePtr->activeCol+tablePtr->colOffset, tablePtr->activeBuf, new, index) != TCL_OK) { ckfree(new); return; } ckfree(tablePtr->activeBuf); tablePtr->activeBuf = new; /* mark the text as changed */ tablePtr->flags |= TEXT_CHANGED; if (tablePtr->icursor >= index) { if (tablePtr->icursor >= (index+count)) { tablePtr->icursor -= count; } else { tablePtr->icursor = index; } } TableSetActiveIndex(tablePtr); TableRefresh(tablePtr, tablePtr->activeRow, tablePtr->activeCol, CELL); } /* *---------------------------------------------------------------------- * * TableInsertChars -- * Add new characters to the active cell of a table widget. * * Results: * None. * * Side effects: * New information gets added to tablePtr; it will be redisplayed * soon, but not necessarily immediately. * *---------------------------------------------------------------------- */ void TableInsertChars(tablePtr, index, value) register Table *tablePtr; /* Table that is to get the new elements. */ int index; /* Add the new elements before this element. */ char *value; /* New characters to add (NULL-terminated * string). */ { #ifdef TCL_UTF_MAX int oldlen, byteIndex, byteCount; char *new, *string; byteCount = strlen(value); if (byteCount == 0) { return; } /* Is this an autoclear and this is the first update */ /* Note that this clears without validating */ if (tablePtr->autoClear && !(tablePtr->flags & TEXT_CHANGED)) { /* set the buffer to be empty */ tablePtr->activeBuf = (char *)ckrealloc(tablePtr->activeBuf, 1); tablePtr->activeBuf[0] = '\0'; /* the insert position now has to be 0 */ index = 0; tablePtr->icursor = 0; } string = tablePtr->activeBuf; byteIndex = Tcl_UtfAtIndex(string, index) - string; oldlen = strlen(string); new = (char *) ckalloc((unsigned)(oldlen + byteCount + 1)); memcpy(new, string, (size_t) byteIndex); strcpy(new + byteIndex, value); strcpy(new + byteIndex + byteCount, string + byteIndex); /* validate potential new active buffer */ /* This prevents inserts on either BREAK or validation error. */ if (tablePtr->validate && TableValidateChange(tablePtr, tablePtr->activeRow+tablePtr->rowOffset, tablePtr->activeCol+tablePtr->colOffset, tablePtr->activeBuf, new, byteIndex) != TCL_OK) { ckfree(new); return; } /* * The following construction is used because inserting improperly * formed UTF-8 sequences between other improperly formed UTF-8 * sequences could result in actually forming valid UTF-8 sequences; * the number of characters added may not be Tcl_NumUtfChars(string, -1), * because of context. The actual number of characters added is how * many characters were are in the string now minus the number that * used to be there. */ if (tablePtr->icursor >= index) { tablePtr->icursor += Tcl_NumUtfChars(new, oldlen+byteCount) - Tcl_NumUtfChars(tablePtr->activeBuf, oldlen); } ckfree(string); tablePtr->activeBuf = new; #else int oldlen, newlen; char *new; newlen = strlen(value); if (newlen == 0) return; /* Is this an autoclear and this is the first update */ /* Note that this clears without validating */ if (tablePtr->autoClear && !(tablePtr->flags & TEXT_CHANGED)) { /* set the buffer to be empty */ tablePtr->activeBuf = (char *)ckrealloc(tablePtr->activeBuf, 1); tablePtr->activeBuf[0] = '\0'; /* the insert position now has to be 0 */ index = 0; } oldlen = strlen(tablePtr->activeBuf); /* get the buffer to at least the right length */ new = (char *) ckalloc((unsigned)(oldlen+newlen+1)); strncpy(new, tablePtr->activeBuf, (size_t) index); strcpy(new+index, value); strcpy(new+index+newlen, (tablePtr->activeBuf)+index); /* make sure this string is null terminated */ new[oldlen+newlen] = '\0'; /* validate potential new active buffer */ /* This prevents inserts on either BREAK or validation error. */ if (tablePtr->validate && TableValidateChange(tablePtr, tablePtr->activeRow+tablePtr->rowOffset, tablePtr->activeCol+tablePtr->colOffset, tablePtr->activeBuf, new, index) != TCL_OK) { ckfree(new); return; } ckfree(tablePtr->activeBuf); tablePtr->activeBuf = new; if (tablePtr->icursor >= index) { tablePtr->icursor += newlen; } #endif /* mark the text as changed */ tablePtr->flags |= TEXT_CHANGED; TableSetActiveIndex(tablePtr); TableRefresh(tablePtr, tablePtr->activeRow, tablePtr->activeCol, CELL); } /* *---------------------------------------------------------------------- * * TableModifyRC -- * Helper function that does the core work of moving rows/cols * and associated tags. * * Results: * None. * * Side effects: * Moves cell data and possibly tag data * *---------------------------------------------------------------------- */ static void TableModifyRC(tablePtr, doRows, flags, tagTblPtr, dimTblPtr, offset, from, to, lo, hi, outOfBounds) Table *tablePtr; /* Information about text widget. */ int doRows; /* rows (1) or cols (0) */ int flags; /* flags indicating what to move */ Tcl_HashTable *tagTblPtr, *dimTblPtr; /* Pointers to the row/col tags * and width/height tags */ int offset; /* appropriate offset */ int from, to; /* the from and to row/col */ int lo, hi; /* the lo and hi col/row */ int outOfBounds; /* the boundary check for shifting items */ { int j, new; char buf[INDEX_BUFSIZE], buf1[INDEX_BUFSIZE]; Tcl_HashEntry *entryPtr, *newPtr; TableEmbWindow *ewPtr; /* * move row/col style && width/height here * If -holdtags is specified, we don't move the user-set widths/heights * of the absolute rows/columns, otherwise we enter here to move the * dimensions appropriately */ if (!(flags & HOLD_TAGS)) { entryPtr = Tcl_FindHashEntry(tagTblPtr, (char *)from); if (entryPtr != NULL) { Tcl_DeleteHashEntry(entryPtr); } entryPtr = Tcl_FindHashEntry(dimTblPtr, (char *)from-offset); if (entryPtr != NULL) { Tcl_DeleteHashEntry(entryPtr); } if (!outOfBounds) { entryPtr = Tcl_FindHashEntry(tagTblPtr, (char *)to); if (entryPtr != NULL) { newPtr = Tcl_CreateHashEntry(tagTblPtr, (char *)from, &new); Tcl_SetHashValue(newPtr, Tcl_GetHashValue(entryPtr)); Tcl_DeleteHashEntry(entryPtr); } entryPtr = Tcl_FindHashEntry(dimTblPtr, (char *)to-offset); if (entryPtr != NULL) { newPtr = Tcl_CreateHashEntry(dimTblPtr, (char *)from-offset, &new); Tcl_SetHashValue(newPtr, Tcl_GetHashValue(entryPtr)); Tcl_DeleteHashEntry(entryPtr); } } } for (j = lo; j <= hi; j++) { if (doRows /* rows */) { TableMakeArrayIndex(from, j, buf); TableMakeArrayIndex(to, j, buf1); TableMoveCellValue(tablePtr, to, j, buf1, from, j, buf, outOfBounds); } else { TableMakeArrayIndex(j, from, buf); TableMakeArrayIndex(j, to, buf1); TableMoveCellValue(tablePtr, j, to, buf1, j, from, buf, outOfBounds); } /* * If -holdselection is specified, we leave the selected cells in the * absolute cell values, otherwise we enter here to move the * selection appropriately */ if (!(flags & HOLD_SEL)) { entryPtr = Tcl_FindHashEntry(tablePtr->selCells, buf); if (entryPtr != NULL) { Tcl_DeleteHashEntry(entryPtr); } if (!outOfBounds) { entryPtr = Tcl_FindHashEntry(tablePtr->selCells, buf1); if (entryPtr != NULL) { Tcl_CreateHashEntry(tablePtr->selCells, buf, &new); Tcl_DeleteHashEntry(entryPtr); } } } /* * If -holdtags is specified, we leave the tags in the * absolute cell values, otherwise we enter here to move the * tags appropriately */ if (!(flags & HOLD_TAGS)) { entryPtr = Tcl_FindHashEntry(tablePtr->cellStyles, buf); if (entryPtr != NULL) { Tcl_DeleteHashEntry(entryPtr); } if (!outOfBounds) { entryPtr = Tcl_FindHashEntry(tablePtr->cellStyles, buf1); if (entryPtr != NULL) { newPtr = Tcl_CreateHashEntry(tablePtr->cellStyles, buf, &new); Tcl_SetHashValue(newPtr, Tcl_GetHashValue(entryPtr)); Tcl_DeleteHashEntry(entryPtr); } } } /* * If -holdwindows is specified, we leave the windows in the * absolute cell values, otherwise we enter here to move the * windows appropriately */ if (!(flags & HOLD_WINS)) { /* * Delete whatever window might be in our destination */ Table_WinDelete(tablePtr, buf); if (!outOfBounds) { /* * buf1 is where the window is * buf is where we want it to be * * This is an adaptation of Table_WinMove, which we can't * use because we are intermediately fiddling with boundaries */ entryPtr = Tcl_FindHashEntry(tablePtr->winTable, buf1); if (entryPtr != NULL) { /* * If there was a window in our source, * get the window pointer to move it */ ewPtr = (TableEmbWindow *) Tcl_GetHashValue(entryPtr); /* and free the old hash table entry */ Tcl_DeleteHashEntry(entryPtr); entryPtr = Tcl_CreateHashEntry(tablePtr->winTable, buf, &new); /* * We needn't check if a window was in buf, since the * Table_WinDelete above should guarantee that no window * is there. Just set the new entry's value. */ Tcl_SetHashValue(entryPtr, (ClientData) ewPtr); ewPtr->hPtr = entryPtr; } } } } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable/version.h�������������������������������������������������������0000644�0000000�0000000�00000000307�13742524721�017454� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#if 0 TBL_MAJOR_VERSION = 2 TBL_MINOR_VERSION = 8 VERSION = $(TBL_MAJOR_VERSION).$(TBL_MINOR_VERSION) #endif #define TBL_MAJOR_VERSION 2 #define TBL_MINOR_VERSION 8 #define VERSION "2.8" �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable/perlPort.pod����������������������������������������������������0000644�0000000�0000000�00000010467�13745605157�020147� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� =head1 NAME perlPort.pod - Notes on Porting tkTable from tcl to perltk =head1 DESCRIPTION =head1 file notes =over 1 =item * tkTableInitScript.h This contains a TCL script that is run when table is loaded. This will probably have to be completly converted to perl. B<Excluded>. =item * conf* Files Used by gnu autoconfigure in the TCL scripts. B<Excluded>. =item * mac_* Files Used for mac port. Don't worry about for now. =item * mm.h Command structure lookup definitions. Called out by tkTable.h =item * tkAppInit.c TCL application Init. A similar file is excluded in ../tclUnix, ../tclWin, etc. B<Excluded>. =item * tkTable.c/h Main tkTable code/header file. =item * tkTableCell.c Functions for the tkTable Cells =item * tkTableCmd.c Implements general commands of the table widget =item * tkTableEdit.c Implements editing functions for the table widget. =item * tkTablePs.c Implements postscript output for table widgets. =item * tkTableTag.c Implements tags for table widgets. =item * tkTableWin.c Implements embedded windows for table widgets =back =head1 Top Level perlTk Calling Notes As an example, Scale.xs references C<Tk_ScaleCmd>, which is defined in tkScale.c. Should the top leved Table.xs do a similar thing? =head1 Conversion from Native tcl/tk notes: These notes are taken from looking at the difference between the tkScale.h and tkScale.c files in the stock tk8.0.5 distribution and the Tk800.022/pTk/mTk distribution. =head2 .h files =over 1 =item * Add tkVMacro.h to include Also add: #include "tkPort.h" #include "tkInt.h" #include "tkVMacro.h" =item * Remove UID type references? Or change to Tk_State type? =item * Change name of variables from char type to Var type =item * Change command variables from char type to LangCallback type. =back =head2 .c files =over =item * Change any tclMath refs to <math.h> =item * Add #include "tkVMacro.h" Before "tkScale.h" or equivalent. =item * Change Tk_ConfigSpec table C<Tk_CONFIG_STRINGS> for commands to C<TK_CONFIG_CALLBACK>. Removed/Change UID type variables Change TK_CONFIG_STRING to TK_CONFIG_SCALAR_VAR for -variable type entries. =item * Change XXXVarProc items From char * name to Var name where appropriate. =item * Change tkNormalUID states to TK_STATE_NORMAL Also for disabled (TK_STATE_DISABLED) =item * Change Tk_SetClass call to TkClassOption calls (Not Needed?) =item * Change any numeric conversions. Anything like C<value = strtod(stringValue, &end)> should be converted to a C<Arg stringValue;> type and a C<(Tcl_GetDouble(interp, stringValue, &value)> call. =item * Change name of variables from char type to Var type =item * Change any calls to Tcl_CreateCommand to Lang_CreateWidget Similar to the way this was changed in the tkCanvas.c file in the main tk distribution. =item * Modify the command routine to return a value like tkCanvas Replace Tcl_SetStringObj with Tcl_ArgResult similar to what is in tkCanvas.c =item * Tcl_VarEval Conversion Any calls to Tcl_VarEval are converted to LangDoCallback =item * Tcl_SplitList Conversion Any calls to Tcl_SplitList are changed to Tcl_ListObjGetElements. =item * Tcl_Merge Conversion Any calls to Tcl_Merge are changed to Tcl_NewListObj. =item * Tcl_GetStringResult Conversion Any calls to Tcl_GetStringResult are changed to Tcl_GetResult. Tcl_GetStringResult wasn't provided as part of the tkGlue.c parkage and Tcl_GetResult appeared to do the same thing. =item * Tcl_GlobalEval/ExpandPercents Conversion The original tktable widget accepts TCL scripts (text) to be used as callbacks (Like for -browsecommand, and the -command options). The tcl/tk code takes the TCL script and performs Expand Percents on it, and then evals it, using Tcl_GlobalEval. To work with perltk, this sequence was changed to a LangDoCallBack. =back =head2 .tcl files Files in the lib directory (tkTable.tcl) are equivalent to the .pm files for the widget, so the tkTable.tcl file has to be converted to perl. See the various .pm files in the Tk distribution for examples. Note the tcl2perl script in the Tk distribution can provided a starting point for the translation. Much hand-editing is still required however. ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable/configure�������������������������������������������������������0000644�0000000�0000000�00000077354�13742524721�017542� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated automatically using autoconf version 2.12 # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. # Defaults: ac_help= ac_default_prefix=/usr/local # Any additions from configure.in: ac_help="$ac_help --with-tcl=<directory> directory containing tclConfig.sh" ac_help="$ac_help --with-tk=<directory> directory containing tkConfig.sh" # Initialize some variables set by options. # The variables have the same names as the options, with # dashes changed to underlines. build=NONE cache_file=./config.cache exec_prefix=NONE host=NONE no_create= nonopt=NONE no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= target=NONE verbose= x_includes=NONE x_libraries=NONE bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datadir='${prefix}/share' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' # Initialize some other variables. subdirs= MFLAGS= MAKEFLAGS= # Maximum number of lines to put in a shell here document. ac_max_here_lines=12 ac_prev= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval "$ac_prev=\$ac_option" ac_prev= continue fi case "$ac_option" in -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; *) ac_optarg= ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case "$ac_option" in -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir="$ac_optarg" ;; -build | --build | --buil | --bui | --bu) ac_prev=build ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build="$ac_optarg" ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file="$ac_optarg" ;; -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | --da=*) datadir="$ac_optarg" ;; -disable-* | --disable-*) ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` eval "enable_${ac_feature}=no" ;; -enable-* | --enable-*) ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "enable_${ac_feature}='$ac_optarg'" ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix="$ac_optarg" ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he) # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat << EOF Usage: configure [options] [host] Options: [defaults in brackets after descriptions] Configuration: --cache-file=FILE cache test results in FILE --help print this message --no-create do not create output files --quiet, --silent do not print \`checking...' messages --version print the version of autoconf that created configure Directory and file names: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [same as prefix] --bindir=DIR user executables in DIR [EPREFIX/bin] --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] --libexecdir=DIR program executables in DIR [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data in DIR [PREFIX/share] --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data in DIR [PREFIX/com] --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] --libdir=DIR object code libraries in DIR [EPREFIX/lib] --includedir=DIR C header files in DIR [PREFIX/include] --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] --infodir=DIR info documentation in DIR [PREFIX/info] --mandir=DIR man documentation in DIR [PREFIX/man] --srcdir=DIR find the sources in DIR [configure dir or ..] --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names EOF cat << EOF Host type: --build=BUILD configure for building on BUILD [BUILD=HOST] --host=HOST configure for HOST [guessed] --target=TARGET configure for TARGET [TARGET=HOST] Features and packages: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --x-includes=DIR X include files are in DIR --x-libraries=DIR X library files are in DIR EOF if test -n "$ac_help"; then echo "--enable and --with options recognized:$ac_help" fi exit 0 ;; -host | --host | --hos | --ho) ac_prev=host ;; -host=* | --host=* | --hos=* | --ho=*) host="$ac_optarg" ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir="$ac_optarg" ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir="$ac_optarg" ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir="$ac_optarg" ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir="$ac_optarg" ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst \ | --locals | --local | --loca | --loc | --lo) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* \ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) localstatedir="$ac_optarg" ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir="$ac_optarg" ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir="$ac_optarg" ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix="$ac_optarg" ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix="$ac_optarg" ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix="$ac_optarg" ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name="$ac_optarg" ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir="$ac_optarg" ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir="$ac_optarg" ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site="$ac_optarg" ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir="$ac_optarg" ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir="$ac_optarg" ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target="$ac_optarg" ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers) echo "configure generated by autoconf version 2.12" exit 0 ;; -with-* | --with-*) ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "with_${ac_package}='$ac_optarg'" ;; -without-* | --without-*) ac_package=`echo $ac_option|sed -e 's/-*without-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` eval "with_${ac_package}=no" ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes="$ac_optarg" ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries="$ac_optarg" ;; -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } ;; *) if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then echo "configure: warning: $ac_option: invalid host type" 1>&2 fi if test "x$nonopt" != xNONE; then { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } fi nonopt="$ac_option" ;; esac done if test -n "$ac_prev"; then { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } fi trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 # File descriptor usage: # 0 standard input # 1 file creation # 2 errors and warnings # 3 some systems may open it to /dev/tty # 4 used on the Kubota Titan # 6 checking for... messages and results # 5 compiler messages saved in config.log if test "$silent" = yes; then exec 6>/dev/null else exec 6>&1 fi exec 5>./config.log echo "\ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. " 1>&5 # Strip out --no-create and --no-recursion so they do not pile up. # Also quote any args containing shell metacharacters. ac_configure_args= for ac_arg do case "$ac_arg" in -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) ac_configure_args="$ac_configure_args '$ac_arg'" ;; *) ac_configure_args="$ac_configure_args $ac_arg" ;; esac done # NLS nuisances. # Only set these to C if already set. These must not be set unconditionally # because not all systems understand e.g. LANG=C (notably SCO). # Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! # Non-C LC_CTYPE values break the ctype check. if test "${LANG+set}" = set; then LANG=C; export LANG; fi if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -rf conftest* confdefs.h # AIX cpp loses on an empty file, so make sure it contains at least a newline. echo > confdefs.h # A filename unique to this package, relative to the directory that # configure is in, which we can look for to find out if srcdir is correct. ac_unique_file=tkTable.c # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then its parent. ac_prog=$0 ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. srcdir=$ac_confdir if test ! -r $srcdir/$ac_unique_file; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r $srcdir/$ac_unique_file; then if test "$ac_srcdir_defaulted" = yes; then { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } else { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } fi fi srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` # Prefer explicitly selected file to automatically selected ones. if test -z "$CONFIG_SITE"; then if test "x$prefix" != xNONE; then CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" else CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi fi for ac_site_file in $CONFIG_SITE; do if test -r "$ac_site_file"; then echo "loading site script $ac_site_file" . "$ac_site_file" fi done if test -r "$cache_file"; then echo "loading cache $cache_file" . $cache_file else echo "creating cache $cache_file" > $cache_file fi ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then ac_n= ac_c=' ' ac_t=' ' else ac_n=-n ac_c= ac_t= fi else ac_n= ac_c='\c' ac_t= fi if test "${prefix}" = "NONE"; then prefix=/usr/local echo "setting prefix to: ${prefix}" fi if test "${exec_prefix}" = "NONE"; then exec_prefix=$prefix echo "setting exec-prefix to: ${exec_prefix}" fi ac_aux_dir= for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do if test -f $ac_dir/install-sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f $ac_dir/install.sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break fi done if test -z "$ac_aux_dir"; then { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } fi ac_config_guess=$ac_aux_dir/config.guess ac_config_sub=$ac_aux_dir/config.sub ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 echo "configure:565: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="${IFS}:" for ac_dir in $PATH; do # Account for people who put trailing slashes in PATH elements. case "$ac_dir/" in /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. for ac_prog in ginstall installbsd scoinst install; do if test -f $ac_dir/$ac_prog; then if test $ac_prog = install && grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. # OSF/1 installbsd also uses dspmsg, but is usable. : else ac_cv_path_install="$ac_dir/$ac_prog -c" break 2 fi fi done ;; esac done IFS="$ac_save_IFS" fi if test "${ac_cv_path_install+set}" = set; then INSTALL="$ac_cv_path_install" else # As a last resort, use the slow shell script. We don't cache a # path for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the path is relative. INSTALL="$ac_install_sh" fi fi echo "$ac_t""$INSTALL" 1>&6 # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' # Check whether --with-tcl or --without-tcl was given. if test "${with_tcl+set}" = set; then withval="$with_tcl" tcl_prefix=$withval else tcl_prefix=${exec_prefix}/lib fi # Check whether --with-tk or --without-tk was given. if test "${with_tk+set}" = set; then withval="$with_tk" tk_prefix=$withval else tk_prefix=${exec_prefix}/lib fi file=${tcl_prefix}/tclConfig.sh . $file file=${tk_prefix}/tkConfig.sh . $file CC=$TCL_CC trap '' 1 2 15 cat > confcache <<\EOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs. It is not useful on other systems. # If it contains results you don't want to keep, you may remove or edit it. # # By default, configure uses ./config.cache as the cache file, # creating it if it does not exist already. You can give configure # the --cache-file=FILE option to use a different cache file; that is # what configure does when it calls configure scripts in # subdirectories, so they share the cache. # Giving --cache-file=/dev/null disables caching, for debugging configure. # config.status only pays attention to the cache file if you give it the # --recheck option to rerun configure. # EOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, don't put newlines in cache variables' values. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. (set) 2>&1 | case `(ac_space=' '; set) 2>&1` in *ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote substitution # turns \\\\ into \\, and sed turns \\ into \). sed -n \ -e "s/'/'\\\\''/g" \ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" ;; *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' ;; esac >> confcache if cmp -s $cache_file confcache; then : else if test -w $cache_file; then echo "updating cache $cache_file" cat confcache > $cache_file else echo "not updating unwritable cache $cache_file" fi fi rm -f confcache trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Any assignment to VPATH causes Sun make to only execute # the first set of double-colon rules, so remove it if not needed. # If there is a colon in the path, we need to keep it. if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' fi trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. cat > conftest.defs <<\EOF s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g s%\[%\\&%g s%\]%\\&%g s%\$%$$%g EOF DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` rm -f conftest.defs # Without the "./", some shells look in PATH for config.status. : ${CONFIG_STATUS=./config.status} echo creating $CONFIG_STATUS rm -f $CONFIG_STATUS cat > $CONFIG_STATUS <<EOF #! /bin/sh # Generated automatically by configure. # Run this file to recreate the current configuration. # This directory was configured as follows, # on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # # $0 $ac_configure_args # # Compiler output produced by configure, useful for debugging # configure, is in ./config.log if it exists. ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" for ac_option do case "\$ac_option" in -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; -version | --version | --versio | --versi | --vers | --ver | --ve | --v) echo "$CONFIG_STATUS generated by autoconf version 2.12" exit 0 ;; -help | --help | --hel | --he | --h) echo "\$ac_cs_usage"; exit 0 ;; *) echo "\$ac_cs_usage"; exit 1 ;; esac done ac_given_srcdir=$srcdir ac_given_INSTALL="$INSTALL" trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 EOF cat >> $CONFIG_STATUS <<EOF # Protect against being on the right side of a sed subst in config.status. sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g; s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF $ac_vpsub $extrasub s%@CFLAGS@%$CFLAGS%g s%@CPPFLAGS@%$CPPFLAGS%g s%@CXXFLAGS@%$CXXFLAGS%g s%@DEFS@%$DEFS%g s%@LDFLAGS@%$LDFLAGS%g s%@LIBS@%$LIBS%g s%@exec_prefix@%$exec_prefix%g s%@prefix@%$prefix%g s%@program_transform_name@%$program_transform_name%g s%@bindir@%$bindir%g s%@sbindir@%$sbindir%g s%@libexecdir@%$libexecdir%g s%@datadir@%$datadir%g s%@sysconfdir@%$sysconfdir%g s%@sharedstatedir@%$sharedstatedir%g s%@localstatedir@%$localstatedir%g s%@libdir@%$libdir%g s%@includedir@%$includedir%g s%@oldincludedir@%$oldincludedir%g s%@infodir@%$infodir%g s%@mandir@%$mandir%g s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g s%@INSTALL_DATA@%$INSTALL_DATA%g s%@CC@%$CC%g s%@INSTALL@%$INSTALL%g s%@TCL_SHLIB_CFLAGS@%$TCL_SHLIB_CFLAGS%g s%@TCL_SHLIB_LD@%$TCL_SHLIB_LD%g s%@TCL_SHLIB_SUFFIX@%$TCL_SHLIB_SUFFIX%g s%@TCL_VERSION@%$TCL_VERSION%g s%@TCL_RANLIB@%$TCL_RANLIB%g s%@TCL_XINCLUDES@%$TCL_XINCLUDES%g s%@TCL_PREFIX@%$TCL_PREFIX%g s%@TCL_EXEC_PREFIX@%$TCL_EXEC_PREFIX%g s%@TCL_CFLAGS@%$TCL_CFLAGS%g s%@TCL_DEFS@%$TCL_DEFS%g s%@TCL_LIB_SPEC@%$TCL_LIB_SPEC%g s%@TCL_LIBS@%$TCL_LIBS%g s%@TCL_LD_FLAGS@%$TCL_LD_FLAGS%g s%@TCL_COMPAT_OBJS@%$TCL_COMPAT_OBJS%g s%@TCL_LD_SEARCH_FLAGS@%$TCL_LD_SEARCH_FLAGS%g s%@TCL_SRC_DIR@%$TCL_SRC_DIR%g s%@TCL_BUILD_LIB_SPEC@%$TCL_BUILD_LIB_SPEC%g s%@TK_VERSION@%$TK_VERSION%g s%@TK_XINCLUDES@%$TK_XINCLUDES%g s%@TK_PREFIX@%$TK_PREFIX%g s%@TK_EXEC_PREFIX@%$TK_EXEC_PREFIX%g s%@TK_DEFS@%$TK_DEFS%g s%@TK_LIBS@%$TK_LIBS%g s%@TK_LIB_SPEC@%$TK_LIB_SPEC%g s%@TK_LD_SEARCH_FLAGS@%$TK_LD_SEARCH_FLAGS%g s%@TK_SRC_DIR@%$TK_SRC_DIR%g s%@TK_BUILD_LIB_SPEC@%$TK_BUILD_LIB_SPEC%g CEOF EOF cat >> $CONFIG_STATUS <<\EOF # Split the substitutions into bite-sized pieces for seds with # small command number limits, like on Digital OSF/1 and HP-UX. ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. ac_file=1 # Number of current file. ac_beg=1 # First line for current file. ac_end=$ac_max_sed_cmds # Line after last line for current file. ac_more_lines=: ac_sed_cmds="" while $ac_more_lines; do if test $ac_beg -gt 1; then sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file else sed "${ac_end}q" conftest.subs > conftest.s$ac_file fi if test ! -s conftest.s$ac_file; then ac_more_lines=false rm -f conftest.s$ac_file else if test -z "$ac_sed_cmds"; then ac_sed_cmds="sed -f conftest.s$ac_file" else ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" fi ac_file=`expr $ac_file + 1` ac_beg=$ac_end ac_end=`expr $ac_end + $ac_max_sed_cmds` fi done if test -z "$ac_sed_cmds"; then ac_sed_cmds=cat fi EOF cat >> $CONFIG_STATUS <<EOF CONFIG_FILES=\${CONFIG_FILES-"Makefile"} EOF cat >> $CONFIG_STATUS <<\EOF for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then # The file is in a subdirectory. test ! -d "$ac_dir" && mkdir "$ac_dir" ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" # A "../" for each directory in $ac_dir_suffix. ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` else ac_dir_suffix= ac_dots= fi case "$ac_given_srcdir" in .) srcdir=. if test -z "$ac_dots"; then top_srcdir=. else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; *) # Relative path. srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" top_srcdir="$ac_dots$ac_given_srcdir" ;; esac case "$ac_given_INSTALL" in [/$]*) INSTALL="$ac_given_INSTALL" ;; *) INSTALL="$ac_dots$ac_given_INSTALL" ;; esac echo creating "$ac_file" rm -f "$ac_file" configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." case "$ac_file" in *Makefile*) ac_comsub="1i\\ # $configure_input" ;; *) ac_comsub= ;; esac ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` sed -e "$ac_comsub s%@configure_input@%$configure_input%g s%@srcdir@%$srcdir%g s%@top_srcdir@%$top_srcdir%g s%@INSTALL@%$INSTALL%g " $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file fi; done rm -f conftest.s* EOF cat >> $CONFIG_STATUS <<EOF EOF cat >> $CONFIG_STATUS <<\EOF exit 0 EOF chmod +x $CONFIG_STATUS rm -fr confdefs* $ac_clean_files test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable/pTk.exc���������������������������������������������������������0000644�0000000�0000000�00000000121�13745605157�017055� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tkAppInit.c tkTableInitScript.h confdefs.h mac_tkTable_prefix.h tkTablePs.c �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/mTk/Tktable/tkTableUtil.c���������������������������������������������������0000644�0000000�0000000�00000024007�13742524721�020211� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * tkTableUtil.c -- * * This module contains utility functions for table widgets. * * Copyright (c) 2000-2002 Jeffrey Hobbs * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tkTableUtil.c,v 1.5 2004/02/08 03:09:46 cerney Exp $ */ #include "tkTable.h" static char * Cmd_GetName _ANSI_ARGS_((const Cmd_Struct *cmds, int val)); static int Cmd_GetValue _ANSI_ARGS_((const Cmd_Struct *cmds, Arg arg)); static void Cmd_GetError _ANSI_ARGS_((Tcl_Interp *interp, const Cmd_Struct *cmds, Arg arg)); /* *-------------------------------------------------------------- * * Table_ClearHashTable -- * This procedure is invoked to clear a STRING_KEY hash table, * freeing the string entries and then deleting the hash table. * The hash table cannot be used after calling this, except to * be freed or reinitialized. * * Results: * Cached info will be lost. * * Side effects: * Can cause redraw. * See the user documentation. * *-------------------------------------------------------------- */ void Table_ClearHashTable(Tcl_HashTable *hashTblPtr) { Tcl_HashEntry *entryPtr; Tcl_HashSearch search; char *value; for (entryPtr = Tcl_FirstHashEntry(hashTblPtr, &search); entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { value = (char *) Tcl_GetHashValue(entryPtr); if (value != NULL) ckfree(value); } Tcl_DeleteHashTable(hashTblPtr); } /* *---------------------------------------------------------------------- * * TableOptionBdSet -- * * This routine configures the borderwidth value for a tag. * * Results: * A standard Tcl result. * * Side effects: * It may adjust the tag struct values of bd[0..4] and borders. * *---------------------------------------------------------------------- */ int TableOptionBdSet(clientData, interp, tkwin, value, widgRec, offset) ClientData clientData; /* Type of struct being set. */ Tcl_Interp *interp; /* Used for reporting errors. */ Tk_Window tkwin; /* Window containing table widget. */ Arg value; /* Value of option. */ char *widgRec; /* Pointer to record for item. */ int offset; /* Offset into item. */ { char **borderStr; int *bordersPtr, *bdPtr; int type = (int) clientData; int result = TCL_OK; int argc; Arg *args; if ((type == BD_TABLE) && (STREQ(Tcl_GetString(value),"") )) { /* * NULL strings aren't allowed for the table global -bd */ Tcl_AppendResult(interp, "borderwidth value may not be empty", (char *) NULL); return TCL_ERROR; } if ((type == BD_TABLE) || (type == BD_TABLE_TAG)) { TableTag *tagPtr = (TableTag *) (widgRec + offset); borderStr = &(tagPtr->borderStr); bordersPtr = &(tagPtr->borders); bdPtr = tagPtr->bd; } else if (type == BD_TABLE_WIN) { TableEmbWindow *tagPtr = (TableEmbWindow *) widgRec; borderStr = &(tagPtr->borderStr); bordersPtr = &(tagPtr->borders); bdPtr = tagPtr->bd; } else { panic("invalid type given to TableOptionBdSet\n"); return TCL_ERROR; /* lint */ } result = Tcl_ListObjGetElements(interp, value, &argc, &args); if (result == TCL_OK) { int i, bd[4]; if (((type == BD_TABLE) && (argc == 0)) || (argc == 3) || (argc > 4)) { Tcl_AppendResult(interp, "1, 2 or 4 values must be specified for borderwidth", (char *) NULL); result = TCL_ERROR; } else { /* * We use the shadow bd array first, in case we have an error * parsing arguments half way through. */ for (i = 0; i < argc; i++) { if (Tk_GetPixels(interp, tkwin, Tcl_GetString(args[i]), &(bd[i])) != TCL_OK) { result = TCL_ERROR; break; } } /* * If everything is OK, store the parsed and given values for * easy retrieval. */ if (result == TCL_OK) { for (i = 0; i < argc; i++) { bdPtr[i] = MAX(0, bd[i]); } if (*borderStr) { ckfree(*borderStr); } if (value) { *borderStr = (char *) ckalloc( strlen( Tcl_GetString(value) ) + 1); strcpy(*borderStr, Tcl_GetString(value)); } else { *borderStr = NULL; } *bordersPtr = argc; } } /*ckfree ((char *) argv);*/ } return result; } /* *---------------------------------------------------------------------- * * TableOptionBdGet -- * * Results: * Value of the -bd option. * * Side effects: * None. * *---------------------------------------------------------------------- */ Arg TableOptionBdGet(clientData, tkwin, widgRec, offset, freeProcPtr) ClientData clientData; /* Type of struct being set. */ Tk_Window tkwin; /* Window containing canvas widget. */ char *widgRec; /* Pointer to record for item. */ int offset; /* Offset into item. */ Tcl_FreeProc **freeProcPtr; /* Pointer to variable to fill in with * information about how to reclaim * storage for return string. */ { register int type = (int) clientData; if (type == BD_TABLE) { return LangStringArg( ((TableTag *) (widgRec + offset))->borderStr); } else if (type == BD_TABLE_TAG) { return LangStringArg( ((TableTag *) widgRec)->borderStr); } else if (type == BD_TABLE_WIN) { return LangStringArg( ((TableEmbWindow *) widgRec)->borderStr); } else { panic("invalid type given to TableOptionBdSet\n"); return NULL; /* lint */ } } /* *---------------------------------------------------------------------- * * TableTagConfigureBd -- * This routine configures the border values based on a tag. * The previous value of the bd string (oldValue) is assumed to * be a valid value for this tag. * * Results: * A standard Tcl result. * * Side effects: * It may adjust the value used by -bd. * *---------------------------------------------------------------------- */ int TableTagConfigureBd(Table *tablePtr, TableTag *tagPtr, Arg oldValue, int nullOK) { int i, argc, result = TCL_OK; Arg *args; /* * First check to see if the value really changed. */ if (strcmp(tagPtr->borderStr ? tagPtr->borderStr : "", Tcl_GetString(oldValue) ? Tcl_GetString(oldValue) : "") == 0) { return TCL_OK; } tagPtr->borders = 0; if (!nullOK && ((tagPtr->borderStr == NULL) || (*(tagPtr->borderStr) == '\0'))) { /* * NULL strings aren't allowed for this tag */ result = TCL_ERROR; } else if (tagPtr->borderStr) { result = Tcl_ListObjGetElements(tablePtr->interp, LangStringArg(tagPtr->borderStr), &argc, &args); if (result == TCL_OK) { if ((!nullOK && (argc == 0)) || (argc == 3) || (argc > 4)) { Tcl_SetResult(tablePtr->interp, "1, 2 or 4 values must be specified to -borderwidth", TCL_STATIC); result = TCL_ERROR; } else { for (i = 0; i < argc; i++) { if (Tk_GetPixels(tablePtr->interp, tablePtr->tkwin, Tcl_GetString(args[i]), &(tagPtr->bd[i])) != TCL_OK) { result = TCL_ERROR; break; } tagPtr->bd[i] = MAX(0, tagPtr->bd[i]); } tagPtr->borders = argc; } /* ckfree ((char *) argv); */ } } if (result != TCL_OK) { if (tagPtr->borderStr) { ckfree ((char *) tagPtr->borderStr); } if (oldValue != NULL) { size_t length = strlen(Tcl_GetString(oldValue)) + 1; /* * We are making the assumption that oldValue is correct. * We have to reparse in case the bad new value had a couple * of correct args before failing on a bad pixel value. */ Tcl_ListObjGetElements(tablePtr->interp, oldValue, &argc, &args); for (i = 0; i < argc; i++) { Tk_GetPixels(tablePtr->interp, tablePtr->tkwin, Tcl_GetString(args[i]), &(tagPtr->bd[i])); } /* ckfree ((char *) argv); */ tagPtr->borders = argc; tagPtr->borderStr = (char *) ckalloc(length); memcpy(tagPtr->borderStr, Tcl_GetString(oldValue), length); } else { tagPtr->borders = 0; tagPtr->borderStr = (char *) NULL; } } return result; } /* *---------------------------------------------------------------------- * * Cmd_OptionSet -- * * * Results: * A standard Tcl result. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Cmd_OptionSet(ClientData clientData, Tcl_Interp *interp, Tk_Window unused, Arg value, char *widgRec, int offset) { Cmd_Struct *p = (Cmd_Struct *)clientData; int mode = Cmd_GetValue(p,value); if (!mode) { Cmd_GetError(interp,p,value); return TCL_ERROR; } *((int*)(widgRec+offset)) = mode; return TCL_OK; } /* *---------------------------------------------------------------------- * * Cmd_OptionGet -- * * * Results: * Value of the option. * * Side effects: * None. * *---------------------------------------------------------------------- */ Arg Cmd_OptionGet(ClientData clientData, Tk_Window unused, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr) { Cmd_Struct *p = (Cmd_Struct *)clientData; int mode = *((int*)(widgRec+offset)); return LangStringArg(Cmd_GetName(p,mode)); } /* * simple Cmd_Struct lookup functions */ char * Cmd_GetName(const Cmd_Struct *cmds, int val) { for(;cmds->name && cmds->name[0];cmds++) { if (cmds->value==val) return cmds->name; } return NULL; } int Cmd_GetValue(const Cmd_Struct *cmds, Arg arg) { unsigned int len = strlen(Tcl_GetString(arg)); for(;cmds->name && cmds->name[0];cmds++) { if (!strncmp(cmds->name, Tcl_GetString(arg), len)) return cmds->value; } return 0; } void Cmd_GetError(Tcl_Interp *interp, const Cmd_Struct *cmds, Arg arg) { int i; char *argstring = Tcl_GetString(arg); Tcl_AppendResult(interp, "bad option \"", argstring, "\" must be ", (char *) 0); for(i=0;cmds->name && cmds->name[0];cmds++,i++) { Tcl_AppendResult(interp, (i?", ":""), cmds->name, (char *) 0); } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/MYMETA.json�����������������������������������������������������������������0000644�0000000�0000000�00000001465�13746047615�015400� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������{ "abstract" : "unknown", "author" : [ "unknown" ], "dynamic_config" : 0, "generated_by" : "ExtUtils::MakeMaker version 7.44, CPAN::Meta::Converter version 2.150010", "license" : [ "unknown" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : 2 }, "name" : "Tk-pTk", "no_index" : { "directory" : [ "t", "inc" ] }, "prereqs" : { "build" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "configure" : { "requires" : { "ExtUtils::MakeMaker" : "0" } } }, "release_status" : "stable", "version" : "1.26", "x_serialization_backend" : "JSON::PP version 4.04" } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/Makefile.PL�����������������������������������������������������������������0000644�0000000�0000000�00000013420�13746047570�015455� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������use Config; use ExtUtils::MakeMaker; use Tk::MMtry qw(try_compile); use Tk::MMutil; if( $tkversion <= 800.022 ){ # Tkversion 800.022 needs the old style LandWidgetArg # instead of the new LangWidgetObj call $define .= ' -DUSE_LANGWIDGETARG'; } # mTk directory to use for munging into the pTk dir. # If Tk804 or greater, use the normal Tktable dir. # If otherwise using the old Tktable800 dir my $mTkDir = 'Tktable'; if( $tkversion < 804.000 ){ print STDERR "### Your Tk version is less than 804. ###\n"; print STDERR "### Ok, Using Tk800.0XX dir 'mTk/Tktable800' ###\n"; $mTkDir = 'Tktable800'; } # Find path to existing pTk include files my $ptkPath = Tk::MMutil::findINC('Tk/pTk/Lang.h'); $ptkPath =~ s/\/Lang.h$//g; Tk::MMutil::TkExtMakefile( 'NAME' => 'Tk::pTk', 'VERSION' => '1.26', 'XS_VERSION'=> '0.9', 'LINKTYPE' => 'static', 'OBJECT' => '$(O_FILES)', macro => { WINARCH => $win_arch }, 'DEFINE' => $define, 'INC' => "$inc -I$ptkPath -I. -Ibitmaps", 'SKIP' => [qw( distclean dist makeaperl xs_o)], 'clean' => {'FILES' => 'libpTk$(LIB_EXT)'} ); sub MY::top_targets { my ($self) = @_; local $_ = $self->MM::top_targets; s/^(\$\(O_FILES\)\s*:.*)$/# Explicit dependancies provided\n# $1/m; return $_; } sub MY::xs_c { ' '; } sub MY::post_initialize { my ($self) = @_; my %mTk; my $dir; my @list = ($mTkDir); print STDERR "Generating Dependencies for $^O, win_arch=$win_arch\n"; foreach $dir (@list) { my %exc; my $src = $self->catdir("mTk",$dir); next unless -d $src; if (open(EXC,$self->catfile($src,"pTk.inc"))) { while (<EXC>) { s/\s+$//s; s/#.*$//; next unless /\S/; $mTk{$_} = $self->catfile($src,$_) unless (exists $mTk{$_}); } close(EXC); } else { opendir(DIR,$src) || die "Cannot open $src:$!"; if (open(EXC,$self->catfile($src,"pTk.exc"))) { while (<EXC>) { s/\s+$//s; s/#.*$//; next unless /\S/; $exc{$_} = 1; if (-f $_) { chmod(0777,$_); unlink($_); warn "Loose $_\n"; } } close(EXC); } else { warn "Cannot open $src/pTk.exc:$!"; } my $file; while (defined($file = readdir(DIR))) { next if $exc{$file}; if ($file =~ /\.[ch]$/) { $mTk{$file} = $self->catfile($src,$file) unless (exists $mTk{$file}); } } closedir(DIR); } } my @loose = (); if (defined($Config{'i_stdlib'}) && try_compile("config/Hstrtoul.c")) { push(@loose,'strtoul.c'); } if (defined($Config{'i_string'}) && try_compile("config/Hstrdup.c")) { push(@loose,'strdup.c'); } if (try_compile("config/Hstrcasecmp.c")) { push(@loose,'strcasecmp.c'); } $self->Tk::MMutil::mTk_CHO(\%mTk,@loose); my %files = (); $files{'windows.h'} = 1 if $win_arch eq 'open32'; my $name; $self->{'dir_targets'} = []; $dir = $self->catdir('$(INST_ARCHLIBDIR)','pTk'); push(@{$self->{'dir_targets'}},$dir); foreach $name ($self->lsdir(".")) { next if ($name =~ /^\./); next unless (-f $name); $files{$name} = 1 if ($name =~ /\.[tm]$/); } foreach $name (sort(@{$self->{H}},keys %files)) { $self->{PM}->{$name} = $self->catfile($dir,$name); } if ($Tk::MMutil::IsWin32 or $win_arch eq 'open32' or $win_arch eq 'pm') {my $ddir = $self->catdir('$(INST_ARCHLIBDIR)','X11'); my $sdir = $self->catdir('mTk','xlib','X11'); push(@{$self->{'dir_targets'}},$ddir); foreach $name ($self->lsdir($sdir)) { next if $name =~ /^\.+$/; my $src = $self->catfile($sdir,$name); next unless -f $src; $self->{PM}->{$src} = $self->catfile($ddir,$name); } } $dir = $self->catdir($dir,"compat"); push(@{$self->{'dir_targets'}},$dir); foreach $name ($self->lsdir("compat")) { next if $name =~ /^\.+$/; my $src = $self->catfile('compat',$name); next unless -f $src; $self->{PM}->{$src} = $self->catfile($dir,$name); } ''; } sub MY::test { q[ test :: @echo 'No tests defined for $(NAME)' ]; } sub MY::post_constants { ' INST_STATIC=libpTk$(LIB_EXT) '; }; sub MY::install { ' install :: all '; } sub MY::dynamic_lib { my $self = shift; "dynamic_lib :: static_lib\n\t".$self->{'NOECHO'}."\$(NOOP)\n" } sub MY::dynamic { my $self = shift; "dynamic :: static\n\t".$self->{'NOECHO'}."\$(NOOP)\n" } sub MY::static { my $self = shift; my $str = $self->MM::static(@_); if ($win_arch eq 'open32' or $win_arch eq 'pm') { $str .= ' static :: dllInit$(LIB_EXT) dllInit$(LIB_EXT): dllMain$(OBJ_EXT) $(AR) $(AR_STATIC_ARGS) $@ dllMain$(OBJ_EXT) && $(RANLIB) $@ '; } return $str; } sub MY::realclean { my $self = shift; my $str = $self->MM::realclean(@_); $str =~ s/(::\s*clean)/$1 mungeclean/; $str .= "\nmungeclean ::\n"; $str .= "\t\$(RM_F) ".join(" \\\n\t",keys %{$self->{'MTK'}})."\n"; return $str; } sub MY::postamble { my $self = shift; my $dep = $self->Tk::MMutil::mTk_postamble; $dep .= $self->dir_target(@{$self->{'dir_targets'}}); # add some additional dir targets - reason currently unknown. Use $(DFSEP) as dir separator or makefile will not find target (target uses $(DFSEP) too). $dep .= "config :: " . join(" \\\n\t",map($_.'$(DFSEP).exists',@{$self->{'dir_targets'}})) . "\n\t".$self->{NOECHO}."\$(NOOP)\n"; $dep . ' '.$self->{NOECHO}.'$(NOOP) '; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/pTk/tkTableUtil.c���������������������������������������������������������������0000444�0000000�0000000�00000024006�13746047614�016072� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * tkTableUtil.c -- * * This module contains utility functions for table widgets. * * Copyright (c) 2000-2002 Jeffrey Hobbs * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tkTableUtil.c,v 1.5 2004/02/08 03:09:46 cerney Exp $ */ #include "tkTable.h" static char * Cmd_GetName _ANSI_ARGS_((const Cmd_Struct *cmds, int val)); static int Cmd_GetValue _ANSI_ARGS_((const Cmd_Struct *cmds, Arg arg)); static void Cmd_GetError _ANSI_ARGS_((Tcl_Interp *interp, const Cmd_Struct *cmds, Arg arg)); /* *-------------------------------------------------------------- * * Table_ClearHashTable -- * This procedure is invoked to clear a STRING_KEY hash table, * freeing the string entries and then deleting the hash table. * The hash table cannot be used after calling this, except to * be freed or reinitialized. * * Results: * Cached info will be lost. * * Side effects: * Can cause redraw. * See the user documentation. * *-------------------------------------------------------------- */ void Table_ClearHashTable(Tcl_HashTable *hashTblPtr) { Tcl_HashEntry *entryPtr; Tcl_HashSearch search; char *value; for (entryPtr = Tcl_FirstHashEntry(hashTblPtr, &search); entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { value = (char *) Tcl_GetHashValue(entryPtr); if (value != NULL) ckfree(value); } Tcl_DeleteHashTable(hashTblPtr); } /* *---------------------------------------------------------------------- * * TableOptionBdSet -- * * This routine configures the borderwidth value for a tag. * * Results: * A standard Tcl result. * * Side effects: * It may adjust the tag struct values of bd[0..4] and borders. * *---------------------------------------------------------------------- */ int TableOptionBdSet(clientData, interp, tkwin, value, widgRec, offset) ClientData clientData; /* Type of struct being set. */ Tcl_Interp *interp; /* Used for reporting errors. */ Tk_Window tkwin; /* Window containing table widget. */ Arg value; /* Value of option. */ char *widgRec; /* Pointer to record for item. */ int offset; /* Offset into item. */ { char **borderStr; int *bordersPtr, *bdPtr; int type = (int) clientData; int result = TCL_OK; int argc; Arg *args; if ((type == BD_TABLE) && (STREQ(Tcl_GetString(value),"") )) { /* * NULL strings aren't allowed for the table global -bd */ Tcl_AppendResult(interp, "borderwidth value may not be empty", NULL); return TCL_ERROR; } if ((type == BD_TABLE) || (type == BD_TABLE_TAG)) { TableTag *tagPtr = (TableTag *) (widgRec + offset); borderStr = &(tagPtr->borderStr); bordersPtr = &(tagPtr->borders); bdPtr = tagPtr->bd; } else if (type == BD_TABLE_WIN) { TableEmbWindow *tagPtr = (TableEmbWindow *) widgRec; borderStr = &(tagPtr->borderStr); bordersPtr = &(tagPtr->borders); bdPtr = tagPtr->bd; } else { Tcl_Panic("invalid type given to TableOptionBdSet\n"); return TCL_ERROR; /* lint */ } result = Tcl_ListObjGetElements(interp, value, &argc, &args); if (result == TCL_OK) { int i, bd[4]; if (((type == BD_TABLE) && (argc == 0)) || (argc == 3) || (argc > 4)) { Tcl_AppendResult(interp, "1, 2 or 4 values must be specified for borderwidth", NULL); result = TCL_ERROR; } else { /* * We use the shadow bd array first, in case we have an error * parsing arguments half way through. */ for (i = 0; i < argc; i++) { if (Tk_GetPixels(interp, tkwin, Tcl_GetString(args[i]), &(bd[i])) != TCL_OK) { result = TCL_ERROR; break; } } /* * If everything is OK, store the parsed and given values for * easy retrieval. */ if (result == TCL_OK) { for (i = 0; i < argc; i++) { bdPtr[i] = MAX(0, bd[i]); } if (*borderStr) { ckfree(*borderStr); } if (value) { *borderStr = (char *) ckalloc( strlen( Tcl_GetString(value) ) + 1); strcpy(*borderStr, Tcl_GetString(value)); } else { *borderStr = NULL; } *bordersPtr = argc; } } /*ckfree ((char *) objv);*/ } return result; } /* *---------------------------------------------------------------------- * * TableOptionBdGet -- * * Results: * Value of the -bd option. * * Side effects: * None. * *---------------------------------------------------------------------- */ Arg TableOptionBdGet(clientData, tkwin, widgRec, offset, freeProcPtr) ClientData clientData; /* Type of struct being set. */ Tk_Window tkwin; /* Window containing canvas widget. */ char *widgRec; /* Pointer to record for item. */ int offset; /* Offset into item. */ Tcl_FreeProc **freeProcPtr; /* Pointer to variable to fill in with * information about how to reclaim * storage for return string. */ { register int type = (int) clientData; if (type == BD_TABLE) { return LangStringArg( ((TableTag *) (widgRec + offset))->borderStr); } else if (type == BD_TABLE_TAG) { return LangStringArg( ((TableTag *) widgRec)->borderStr); } else if (type == BD_TABLE_WIN) { return LangStringArg( ((TableEmbWindow *) widgRec)->borderStr); } else { Tcl_Panic("invalid type given to TableOptionBdSet\n"); return NULL; /* lint */ } } /* *---------------------------------------------------------------------- * * TableTagConfigureBd -- * This routine configures the border values based on a tag. * The previous value of the bd string (oldValue) is assumed to * be a valid value for this tag. * * Results: * A standard Tcl result. * * Side effects: * It may adjust the value used by -bd. * *---------------------------------------------------------------------- */ int TableTagConfigureBd(Table *tablePtr, TableTag *tagPtr, Arg oldValue, int nullOK) { int i, argc, result = TCL_OK; Arg *args; /* * First check to see if the value really changed. */ if (strcmp(tagPtr->borderStr ? tagPtr->borderStr : "", Tcl_GetString(oldValue) ? Tcl_GetString(oldValue) : "") == 0) { return TCL_OK; } tagPtr->borders = 0; if (!nullOK && ((tagPtr->borderStr == NULL) || (*(tagPtr->borderStr) == '\0'))) { /* * NULL strings aren't allowed for this tag */ result = TCL_ERROR; } else if (tagPtr->borderStr) { result = Tcl_ListObjGetElements(tablePtr->interp, LangStringArg(tagPtr->borderStr), &argc, &args); if (result == TCL_OK) { if ((!nullOK && (argc == 0)) || (argc == 3) || (argc > 4)) { Tcl_SetResult(tablePtr->interp, "1, 2 or 4 values must be specified to -borderwidth", TCL_STATIC); result = TCL_ERROR; } else { for (i = 0; i < argc; i++) { if (Tk_GetPixels(tablePtr->interp, tablePtr->tkwin, Tcl_GetString(args[i]), &(tagPtr->bd[i])) != TCL_OK) { result = TCL_ERROR; break; } tagPtr->bd[i] = MAX(0, tagPtr->bd[i]); } tagPtr->borders = argc; } /* ckfree ((char *) objv); */ } } if (result != TCL_OK) { if (tagPtr->borderStr) { ckfree ((char *) tagPtr->borderStr); } if (oldValue != NULL) { size_t length = strlen(Tcl_GetString(oldValue)) + 1; /* * We are making the assumption that oldValue is correct. * We have to reparse in case the bad new value had a couple * of correct args before failing on a bad pixel value. */ Tcl_ListObjGetElements(tablePtr->interp, oldValue, &argc, &args); for (i = 0; i < argc; i++) { Tk_GetPixels(tablePtr->interp, tablePtr->tkwin, Tcl_GetString(args[i]), &(tagPtr->bd[i])); } /* ckfree ((char *) objv); */ tagPtr->borders = argc; tagPtr->borderStr = (char *) ckalloc(length); memcpy(tagPtr->borderStr, Tcl_GetString(oldValue), length); } else { tagPtr->borders = 0; tagPtr->borderStr = NULL; } } return result; } /* *---------------------------------------------------------------------- * * Cmd_OptionSet -- * * * Results: * A standard Tcl result. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Cmd_OptionSet(ClientData clientData, Tcl_Interp *interp, Tk_Window unused, Arg value, char *widgRec, int offset) { Cmd_Struct *p = (Cmd_Struct *)clientData; int mode = Cmd_GetValue(p,value); if (!mode) { Cmd_GetError(interp,p,value); return TCL_ERROR; } *((int*)(widgRec+offset)) = mode; return TCL_OK; } /* *---------------------------------------------------------------------- * * Cmd_OptionGet -- * * * Results: * Value of the option. * * Side effects: * None. * *---------------------------------------------------------------------- */ Arg Cmd_OptionGet(ClientData clientData, Tk_Window unused, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr) { Cmd_Struct *p = (Cmd_Struct *)clientData; int mode = *((int*)(widgRec+offset)); return LangStringArg(Cmd_GetName(p,mode)); } /* * simple Cmd_Struct lookup functions */ char * Cmd_GetName(const Cmd_Struct *cmds, int val) { for(;cmds->name && cmds->name[0];cmds++) { if (cmds->value==val) return cmds->name; } return NULL; } int Cmd_GetValue(const Cmd_Struct *cmds, Arg arg) { unsigned int len = strlen(Tcl_GetString(arg)); for(;cmds->name && cmds->name[0];cmds++) { if (!strncmp(cmds->name, Tcl_GetString(arg), len)) return cmds->value; } return 0; } void Cmd_GetError(Tcl_Interp *interp, const Cmd_Struct *cmds, Arg arg) { int i; char *argstring = Tcl_GetString(arg); Tcl_AppendResult(interp, "bad option \"", argstring, "\" must be ", (char *) 0); for(i=0;cmds->name && cmds->name[0];cmds++,i++) { Tcl_AppendResult(interp, (i?", ":""), cmds->name, (char *) 0); } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/debug.bat�����������������������������������������������������������������������0000755�0000000�0000000�00000000645�13742524721�014525� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������@perl -Sx %0.bat %* @goto end_of_perl #!perl -w my $perl = $^X; $perl .= '.exe' unless $perl =~ /\.exe$/i; unless (-x $^X) { my $leaf = $perl; foreach my $dir (split(/;/,$ENV{'Path'})) { my $try = "$dir/$leaf"; if (-x $try) { $perl = $try; $perl =~ tr,\\,/,; last; } } } print join(' ',$perl,$0,@ARGV),"\n"; system("gdb $perl"); __END__ :end_of_perl�������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/TableMatrix.xs������������������������������������������������������������������0000644�0000000�0000000�00000001723�13745605157�015540� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� #define PERL_NO_GET_CONTEXT #include <EXTERN.h> #include <perl.h> #include <XSUB.h> #undef MAX #undef MIN #include "tkGlue.def" #include "pTk/tkPort.h" #include "pTk/tkTable.h" #include "pTk/tkInt.h" #include "pTk/tixPort.h" #include "pTk/tixInt.h" #include "tkGlue.h" #include "tkGlue.m" #include "pTk/tkVMacro.h" /* perltk TableMatrix's replacement for TCL_unsetVar. deletes an element in a hash */ EXTERN void tkTableUnsetElement _ANSI_ARGS_((Var hashEntry, char * key)){ int len; dTHX; len = strlen(key); hv_delete( (HV*) hashEntry, key, len, G_DISCARD); } DECLARE_VTABLES; MODULE = Tk::TableMatrix PACKAGE = Tk PROTOTYPES: DISABLE #ifdef TK800XSTK void tablematrix(...) CODE: { XSRETURN(XSTkCommand(cv,(Tcl_CmdProc *)Tk_TableObjCmd,items,&ST(0))); } #else void tablematrix(...) CODE: { XSRETURN(XSTkCommand(cv,1,Tk_TableObjCmd,items,&ST(0))); } #endif BOOT: { IMPORT_VTABLES; } ���������������������������������������������Tk-TableMatrix-1.26/demos/��������������������������������������������������������������������������0000755�0000000�0000000�00000000000�13746050164�014045� 5����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/demos/tagMerge������������������������������������������������������������������0000644�0000000�0000000�00000001772�13742524721�015533� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Script show tag merging behavior with an option set in the # option database. # # Should display with one row hightlighted red and a cell in the row left-justified use Tk; use Tk::TableMatrix; use strict; my $mw = MainWindow->new; #$mw->optionAdd('*background', 'blue', 'interactive'); $mw->optionAdd('*tablematrix*background', 'skyblue'); my $table = $mw->TableMatrix(-rows => 5, -cols => 8, -cache => 1, #-bg => 'blue', ); $table->pack(-expand => 1, -fill => 'both'); $table->tagConfigure("invalid", -background => 'red'); $table->tagConfigure("left", -anchor => 'w'); foreach my $row (0..4) { #$table->tagRow('invalid', $row); # swap foreach my $column (0..7) { $table->set("$row,$column", "hello"); #$table->tagCell('left', "$row,$column"); # swap } } $table->tagCell('left', '2,3'); $table->tagRow('invalid', 2); MainLoop; ������Tk-TableMatrix-1.26/demos/TableMatrixTest�����������������������������������������������������������0000644�0000000�0000000�00000001733�13745605157�017057� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� use Tk; use Tk::TableMatrix; use Data::Dumper qw( DumperX); my $top = MainWindow->new; my $arrayVar = {}; foreach my $row (0..20){ foreach my $col (0..10){ $arrayVar->{"$row,$col"} = "r$row, c$col"; } } my $t = $top->Scrolled('TableMatrix', -rows => 21, -cols => 11, -width => 6, -height => 6, -titlerows => 1, -titlecols => 1, -variable => $arrayVar, -selectmode => 'extended', -resizeborders => 'both', -titlerows => 1, -titlecols => 1, -bg => 'white', # -state => 'disabled' # -colseparator => "\t", # -rowseparator => "\n" ); $t->tagConfigure('active', -bg => 'gray90', -relief => 'sunken'); $t->tagConfigure( 'title', -bg => 'gray85', -fg => 'black', -relief => 'sunken'); # $t->bind("<Any-Enter>", sub { $t->focus }); $t->pack(-expand => 1, -fill => 'both'); Tk::MainLoop; �������������������������������������Tk-TableMatrix-1.26/demos/tagMerge2�����������������������������������������������������������������0000644�0000000�0000000�00000002637�13742524721�015616� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Script show tag merging behavior with an option set in the # option database. # # Should display with one row hightlighted red and a cell in the row left-justified use Tk; use Tk::TableMatrix; use strict; my $mw = MainWindow->new; #$mw->optionAdd('*background', 'blue', 'interactive'); $mw->optionAdd('*tablematrix*background', 'skyblue'); my $table = $mw->TableMatrix(-rows => 5, -cols => 8, -cache => 1, #-bg => 'blue', ); $table->pack(-expand => 1, -fill => 'both'); foreach my $row (0..4) { #$table->tagRow('invalid', $row); # swap foreach my $column (0..7) { $table->set("$row,$column", "hello"); #$table->tagCell('left', "$row,$column"); # swap } } # 'invalid' tag takes priority of 'left' tag, because it is created first, # so the cell 2,3 should be red and center anchored, but see below... $table->tagConfigure("invalid", -background => 'red', -anchor => 'center'); $table->tagConfigure("left", -background => 'green', -anchor => 'w'); $table->tagCell('left', '2,3'); $table->tagRow('invalid', 2); # The tag priority is changed, so the cell 2,3 will be gree and 'w' achored. $table->tagRaise('left', 'invalid'); # This would have the same effect as the above tagRaise #$table->tagLower('invalid', 'left'); MainLoop; �������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/demos/command�������������������������������������������������������������������0000644�0000000�0000000�00000005577�13745605157�015433� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## command.tcl ## ## This demo shows the use of the table widget's -command options ## ## jeff.hobbs@acm.org ## Converted to perl/tk by John Cerney use Tk; use Tk::TableMatrix; my ($rows,$cols) = (10,10); # number of rows/cols my $top = MainWindow->new; # Sub to fill the array variable sub fill{ my ($array,$x,$y) = @_; my ($i,$j); for( $i = -$x; $i<$x; $i++){ for( $j = -$y; $j<$y; $j++){ $array->{"$i,$j"} = "$i x $j"; } } } ## Test out the use of a callback to define tags on rows and columns sub rowSub{ my $row = shift; return "OddRow" if( $row > 0 && $row % 2) } sub colSub{ my $col = shift; return "OddCol" if( $col > 0 && $col%2) ; } sub tblCmd{ my ($array, $set, $row,$col,$val) = @_; # my @args = @_; # print "In Table Command, Args = '".join("', '",@args)."'\n"; my $index = "$row,$col"; if( $set ){ $array->{$index} = $val; } else{ if( defined( $array->{$index})){ return $array->{$index}; } else{ return ''; } } } my $label = $top->Label(-text => "TableMatrix -command Example"); # Label the changes with the value of currentTest my $currentText = ''; my $currentLabel = $top->Label(-textvariable => \$currentText); # Entry that changes with the value of activeText my $activeText = ''; my $activeEntry = $top->Entry(-textvariable => \$activeText); my $arrayVar = {}; fill($arrayVar, $rows,$cols); # fill up the array variable my $t = $top->Scrolled('TableMatrix', -rows => $rows, -cols => $cols, -width => 6, -height => 6, -titlerows => 1, -titlecols => 2, -command => [\&tblCmd, $arrayVar], -roworigin => -1, -colorigin => -2, -rowtagcommand => \&rowSub, -coltagcommand => \&colSub, -selectmode => 'extended', -flashmode => 'on', -variable => $arrayVar, ); $t->configure( -browsecommand => sub{ my ($index) = @_; $currentText = $index; $activeText = $t->get($index); }); $t->configure( -validate => 1, -validatecommand => sub{ my ($row,$col,$old,$new,$index) = @_; $activeText = $new; return 1; } ); $t->configure( -selectioncommand => sub{ my ($NumRows,$Numcols,$selection,$noCells) = @_; my @args = @_; print "In Selection Command, Args = '".join("', '",@args)."'\n"; return $selection; } ); # hideous Color definitions here: $t->tagConfigure('OddRow', -bg => 'orange', -fg => 'purple'); $t->tagConfigure('OddCol', -bg => 'brown', -fg => 'pink'); $t->colWidth( -2 => 7, -1 => 7, 1=> 5, 2 => 8, 4=> 14); $label->pack( -expand => 1, -fill => 'both'); $currentLabel->pack( -expand => 1, -fill => 'both'); $activeEntry->pack( -expand => 1, -fill => 'both'); $t->pack(-expand => 1, -fill => 'both'); Tk::MainLoop; ���������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/demos/basic���������������������������������������������������������������������0000644�0000000�0000000�00000003117�13745605157�015062� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## basic ## ## This demo shows the basic use of the table widget ## ## jeff.hobbs@acm.org use Tk; use Tk::TableMatrix; use Data::Dumper qw( DumperX); my $top = MainWindow->new; my $arrayVar = {}; foreach my $row (-1..6){ foreach my $col (-2..5){ $arrayVar->{"$row,$col"} = "r$row, c$col"; } } ## Test out the use of a callback to define tags on rows and columns sub rowSub{ my $row = shift; return "OddRow" if( $row > 0 && $row % 2) } sub colSub{ my $col = shift; return "OddCol" if( $col > 0 && $col%2) ; } my $label = $top->Label(-text => "TableMatrix v1 Example"); my $t = $top->Scrolled('TableMatrix', -rows => 8, -cols => 8, -width => 6, -height => 6, -titlerows => 1, -titlecols => 2, -variable => $arrayVar, -roworigin => -1, -colorigin => -2, -rowtagcommand => \&rowSub, -coltagcommand => \&colSub, -colstretchmode => 'last', -rowstretchmode => 'last', -selectmode => 'extended', -sparsearray => 0, ); my $button = $top->Button( -text => "Exit", -command => sub{ $top->destroy}); # hideous Color definitions here: $t->tagConfigure('OddRow', -bg => 'orange', -fg => 'purple'); $t->tagConfigure('OddCol', -bg => 'brown', -fg => 'pink'); $t->colWidth( -2 => 7, -1 => 7, 1=> 5, 2 => 8, 4=> 14); $label->pack( -expand => 1, -fill => 'both'); $t->pack(-expand => 1, -fill => 'both'); $button->pack(-expand => 1, -fill => 'both'); my $variable = $t->cget( -var); Tk::MainLoop; �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/demos/maxsize�������������������������������������������������������������������0000644�0000000�0000000�00000003775�13745605157�015473� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## maxsize.tcl ## ## This demo uses a really big table. The big startup time is in ## filling the table's Tcl array var. ## ## jeff.hobbs@acm.org ## Converted to perl/tk by John Cerney 7/24/00 use Tk; use Tk::TableMatrix; my $top = MainWindow->new; my $arrayVar = {}; print "Filling Array...\n"; my ($rows,$cols) = (40000, 10); foreach my $row (0..($rows-1)){ foreach my $col (0..($cols-1)){ $arrayVar->{"$row,$col"} = "$row,$col"; } } print "Creating Table...\n"; ## Test out the use of a callback to define tags on rows and columns sub colSub{ my $col = shift; return "OddCol" if( $col > 0 && $col%2) ; } my $label = $top->Label(-text => "TableMatrix v2 Example"); my $t = $top->Scrolled('TableMatrix', -rows => $rows, -cols => $cols, -width => 6, -height => 6, -titlerows => 1, -titlecols => 1, -variable => $arrayVar, -coltagcommand => \&colSub, -colstretchmode => 'last', -rowstretchmode => 'last', -selectmode => 'extended', -selecttitles => 0, -drawmode => 'slow', ); my $button = $top->Button( -text => "Exit", -command => sub{ $top->destroy}); # hideous Color definitions here: $t->tagConfigure('OddCol', -bg => 'brown', -fg => 'pink'); $t->tagConfigure('title', -bg => 'red', -fg => 'blue', -relief => 'sunken'); $t->tagConfigure('dis', -state => 'disabled'); my $i = -1; my $first = $t->cget(-colorigin); my $anchor; foreach $anchor( qw/ n s e w nw ne sw se c /){ $t->tagConfigure($anchor, -anchor => $anchor); $t->tagRow($anchor, ++$i); $t->set( "$i,$first",$anchor); } $top->fontCreate('courier', -family => 'courier', -size => 10); $t->tagConfigure('s', -font => 'courier', -justify => 'center'); $t->colWidth( -2 => 8, -1 => 9, 0=> 12, 4=> 14); $label->pack( -expand => 1, -fill => 'both'); $t->pack(-expand => 1, -fill => 'both'); $button->pack(-expand => 1, -fill => 'both'); Tk::MainLoop; ���Tk-TableMatrix-1.26/demos/buttons�������������������������������������������������������������������0000644�0000000�0000000�00000004175�13745605157�015504� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## buttons.tcl ## ## demonstrates the simulation of a button array ## ## ellson@lucent.com ## modifications made by jeff.hobbs@acm.org ## Mdofied by John Cerney for perl/tk use Tk; use Tk::TableMatrix; use Data::Dumper qw( DumperX); my $top = MainWindow->new; my $tab = {}; my ($rows,$cols) = (10,10); # number of rows/cols # create the table my $t = $top->Scrolled('TableMatrix', -rows => $rows, -cols => $cols, -titlerows => 1, -titlecols => 1 , -roworigin => -1, -colorigin => -1 , -colwidth => 4 , -width => 8, -height => 8 , -variable => $tab , -flashmode => 'off', -cursor => 'top_left_arrow' , -borderwidth => 2 , -state => 'disabled' ); $t->pack; # set up tags for the various states of the buttons $t->tagConfigure('OFF', -bg => 'red', -relief => 'raised'); $t->tagConfigure('ON', -bg => 'green', -relief => 'sunken'); $t->tagConfigure('sel', -bg => 'gray75', -relief => 'flat'); # clean up if mouse leaves the widget $t->bind('<FocusOut>',sub{ my $w = shift; $w->selectionClear('all'); }); # highlight the cell under the mouse $t->bind('<Motion>', sub{ my $w = shift; my $Ev = $w->XEvent; if( $w->selectionIncludes('@' . $Ev->x.",".$Ev->y)){ Tk->break; } $w->selectionClear('all'); $w->selectionSet('@' . $Ev->x.",".$Ev->y); Tk->break; ## "break" prevents the call to TableMatrixCheckBorder }); # mousebutton 1 toggles the value of the cell # use of "selection includes" would work here $t->bind('<1>', sub { my $w = shift; $w->focus; my $dude = $w->curselection; my ($rc) = @{$w->curselection}; my $var = $w->cget(-var); if( $var->{$rc} =~ /ON/ ){ $var->{$rc} = 'OFF'; $w->tagCell('OFF',$rc); } else{ $var->{$rc} = 'ON'; $w->tagCell('ON',$rc); } }); # inititialize the array, titles, and celltags for( $i = 0; $i < $rows; $i++){ $tab->{"$i,-1"} = $i; for( $j = 0; $j < $cols; $j++){ unless($i) { $tab->{"-1,$j"}= $j;}; $tab->{"$i,$j"} = "OFF"; $t->tagCell('OFF', "$i,$j"); } } Tk::MainLoop; ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/demos/dynarows������������������������������������������������������������������0000644�0000000�0000000�00000005341�13745605157�015650� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## dynarows.tcl ## ## This demos shows the use of the validation mechanism of the table ## and uses the table's cache (no -command or -variable) with a cute ## dynamic row routine. ## ## jeff.hobbs@acm.org ## Converted to perl/tk by John Cerney use Tk; use Tk::TableMatrix; use Date::Parse; use Date::Format; my $top = MainWindow->new; my $t = $top->Scrolled('TableMatrix', -rows => 2, -cols => 3, -cache => 1, -selecttype => 'row', -titlerows => 1, -titlecols => 1, -height => 5, -autoclear => 1, ); $t->configure( -browsecommand => sub{ my ($index) = @_; my $val = $t->get($index); return unless $val; my ($row,$col) = split(",",$index); ## Entries in the last row are allowed to be empty my $nrows = $t->cget(-rows); if( ($row == ($nrows-1)) && $val eq ''){ return; }; return if( $row == 0 || $col == 0); #don't check the title row/cols my $timenumber; # try to parse date from value in cell $timenumber = str2time($val); if( !$timenumber || !$val){ # not a valid date: print "'$val' is not a valid date\n"; $t->bell; $t->activate($index); $t->selectionClear('all'); $t->selectionSet('active'); $t->see('active'); } else{ # Convert to a common date format my $date; $date = time2str("%m/%d/%Y",$timenumber); $t->set($index,$date); if( $row == ($nrows-1) ){ ## if this is the last row and both cols 1 && 2 are not empty ## then add a row and redo configs if( $t->get("$row,1") ne '' && $t->get("$row,2") ne ''){ $t->tagRow('', $row); $t->set("$row,0", $row); $t->configure( -rows => ++$nrows); $t->tagRow('unset', ++$row); $t->set("$row,0","*"); $t->see("$row,1"); $t->activate("$row,1"); } } } }); $t->set("0,1" => "Begin", "0,2" => 'End', "1,0"=>"*"); # hideous Color definitions here: $t->tagConfigure('unset', -fg => '#008811'); $t->tagConfigure('title', -fg => 'red'); $t->tagRow('unset', 1); $t->colWidth( 0 => 3); my $label = $top->Label(-text => "Dynamic Date Validated Rows"); $label->pack( -expand => 1, -fill => 'both'); $t->pack(-expand => 1, -fill => 'both'); # Bindings: # Make the active area move after we press return: # We Have to use class binding here so that we override # the default return binding $t->bind('Tk::TableMatrix','<Return>', sub{ my $r = $t->index('active', 'row'); my $c = $t->index('active', 'col'); if( $c == 2){ $t->activate(++$r.",1"); } else{ $t->activate("$r,".++$c); } $t->see('active'); Tk->break; }); # Make enter do the same thing as return: $t->bind('<KP_Enter>', $t->bind('<Return>')); Tk::MainLoop; �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/demos/debug���������������������������������������������������������������������0000644�0000000�0000000�00000006431�13745605157�015071� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## version2.tcl ## ## This demo uses most features of the table widget ## ## jeff.hobbs@acm.org ## Converted to perl/tk by John Cerney use Tk; use Tk::TableMatrix; my ($rows,$cols) = (25,20); # number of rows/cols my $top = MainWindow->new; # Sub to fill the array variable sub fill{ my ($array,$x,$y) = @_; my ($i,$j); for( $i = -$x; $i<$x; $i++){ for( $j = -$y; $j<$y; $j++){ $array->{"$i,$j"} = "r$i,c$j"; } } } ## Test out the use of a callback to define tags on rows and columns sub colSub{ my $col = shift; return "OddCol" if( $col > 0 && $col%2) ; } my $label = $top->Label(-text => "TableMatrix v2 Example"); my $arrayVar = {}; fill($arrayVar, $rows,$cols); # fill up the array variable my $t = $top->Scrolled('TableMatrix', -rows => $rows, -cols => $cols, -variable => $arrayVar, -width => 6, -height => 8, -titlerows => 1, -titlecols => 2, -roworigin => -5, -colorigin => -2, -coltagcommand => \&colSub, -selectmode => 'extended', -selecttitles => 0, -drawmode => 'single', ); my $button = $top->Button( -text => "Exit", -command => sub{ $top->destroy}); $label->pack( -expand => 1, -fill => 'both'); $t->pack(-expand => 1, -fill => 'both'); $button->pack(-expand => 1, -fill => 'both'); # hideous Color definitions here: $t->tagConfigure('OddCol', -bg => 'brown', -fg => 'pink'); $t->tagConfigure('title', -bg => 'red', -fg => 'blue', -relief => 'sunken'); $t->tagConfigure('dis', -state => 'disabled'); my $i = -1; my $first = $t->cget(-colorigin); my $anchor; foreach $anchor( qw/ n s e w nw ne sw se c /){ $t->tagConfigure($anchor, -anchor => $anchor); $t->tagRow($anchor, ++$i); $t->set( "$i,$first",$anchor); } $top->fontCreate('courier', -family => 'courier', -size => 10); $t->tagConfigure('s', -font => 'courier', -justify => 'center'); # $initWindow->Label(-image => $top->Photo(-file => Tk->findINC('Xcamel.gif')))->pack; my $perltkLogo = $top->Photo(-file => Tk->findINC('Xcamel.gif')); $t->tagConfigure('logo', -image => $perltkLogo, -showtext => 1); $t->tagCell('logo', '1,2', '2,3', '4,1'); $t->tagCell('dis', '2,1', '1,-1', '3,0'); $t->colWidth(qw/ -2 8 -1 9 0 12 4 14/); $t->set( '1,1' => "multi-line\ntext\nmight be\ninteresting" , '3,2' => "more\nmulti-line\nplaying\n" , '2,2' => "null\0byte" ); $i = -1; # This is in the row span my $l = $top->Label(-text => "Window s", -bg => 'yellow'); $t->windowConfigure("6,0", -sticky => 's', -window => $l); # This is in the row titles $l = $top->Label(-text => "Window ne", -bg => 'yellow'); $t->windowConfigure("4,-1", -sticky => 'ne', -window => $l); # This will get swallowed by a span $l = $top->Label(-text => "Window ew", -bg => 'yellow'); $t->windowConfigure("5,3", -sticky => 'ew', -window => $l); # This is in the col titles $l = $top->Label(-text => "Window nsew", -bg => 'yellow'); $t->windowConfigure("-5,1", -sticky => 'nsew', -window => $l); $l = $t->parent->Label(-text => "Sibling l", -bg => 'orange'); $t->windowConfigure("5,1", -sticky => 'nsew', -window => $l); $t->spans( '-1,-2' => '0,3', '1,2' => '0,5','3,2' => '2,2', '6,0' => '4,0'); Tk::MainLoop; ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/demos/SpreadsheetHideRows�������������������������������������������������������0000644�0000000�0000000�00000005630�13745605157�017717� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Example of Tk::TableMatrix::SpreadsheetHideRows widget: # Table display with hidden detail data # # This example displays made-up average temperature data # for different time periods (quarter and months), and regions. # Updated to have more spans. 3/8/06. Fully expanding Row 2 and the # lower level Rows should look ok, with the spans restoring back # to where they were. use Tk; use Tk::TableMatrix::SpreadsheetHideRows; my $top = MainWindow->new; my $arrayVar = {}; my @rawdata = (qw/ Quarter Month Region State AvgTemp 1 -- South -- 39 2 -- South -- 61 3 -- South -- 65 4 -- South -- 45 /); foreach my $row (0..4){ foreach my $col (0..5){ next if( $col == 0); $arrayVar->{"$row,$col"} = shift @rawdata; } } my $expandData = { 1 => { data => [ [ '','','Jan', 'South','--',33], [ '','','Feb', 'South','--',38], [ '','','Mar', 'South','--',45], ], tag => 'detail', expandData => { 1 => { data => [ [ '','','', '','Texas',35], [ '','','', '','Ok',36], [ '','','', '','Ark',37], ], tag => 'detail2', }, 2 => { data => [ [ '','','', '','Texas',41], [ '','','', '','Ok',42], [ '','','', '','Ark',43], ], tag => 'detail2', }, 3 => { data => [ [ '','','', '','Texas',51], [ '','','', '','Ok',52], [ '','','', '','Ark',53], ], tag => 'detail2', }, }, }, 2 => { data => [ [ '','','Apr', 'South','--',55], [ '','','May', 'South','--',61], [ '','','Jun', 'South','--',68], ], tag => 'detail', spans => [ 1 => '0,1'], expandData => { 2 => { data => [ [ '','','', '','Texas',58], [ '','','', '','Ok',65], [ '','','', '','Ark',60], ], tag => 'detail2', } } }, 4 => { data => [['','Sorry, Detail Data Not Available Until Next month']], tag => 'detail', spans => [ 1 => '0,3'] }, }; my $t = $top->Scrolled('SpreadsheetHideRows', -rows => 5, -cols => 6, -width => 6, -height => 6, -titlerows => 1, -titlecols => 1, -variable => $arrayVar, -selectmode => 'extended', -resizeborders => 'both', -selectorCol => 0, -expandData => $expandData # -state => 'disabled' # -colseparator => "\t", # -rowseparator => "\n" ); # Tags for the detail data: $t->tagConfigure('detail', -bg => 'palegreen', -relief => 'sunken'); $t->tagConfigure('detail2', -bg => 'lightskyblue1', -relief => 'sunken'); $t->pack(-expand => 1, -fill => 'both'); Tk::MainLoop; ��������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/demos/edit_styles.pl������������������������������������������������������������0000644�0000000�0000000�00000017566�13745605157�016760� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## edit_styles.pl ## ## demonstrates different edit styles within cells ## ## ewaldhei@idd.com ## This script uses tags and some logic to simulate check ## buttons, browseEntries, etc in cells. This approach is ## faster than using embedded windows, especially for large ## tables. use Tk; use Tk::TableMatrix; main(); sub main { my $top = MainWindow->new; my $_data = {}; my ($rows,$cols) = (12,7); # number of rows/cols # create the table my $t = $top->Scrolled (TableMatrix => -rows => $rows, -cols => $cols, -titlerows => 1, -titlecols => 1, -width => 8, -height => 8 , -colwidth => 11, -variable => $_data, -cursor => 'top_left_arrow' , -borderwidth => 2 , -ipadx => 15, -scrollbars => 'se', )->pack(qw/-expand 1 -fill both/); my $tm = $t->Subwidget('scrolled'); $tm->{columneditstyles} = {qw(1 readonly 2 editable 3 button 4 optionmenu 5 browseentry 6 checkbutton )}; # set up tags for the various states of the buttons $t->tagConfigure('OFF', -bg => 'gray60', -relief => 'raised'); $t->tagConfigure('ON', -bg => 'gray80', -relief => 'sunken'); $t->tagConfigure('sel', -bg => 'gray70', -relief => 'flat'); $t->tagConfigure('readonly', -relief => 'groove'); my %images = define_bitmaps($top); $t->tagConfigure('optionmenu', -image => $images{optionmenu}, -anchor => 'e', -showtext => 1, ); $t->tagConfigure('browseentry', -image => $images{browseentry}, -anchor => 'e', -showtext => 1); $t->tagConfigure('checkbutton0', -image => $images{checkbutton0}); $t->tagConfigure('checkbutton1', -image => $images{checkbutton1}); $t->bind('<Key-Escape>' => \&end_edit); # clean up if mouse leaves the widget $t->bind('<FocusOut>',sub { my $w = shift; $w->selectionClear('all'); $w->configure(-state => 'disabled'); }); # highlight the cell under the mouse $t->bind('<Motion>', sub { my $w = shift; my $Ev = $w->XEvent; if( $w->selectionIncludes('@' . $Ev->x.",".$Ev->y)){ Tk->break; } $w->selectionClear('all'); $w->selectionSet('@' . $Ev->x.",".$Ev->y); Tk->break; ## "break" prevents the call to TableMatrixCheckBorder }); # mousebutton 1 edits the cell (or not) appropriately $t->bind('<1>', sub { my ($w) = @_; withdraw_edit_widgets($w); my $Ev = $w->XEvent; my ($x, $y) = ($Ev->x, $Ev->y); my $rc = $w->index("\@$x,$y"); my $var = $w->cget(-var); my ($r, $c) = split(/,/, $rc); $r && $c || return; $w->{_b1_row_col} = "$r,$c"; set_style_state($w); my $style= $w->{columneditstyles}{$c} || 'editable'; if ($style eq 'optionmenu' || $style eq 'browseentry') { setup_toplevel_lbox($w, $r, $c); } elsif ($style eq 'button') { my $newval = $var->{$rc} =~ /ON/ ? 'OFF' : 'ON'; $var->{$rc} = $newval; $w->tagCell($newval, $rc); } elsif ($style eq 'checkbutton') { $var->{$rc} = !$var->{$rc}; my $tag = $var->{$rc} ? 'checkbutton1' : 'checkbutton0'; $w->tagCell($tag, $rc); } }); # replace std b1-release $t->bind('Tk::TableMatrix' => '<ButtonRelease-1>', \&set_style_state); # inititialize the array, titles, and celltags for (my $r = 0; $r < $rows; $r++) { for (my $c = 0; $c < $cols; $c++) { my $rc = "$r,$c"; if (!$r || !$c) { $_data->{$rc} = $r || $tm->{columneditstyles}{$c} || ""; } else { $_data->{$rc} = $rc; my $style = $tm->{columneditstyles}{$c} || 'editable'; if ($style eq 'readonly') { $t->tagCell('readonly', $rc); } if ($style eq 'optionmenu') { $_data->{$rc} = "$r options"; $t->tagCell('optionmenu', $rc); } elsif ($style eq 'browseentry') { $_data->{$rc} = "browse$r"; $t->tagCell('browseentry', $rc); } elsif ($style eq 'button') { $_data->{$rc} = $r % 4 ? 'ON' : 'OFF'; $t->tagCell($_data->{$rc}, $rc); } elsif ($style eq 'checkbutton') { $_data->{$rc} = $r % 3 ? 0 : 1; $t->tagCell('checkbutton' . $_data->{$rc}, $rc); } } } } Tk::MainLoop; } sub set_style_state { my ($w) = @_; my ($r, $c) = split(/,/, $w->{_b1_row_col}); if (grep(!$w->{columneditstyles}{$c} || $_ eq $w->{columneditstyles}{$c}, qw(optionmenu readonly button checkbutton))) { $w->selectionClear('all'); $w->configure(state => 'disabled'); } else { $w->configure(state => 'normal'); $w->activate($w->{_b1_row_col}); } } sub end_edit { my ($w) = @_; $w->configure(-state => 'disabled'); $w->selectionClear('all'); } sub setup_toplevel_lbox { my ($w, $r, $c) = @_; my $toplevel = $w->{toplevel} ||= $w->Toplevel(-bd => 2, -relief => 'raised'); my $lbox = $toplevel->{lbox}; $lbox->destroy() if $lbox; $toplevel->overrideredirect(1); my @options = map(chr(ord('A') + $_ - 1) x $_, 1..$r); my $height = @options > 8 ? 8 : (@options || 1); my $width = 2; foreach (@options) { $width = length($_) if length($_) > $width; } $lbox = $toplevel->{lbox} = $toplevel->Scrolled (Listbox => -height => $height, -width => $width + 1, -relief => 'raised', -borderwidth => 1, -highlightthickness => 0, -bg => $w->cget('bg'), -scrollbars => 'oe', )->pack(-side => 'left'); $lbox->Subwidget('scrolled')->{_table_matrix} = $w; $lbox->delete(0, 'end'); $lbox->insert(0, @options); my ($gx, $gy) = ($w->rootx(), $w->rooty()); my @bbox = $w->bbox("$r,$c"); my ($mx, $my) = (int($gx + $bbox[0] + $bbox[2]), int($gy + $bbox[1])); my $toplevel_ypixels = $height * $bbox[3] + $toplevel->cget("-bd") * 2 + $toplevel->cget("-highlightthickness"); my $y2 = $my + $toplevel_ypixels; $my = $w->vrootheight - $toplevel_ypixels if ($y2 > $w->vrootheight); $toplevel->transient($w->toplevel()); $toplevel->geometry("+$mx+$my"); $toplevel->deiconify(); $toplevel->raise(); $lbox->bind('<ButtonRelease-1>', sub { my ($lbox) = @_; my $i = $lbox->curselection(); my $val = $lbox->get($i); my $w = delete $lbox->{_table_matrix}; my $rc = delete $w->{_b1_row_col}; my $var = $w->cget(-var); $var->{$rc} = $val; $w->set($rc => $val); $w->selectionClear('all'); $w->configure(-state => 'disabled'); withdraw_edit_widgets($w); } ); } sub withdraw_edit_widgets { my ($w) = @_; my $toplevel = $w->{toplevel}; if ($toplevel && $toplevel->state eq 'normal') { $toplevel->withdraw(); } } #-------------------------------------------------------------- sub define_bitmaps { my ($w) = @_; my $optionmenu = ' /* XPM */ static char * xpm[] = { "11 5 3 1", " c None", "+ c #D0D0D0", "@ c #555555", "+++++++++++", "++++++++++@", "++ @@", "++@@@@@@@@@", "+@@@@@@@@@@"}; '; my $browseentry = ' /* XPM */ static char * xpm[] = { "11 7 3 1", " c None", "+ c #D0D0D0", "@ c #555555", "+++++++++++", "++++++++++@", "+++ @@@", " +++ @@@ ", " +++ @@@ ", " ++@@@ ", " @@@ ", }; '; my $cbutton0 = ' /* XPM */ static char * xpm[] = { "9 8 3 1", " c None", "@ c #B8B8B8", "+ c #555555", "+++++++++", "++++++++@", "++ @@", "++ @@", "++ @@", "++ @@", "++@@@@@@@", "+@@@@@@@@"}; }; '; my $cbutton1 = ' /* XPM */ static char * xpm[] = { "9 8 4 1", " c None", "@ c #B8B8B8", "+ c #555555", ". c #FF0000", "+++++++++", "++++++++@", "++.....@@", "++.....@@", "++.....@@", "++.....@@", "++@@@@@@@", "+@@@@@@@@"}; }; '; my %images; $images{optionmenu} = $w->Pixmap('optionmenu', -data => $optionmenu); $images{browseentry} = $w->Pixmap('browseentry', -data => $browseentry); $images{checkbutton0} = $w->Pixmap('cbutton0', -data => $cbutton0); $images{checkbutton1} = $w->Pixmap('cbutton1', -data => $cbutton1); %images; } ������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/demos/TableMatrixSpreadsheetTest������������������������������������������������0000644�0000000�0000000�00000001700�13745605157�021241� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� use Tk; use Tk::TableMatrix::Spreadsheet; use Data::Dumper qw( DumperX); my $top = MainWindow->new; my $arrayVar = {}; foreach my $row (0..20){ foreach my $col (0..10){ $arrayVar->{"$row,$col"} = "r$row, c$col"; } } print "Got Here \n"; my $t = $top->Scrolled('Spreadsheet', -rows => 21, -cols => 11, -width => 6, -height => 6, -titlerows => 1, -titlecols => 1, -variable => $arrayVar, -selectmode => 'extended', -titlerows => 1, -titlecols => 1, # -state => 'disabled' # -colseparator => "\t", # -rowseparator => "\n" ); #$t->tagConfigure('active', -bg => 'gray90', -relief => 'sunken'); #$t->tagConfigure( 'title', -bg => 'gray85', -fg => 'black', -relief => 'sunken'); # $t->bind("<Any-Enter>", sub { $t->focus }); $t->pack(-expand => 1, -fill => 'both'); Tk::MainLoop; ����������������������������������������������������������������Tk-TableMatrix-1.26/demos/spreadsheet���������������������������������������������������������������0000644�0000000�0000000�00000006633�13745605157�016316� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## spreadsheet.tcl ## ## This demos shows how you can simulate a 3D table ## and has other basic features to begin a basic spreadsheet ## ## jeff.hobbs@acm.org ## Converted to perl/tk by John Cerney use Tk; use Tk::TableMatrix; my ($rows,$cols) = (10,10); # number of rows/cols my $page = 'AA'; my $oldPage = ''; my $tableColors = { default => 'pink',AA => 'orange', BB => 'blue', CC => 'green'}; my $top = MainWindow->new; sub colorize{ my ($num) = @_; return 'colored' if( $num > 0 && $num%2); return ''; } # Sub to fill the array variable sub fill{ my ($name, $array,$r,$c) = @_; my ($i,$j); $r ||= $rows; $c ||= $cols; for( $i = 0; $i<$r; $i++){ for( $j = 0; $j<$c; $j++){ if( $j && $i){ $array->{"$i,$j"} = "$name $i,$j"; } elsif( $i ){ $array->{"$i,$j"} = "$i"; } elsif( $j ){ $array->{"$i,$j"} = sprintf("%c",($j+64)); } } } } my $arrayVar = { AA => {}, BB => {}, CC => {}}; fill('AA',$arrayVar->{AA}, $rows,$cols); # fill up the array variable fill('BB',$arrayVar->{BB}, $rows/2,$cols/2); # fill up the array variable my $t = $top->Scrolled('TableMatrix', -rows => $rows, -cols => $cols, -width => 5, -height => 5, -titlerows => 1, -titlecols => 1, -coltagcommand => \&colorize, -selectmode => 'extended', -flashmode => 'on', -variable => $arrayVar->{$page}, ); my $label = $top->Label(-text => "TableMatrix vs Spreadsheet Example"); # Label the changes with the value of currentTest my $currentText = ''; my $currentLabel = $top->Label(-textvariable => \$currentText); # Entry that changes with the value of activeText my $activeText = ''; my $activeEntry = $top->Entry(-textvariable => \$activeText); my $pageLabel = $top->Label(-text => 'PAGE:', -width => 6, -anchor => 'e'); my $pageSelect = $top->Optionmenu( -options => [ qw/ AA BB CC/], -variable => \$page, -command => [ \&changepage]); sub changepage{ my ($newPage) = @_; if( $newPage ne $oldPage){ $t->selectionClear('all'); $t->activate(''); # unactivate anything $t->configure(-variable => $arrayVar->{$newPage}); # $e config -textvar ${i}(active) $t->activate('origin'); if( exists $tableColors->{$newPage}){ $t->tagConfigure('colored', -bg => $tableColors->{$newPage}); } else{ $t->tagConfigure('colored', -bg => $tableColors->{'default'}); } $t->see('active'); $oldPage = $newPage; } } $t->configure( -browsecommand => sub{ my ($oldindex,$index) = @_; $currentText = $index; $activeText = $t->get($index); }); # hideous Color definitions here: $t->tagConfigure('colored', -bg => $tableColors->{$page}); $t->tagConfigure('title', -fg => 'red', -relief => 'groove'); $t->tagConfigure('blue', -bg => 'blue'); $t->tagConfigure('green', -bg => 'green'); $t->tagCell('green', '6,3','5,7','4,9'); $t->tagCell('blue', '8,8'); $t->tagRow('blue', 7); $t->tagCol('blue', 6,8); $t->colWidth( 0 => 3, 2 => 7); $label->grid( '-', '-', '-', '-', '-sticky' => 'ew'); $currentLabel->grid( $currentLabel, $activeEntry, $pageLabel, $pageSelect, '-', '-sticky' => 'ew'); $t->grid( '-', '-', '-', '-', '-sticky' => 'nsew'); $top->gridColumnconfigure(1, -weight => 1); $top->gridRowconfigure(2, -weight => 1); Tk::MainLoop; �����������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/demos/embeddedWindows.pl��������������������������������������������������������0000644�0000000�0000000�00000003614�13742524721�017513� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������########## ### Demo of using embedded windows in TableMatrix ### This works well, but can be slow for very large tables with many ### windows. ### ### See edit_styles.pl for an alternative that is faster for larger ### tables use Tk; use Tk::BrowseEntry; use Tk::TableMatrix; use Data::Dumper qw( DumperX); my $top = MainWindow->new; my $arrayVar = {}; foreach my $row (0..20){ foreach my $col (0..10){ $arrayVar->{"$row,$col"} = "r$row, c$col"; } } my $t = $top->Scrolled('TableMatrix', -rows => 21, -cols => 11, -width => 6, -height => 6, -titlerows => 1, -titlecols => 1, -variable => $arrayVar, -selectmode => 'extended', -resizeborders => 'both', -titlerows => 1, -titlecols => 1, -bg => 'white', # -state => 'disabled' # -colseparator => "\t", # -rowseparator => "\n" ); $t->tagConfigure('active', -bg => 'gray90', -relief => 'sunken'); $t->tagConfigure( 'title', -bg => 'gray85', -fg => 'black', -relief => 'sunken'); ################ Put in some embedded windows ################ my $l = $top->Checkbutton(-text => 'CheckButton'); $t->windowConfigure("3,3", -sticky => 's', -window => $l); my $c = $top->BrowseEntry(-label => "Month:"); $c->insert("end", "January"); $c->insert("end", "February"); $c->insert("end", "March"); $c->insert("end", "April"); $c->insert("end", "May"); $c->insert("end", "June"); $c->insert("end", "July"); $c->insert("end", "August"); $c->insert("end", "September"); $c->insert("end", "October"); $c->insert("end", "November"); $c->insert("end", "December"); $t->windowConfigure("2,2", -sticky => 'ne', -window => $c); # Leave enough room for the windows $t->colWidth(2,20); $t->colWidth(3,20); $t->pack(-expand => 1, -fill => 'both'); Tk::MainLoop; ��������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/demos/tagBorderWidth������������������������������������������������������������0000644�0000000�0000000�00000002266�13742524721�016710� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Script show the new multi-number borderwidth option for tags # Borderwidth can be specified as a space separated list of # 4 numbers representing left right top bottom borders drawn in a cell # # In this example, the tag'ed row will have a large top/bottom border, and a normal # size left/right border use Tk; use Tk::TableMatrix; use strict; my $mw = MainWindow->new; #$mw->optionAdd('*background', 'blue', 'interactive'); $mw->optionAdd('*tablematrix*background', 'skyblue'); my $table = $mw->TableMatrix(-rows => 5, -cols => 8, -cache => 1, #-bg => 'blue', ); $table->pack(-expand => 1, -fill => 'both'); $table->tagConfigure("invalid", -background => 'red', -relief => 'raised', -bd => '1 1 5 5'); $table->tagConfigure("left", -anchor => 'w'); foreach my $row (0..4) { #$table->tagRow('invalid', $row); # swap foreach my $column (0..7) { $table->set("$row,$column", "hello"); #$table->tagCell('left', "$row,$column"); # swap } } $table->tagCell('left', '2,3'); $table->tagRow('invalid', 2); MainLoop; ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/META.json�����������������������������������������������������������������������0000644�0000000�0000000�00000002305�13746047633�014366� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������{ "abstract" : "Tk::tkTable - a Spreadsheet/Table Widget", "author" : [ "jcerney@home.com (John Cerney)" ], "dynamic_config" : 1, "generated_by" : "ExtUtils::MakeMaker version 7.44, CPAN::Meta::Converter version 2.150010", "license" : [ "unknown" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : 2 }, "name" : "Tk-TableMatrix", "no_index" : { "directory" : [ "t", "inc" ] }, "prereqs" : { "build" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "configure" : { "requires" : { "ExtUtils::MakeMaker" : "6.52", "Tk::MMtry" : "0", "Tk::MMutil" : "0" } }, "runtime" : { "requires" : { "Tk" : "800.022" } } }, "release_status" : "stable", "resources" : { "repository" : { "type" : "git", "url" : "https://github.com/asb-capfan/Tk-TableMatrix.git", "web" : "https://github.com/asb-capfan/Tk-TableMatrix" } }, "version" : "1.26", "x_serialization_backend" : "JSON::PP version 4.04" } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/MANIFEST������������������������������������������������������������������������0000644�0000000�0000000�00000005467�13746047633�014112� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ChangeLog Changes COPYING debug debug.bat demos/basic demos/buttons demos/command demos/debug demos/dynarows demos/edit_styles.pl demos/embeddedWindows.pl demos/maxsize demos/spreadsheet demos/SpreadsheetHideRows demos/TableMatrixSpreadsheetTest demos/TableMatrixTest demos/tagBorderWidth demos/tagMerge demos/tagMerge2 Makefile.PL MANIFEST This list of files myConfig pod/Makefile.PL pod/MYMETA.json pod/MYMETA.yml pod/TableMatrix.pod pTk/chext pTk/counts pTk/defs pTk/fakeld pTk/findcore pTk/findstrings pTk/findX pTk/from pTk/genexc pTk/license.html_lib pTk/license.terms pTk/makeenglish pTk/Makefile.PL pTk/mkmethods pTk/mkneed pTk/mkXinfo pTk/mm.h pTk/mTk/license.terms pTk/mTk/README pTk/mTk/Tktable/confdefs.h pTk/mTk/Tktable/config.cache pTk/mTk/Tktable/config.log pTk/mTk/Tktable/configure pTk/mTk/Tktable/configure.in pTk/mTk/Tktable/mac_tkTable.mcp pTk/mTk/Tktable/mac_tkTable.r pTk/mTk/Tktable/mac_tkTable_prefix.h pTk/mTk/Tktable/Makefile.in pTk/mTk/Tktable/makefile.vc pTk/mTk/Tktable/mm.h pTk/mTk/Tktable/perlPort.pod pTk/mTk/Tktable/pTk.exc pTk/mTk/Tktable/tkAppInit.c pTk/mTk/Tktable/tkTable.c pTk/mTk/Tktable/tkTable.h pTk/mTk/Tktable/tkTableCell.c pTk/mTk/Tktable/tkTableCellSort.c pTk/mTk/Tktable/tkTableCmds.c pTk/mTk/Tktable/tkTableEdit.c pTk/mTk/Tktable/tkTableInitScript.h pTk/mTk/Tktable/tkTablePs.c pTk/mTk/Tktable/tkTableTag.c pTk/mTk/Tktable/tkTableUtil.c pTk/mTk/Tktable/tkTableversion.h pTk/mTk/Tktable/tkTableWin.c pTk/mTk/Tktable/version.h pTk/mTk/Tktable800/confdefs.h pTk/mTk/Tktable800/config.cache pTk/mTk/Tktable800/config.log pTk/mTk/Tktable800/configure pTk/mTk/Tktable800/configure.in pTk/mTk/Tktable800/mac_tkTable.mcp pTk/mTk/Tktable800/mac_tkTable.r pTk/mTk/Tktable800/mac_tkTable_prefix.h pTk/mTk/Tktable800/Makefile.in pTk/mTk/Tktable800/makefile.vc pTk/mTk/Tktable800/mm.h pTk/mTk/Tktable800/pTk.exc pTk/mTk/Tktable800/tkAppInit.c pTk/mTk/Tktable800/tkTable.c pTk/mTk/Tktable800/tkTable.h pTk/mTk/Tktable800/tkTableCell.c pTk/mTk/Tktable800/tkTableCellSort.c pTk/mTk/Tktable800/tkTableCmds.c pTk/mTk/Tktable800/tkTableEdit.c pTk/mTk/Tktable800/tkTableInitScript.h pTk/mTk/Tktable800/tkTablePs.c pTk/mTk/Tktable800/tkTableTag.c pTk/mTk/Tktable800/tkTableUtil.c pTk/mTk/Tktable800/tkTableversion.h pTk/mTk/Tktable800/tkTableWin.c pTk/mTk/Tktable800/version.h pTk/MYMETA.json pTk/MYMETA.yml pTk/p4e pTk/process_object pTk/refs pTk/Tcl-pTk pTk/tdiff pTk/tkTable.c pTk/tkTable.h pTk/tkTableCell.c pTk/tkTableCellSort.c pTk/tkTableCmds.c pTk/tkTableEdit.c pTk/tkTableTag.c pTk/tkTableUtil.c pTk/tkTableversion.h pTk/tkTableWin.c pTk/version.h pTk/why README t/create.t TableMatrix.pm TableMatrix.xs TableMatrix/Spreadsheet.pm TableMatrix/SpreadsheetHideRows.pm META.yml Module YAML meta-data (added by MakeMaker) META.json Module JSON meta-data (added by MakeMaker) ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/TableMatrix.pm������������������������������������������������������������������0000644�0000000�0000000�00000066365�13746047570�015537� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This file converted to perltk using the tcl2perl script and much hand-editing. # jc 6/26/00 # # table.tcl -- # # version align with tkTable 2.7, jeff.hobbs@acm.org # This file defines the default bindings for Tk table widgets # and provides procedures that help in implementing those bindings. # #-------------------------------------------------------------------------- # tkPriv elements used in this file: # # afterId - Token returned by "after" for autoscanning. # tablePrev - The last element to be selected or deselected # during a selection operation. # mouseMoved - Boolean to indicate whether mouse moved while # the button was pressed. # borderInfo - Boolean to know if the user clicked on a border # borderB1 - Boolean that set whether B1 can be used for the # interactiving resizing #-------------------------------------------------------------------------- ## Interactive cell resizing, affected by -resizeborders option ## package Tk::TableMatrix; use AutoLoader; use Carp; use strict; use vars( '%tkPriv', '$VERSION'); $VERSION = '1.26'; use Tk qw( Ev ); use base qw(Tk::Widget); Construct Tk::Widget 'TableMatrix'; bootstrap Tk::TableMatrix; sub Tk_cmd { \&Tk::tablematrix }; sub Tk::Widget::ScrlTableMatrix { shift->Scrolled('TableMatrix' => @_) } Tk::Methods("activate", "bbox", "border", "cget", "clear", "configure", "curselection", "curvalue", "delete", "get", "rowHeight", "hidden", "icursor", "index", "insert", "postscript", "reread", "scan", "see", "selection", "set", "spans", "tag", "validate", "version", "window", "colWidth", "xview", "yview"); use Tk::Submethods ( 'border' => [qw(mark dragto)], 'clear' => [qw(cache sizes tags all)], 'delete' => [qw(active cols rows)], 'insert' => [qw(active cols rows)], 'scan' => [qw(mark dragto)], 'selection'=> [qw(anchor clear includes set)], 'tag' => [qw(cell cget col configure delete exists includes names row raise lower)], 'window' => [qw(cget configure delete move names)], 'xview' => [qw(moveto scroll)], 'yview' => [qw(moveto scroll)], ); sub ClassInit { my ($class,$mw) = @_; $tkPriv{borderB1} = 1; # initialize borderB1 $mw->bind($class,'<3>', sub { my $w = shift; my $Ev = $w->XEvent; ## You might want to check for cell returned if you want to ## restrict the resizing of certain cells $w->border('mark',$Ev->x,$Ev->y); } ); $mw->bind($class,'<B3-Motion>',['border','dragto',Ev('x'),Ev('y')]); $mw->bind($class,'<1>', sub { my $w = shift; my $Ev = $w->XEvent; $w->Button1($Ev->x,$Ev->y); } ); $mw->bind($class,'<B1-Motion>', sub { my $w = shift; my $Ev = $w->XEvent; $w->B1Motion($Ev->x,$Ev->y); } ); $mw->bind($class,'<ButtonRelease-1>', sub { my $w = shift; my $Ev = $w->XEvent; $tkPriv{borderInfo} = ""; if ($w->exists) { $w->CancelRepeat; $w->activate('@' . $Ev->x.",".$Ev->y); } } ); $mw->bind($class,'<Shift-1>', sub { my $w = shift; my $Ev = $w->XEvent; $w->BeginExtend( $w->index('@' . $Ev->x.",".$Ev->y)); } ); $mw->bind($class,'<Control-1>', sub { my $w = shift; my $Ev = $w->XEvent; $w->BeginToggle($w->index('@' . $Ev->x.",".$Ev->y)); } ); $mw->bind($class,'<B1-Enter>','CancelRepeat'); $mw->bind($class,'<B1-Leave>', sub { my $w = shift; my $Ev = $w->XEvent; if( !$tkPriv{borderInfo} ){ $tkPriv{x} = $Ev->x; $tkPriv{y} = $Ev->y; $w->AutoScan; } } ); $mw->bind($class,'<2>', sub { my $w = shift; my $Ev = $w->XEvent; $w->scan('mark',$Ev->x,$Ev->y); $tkPriv{x} = $Ev->x; $tkPriv{y} = $Ev->y; $tkPriv{'mouseMoved'} = 0; } ); $mw->bind($class,'<B2-Motion>', sub { my $w = shift; my $Ev = $w->XEvent; $tkPriv{'mouseMoved'} = 1 if ($Ev->x ne $tkPriv{'x'} || $Ev->y ne $tkPriv{'y'}); $w->scan('dragto',$Ev->x,$Ev->y) if ($tkPriv{'mouseMoved'}); } ); $mw->bind($class,'<ButtonRelease-2>', sub { my $w = shift; my $Ev = $w->XEvent; $w->Paste($w->index('@' . $Ev->x.",".$Ev->y)) unless ($tkPriv{'mouseMoved'}); } ); ClipboardKeysyms( $mw, $class, qw/ <Copy> <Cut> <Paste> /); ClipboardKeysyms( $mw, $class, 'Control-c', 'Control-x', 'Control-v'); ############################ $mw->bind($class,'<<Table_Commit>>', sub { my $w = shift; my $Ev = $w->XEvent; eval { $w->activate('active'); } ; } ); # Remove this if you don't want cell commit to occur on every Leave for # the table (via mouse) or FocusOut (loss of focus by table). $mw->eventAdd( qw[ <<Table_Commit>> <Leave> <FocusOut> ]); $mw->bind($class,'<Shift-Up>',['ExtendSelect',-1,0]); $mw->bind($class,'<Shift-Down>',['ExtendSelect',1,0]); $mw->bind($class,'<Shift-Left>',['ExtendSelect',0,-1]); $mw->bind($class,'<Shift-Right>',['ExtendSelect',0,1]); $mw->bind($class,'<Prior>', sub { my $w = shift; my $Ev = $w->XEvent; $w->yview('scroll',-1,'pages'); $w->activate('@0,0'); } ); $mw->bind($class,'<Next>', sub { my $w = shift; my $Ev = $w->XEvent; $w->yview('scroll',1,'pages'); $w->activate('@0,0'); } ); $mw->bind($class,'<Control-Prior>',['xview','scroll',-1,'pages']); $mw->bind($class,'<Control-Next>',['xview','scroll',1,'pages']); $mw->bind($class,'<Home>',['see','origin']); $mw->bind($class,'<End>',['see','end']); $mw->bind($class,'<Control-Home>', sub { my $w = shift; my $Ev = $w->XEvent; $w->selection('clear','all'); $w->activate('origin'); $w->selection('set','active'); $w->see('active'); } ); $mw->bind($class,'<Control-End>', sub { my $w = shift; my $Ev = $w->XEvent; $w->selection('clear','all'); $w->activate('end'); $w->selection('set','active'); $w->see('active'); } ); $mw->bind($class,'<Shift-Control-Home>',['DataExtend','origin']); $mw->bind($class,'<Shift-Control-End>',['DataExtend','end']); $mw->bind($class,'<Select>',['BeginSelect',Ev('index','active')]); $mw->bind($class,'<Shift-Select>',['BeginExtend',Ev('index','active')]); $mw->bind($class,'<Control-slash>','SelectAll'); $mw->bind($class,'<Control-backslash>', sub { my $w = shift; my $Ev = $w->XEvent; $w->selection('clear','all') if ($w->cget(-selectmode) =~ /browse/); } ); $mw->bind($class,'<Up>',['MoveCell',-1,0]); $mw->bind($class,'<Down>',['MoveCell',1,0]); $mw->bind($class,'<Left>',['MoveCell',0,-1]); $mw->bind($class,'<Right>',['MoveCell',0,1]); $mw->bind($class,'<KeyPress>',['TableInsert',Ev('A')]); $mw->bind($class,'<BackSpace>',['BackSpace']); $mw->bind($class,'<Delete>',['delete','active','insert']); $mw->bind($class,'<Escape>','reread'); $mw->bind($class,'<Return>',['TableInsert',"\n"]); $mw->bind($class,'<Control-Left>', sub { my $w = shift; my $Ev = $w->XEvent; my $posn = $w->icursor; $w->icursor($posn - 1); } ); $mw->bind($class,'<Control-Right>', sub { my $w = shift; my $Ev = $w->XEvent; my $posn = $w->icursor; $w->icursor($posn + 1); } ); $mw->bind($class,'<Control-e>',['icursor','end']); $mw->bind($class,'<Control-a>',['icursor',0]); $mw->bind($class,'<Control-k>',['delete','active','insert','end']); $mw->bind($class,'<Control-equal>',['ChangeWidth','active',1]); $mw->bind($class,'<Control-minus>',['ChangeWidth','active',-1]); # Ignore all Alt, Meta, and Control keypresses unless explicitly bound. # Otherwise, if a widget binding for one of these is defined, the # <KeyPress> class binding will also fire and insert the character, # which is wrong. Ditto for Tab. $mw->bind($class,'<Alt-KeyPress>', sub { my $w = shift; my $Ev = $w->XEvent; # nothing } ); $mw->bind($class,'<Meta-KeyPress>', sub { my $w = shift; my $Ev = $w->XEvent; # nothing } ); $mw->bind($class,'<Control-KeyPress>', sub { my $w = shift; my $Ev = $w->XEvent; # } ); $mw->bind($class,'<Any-Tab>', sub { my $w = shift; my $Ev = $w->XEvent; # } ); } # ::tk::table::GetSelection -- # This tries to obtain the default selection. On Unix, we first try # and get a UTF8_STRING, a type supported by modern Unix apps for # passing Unicode data safely. We fall back on the default STRING # type otherwise. On Windows, only the STRING type is necessary. # Arguments: # w The widget for which the selection will be retrieved. # Important for the -displayof property. # sel The source of the selection (PRIMARY or CLIPBOARD) # Results: # Returns the selection, or an error if none could be found # sub GetSelection{ my $w = shift; my $sel = shift; $sel ||= 'PRIMARY'; my $txt; if( $Tk::platform eq 'unix'){ eval{ $txt = $w->SelectionGet( -selection => $sel) }; if( $@){ warn("Could not find default selection\n"); return undef; } return $txt; } else{ eval{ $txt = $w->SelectionGet( -selection => $sel) }; if( $@){ warn("Could not find default selection\n"); return undef; } return $txt; } } # ClipboardKeysyms -- # This procedure is invoked to identify the keys that correspond to # the "copy", "cut", and "paste" functions for the clipboard. # # Arguments: # copy - Name of the key (keysym name plus modifiers, if any, # such as "Meta-y") used for the copy operation. # cut - Name of the key used for the cut operation. # paste - Name of the key used for the paste operation. sub ClipboardKeysyms { my $mw = shift; my $class = shift; my $copy = shift; my $cut = shift; my $paste = shift; $mw->bind($class,"<$copy>",'Copy'); $mw->bind($class,"<$cut>",'Cut'); $mw->bind($class,"<$paste>",'Paste'); } # TableInsert -- # # Insert into the active cell # # Arguments: # w - the table widget # s - the string to insert # Results: # Returns nothing # sub TableInsert { my $w = shift; my $s = shift; $w->insert('active','insert',$s) if ($s ne '' ) ; } # ::tk::table::BackSpace -- # # BackSpace in the current cell # # Arguments: # w - the table widget # Results: # Returns nothing # sub BackSpace{ my $w = shift; my $Ev = $w->XEvent; my $posn = $w->icursor; $w->delete('active',$posn - 1) if( $posn > -1); } # Button1 -- # # This procedure is called to handle selecting with mouse button 1. # It will distinguish whether to start selection or mark a border. # # Arguments: # w - the table widget # x - x coord # y - y coord # Results: # Returns nothing # sub Button1 { my $w = shift; my ( $x, $y ) = @_; # borderInfo is null if the user did not click on a border if ( $tkPriv{borderB1} == 1 ) { $tkPriv{borderInfo} = $w->borderMark( $x, $y ); } else { $tkPriv{borderInfo} = ""; } if ( ! $tkPriv{borderInfo} ) { # # Only do this when a border wasn't selected # if ( $w->exists ) { $w->BeginSelect( $w->index( '@' . "$x,$y" ) ); $w->focus; } $tkPriv{x} = $x; $tkPriv{y} = $y; $tkPriv{mouseMoved} = 0; } } # B1Motion -- # # This procedure is called to start processing mouse motion events while # button 1 moves while pressed. It will distinguish whether to change # the selection or move a border. # # Arguments: # w - the table widget # x - x coord # y - y coord # Results: # Returns nothing # sub B1Motion { my $w = shift; my ( $x, $y ) = @_; # If we already had motion, or we moved more than 1 pixel, # then we start the Motion routine if ( $tkPriv{borderInfo} ) { # # If the motion is on a border, drag it and skip the rest # of this binding. # $w->borderDragto( $x, $y ); } else { # # If we already had motion, or we moved more than 1 pixel, # then we start the Motion routine # if ( $tkPriv{mouseMoved} || abs( $x - $tkPriv{x} ) > 1 || abs( $y - $tkPriv{y} ) > 1 ) { $tkPriv{mouseMoved} = 1; } if ( $tkPriv{mouseMoved} ) { $w->Motion( $w->index( '@' . "$x,$y" ) ); } } } # BeginSelect -- # # This procedure is typically invoked on button-1 presses. It begins # the process of making a selection in the table. Its exact behavior # depends on the selection mode currently in effect for the table; # see the Motif documentation for details. # # Arguments: # w - The table widget. # el - The element for the selection operation (typically the # one under the pointer). Must be in row,col form. sub BeginSelect { my $w = shift; my $el = shift; my $r; my $c; my $inc; my $el2; return unless( scalar( ($r,$c) = split(",",$el)) ==2); # Get Rol Col or return my $selectmode = $w->cget('-selectmode'); if ($selectmode eq 'multiple') { if ($w->tag('includes','title',$el)) { ## in the title area if ($r < ($w->cget('-titlerows') + $w->cget('-roworigin')) ) { ## We're in a column header if ($c < ( $w->cget('-titlecols') + $w->cget('-colorigin'))) { ## We're in the topleft title area $inc = 'topleft'; $el2 = 'end'; } else { $inc = $w->index('topleft','row').",$c"; $el2 = $w->index('end','row').",$c"; } } else { ## We're in a row header $inc = "$r,".$w->index('topleft','col'); $el2 = "$r,".$w->index('end','col'); } } else { $inc = $el; $el2 = $el; } if ($w->selection('includes',$inc)) { $w->selection('clear',$el,$el2); } else { $w->selection('set',$el,$el2); } } elsif ($selectmode eq 'extended') { $w->selection('clear','all'); if ($w->tag('includes','title',$el)) { if ($r < ($w->cget('-titlerows') + $w->cget('-roworigin'))) { ## We're in a column header if ($c < ( $w->cget('-titlecols') + $w->cget('-colorigin')) ) { $w->selection('set',$el,'end'); } else { $w->selection('set',$el,$w->index('end','row').",$c"); } } else { ## We're in a row header $w->selection('set',$el,"$r,".$w->index('end','col')); } } else { $w->selection('set',$el); } $w->selection('anchor',$el); $tkPriv{'tablePrev'} = $el; } elsif ($selectmode eq 'default') { unless ($w->tag('includes','title',$el)) { $w->selection('clear','all'); $w->selection('set',$el); $tkPriv{'tablePrev'} = $el; } $w->selection('anchor',$el); } } # Motion -- # # This procedure is called to process mouse motion events while # button 1 is down. It may move or extend the selection, depending # on the table's selection mode. # # Arguments: # w - The table widget. # el - The element under the pointer (must be in row,col form). sub Motion { my $w = shift; my $el = shift; my $r; my $c; my $elc; my $elr; unless (exists($tkPriv{'tablePrev'})) { $tkPriv{'tablePrev'} = $el; return; } return if ($tkPriv{'tablePrev'} eq $el ); my $selectmode = $w->cget('-selectmode'); if ($selectmode eq 'browse') { $w->selection('clear','all'); $w->selection('set',$el); $tkPriv{'tablePrev'} = $el; } elsif ($selectmode eq 'extended') { # avoid tables that have no anchor index yet. my $indexAnchor; eval{ $indexAnchor = $w->index('anchor') }; return if( $@ || !$indexAnchor); ($r,$c) = split(",",$tkPriv{tablePrev}); ($elr,$elc) = split(",",$el); if ($w->tag('includes','title',$el)) { if ($r < ($w->cget('-titlerows') + $w->cget('-roworigin')) ) { ## We're in a column header if ($c < ( $w->cget('-titlecols') + $w->cget('-colorigin')) ) { ## We're in the topleft title area $w->selection('clear','anchor','end'); } else { $w->selection('clear','anchor',$w->index('end','row').",$c"); } ##### perltk: Removed comma $w->selection('set','anchor',$w->index('end','row').",$elc"); } else { ## We're in a row header $w->selection('clear','anchor',"$r,".$w->index('end','col')); $w->selection('set','anchor',"$elr,".$w->index('end','col')); } } else { $w->selection('clear','anchor',$tkPriv{'tablePrev'}); $w->selection('set','anchor',$el); } $tkPriv{'tablePrev'} = $el; } } # BeginExtend -- # # This procedure is typically invoked on shift-button-1 presses. It # begins the process of extending a selection in the table. Its # exact behavior depends on the selection mode currently in effect # for the table; see the Motif documentation for details. # # Arguments: # w - The table widget. # el - The element for the selection operation (typically the # one under the pointer). Must be in numerical form. sub BeginExtend { my $w = shift; my $el = shift; $w->Motion($el) if ($w->cget(-selectmode) eq 'extended' && $w->selectionIncludes('anchor')); } # BeginToggle -- # # This procedure is typically invoked on control-button-1 presses. It # begins the process of toggling a selection in the table. Its # exact behavior depends on the selection mode currently in effect # for the table; see the Motif documentation for details. # # Arguments: # w - The table widget. # el - The element for the selection operation (typically the # one under the pointer). Must be in numerical form. sub BeginToggle { my $w = shift; my $el = shift; my $r; my $c; my $end; if ( $w->cget( -selectmode ) =~ /extended/i ) { $tkPriv{'tablePrev'} = $el; $w->selection('anchor',$el); if ($w->tag('includes','title',$el)) { # scan $el %d,%d r c ($r,$c) = split( ",",$el); if ($r < ($w->cget('-titlerows') + $w->cget('-roworigin')) ) { ## We're in a column header if ($c < ($w->cget('-titlecols') + $w->cget('-colorigin'))) { ## We're in the topleft title area $end = 'end'; } else { $end = $w->index('end','row'); } } else { ## We're in a row header $end = "$r,".$w->index('end','row'); } } else { ## We're in a non-title cell $end = $el; } if ($w->selection('includes',$end)) { $w->selection('clear',$el,$end); } else { $w->selection('set',$el,$end); } } } # AutoScan -- # This procedure is invoked when the mouse leaves an table window # with button 1 down. It scrolls the window up, down, left, or # right, depending on where the mouse left the window, and reschedules # itself as an "after" command so that the window continues to scroll until # the mouse moves back into the window or the mouse button is released. # # Arguments: # w - The table window. sub AutoScan { my $w = shift; my $x; my $y; return unless ($w->exists); $x = $tkPriv{'x'}; $y = $tkPriv{'y'}; if ($y >= $w->SUPER::height) # we don't want our height here, we want the # actual height of the window { $w->yview('scroll',1,'units'); } elsif ($y < 0) { $w->yview('scroll',-1,'units'); } elsif ($x >= $w->SUPER::width) { $w->xview('scroll',1,'units'); } elsif ($x < 0) { $w->xview('scroll',-1,'units'); } else { return; } $w->Motion($w->index('@' . $x.','.$y)); $tkPriv{'afterId'} = $w->after(50,[$w,'AutoScan']); } # MoveCell -- # # Moves the location cursor (active element) by the specified number # of cells and changes the selection if we're in browse or extended # selection mode. If the new cell is "hidden", we skip to the next # visible cell if possible, otherwise just abort. # # Arguments: # w - The table widget. # x - +1 to move down one cell, -1 to move up one cell. # y - +1 to move right one cell, -1 to move left one cell. sub MoveCell { my $w = shift; my $x = shift; my $y = shift; my $c; my $cell; my $r; my $true; eval { $r = $w->index('active','row') }; return if( $@); $c = $w->index('active','col'); # set cell [$w index [incr r $x],[incr c $y]] $cell = $w->index(($r += $x).",".($c += $y)); while ( ($true = $w->index('active')) eq '') { # The cell is in some way hidden if ($true eq $w->index('active')) { # The span cell wasn't the previous cell, so go to that $cell = $true; last; } if ($x > 0) { ++ $r; } elsif ($x < 0) { $r += -1; } if ($y > 0) { ++ $c; } elsif ($y < 0) { $c += -1; } if ($cell eq $w->index($r.",".$c)) { $cell = $w->index("$r,$c"); } else { # We couldn't find a non-hidden cell, just don't move return; } } $w->activate($cell); $w->see('active'); if ($w->cget('-selectmode') eq 'browse') { $w->selection('clear','all'); $w->selection('set','active'); } elsif ($w->cget('-selectmode') eq 'extended') { $w->selection('clear','all'); $w->selection('set','active'); $w->selection('anchor','active'); $tkPriv{'tablePrev'} = $w->index('active'); } } # ExtendSelect -- # # Does nothing unless we're in extended selection mode; in this # case it moves the location cursor (active element) by the specified # number of cells, and extends the selection to that point. # # Arguments: # w - The table widget. # x - +1 to move down one cell, -1 to move up one cell. # y - +1 to move right one cell, -1 to move left one cell. sub ExtendSelect { my $w = shift; my $x = shift; my $y = shift; my $c; my $r; #### Perltk notes: (should be 'ne' instead of 'eq' ??? return unless ( $w->cget(-selectmode) eq 'extended'); eval { $r = $w->index('active','row'); }; return if($@); $c = $w->index('active','col'); $w->activate( ($r += $x).",".($c += $y)); $w->see('active'); $w->Motion($w->index('active')); } # DataExtend # # This procedure is called for key-presses such as Shift-KEndData. # If the selection mode isnt multiple or extend then it does nothing. # Otherwise it moves the active element to el and, if we're in # extended mode, extends the selection to that point. # # Arguments: # w - The table widget. # el - An integer cell number. sub DataExtend { my $w = shift; my $el = shift; my $mode; $mode = $w->cget('-selectmode'); if ($mode =~ /extended/i ) { $w->activate($el); $w->see($el); $w->Motion($el) if ($w->selection('includes','anchor')); } elsif ($mode =~ /multiple/i) { $w->activate($el); $w->see($el); } } # SelectAll # # This procedure is invoked to handle the "select all" operation. # For single and browse mode, it just selects the active element. # Otherwise it selects everything in the widget. # # Arguments: # w - The table widget. sub SelectAll { my $w = shift; if ( $w->cget(-selectmode) =~ /^(single|browse)$/) { $w->selection('clear','all'); $w->selection('set','active'); $w->TableMatrixHandleType($w->index('active')); } else { $w->selection('set','origin','end'); } } # ChangeWidth -- # Adjust the widget of the specified cell by $a. # # Arguments: # w - The table widget. # i - cell index # a - amount to adjust by sub ChangeWidth { my $w = shift; my $i = shift; my $a = shift; my $tmp; my $width; $tmp = $w->index($i,'col'); if (($width = $w->colWidth($tmp)) >= 0) { $w->colWidth($tmp,$width += $a); } else { $w->colWidth($tmp,$width += -$a); } } # Copy -- # This procedure copies the selection from a table widget into the # clipboard. # # Arguments: # w - Name of a table widget. sub Copy { my $w = shift; if ($w->SelectionOwner() eq $w) { $w->clipboardClear; eval { $w->clipboardAppend($w->GetSelection); } ; } } # Cut -- # This procedure copies the selection from a table widget into the # clipboard, then deletes the selection (if it exists in the given # widget). # # Arguments: # w - Name of a table widget. sub Cut { my $w = shift; if ($w->SelectionOwner() eq $w) { $w->clipboardClear; eval { $w->clipboardAppend($w->GetSelection); $w->curselection('');# Clear whatever is selected $w->selectionClear(); } ; } } # Paste -- # This procedure pastes the contents of the clipboard to the specified # cell (active by default) in a table widget. # # Arguments: # w - Name of a table widget. # cell - Cell to start pasting in. sub Paste { my $w = shift; my $cell = shift || ''; ## Perltk not sure if translated correctly my $data; if ($cell ne '') { eval{ $data = $w->GetSelection(); }; return if($@); } else { eval{ $data = $w->GetSelection('CLIPBOARD'); }; return if($@); $cell = 'active'; } $w->PasteHandler($w->index($cell),$data); $w->focus if ($w->cget('-state') eq 'normal'); } # PasteHandler -- # This procedure handles how data is pasted into the table widget. # This handles data in the default table selection form. # NOTE: this allows pasting into all cells, even those with -state disabled # # Arguments: # w - Name of a table widget. # cell - Cell to start pasting in. sub PasteHandler { my $w = shift; my $cell = shift; my $data = shift; # # Don't allow pasting into the title cells # return if( $w->tagIncludes('title', $cell)); my $rows; my $cols; my $r; my $c; my $rsep; my $csep; my $row; my $line; my $col; my $item; $rows = $w->cget('-rows') - $w->cget('-roworigin'); $cols = $w->cget('-cols') - $w->cget('-colorigin'); $r = $w->index($cell,'row'); $c = $w->index($cell,'col'); $rsep = $w->cget('-rowseparator'); $csep = $w->cget('-colseparator'); ## Assume separate rows are split by row separator if specified ## If you were to want multi-character row separators, you would need: # regsub -all $rsep $data <newline> data # set data [join $data <newline>] my @data; @data = split($rsep,$data) if ($rsep ne ''); $row = $r; foreach $line (@data) { last if ($row > $rows); $col = $c; ## Assume separate cols are split by col separator if specified ## Unless a -separator was specified my @line = split($csep, $line) if ($csep ne ''); ## If you were to want multi-character col separators, you would need: # regsub -all $csep $line <newline> line # set line [join $line <newline>] foreach $item (@line) { last if ($col > $cols); $w->set("$row,$col",$item); ++ $col; } ++ $row; } } ############################################################# ## CancelRepeat # This procedure is invoked to cancel an auto-repeat action described # by $Tk::TableMatrix::tkPriv{afterId}. It's used by several widgets to auto-scroll # the widget when the mouse is dragged out of the widget with a # button pressed. sub CancelRepeat{ my $w = shift; my $id = delete $tkPriv{'afterId'}; $w->afterCancel($id) if($id); } 1; __END__ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/COPYING�������������������������������������������������������������������������0000644�0000000�0000000�00000002154�13745605157�014002� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Copyright (c) 2000-2002 John Cerney. All rights reserved. This package is free software; you can redistribute it and/or modify it under the same terms as Perl itself, with the exception of the files in the pTk sub-directory which have separate terms derived from those of the original Tk4.0 sources and/or TkTable. IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. See pTk/license.terms for details of this Tk license, and the source code in pTk/mTk/Tktable for the TkTable license. ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/README��������������������������������������������������������������������������0000644�0000000�0000000�00000006635�13745605157�013637� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * This is a port of the tcl/tk Tktable Widget version 2.8 to perl/tk */ ************************************* The Tk::TableMatrix Widget ************************************* INTRODUCTION Tk::TableMatrix is a table/matrix widget extension to perl/tk for displaying data in a table (or spreadsheet) format. The basic features of the widget are: * multi-line cells * support for embedded windows (one per cell) * row & column spanning * variable width columns / height rows (interactively resizable) * row and column titles * multiple data sources ((perl hash|| perl callback) &| internal caching) * supports standard Tk reliefs, fonts, colors, etc. * x/y scrollbar support * 'tag' styles per row, column or cell to change visual appearance * in-cell editing - returns value back to data source * support for disabled (read-only) tables or cells (via tags) * multiple selection modes, with "active" cell * multiple drawing modes to get optimal performance for larger tables * optional 'flashes' when things update * cell validation support * Works everywhere Tk does (including Windows and Mac!) (Note perltk version has only been tested on Solaris, Linux, win98/NT/mingw32 as of 11/12/02) FINDING THE WIDGET The Section TBD BUILDING AND INSTALLING THE WIDGET 1. Uncompress and unpack the distribution ON UNIX: gzip -d Tk-TableMatrix<version>.tar.gz tar -xf Tk-TableMatrix<version>.tar ON WINDOWS: use something like WinZip to unpack the archive. This will create a subdirectory TableMatrix<version> with all the files in it. 2. Build/Test perl Makefile.PL make make test There are also some demos in the demo directory: perl -Mblib demos/TableMatrixTest perl -Mblib demos/spreadsheet . . etc. 3. Install make install 4. Read the documentation The tcl/tk html documentation has been translated to TableMatrix.pod. You can read it using the standard 'perldoc Tk::TableMatrix' command. THINGS TO WATCH OUT FOR Packing The table tries not to allocate huge chunks of screen real estate if you ask it for a lot of rows and columns. You can always stretch out the frame or explicitly tell it how big it can be. If you want to stretch the table, remember to pack it with fill both and expand on, or with grid, give it -sticky news and configure the grid row and column for some weighting. Array The array (actually a perl hash in the perltk implementation) elements for the table are of the form $array{"2,3"} etc. Make sure there are no spaces around the ','. Negative indices are allowed. Editing If you can't edit, remember that the focus model in tk is explicit, so you need to click on the table or give it the focus command. Just having a selected cell is not the same thing as being able to edit. You also need the editing cursor. If you can't get the cursor, make sure that you actually have a variable assigned to the table, and that the "state" of the cell is not disabled. COMMENTS, BUGS, etc. * Please can you send comments and bug reports to the current maintainer and their best will be done to address them. * If you find a bug, a short piece of Perl Code that exercises it would be very useful, or even better, compile with debugging and specify where it crashed in that short piece of Code. ���������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/Makefile.PL���������������������������������������������������������������������0000644�0000000�0000000�00000011036�13746047570�014720� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������use 5.00404; use Cwd; use Config; no lib '.'; BEGIN { warn("### Note: 'Building Outside of Tk itself' Messages are Expected Here ####\n"); $IsWin32 = ($^O eq 'MSWin32' || $Config{'ccflags'} =~ /-D_?WIN32_?/); $VERSION = '1.26'; $win_arch = shift @ARGV if @ARGV and $ARGV[0] =~ /^(open32|pm|x|MSWin32)$/; require('fix_4_os2.pl'), OS2_massage() if $^O eq 'os2'; $win_arch = ($IsWin32) ? 'MSWin32' : 'x' if not defined $win_arch; # Currently 'x', 'pm', 'open32', 'MSWin32' require "./myConfig"; # use lib ($Tk::MMutil::dir=getcwd); } use Tk::MMutil; # Get existing tk version for figuring $tkversion = eval 'use Tk; $Tk::VERSION;'; #print "################tkversion = $tkversion\n"; my $mydefine =''; if( $tkversion < 804.000 ){ # Tk 800 and below need the old-style XSTkCommand call # in TableMatrix.xs $mydefine .= " -DTK800XSTK"; } if ($IsWin32) { *MY::makeaperl = \&makeWin32perl; if ($Config{cc} =~ /^gcc/i) { @libs = (''); } } else { my $plibs = $Config{'libs'}; my $libs = "$xlib -lX11"; # Used to have -lpt in here as well. my @try = qw(-lsocket -lnsl -lm); push(@try,'-lc') if $^O =~ /svr4/i; my $lib; # perl needs sockets and math library too # so only include these if they made it through perl's Configure foreach $lib (@try) { $libs .= " $lib" if ($plibs =~ /$lib\b/); } @libs = ("$libs"); } my $dir = Tk::MMutil::find_subdir(); delete $dir->{'pTk'}; # Find path to existing pTk include files my $ptkPath = Tk::MMutil::findINC('Tk/pTk/Lang.h'); $ptkPath =~ s/\/Lang.h$//g; Tk::MMutil::TkExtMakefile( 'VERSION' => $VERSION, 'XS_VERSION' => $VERSION, 'EXE_FILES' => [], 'NAME' => 'Tk::TableMatrix', 'DIR' => ['pTk',reverse(sort(keys %$dir))], 'DISTNAME' => "Tk-TableMatrix", 'DEFINE' => $mydefine, 'MYEXTLIB' => 'pTk/libpTk$(LIB_EXT)' . ($win_arch =~ /^(open32|pm)$/ ? ' pTk/dllInit$(LIB_EXT)' : ''), 'INC' => "-I$ptkPath", 'LIBS' => \@libs, 'OBJECT' => '$(O_FILES)', 'clean' => { FILES => 'pTk/tkConfig.h ' }, 'PREREQ_PM' => { Tk => 800.022, }, 'CONFIGURE_REQUIRES' => { "ExtUtils::MakeMaker" => 6.52, "Tk::MMtry" => 0, "Tk::MMutil" => 0, }, 'META_MERGE' => { "meta-spec" => { version => 2 }, resources => { repository => { type => 'git', url => 'https://github.com/asb-capfan/Tk-TableMatrix.git', web => 'https://github.com/asb-capfan/Tk-TableMatrix', }, }, }, @macro ); sub MY::top_targets { my ($self) = @_; my $str = $self->MM::top_targets; $str =~ s/\bmanifypods\b/html/g; return $str; } sub MY::post_initialize { my ($self) = @_; my ($ret) = ''; my %files = (); my $dir = $self->catdir('$(INST_ARCHLIBDIR)','Tk'); my $name; foreach $name (grep /(%|\.q4|\.bck|\.old)$/,keys %{$self->{PM}}) { delete $self->{PM}->{$name}; } # delete $self->{PM}->{'Tk/Config.pm'}; # $self->{PM}->{'Tk/Config.pm'} = $self->catfile($dir,'Config.pm'); # $files{'typemap'} = 1; foreach $name ($self->lsdir(".")) { next if ($name =~ /^\./); next unless (-f $name); $files{$name} = 1 if ($name =~ /\.[tm]$/); $files{$name} = 1 if ($name =~ /\.def$/); } foreach $name (sort(@{$self->{H}},keys %files)) { $self->{PM}->{$name} = $self->catfile($dir,$name); } $ret; } sub needs_Test { my $file = shift; local $_; unless (open(TFILE,"$file")) { warn "Cannot open $file:$!"; return 1; } my $code = 0; while (<TFILE>) { last if ($code = m/^\s*(use|require)\s+Test\b/); } close(TFILE); warn "Skipping test $file needs 'Test.pm':$_" if $code; return $code; } sub MY::test { my ($self,%attrib) = @_; my @tests = sort glob($self->catfile('t','*.t')); eval { require Test }; if ($@) { @tests = grep(!needs_Test($_),@tests); } $attrib{'TESTS'} = join(' ',@tests); # Temporarily remove sub-dirs from $self as we 'know' # there are no tests down there my $dir = delete $self->{'DIR'}; my $str = $self->MM::test(%attrib); # Put sub-dirs back $self->{'DIR'} = $dir; return $str; } sub MY::postamble { ' html : subdirs manifypods @cd pod && $(MAKE) html $(PASTHRU) Makefile : myConfig $(MYEXTLIB) : config FORCE cd pTk && $(MAKE) perlmain.c : config Makefile pTk/tk.res : $(MYEXTLIB) basic : $(INST_DYNAMIC) pm_to_blib MANIFEST : MANIFEST.SKIP $(FIRST_MAKEFILE) $(MAKE) manifest '; } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tk-TableMatrix-1.26/META.yml������������������������������������������������������������������������0000644�0000000�0000000�00000001251�13746047631�014213� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������--- abstract: 'Tk::tkTable - a Spreadsheet/Table Widget' author: - 'jcerney@home.com (John Cerney)' build_requires: ExtUtils::MakeMaker: '0' configure_requires: ExtUtils::MakeMaker: '6.52' Tk::MMtry: '0' Tk::MMutil: '0' dynamic_config: 1 generated_by: 'ExtUtils::MakeMaker version 7.44, CPAN::Meta::Converter version 2.150010' license: unknown meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: Tk-TableMatrix no_index: directory: - t - inc requires: Tk: '800.022' resources: repository: https://github.com/asb-capfan/Tk-TableMatrix.git version: '1.26' x_serialization_backend: 'CPAN::Meta::YAML version 0.018' ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������