home *** CD-ROM | disk | FTP | other *** search
-
- // DBTableViewPrinter -- An object for printing DBTableViews.
- //
- // By Eric T. Seymour, NeXT Computer, Inc.
- //
- // This object formats and prints DBTableViews. Basically, the drawself:
- // method draws the table (in brute force fashion). It also contains methods
- // for setting options.
- //
- // You may freely copy, distribute, and reuse the code in this example.
- // NeXT disclaims any warranty of any kind, expressed or implied, as to its
- // fitness for any particular use.
- //
- // This file looks best when using tabstops of 3.
-
-
- #import <dbkit/dbkit.h>
- #import <appkit/appkit.h>
- #import "DBTableViewPrinter.h"
- #import "TablePrintPanel.h"
-
- #define CURRENT_CLASS_VERSION 1
-
- @interface DBTableViewPrinter(Private)
- - refreshLayout; // Page Layout stuff
- @end
-
- @implementation DBTableViewPrinter
-
- + initialize
- {
- // Set version for read/write backward compatibility
- if ( self == [DBTableViewPrinter class] )
- [DBTableViewPrinter setVersion:CURRENT_CLASS_VERSION];
-
- return self;
- }
-
- - initFrame:(const NXRect *)frameRect
- {
- // initialize the frame
- [super initFrame:frameRect];
- [self setFlipped:YES];
-
- // Initialize some flags and variables
- tableView = nil;
- rowHeight = 0.0;
- pageNumSepChar = '-';
- isPrinting = NO;
- isPageNumbersEnabled = NO;
- isRowNumbersEnabled = NO;
- isSelectedRowsOnly = NO;
- isForceDrawColor = NO;
- startingPageNumber = 1;
- startingRowNumber = 1;
- isGridLinesOn = YES;
- strcpy(rowNumberHeaderTitle,"#");
- gridColor = NX_COLORBLACK;
- backgroundColor = NX_COLORWHITE;
- rowNumbersBackColor = NXConvertGrayToColor(0.17);
-
- // Create Cell with which to draw titles
- headerTextCell = [[TextFieldCell alloc] initTextCell:""];
- [headerTextCell setFont:
- [Font boldSystemFontOfSize:12.0 matrix:NX_FLIPPEDMATRIX]];
- [headerTextCell setWrap:NO];
- [headerTextCell setAlignment:NX_CENTERED];
- [headerTextCell setTextColor:NX_COLORWHITE];
- [headerTextCell setTextGray:NX_WHITE];
- [headerTextCell setBackgroundGray:0.17];
- [headerTextCell calcCellSize:&headerTextCellSize];
-
- // Create Cell with which to draw row number headers
- rowNumberHeaderCell = [[TextFieldCell alloc] initTextCell:""];
- [rowNumberHeaderCell setFont:
- [Font boldSystemFontOfSize:12.0 matrix:NX_FLIPPEDMATRIX]];
- [rowNumberHeaderCell setWrap:NO];
- [rowNumberHeaderCell setAlignment:NX_CENTERED];
- [rowNumberHeaderCell setTextColor:NX_COLORWHITE];
- [rowNumberHeaderCell setTextGray:NX_WHITE];
- [rowNumberHeaderCell setBackgroundGray:0.17];
-
- // Create Cell with which to draw row numbers
- rowNumberCell = [[TextFieldCell alloc] initTextCell:""];
- [rowNumberCell setFont:
- [Font boldSystemFontOfSize:12.0 matrix:NX_FLIPPEDMATRIX]];
- [rowNumberCell setWrap:NO];
- [rowNumberCell setAlignment:NX_RIGHTALIGNED];
- [rowNumberCell setTextColor:NX_COLORWHITE];
- [rowNumberCell setTextGray:NX_WHITE];
- [rowNumberCell setBackgroundGray:-1.0]; // Make background 100% Alpha
-
- // Create Cell with which to draw page number
- pageNumberCell = [[TextFieldCell alloc] initTextCell:""];
- [pageNumberCell setWrap:NO];
- [pageNumberCell setTextColor:NX_COLORBLACK];
- [pageNumberCell setTextGray:NX_BLACK];
- [pageNumberCell calcCellSize:&pageNumberCellSize];
- [pageNumberCell setBackgroundGray:-1.0];
-
- // set my page frame
- if ( frameRect )
- {
- pageFrame.origin.x = frameRect->origin.x;
- pageFrame.origin.y = frameRect->origin.y;
- pageFrame.size.width = frameRect->size.width;
- pageFrame.size.height = frameRect->size.height;
- }
- else
- {
- pageFrame.origin.x = pageFrame.origin.y = 0.0;
- pageFrame.size.width = pageFrame.size.height = 20.0;
- }
-
- return self;
- }
-
- // Toggles and methods for color drawing
- - setForceDrawColor:(BOOL)toggle
- {
- isForceDrawColor = toggle;
- return self;
- }
- - (BOOL)isForceDrawColor{return isForceDrawColor;}
-
- - (BOOL)shouldDrawColor
- {
- if ( isForceDrawColor ) return YES;
- else return [super shouldDrawColor];
- }
-
- - free
- {
- // Free the Cells I was using
- [headerTextCell free];
- [rowNumberHeaderCell free];
- [rowNumberCell free];
- [pageNumberCell free];
- return [super free];
- }
-
- - setPageNumbersEnabled:(BOOL)toggle
- {
- isPageNumbersEnabled = toggle;
- if ( isPrinting ) [self refreshLayout];
- return self;
- }
- - (BOOL)isPageNumbersEnabled{return isPageNumbersEnabled;}
-
- - setStartingPageNumber:(int)num
- {
- startingPageNumber = num;
- return self;
- }
- - (int)startingPageNumber{return startingPageNumber;}
-
- - setPageNumberSeparator:(char)ch
- {
- if ( NXIsPrint(ch) ) pageNumSepChar = ch;
- return self;
- }
- - (char)pageNumberSeparator{return pageNumSepChar;}
-
- - setRowNumbersEnabled:(BOOL)toggle
- {
- isRowNumbersEnabled = toggle;
- if ( isPrinting ) [self refreshLayout];
- return self;
- }
- - (BOOL)isRowNumbersEnabled{return isRowNumbersEnabled;}
-
- - setStartingRowNumber:(int)num
- {
- startingRowNumber = num;
- if ( isPrinting ) [self refreshLayout];
- return self;
- }
- - (int)startingRowNumber{return startingRowNumber;}
-
- - setRowNumbersTitle:(const char *)title
- {
- if ( title == NULL ) return nil;
- memset(rowNumberHeaderTitle,0,51);
- strncpy(rowNumberHeaderTitle,title,50);
- if ( isPrinting ) [self refreshLayout];
- return self;
- }
- - (const char *)rowNumbersTitle{return rowNumberHeaderTitle;}
-
- - setGridLinesOn:(BOOL)toggle
- {
- isGridLinesOn = toggle;
- return self;
- }
- - (BOOL)isGridLinesOn{return isGridLinesOn;}
-
- - setSelectedRowsOnly:(BOOL)toggle
- {
- isSelectedRowsOnly = toggle;
- if ( isPrinting ) [self refreshLayout];
- return self;
- }
- - (BOOL)isSelectedRowsOnly{return isSelectedRowsOnly;}
-
- // Set Headers Bezeled Toggle
-
- - setColumnHeadersBezeled:(BOOL)toggle
- {
- [headerTextCell setBezeled:toggle];
- [rowNumberHeaderCell setBezeled:toggle];
- [headerTextCell calcCellSize:&headerTextCellSize];
- return self;
- }
- - (BOOL)isColumnHeadersBezeled{return [headerTextCell isBezeled];}
-
- // Colors
-
- - setColumnHeadersTextColor:(NXColor)color
- {
- float gray;
-
- NXConvertColorToGray(color,&gray);
- [headerTextCell setTextColor:color];
- [headerTextCell setTextGray:gray];
- [rowNumberHeaderCell setTextColor:color];
- [rowNumberHeaderCell setTextGray:gray];
- return self;
- }
- - (NXColor)columnHeadersTextColor{return [headerTextCell textColor];}
-
- - setColumnHeadersBackColor:(NXColor)color
- {
- float gray;
-
- NXConvertColorToGray(color,&gray);
- [headerTextCell setBackgroundColor:color];
- [headerTextCell setBackgroundGray:gray];
- [rowNumberHeaderCell setBackgroundColor:color];
- [rowNumberHeaderCell setBackgroundGray:gray];
- return self;
- }
- - (NXColor)columnHeadersBackColor{return [headerTextCell backgroundColor];}
-
- - setRowNumbersTextColor:(NXColor)color
- {
- float gray;
-
- NXConvertColorToGray(color,&gray);
- [rowNumberCell setTextColor:color];
- [rowNumberCell setTextGray:gray];
- return self;
- }
- - (NXColor)rowNumbersTextColor{return [rowNumberCell textColor];}
-
- - setRowNumbersBackColor:(NXColor)color
- {
- rowNumbersBackColor = color;
- return self;
- }
- - (NXColor)rowNumbersBackColor{return rowNumbersBackColor;}
-
- - setGridLinesColor:(NXColor)color
- {
- gridColor = color;
- return self;
- }
- - (NXColor)gridLinesColor{return gridColor;}
-
- - setPageNumberColor:(NXColor)color
- {
- float gray;
-
- NXConvertColorToGray(color,&gray);
- [pageNumberCell setTextColor:color];
- [pageNumberCell setTextGray:gray];
- return self;
- }
- - (NXColor)pageNumberColor{return [pageNumberCell textColor];}
-
- - setBackgroundColor:(NXColor)color
- {
- backgroundColor = color;
- return self;
- }
- - (NXColor)backgroundColor{return backgroundColor;}
-
- - printPSCode:sender
- {
- id rv;
-
- // Print only if table has been set to a valid DBTableView or subclass
- // thereof
- if ( !tableView || ![tableView isKindOfClassNamed:"DBTableView"] )
- return nil;
-
- // set all instance variables before printing
- [self refreshLayout];
-
- // turn on printing flag and print
- isPrinting = YES;
- rv = [super printPSCode:sender];
-
- // turn off printing flag and return
- isPrinting = NO;
- return rv;
- }
-
- // Setting/Get the current DBTableView
- - setTableView:table
- {
- tableView = table;
- return self;
- }
- - tableView{return tableView;}
-
- - drawSelf:(const NXRect *)rects :(int)rectCount
- {
- id aVector;
- int page,subPage,
- i,j,
- colStart,colEnd,colsThisPage;
- unsigned int row,actualRow,actualPageRowStart,pageRowStart,
- rowNumber,actualRowNumberStart;
- double tmpDouble;
- NXSize cellSize;
- NXCoord theSize;
- char pageNumberString[50];
- float gray;
- NXColor localBackgroundColor = backgroundColor,
- localGridColor = gridColor,
- localRowNumberBackColor = rowNumbersBackColor;
- NXRect aRect;
- int bezelDrawOffset = 0,
- bezelForwardOffset = 0;
- BOOL isBezeledHeaders = NO;
-
- // don't waste time if this is not a call from printPSCode
- if ( !isPrinting ) return [super drawSelf:rects :rectCount];
-
- // set an offset for bezeled headers
- if ( [headerTextCell isBezeled] )
- {
- bezelDrawOffset = 5; // offset to forward origin.y after header
- bezelForwardOffset = 4; // offset to consider when advancing to next page
- isBezeledHeaders = YES;
- }
- else
- {
- bezelDrawOffset = -1; // offset to forward origin.y after header
- bezelForwardOffset = -2;// offset to consider when advancing to next page
- isBezeledHeaders = NO;
- }
-
- // Clear to proper colors. If drawing in B&W, then convert the gray values
- if ( ![self shouldDrawColor] )
- {
- NXConvertColorToGray(backgroundColor,&gray);
- localBackgroundColor = NXConvertGrayToColor(gray);
- NXConvertColorToGray(gridColor,&gray);
- localGridColor = NXConvertGrayToColor(gray);
- NXConvertColorToGray(rowNumbersBackColor,&gray);
- localRowNumberBackColor = NXConvertGrayToColor(gray);
- }
- NXSetColor(localBackgroundColor);
- NXRectFill(&pageFrame);
-
- // Now go through and print each full tableview page
- row = 0;
- page = startingPageNumber;
- theRect.origin.y = 0.0;
- actualRow = 0;
- rowNumber = startingRowNumber;
- while ( actualRow < maxRows )
- {
- colStart = 0;
-
- // determine how many cols can fit on this page
- for ( colsThisPage = 0,tmpDouble = 0.0,i = colStart;i < maxColumns;i++ )
- {
- [headerTextCell setStringValue:[[columnList objectAt:i] title]];
- [headerTextCell calcCellSize:&cellSize];
- theSize = [(DBTableVector *)[columnList objectAt:i] size];
- if ( theSize < cellSize.width ) theSize = cellSize.width;
- tmpDouble += theSize;
- if ( tmpDouble > rowNumberedWidth ) break;
- else colsThisPage++;
- }
- if ( colsThisPage == 0 ) colsThisPage = 1;
-
- colEnd = colsThisPage;
- pageRowStart = row;
- actualPageRowStart = actualRow;
- actualRowNumberStart = rowNumber;
- subPage = 1;
- while ( colStart < maxColumns )
- {
- row = pageRowStart;
- actualRow = actualPageRowStart;
- rowNumber = actualRowNumberStart;
-
- // Draw Page number if required
- if ( isPageNumbersEnabled )
- {
- theRect.origin.y += pageNumberHeight;
- if ( NXPointInRect(&theRect.origin,&rects[0]) )
- {
- if ( pagesPerRow > 1 )
- sprintf(pageNumberString,"%d%c%d",
- page,pageNumSepChar,subPage);
- else sprintf(pageNumberString,"%d",page);
- [pageNumberCell setStringValue:pageNumberString];
- [pageNumberCell calcCellSize:&cellSize];
- theRect.origin.x = pageFrame.size.width - cellSize.width;
- theRect.size.width = cellSize.width;
- theRect.size.height = pageNumberHeight;
- [pageNumberCell drawSelf:&theRect inView:self];
- }
- }
-
- // Initialize the first draw rect for the header row
- theRect.origin.x = 0.0;
- theRect.origin.y += headerTextCellSize.height;
- theRect.size.height = headerTextCellSize.height;
-
- // Put a header at the top of the page
- if ( NXPointInRect(&theRect.origin,&rects[0]) )
- {
- // Put the Row Number Header if required
- if ( isRowNumbersEnabled )
- {
- theRect.size.width = rowNumberHeaderCellSize.width;
- [rowNumberHeaderCell drawSelf:&theRect inView:self];
-
- // Draw border around row number header
- if ( isGridLinesOn && !isBezeledHeaders )
- {
- // Set the color of the lines
- NXSetColor(localGridColor);
-
- // Draw Left, Top, and Right Borders
- PSmoveto(theRect.origin.x,
- theRect.origin.y + rowNumberHeaderCellSize.height);
- PSlineto(theRect.origin.x,theRect.origin.y);
- PSlineto(theRect.origin.x +
- rowNumberHeaderCellSize.width - 1,
- theRect.origin.y);
- PSlineto(theRect.origin.x +
- rowNumberHeaderCellSize.width - 1,
- theRect.origin.y + rowNumberHeaderCellSize.height);
- }
-
- theRect.origin.x += rowNumberHeaderCellSize.width;
- }
-
- // Put the rest of the header
- for ( i = colStart; i < colEnd; i++ )
- {
- aVector = [columnList objectAt:i];
- [headerTextCell setStringValue:[aVector title]];
- [headerTextCell calcCellSize:&cellSize];
- theSize = [(DBTableVector *)aVector size];
- if ( theSize < cellSize.width ) theSize = cellSize.width;
- theRect.size.width = theSize;
- [headerTextCell setAlignment:[aVector titleAlignment]];
- [headerTextCell drawSelf:&theRect inView:self];
-
- // Draw border around each header
- if ( isGridLinesOn && !isBezeledHeaders )
- {
- // Set the color of the lines
- NXSetColor(localGridColor);
-
- // Draw Top and Right Borders
- PSmoveto(theRect.origin.x,theRect.origin.y);
- PSlineto(theRect.origin.x + theRect.size.width - 1,
- theRect.origin.y);
- PSlineto(theRect.origin.x + theRect.size.width - 1,
- theRect.origin.y + theRect.size.height);
- }
-
- theRect.origin.x += theSize;
- }
- }
-
- // Now print rows on this page until no more fit
- theRect.size.height = rowHeight;
- theRect.origin.y += bezelDrawOffset;
- for ( i = 0; i < maxRowsPerPage && actualRow < maxRows; row++ )
- {
- // Skip if selection is on and this is not selected
- if ( isSelectedRowsOnly && ![tableView isRowSelected:row] )
- continue;
-
- // Initialize the first draw rect for the current row
- theRect.origin.x = 0.0;
- theRect.origin.y += rowHeight;
-
- // Now do each cell by having each formatter draw itself
- if ( NXPointInRect(&theRect.origin,&rects[0]) )
- {
- // Draw a Row Number Cell if required
- if ( isRowNumbersEnabled )
- {
- // Draw the background
- NXSetColor(localRowNumberBackColor);
- NXSetRect(&aRect,theRect.origin.x,theRect.origin.y + 1,
- rowNumberHeaderCellSize.width - 1,rowHeight);
-
- // If the first row, then narrow the gap above the first
- // row number with row number background color
- if ( actualRow == actualPageRowStart )
- {
- aRect.origin.y--;
- aRect.size.height++;
- if ( !isGridLinesOn )
- {
- aRect.origin.y--;
- aRect.size.height++;
- }
- }
- NXRectFill(&aRect);
-
- // Draw the number using the cell
- [rowNumberCell setIntValue:rowNumber];
- NXSetRect(&aRect,theRect.origin.x,theRect.origin.y,
- rowNumberHeaderCellSize.width,rowHeight);
- [rowNumberCell drawSelf:&aRect inView:self];
-
- // Draw draw lines around row numbers if required
- if ( isGridLinesOn )
- {
- // Set the color of the lines
- NXSetColor(localGridColor);
-
- // Draw Left Border
- PSmoveto(theRect.origin.x,theRect.origin.y);
- PSlineto(theRect.origin.x,theRect.origin.y+rowHeight);
-
- // Always draw bottom and right borders
- PSlineto(theRect.origin.x +
- rowNumberHeaderCellSize.width - 1,
- theRect.origin.y + rowHeight);
- PSlineto(theRect.origin.x +
- rowNumberHeaderCellSize.width - 1,
- theRect.origin.y);
-
- // Only put top border on first rows
- if ( actualRow == actualPageRowStart )
- PSlineto(theRect.origin.x - 1,theRect.origin.y);
- }
- theRect.origin.x += rowNumberHeaderCellSize.width;
- }
-
- // Draw the rest of the cells
- for ( j = colStart; j < colEnd; j++ )
- {
- [headerTextCell
- setStringValue:[[columnList objectAt:j] title]];
- [headerTextCell calcCellSize:&cellSize];
- theSize = [(DBTableVector *)[columnList objectAt:j] size];
- if ( theSize < cellSize.width ) theSize = cellSize.width;
-
- theRect.size.width = theSize;
- [[tableView formatterAt:row :j] beginBatching:nil];
- theRect.origin.y++;
- [[tableView formatterAt:row :j] drawFieldAt:row :j
- inside:&theRect inView:self
- withAttributes:[tableView rowAt:row]
- :[tableView columnAt:j] usePositions:YES :NO];
- theRect.origin.y--;
- [[tableView formatterAt:row :j] endBatching];
-
- // Draw the grid lines if required
- if ( isGridLinesOn )
- {
- // Set the color of the lines
- NXSetColor(localGridColor);
-
- // Only put left borders on first columns and
- // if row numbers are turned off
- if ( j == colStart && !isRowNumbersEnabled )
- {
- PSmoveto(theRect.origin.x,theRect.origin.y);
- PSlineto(theRect.origin.x,theRect.origin.y+rowHeight);
- }
- else
- PSmoveto(theRect.origin.x - 1,
- theRect.origin.y+rowHeight);
-
- // Always draw bottom and right borders
- PSlineto(theRect.origin.x + theRect.size.width - 1,
- theRect.origin.y + rowHeight);
- PSlineto(theRect.origin.x + theRect.size.width - 1,
- theRect.origin.y);
-
- // Only put top border on first rows
- if ( actualRow == actualPageRowStart )
- {
- if ( j == colStart )
- PSlineto(theRect.origin.x,theRect.origin.y);
- else PSlineto(theRect.origin.x - 1,theRect.origin.y);
- }
- }
- theRect.origin.x += theRect.size.width;
- }
- if ( isGridLinesOn || isRowNumbersEnabled ) PSstroke();
- }
- rowNumber++;
- actualRow++;
- i++;
- }
- theRect.origin.y--;
- // advance the draw rect's origin to the next page
- // The bezelForwardOffset is to compensate jumping bezelDrawOffset
- // pixels after drawing the header
- if ( i == maxRowsPerPage )
- theRect.origin.y += pageAdvanceOffset - bezelForwardOffset;
- else
- theRect.origin.y += pageHeight -
- ((i * rowHeight) + headerTextCellSize.height +
- pageNumberHeight + bezelForwardOffset);
- colStart = colEnd;
-
- // determine how many cols can fit on next page
- for ( colsThisPage = 0,tmpDouble = 0.0,i = colStart;
- i < maxColumns; i++ )
- {
- [headerTextCell setStringValue:[[columnList objectAt:i] title]];
- [headerTextCell calcCellSize:&cellSize];
- theSize = [(DBTableVector *)[columnList objectAt:i] size];
- if ( theSize < cellSize.width ) theSize = cellSize.width;
- tmpDouble += theSize;
- if ( tmpDouble > rowNumberedWidth ) break;
- else colsThisPage++;
- }
- if ( colsThisPage == 0 ) colsThisPage = 1;
- colEnd += colsThisPage;
- subPage++;
- }
- page++;
- }
-
- return self;
- }
-
- - read:(NXTypedStream*)stream
- {
- int version;
-
- [super read:stream];
-
- // Get the version
- version = NXTypedStreamClassVersion(stream,"DBTableViewPrinter");
-
- // Read all version 0 stuff first
- NXReadTypes(stream,"cccccc@",&isPrinting,&isPageNumbersEnabled,
- &isRowNumbersEnabled,&isSelectedRowsOnly,&isGridLinesOn,
- &isForceDrawColor,&columnList);
- headerTextCell = NXReadObject(stream);
- pageNumberCell = NXReadObject(stream);
- rowNumberHeaderCell = NXReadObject(stream);
- rowNumberCell = NXReadObject(stream);
- NXReadTypes(stream,"c[51c]",&pageNumSepChar,&rowNumberHeaderTitle);
- NXReadTypes(stream,"{ffff}",&pageFrame);
- NXReadTypes(stream,"{ffff}",&theRect);
- NXReadTypes(stream,"fffff",&rowHeight,&pageHeight,
- &pageAdvanceOffset,&pageNumberHeight,&rowNumberedWidth);
- NXReadTypes(stream,"{ff}{ff}{ff}",
- &headerTextCellSize,&pageNumberCellSize,&rowNumberHeaderCellSize);
- NXReadTypes(stream,"iiiiii",
- &maxColumns,&maxRows,&maxRowsPerPage,&pagesPerRow,
- &startingPageNumber,&startingRowNumber);
- gridColor = NXReadColor(stream);
- backgroundColor = NXReadColor(stream);
- NXReadTypes(stream,"@",&tableView);
-
- // Read Version 1 stuff
- if ( version > 0 ) rowNumbersBackColor = NXReadColor(stream);
-
- return self;
- }
-
- - write:(NXTypedStream*)stream
- {
- [super write:stream];
-
- // Write version 0 stuff first
- NXWriteTypes(stream,"cccccc@",&isPrinting,&isPageNumbersEnabled,
- &isRowNumbersEnabled,&isSelectedRowsOnly,&isGridLinesOn,
- &isForceDrawColor,&columnList);
- NXWriteObject(stream,headerTextCell);
- NXWriteObject(stream,pageNumberCell);
- NXWriteObject(stream,rowNumberHeaderCell);
- NXWriteObject(stream,rowNumberCell);
- NXWriteTypes(stream,"c[51c]",&pageNumSepChar,&rowNumberHeaderTitle);
- NXWriteTypes(stream,"{ffff}",&pageFrame);
- NXWriteTypes(stream,"{ffff}",&theRect);
- NXWriteTypes(stream,"fffff",&rowHeight,&pageHeight,
- &pageAdvanceOffset,&pageNumberHeight,&rowNumberedWidth);
- NXWriteTypes(stream,"{ff}{ff}{ff}",
- &headerTextCellSize,&pageNumberCellSize,&rowNumberHeaderCellSize);
- NXWriteTypes(stream,"iiiiii",
- &maxColumns,&maxRows,&maxRowsPerPage,&pagesPerRow,
- &startingPageNumber,&startingRowNumber);
- NXWriteColor(stream,gridColor);
- NXWriteColor(stream,backgroundColor);
- NXWriteTypes(stream,"@",&tableView);
-
- // write version 1 stuff
- NXWriteColor(stream,rowNumbersBackColor);
-
- return self;
- }
-
- @end
-
- @implementation DBTableViewPrinter(Private)
-
- // refreshLayout gets the page size and determines all size parameters like
- // the number of rows per page, the number of columns per page, etc.
-
- - refreshLayout
- {
- int i,
- bezelDrawOffset = 0,
- maxPages;
- NXRect visibleRect;
- NXSize cellSize;
- NXCoord theSize,
- leftMargin,rightMargin,topMargin,bottomMargin;
- const NXRect *paperRect;
- double tmpDouble;
- char title[51];
- id thePrintPanel = nil;
-
- // Get some formatter and size information from the tableView
- columnList = [tableView columnList];
- maxColumns = [columnList count];
- if ( isSelectedRowsOnly ) maxRows = [tableView selectedRowCount];
- else maxRows = [tableView rowCount];
- if ( [tableView rowCount] > 0 ) rowHeight = [[tableView rowAt:0] size];
- if ( rowHeight <= 0.0 ) rowHeight = 18;
-
- // Lock the table's window and make sure everything has been displayed
- // if everything has not been displayed, it will not get printed, so I
- // have to "force a dislay" here, even if it is off screen.
- [[tableView window] disableFlushWindow];
- [[[tableView docView] superview] getDocVisibleRect:&visibleRect];
- for ( i = 0; i < maxColumns; i++ )
- [(DBTableView *)tableView scrollColumnToVisible:i];
- [tableView scrollClip:[tableView docView] to:&visibleRect.origin];
- [tableView reflectScroll:[[tableView docView] superview]];
- [tableView layoutChanged:self];
- [[tableView window] reenableFlushWindow];
-
- // Get the width of a page
- [[NXApp printInfo] getMarginLeft:&leftMargin right:&rightMargin
- top:&topMargin bottom:&bottomMargin];
- paperRect = [[NXApp printInfo] paperRect];
- pageFrame.size.width =
- (NXCoord)paperRect->size.width - (NXCoord)(rightMargin + leftMargin);
- rowNumberedWidth = pageFrame.size.width;
-
- // If row numbering is on, set the row header cell to the correct width
- if ( isRowNumbersEnabled )
- {
- // Get the size of the number of digits in maxRow
- [rowNumberHeaderCell setIntValue:(maxRows + startingRowNumber) * 10];
- [rowNumberHeaderCell calcCellSize:&cellSize];
-
- // Initialize the rowHeader sizes and values
- [rowNumberHeaderCell setStringValue:rowNumberHeaderTitle];
- [rowNumberHeaderCell calcCellSize:&rowNumberHeaderCellSize];
-
- // Keep making the Row Header wider until it's wide enough
- memset(title,0,51);
- strncpy(title,rowNumberHeaderTitle,50);
- while ( rowNumberHeaderCellSize.width < cellSize.width &&
- strlen(title) < 45 )
- {
- sprintf(title," %s ",[rowNumberHeaderCell stringValue]);
- [rowNumberHeaderCell setStringValue:title];
- [rowNumberHeaderCell calcCellSize:&rowNumberHeaderCellSize];
- }
- rowNumberedWidth -= rowNumberHeaderCellSize.width;
- }
-
- // Get total pages to print a row
- for ( pagesPerRow = 1, tmpDouble = 0.0, i = 0; i < maxColumns; i++ )
- {
- [headerTextCell setStringValue:[[columnList objectAt:i] title]];
- [headerTextCell calcCellSize:&cellSize];
- theSize = [(DBTableVector *)[columnList objectAt:i] size];
- if ( theSize < cellSize.width ) theSize = cellSize.width;
- tmpDouble += theSize;
- if ( tmpDouble > rowNumberedWidth )
- {
- if ( i < (maxColumns - 1) && !(theSize > rowNumberedWidth &&
- tmpDouble == theSize) ) i--;
- pagesPerRow++;
- tmpDouble = 0.0;
- }
- }
-
- // Set the height of the page number cell if desired
- if ( isPageNumbersEnabled ) pageNumberHeight = pageNumberCellSize.height;
- else pageNumberHeight = 0.0;
-
- // offset to forward origin.y after drawing each header
- if ( [headerTextCell isBezeled] ) bezelDrawOffset = 5;
-
- // Get the single page height and the whole rect needed to print this thing
- pageHeight = paperRect->size.height - (topMargin + bottomMargin);
- tmpDouble =
- (double)((pageHeight - headerTextCellSize.height) -
- (pageNumberHeight + bezelDrawOffset)) / (double)rowHeight;
- maxRowsPerPage = (int)floor(tmpDouble) - 1;
- tmpDouble = (double)maxRows / (double)maxRowsPerPage;
- maxPages = (int)ceil(tmpDouble) * pagesPerRow;
- if ( maxPages <= 0 ) maxPages = 1;
- pageFrame.size.height = (NXCoord)maxPages * (NXCoord)pageHeight;
-
- // Size the View in which to draw
- [self sizeTo:pageFrame.size.width :pageFrame.size.height];
-
- // Get the offset to add to advance to the next page
- pageAdvanceOffset = pageHeight - ((maxRowsPerPage * rowHeight) +
- headerTextCellSize.height + pageNumberHeight);
-
- // Get my subclass of print panel and print with the proper pagesPerRow
- thePrintPanel = [TablePrintPanel new];
- if ( thePrintPanel &&
- [thePrintPanel respondsTo:@selector(setPagesPerRow:)] )
- [thePrintPanel setPagesPerRow:pagesPerRow];
-
- return self;
- }
-
- @end