Composer performance optimization work - FixupTableData optimizations. Added SingleSignon feature for Composer publishing. Fixed layout cell background bug - permission by nisheeth

This commit is contained in:
cmanske%netscape.com 1998-08-25 20:16:10 +00:00
Родитель 7bcff11cb6
Коммит 250e125823
10 изменённых файлов: 544 добавлений и 253 удалений

Просмотреть файл

@ -920,16 +920,16 @@ public:
// This gets the next geometric column or row
// using supplied X or Y value as current location
// (these use the tables m_RowLayoutData and m_ColumnLayoutData)
// (these use the tables m_pRowLayoutData and m_pColumnLayoutData)
CEditTableCellElement* GetFirstCellInNextColumn(int32 iCurrentColumnX);
CEditTableCellElement* GetFirstCellInNextRow(int32 iCurrentRowY);
// Get the defining left (for columns) and top (for rows) value from
// the index into m_ColumnLayoutData and m_RowLayoutData
// the index into m_pColumnLayoutData and m_pRowLayoutData
int32 GetColumnX(intn iIndex);
int32 GetRowY(intn iIndex);
// Use m_ColumnLayoutData and m_RowLayoutData
// Use m_pColumnLayoutData and m_pRowLayoutData
// to get grid coordinates of a cell
intn GetColumnIndex(int32 X);
intn GetRowIndex(int32 Y);
@ -970,7 +970,7 @@ public:
// ... to be restored by this after relayout after table, col, or row resizing
void RestoreSizeMode(MWContext *pContext);
// Next two use m_RowLayoutData and m_ColumnLayoutData
// Next two use m_pRowLayoutData and m_pColumnLayoutData
// Clear all row and column layout data
void DeleteLayoutData();
@ -998,7 +998,7 @@ public:
// Analogous routine for rows
CEditTableRowElement* GetFirstRow();
// Use following BEFORE we layout and build our m_RowLayoutData and m_ColumnLayoutData
// Use following BEFORE we layout and build our m_pRowLayoutData and m_pColumnLayoutData
// This counts row elements in table and also saves result in m_iRows
intn CountRows();
// Max of number of columns
@ -1006,9 +1006,9 @@ public:
// row because of ROWSPAN effect)
intn CountColumns();
intn GetRows() {m_iRows = m_RowLayoutData.Size(); return m_iRows;}
intn GetColumns() {m_iColumns = m_ColumnLayoutData.Size(); return m_iColumns;}
intn GetRows() {return m_iRows;}
intn GetColumns() {return m_iColumns;}
// Get number of columns between given values
intn GetColumnsSpanned(int32 iStartX, int32 iEndX);
@ -1021,7 +1021,7 @@ public:
// that is bad, so fix it. Same for ROWSPAN
// 2. Save accurate number of cells in each column,
// compensating for COLSPAN and ROWSPAN
// Uses m_ColumnLayoutData and m_RowLayoutData
// Uses m_pColumnLayoutData and m_pRowLayoutData
void FixupColumnsAndRows();
// Add empty cells to each row so table looks rectangular
@ -1082,9 +1082,17 @@ public:
intn m_iBackgroundSaveIndex;
// Let CEditBuffer access this directly
TXP_GrowableArray_EDT_CellLayoutData m_ColumnLayoutData;
TXP_GrowableArray_EDT_CellLayoutData m_RowLayoutData;
// Very weird, but these are very slow when dereferencing pointer
//TXP_GrowableArray_EDT_CellLayoutData m_pColumnLayoutData;
//TXP_GrowableArray_EDT_CellLayoutData m_pRowLayoutData;
// Lets use simple arrays instead
EDT_CellLayoutData *m_pColumnLayoutData;
EDT_CellLayoutData *m_pRowLayoutData;
// Sizes of these arrays - initially 1000 each,
// and expanded as needed
int32 m_iColumnLayoutSize;
int32 m_iRowLayoutSize;
};
class CEditTableRowElement: public CEditElement {
@ -1192,9 +1200,15 @@ public:
virtual void StreamOut(IStreamOut *pOut);
void SetData( EDT_TableCellData *pData );
// This gets current params using GetData(),
// then overrides the size-related values from suppled data
void SetSizeData( EDT_TableCellData *pData );
// Supply the csid if getting data for table not
// yet part of doc, as when pasting from stream
EDT_TableCellData* GetData(int16 csid = 0);
// No tag param parsing - get just member variables
// Supply a struct to avoid allocating another struct
EDT_TableCellData* GetSizeData(EDT_TableCellData *pData = NULL);
// Clear mask bits for attributes different from supplied data
void MaskData( EDT_TableCellData *pData );
@ -1250,6 +1264,7 @@ public:
// Move contents of supplied cell into this cell
void MergeCells(CEditTableCellElement* pCell);
void SplitCell();
// Delete all contents, leaving just the minimum empty text element
// Set param to TRUE only when deleting all selected cells
@ -1325,6 +1340,7 @@ public:
void SetWidth(XP_Bool bWidthDefined, XP_Bool bWidthPercent, int32 iWidthPixels);
void SetHeight(XP_Bool bHeightDefined, XP_Bool bHeightPercent, int32 iHeightPixels);
void SetRow(intn iRow) {m_iRow = iRow;}
// Next two are used when dragging the right border
// Set all cells in a column to the width supplied
@ -1344,14 +1360,14 @@ private:
char* m_pBackgroundImage;
// Cache this for efficiency
XP_Bool m_bWidthDefined;
XP_Bool m_bHeightDefined;
XP_Bool m_bWidthPercent;
XP_Bool m_bHeightPercent;
int32 m_iColSpan;
int32 m_iRowSpan;
// These are set only by FixupTableData(),
//FIGURING OUT INDEXES IS TOO COMPLICATED!
// USE REAL LOCATIONS INSTEAD
// These are set only by FixupTableData() during Relayou
int32 m_X;
int32 m_Y;
intn m_iRow; // Current logical and actual row index
@ -3201,7 +3217,7 @@ public:
// sizes calculated by Layout. Must do for all tables during Relayout()
// else generated HTML is very misleading!
void FixupTableData();
CEditElement* FindRelayoutStart( CEditElement *pStartElement );
CEditElement* FindRelayoutStart( CEditElement *pStartElement, XP_Bool bRelayoutEntireTable = TRUE );
void Relayout( CEditElement *pStartElement, int iOffset,
CEditElement *pEndElement = 0, intn relayoutFlags = 0 );
@ -4458,6 +4474,9 @@ inline char *edt_StrDup( char *pStr ){
}
}
// Moved from EDT.H since we don't call it from FE any more
void edt_SyncPublishingHistory(MWContext *pMWContext);
#ifdef DEBUG
class CEditTestManager {

Просмотреть файл

@ -1770,12 +1770,12 @@ void CEditBuffer::DocumentStored(){
GetCommandLog()->DocumentStored();
}
CEditElement* CEditBuffer::FindRelayoutStart( CEditElement *pStartElement ){
CEditElement* CEditBuffer::FindRelayoutStart( CEditElement *pStartElement, XP_Bool bRelayoutEntireTable ){
CEditElement* pOldElement = NULL;
while ( pStartElement && pStartElement != pOldElement ) {
pOldElement = pStartElement;
CEditElement* pTable = pStartElement->GetTopmostTableOrLayer();
if ( m_bDisplayTables && pTable ) {
if ( m_bDisplayTables && bRelayoutEntireTable && pTable ) {
// If this is in a table, skip before it.
pStartElement = pTable->PreviousLeaf();
}
@ -1811,7 +1811,13 @@ void EDT_FixupTableData(MWContext *pMWContext)
// else generated HTML is very misleading!
void CEditBuffer::FixupTableData()
{
// return;
// Reuse one cell data struct for maximumn efficiency
EDT_TableCellData *pCellData = XP_NEW( EDT_TableCellData );
if( pCellData )
XP_MEMSET( pCellData, 0, sizeof(EDT_TableCellData));
else
return;
for( int i = 0; i < edt_RelayoutTables.Size(); i++ )
{
LO_TableStruct *pLoTable = edt_RelayoutTables[i];
@ -1831,7 +1837,7 @@ void CEditBuffer::FixupTableData()
EDT_TableData *pTableData = pEdTable->GetData();
if(!pTableData)
return;
continue;
// Get space between cells
pTableData->iCellSpacing = pLoTable->inter_cell_space;
@ -1843,7 +1849,7 @@ void CEditBuffer::FixupTableData()
pEdTable->GetParentSize(m_pContext, &iMaxWidth, &iMaxHeight, pLoTable);
// Save correct width even if bWidthDefined is FALSE
// (NOTE: width will NOT be save in m_pTagData if bWidthDefined == FALSE)
// (NOTE: width will NOT be saved in m_pTagData if bWidthDefined == FALSE)
pTableData->iWidthPixels = pLoTable->width;
if( pTableData->bWidthPercent )
{
@ -1883,9 +1889,10 @@ void CEditBuffer::FixupTableData()
}
XP_MEMSET( ExtraColumns, 0, iArraySize );
// This may actually be a CaptionElement,
// but we will test for rows below
CEditElement *pRow = pEdTable->GetChild();
// There may be a CaptionElement as the first or last
// child in a table. Be sure to use GetFirstRow(), GetNextRow()
// which guarentee a non-caption row
CEditTableRowElement *pRow = pEdTable->GetFirstRow();
intn iRow = 0;
// Clear existing layout data
@ -1893,112 +1900,122 @@ void CEditBuffer::FixupTableData()
while( pRow )
{
// A Caption element may be a child, so test type first
if( pRow->IsTableRow() )
pEdCell = pRow->GetFirstCell();
// We will count number of actual cell locations in each row
// Start with extra columns caused by ROWSPAN in previous rows
int32 iColumnsInRow = ExtraColumns[iRow];
while( pEdCell )
{
pEdCell = (CEditTableCellElement*)(pRow->GetChild());
// We will count number of actual cell locations in each row
// Start with extra columns caused by ROWSPAN in previous rows
int32 iColumnsInRow = ExtraColumns[iRow];
while( pEdCell )
intn iColSpan = pEdCell->GetColSpan();
intn iRowSpan = pEdCell->GetRowSpan();
iColumnsInRow += iColSpan;
#if 0 //#ifdef DEBUG
// Test if list scan is in sync between layout and editor objects
LO_Element *pNextCell = (LO_Element*)(pEdCell->GetLoCell());
if( !pLoCell || pLoCell != pNextCell)
{
intn iColSpan = pEdCell->GetColSpan();
intn iRowSpan = pEdCell->GetRowSpan();
iColumnsInRow += iColSpan;
#ifdef DEBUG
// Test if list scan is in sync between layout and editor objects
LO_Element *pNextCell = (LO_Element*)(pEdCell->GetLoCell());
if( !pLoCell || pLoCell != pNextCell)
XP_TRACE(("**** pNextCell (%d) is not correct", pLoCell));
}
else
#endif
{
// If current cell has extra ROWSPAN,
// then it will cause extra columns in following row(s)
if( iRowSpan > 1 )
{
XP_TRACE(("**** pNextCell (%d) is not correct", pLoCell));
}
else
#endif
{
// If current cell has extra ROWSPAN,
// then it will cause extra columns in following row(s)
if( iRowSpan > 1 )
for( intn j = 1; j < iRowSpan; j++ )
{
for( intn j = 1; j < iRowSpan; j++ )
{
// We may overrun our array if table is "bad"
// because of a ROWSPAN value that exceeds actual
// number of rows. Just skip attempts to access a value too high
// since there is no row to use the "ExtraColumns" anyway.
if( iRow+j < iRows )
ExtraColumns[iRow+j] += iColSpan;
}
// We may overrun our array if table is "bad"
// because of a ROWSPAN value that exceeds actual
// number of rows. Just skip attempts to access a value too high
// since there is no row to use the "ExtraColumns" anyway.
if( iRow+j < iRows )
ExtraColumns[iRow+j] += iColSpan;
}
// Save actual location and size data
EDT_TableCellData *pCellData = pEdCell->GetData();
if( pCellData )
}
// Save actual location and size data
// GetSizeData only returns valid size-related info
// and is much more efficient than GetData (no tag param parsing)
pEdCell->GetSizeData(pCellData);
if( pCellData )
{
XP_Bool bChangedX = pLoCell->lo_any.x != pCellData->X;
XP_Bool bChangedY = pLoCell->lo_any.y != pCellData->Y;
// The LO_Element's concept of cell "width" INCLUDES
// the border and cell padding, but the HTML tag value excludes these,
// so we must compensate here.
int32 iWidthPixels = lo_GetCellTagWidth(pLoCell);
int32 iHeightPixels = lo_GetCellTagHeight(pLoCell);
if( iWidthPixels != pCellData->iWidthPixels ||
iHeightPixels != pCellData->iHeightPixels )
{
// Only write new size data if it really changed,
// since this formats HTML tag and is slow
pCellData->X = pLoCell->lo_any.x;
pCellData->Y = pLoCell->lo_any.y;
pCellData->iRow = iRow;
// The LO_Element's concept of cell "width" INCLUDES
// the border and cell padding, but the HTML tag value excludes these,
// so we must compensate here.
pCellData->iWidthPixels = lo_GetCellTagWidth(pLoCell);
pCellData->iHeightPixels = lo_GetCellTagHeight(pLoCell);
if( pCellData->bWidthPercent )
{
// Use "full" width of cell for % calculation
pCellData->iWidth = (pLoCell->lo_any.width * 100) / iMaxWidth;
} else {
pCellData->iWidth = pCellData->iWidthPixels;
}
if( pCellData->bHeightPercent )
{
pCellData->iHeight = (pLoCell->lo_any.height * 100) / iMaxHeight;
} else {
pCellData->iHeight = pCellData->iHeightPixels;
}
pEdCell->SetData(pCellData);
EDT_FreeTableCellData(pCellData);
pCellData->iWidthPixels = iWidthPixels;
pCellData->iHeightPixels = iHeightPixels;
pEdCell->SetSizeData(pCellData);
}
else
{
// These don't affect tag params
if( iRow != pCellData->iRow )
pEdCell->SetRow(iRow);
if( bChangedX )
pEdCell->SetX(pLoCell->lo_any.x);
if( bChangedY )
pEdCell->SetY(pLoCell->lo_any.y);
}
}
// Add this cell to Column and Row layout data
// Note: Can do only after setting size params above
//if( bChangedX || bChangedY )
// This sucks, but we have to do it for all cells each time
pEdTable->AddLayoutData(pEdCell, pLoCell);
CEditTableCellElement *pNextEdCell = (CEditTableCellElement*)(pEdCell->GetNextSibling());
// Next cell in row
// (or signal to get next row if NULL)
pEdCell = pNextEdCell;
// If cell scanning is in sync
// this should be much quicker than searching for
// a LO_Element from each CEditElement or vice versa
if( pLoCell )
{
pLoCell = pLoCell->lo_any.next;
// Skip over non-cells
while( pLoCell && pLoCell->type != LO_CELL )
pLoCell = pLoCell->lo_any.next;
}
}
// Save the column count in Row
pRow->TableRow()->SetColumns(iColumnsInRow);
// PLEASE!!! I hope this rule holds: "We can never have an empty row"
iRow++;
CEditTableCellElement *pNextEdCell = (CEditTableCellElement*)(pEdCell->GetNextSibling());
// Next cell in row
// (or signal to get next row if NULL)
pEdCell = pNextEdCell;
// If cell scanning is in sync
// this should be much quicker than searching for
// a LO_Element from each CEditElement or vice versa
if( pLoCell )
{
pLoCell = pLoCell->lo_any.next;
// Skip over non-cells
while( pLoCell && pLoCell->type != LO_CELL )
pLoCell = pLoCell->lo_any.next;
}
}
pRow = pRow->GetNextSibling();
// Save the column count in Row
pRow->TableRow()->SetColumns(iColumnsInRow);
// PLEASE!!! I hope this rule holds: "We can never have an empty row"
iRow++;
pRow = pRow->GetNextRow();
}
// Safety check
XP_ASSERT(iRow == iRows);
// Now we know maximum number of columns to set in table
pTableData->iColumns = pEdTable->m_ColumnLayoutData.Size();
pTableData->iRows = iRows;
// (This is actually already set correctly by AddLayoutData,
// but we need to set the new width and height data anyway)
pTableData->iColumns = pEdTable->GetColumns();
pTableData->iRows = iRows; // Should = pTable->m_iRows;
pEdTable->SetData(pTableData);
EDT_FreeTableData(pTableData);
@ -2007,6 +2024,8 @@ void CEditBuffer::FixupTableData()
// We need to do this just once, so clear the list
edt_RelayoutTables.Empty();
EDT_FreeTableCellData(pCellData);
}
//
@ -2072,16 +2091,26 @@ void CEditBuffer::Reflow( CEditElement* pStartElement,
#endif
}
pNewStartElement = FindRelayoutStart(pStartElement);
if( pNewStartElement && pNewStartElement != pStartElement ){
// 2nd param: Do NOT move start outside the table
pNewStartElement = FindRelayoutStart(pStartElement, FALSE);
if( pNewStartElement && pNewStartElement != pStartElement )
{
// we had to back up some. Layout until we pass this point.
if( pEndElement == 0 ){
if( pEndElement == 0 )
pEndElement = pStartElement;
}
pStartElement = pNewStartElement;
iEditOffset = pStartElement->Leaf()->GetLen();
}
else if( pEndElement == 0 )
{
if( pStartElement->IsLeaf() )
pEndElement = pStartElement;
else
pEndElement = pStartElement->NextLeafAll();
}
#if 0
// If the end is in a table, move it outside of the table.
if ( pEndElement ) {
CEditElement* pTable = pEndElement->GetTopmostTableOrLayer();
@ -2091,6 +2120,9 @@ void CEditBuffer::Reflow( CEditElement* pStartElement,
pEndElement = pTable->GetLastMostChild();//->NextLeaf();
}
}
#endif
XP_Bool bInTableCell = pStartElement ? (pStartElement->GetTableIgnoreSubdoc() != NULL) : FALSE;
// laying out from the beginning of the document
if( pNewStartElement == 0 ){
@ -2120,15 +2152,30 @@ void CEditBuffer::Reflow( CEditElement* pStartElement,
pEndElement : pStartElement, relayoutFlags );
return;
}
//
// Find the first element on this line.
pLoStartLine = FirstElementOnLine( pLayoutElement, &iLineNum );
// Note: If here, we must have a pStartElement and associated LO_Element
XP_ASSERT(pStartElement && pLayoutElement);
// Find the first element on this line and get the current line number
pLoStartLine = FirstElementOnLine( pLayoutElement, &iLineNum );
//
// Position the tag cursor at this position
//
pEdStart = pLoStartLine->lo_any.edit_element;
iOffset = pLoStartLine->lo_any.edit_offset;
// **** TESTING NEW REFLOW WITHIN TABLE CELL
//pLoStartLine = FirstElementOnLine( pLayoutElement, &iLineNum );
//pEdStart = pLoStartLine->lo_any.edit_element;
//iOffset = pLoStartLine->lo_any.edit_offset;
if( bInTableCell )
{
// Trust the given element if inside a cell
pEdStart = pStartElement;
iOffset = iEditOffset;
}
else
{
pEdStart = pLoStartLine->lo_any.edit_element;
iOffset = pLoStartLine->lo_any.edit_offset;
}
}
@ -2147,8 +2194,18 @@ void CEditBuffer::Reflow( CEditElement* pStartElement,
// Search for zero-length text elements, and remove the non-breaking spaces we put
// in.
CEditElement* pElement= m_pRoot;
while ( NULL != (pElement = pElement->FindNextElement(&CEditElement::FindLeafAll,0))){
// Why do this for entire doc? Changed to do only from pStartElement to pEndElement
//CEditElement* pElement= pStartElement; // m_pRoot;
CEditElement* pElement;
if( pStartElement->IsLeaf() )
pElement = pStartElement;
else
pElement = pStartElement->FindNextElement(&CEditElement::FindLeafAll,0);
if( pEndElement && !pEndElement->IsLeaf() )
pEndElement = pEndElement->FindNextElement(&CEditElement::FindLeafAll,0);
do {
switch ( pElement->GetElementType() ) {
case eTextElement:
{
@ -2230,7 +2287,13 @@ void CEditBuffer::Reflow( CEditElement* pStartElement,
}
}
}
pElement = pElement->FindNextElement(&CEditElement::FindLeafAll,0);
if( pElement && pElement == pEndElement )
break;
}
while ( pElement != NULL );
if( (relayoutFlags & RELAYOUT_NOCARET) == 0 && !bWasSelected){
SetCaret();
}
@ -2386,11 +2449,21 @@ void CEditBuffer::Relayout( CEditElement* pStartElement,
XP_TRACE(("\n\nEDITOR RELAYOUT"));
lo_PrintLayout(m_pContext);
#endif
// Search for zero-length text elements, and remove the non-breaking spaces we put
// Search for zero-length text elements, and remove the non-breaking spaces we put in
// in.
CEditElement* pElement= m_pRoot;
while ( NULL != (pElement = pElement->FindNextElement(&CEditElement::FindLeafAll,0))){
// Why do this for entire doc? Changed to do only from pStartElement to pEndElement
//CEditElement* pElement= pStartElement; // m_pRoot;
CEditElement* pElement;
if( pStartElement->IsLeaf() )
pElement = pStartElement;
else
pElement = pStartElement->FindNextElement(&CEditElement::FindLeafAll,0);
if( pEndElement && !pEndElement->IsLeaf() )
pEndElement = pEndElement->FindNextElement(&CEditElement::FindLeafAll,0);
do {
switch ( pElement->GetElementType() ) {
case eTextElement:
{
@ -2537,7 +2610,12 @@ void CEditBuffer::Relayout( CEditElement* pStartElement,
}
}
}
pElement = pElement->FindNextElement(&CEditElement::FindLeafAll,0);
if( pElement && pElement == pEndElement )
break;
}
while ( pElement != NULL );
// For each table just layed out, readjust all table and cell width data
// to reflect the complicated Layout algorithm's size data
// Moved ABOVE next block (was below)
@ -2710,6 +2788,7 @@ EDT_ClipboardResult CEditBuffer::InsertChars( char* pNewChars, XP_Bool bTyping,
}
else
{
ClearTableAndCellSelection();
CEditTableCellElement* pTableCell = m_pCurrent->GetTableCellIgnoreSubdoc();
CEditElement *pParent = m_pCurrent->GetParent();
CEditElement* pPrev = m_pCurrent->GetPreviousSibling();
@ -2730,16 +2809,17 @@ EDT_ClipboardResult CEditBuffer::InsertChars( char* pNewChars, XP_Bool bTyping,
ElementOffset iOffset;
XP_Bool bStickyAfter;
GetInsertPoint( &pEle, &iOffset, &bStickyAfter );
// Delete forward if to the left of the space,
// or delete back if to the right.
DeleteChar(iOffset == 0, bTyping);
}
}
}
//ClearSelection();
ClearMove(FALSE);
// This will move the insert point that is at the beginning of
// Following will move the insert point that is at the beginning of
// one element to the end of the previous.
// Don't do this if we are at an empty element or we set the flag
// to use the current element's text formatting
@ -2753,22 +2833,7 @@ EDT_ClipboardResult CEditBuffer::InsertChars( char* pNewChars, XP_Bool bTyping,
// If this assert ever fails, it means that we've
// got to uncomment this and make it work.
XP_ASSERT(IsMultiSpaceMode());
#if 0
// Check for space after space case.
if ( newChar == ' ' && !m_pCurrent->InFormattedText()
&& !IsMultiSpaceMode() ) {
CEditInsertPoint p(m_pCurrent, m_iCurrentOffset);
// move to the right on spacebar if we are under a space.
if( p.IsSpace() ){
NextChar( FALSE );
return result;
}
if ( p.IsSpaceBeforeOrAfter() ) {
return result;
}
}
#endif
//
// The edit element can choose not to insert a character if it is
// a space and at the insertion point there already is a space.
//
@ -6779,7 +6844,13 @@ void CEditBuffer::MergeTableCells()
*/
void CEditBuffer::SplitTableCell()
{
//TODO: WRITE THIS!
CEditInsertPoint ip;
GetTableInsertPoint(ip);
CEditTableCellElement* pCell = ip.m_pElement->GetTableCellIgnoreSubdoc();
if( !pCell )
return;
pCell->SplitCell();
}
@ -12351,7 +12422,7 @@ void CEditBuffer::DeleteSelectedCells(XP_Bool bNoSpaceInNewCells)
// We don't want to use GetNextCellInColumn() because of
// ROWSPAN effect. This gets the first cell in the
// next geometric row using the table's layout data
pCell = pTable->GetFirstCellInNextRow(pCell->GetX());
pCell = pTable->GetFirstCellInNextRow(pCell->GetY());
while( pCell )
{
if( pCell->AllCellsInRowAreSelected() )
@ -12359,7 +12430,7 @@ void CEditBuffer::DeleteSelectedCells(XP_Bool bNoSpaceInNewCells)
else
break;
pCell = pTable->GetFirstCellInNextRow(pCell->GetX());
pCell = pTable->GetFirstCellInNextRow(pCell->GetY());
}
AdoptAndDo(new CDeleteTableRowCommand(this, number));
@ -15710,6 +15781,18 @@ void CEditBuffer::SetReplaceCellSelection()
// Reset replace cell
edt_pPrevReplaceCellSelected = m_pDragTableData->pDragOverCell;
LO_TableStruct *pSourceTable = lo_GetParentTable(m_pContext, m_pDragTableData->pFirstSelectedCell);
LO_TableStruct *pDragOverTable = lo_GetParentTable(m_pContext, m_pDragTableData->pDragOverCell);
if( pSourceTable && pSourceTable != pDragOverTable &&
(m_pDragTableData->pDragOverCell->lo_cell.ele_attrmask & LO_ELE_SELECTED) != 0 )
{
// We are hovering over selected cells in a different table
// Set all selected cells to the "special selection" mode
// so they will be the ones replaced
DisplaySpecialCellSelection();
return;
}
LO_Element *pLoEle = m_pDragTableData->pDragOverCell;
// This will get updated by edt_SetSpecialSelectRow for each row
int32 iRowY = pLoEle->lo_cell.y;
@ -15852,8 +15935,11 @@ void CEditBuffer::ClearTableAndCellSelection()
int iLoSize = m_SelectedLoCells.Size();
if( m_pSelectedEdTable == 0 &&
iEdSize == 0 )
// Nothing to do
{
XP_ASSERT(iLoSize == 0);
// Nothing was selected
return;
}
SelectTable(FALSE);

Просмотреть файл

@ -1910,6 +1910,8 @@ XP_Bool CEditSubDocElement::Reduce( CEditBuffer* /* pBuffer */ ){
return FALSE;
}
#define LAYOUT_ARRAY_SIZE 500
// class CEditTableElement
// Default table params for constructors and ::NewData()
@ -1949,13 +1951,17 @@ CEditTableElement::CEditTableElement(intn columns, intn rows)
m_bSaveWidthPercent(FALSE),
m_bSaveHeightPercent(FALSE),
m_bSaveWidthDefined(FALSE),
m_bSaveHeightDefined(FALSE)
m_bSaveHeightDefined(FALSE),
m_iColumnLayoutSize(LAYOUT_ARRAY_SIZE),
m_iRowLayoutSize(LAYOUT_ARRAY_SIZE)
{
EDT_TRY {
for (intn row = 0; row < rows; row++ ){
CEditTableRowElement* pRow = new CEditTableRowElement(columns);
pRow->InsertAsFirstChild(this);
}
m_pColumnLayoutData = (EDT_CellLayoutData*)XP_ALLOC(LAYOUT_ARRAY_SIZE*sizeof(EDT_CellLayoutData));
m_pRowLayoutData = (EDT_CellLayoutData*)XP_ALLOC(LAYOUT_ARRAY_SIZE*sizeof(EDT_CellLayoutData));
}
EDT_CATCH_ALL {
Finalize();
@ -1991,7 +1997,9 @@ CEditTableElement::CEditTableElement(CEditElement *pParent, PA_Tag *pTag, int16
m_bSaveWidthPercent(FALSE),
m_bSaveHeightPercent(FALSE),
m_bSaveWidthDefined(FALSE),
m_bSaveHeightDefined(FALSE)
m_bSaveHeightDefined(FALSE),
m_iColumnLayoutSize(LAYOUT_ARRAY_SIZE),
m_iRowLayoutSize(LAYOUT_ARRAY_SIZE)
{
switch( m_align ) {
case ED_ALIGN_CENTER:
@ -2015,6 +2023,8 @@ CEditTableElement::CEditTableElement(CEditElement *pParent, PA_Tag *pTag, int16
SetData(pData);
FreeData(pData);
}
m_pColumnLayoutData = (EDT_CellLayoutData*)XP_ALLOC(LAYOUT_ARRAY_SIZE*sizeof(EDT_CellLayoutData));
m_pRowLayoutData = (EDT_CellLayoutData*)XP_ALLOC(LAYOUT_ARRAY_SIZE*sizeof(EDT_CellLayoutData));
}
CEditTableElement::CEditTableElement(IStreamIn *pStreamIn, CEditBuffer *pBuffer)
@ -2043,7 +2053,9 @@ CEditTableElement::CEditTableElement(IStreamIn *pStreamIn, CEditBuffer *pBuffer)
m_bSaveWidthPercent(FALSE),
m_bSaveHeightPercent(FALSE),
m_bSaveWidthDefined(FALSE),
m_bSaveHeightDefined(FALSE)
m_bSaveHeightDefined(FALSE),
m_iColumnLayoutSize(LAYOUT_ARRAY_SIZE),
m_iRowLayoutSize(LAYOUT_ARRAY_SIZE)
{
m_align = (ED_Alignment) pStreamIn->ReadInt();
m_malign = (ED_Alignment) pStreamIn->ReadInt();
@ -2076,6 +2088,9 @@ CEditTableElement::CEditTableElement(IStreamIn *pStreamIn, CEditBuffer *pBuffer)
EDT_FreeTableData(pData);
}
PA_FreeTag( pTag );
m_pColumnLayoutData = (EDT_CellLayoutData*)XP_ALLOC(LAYOUT_ARRAY_SIZE*sizeof(EDT_CellLayoutData));
m_pRowLayoutData = (EDT_CellLayoutData*)XP_ALLOC(LAYOUT_ARRAY_SIZE*sizeof(EDT_CellLayoutData));
}
CEditTableElement::~CEditTableElement(){
@ -2167,6 +2182,14 @@ CEditTableRowElement* CEditTableElement::GetFirstRow()
{
return pChild->TableRow();
}
else if( pChild )
{
// Most likely we have a caption
XP_ASSERT(pChild->IsCaption());
pChild = pChild->GetNextSibling();
if( pChild && pChild->IsTableRow() )
return pChild->TableRow();
}
return NULL;
}
@ -2216,7 +2239,7 @@ intn CEditTableElement::CountRows()
// pushes cells in following rows to the right.
// Thus the total number of geometric columns may be greater
// than a simple count of the number of cells in a row
// So we use a strategy similar to how we fill in m_ColumnLayoutData:
// So we use a strategy similar to how we fill in m_pColumnLayoutData:
// we count the number of unique X values for all cells
intn CEditTableElement::CountColumns()
{
@ -2264,7 +2287,7 @@ CEditTableRowElement* CEditTableElement::GetRow(int32 Y, intn *pRow)
// Old method -- less efficient.
// Needed only if we must use GetRow() before table is layed out,
// because thats when the m_RowLayoutData is built (in CEditBuffer::FixupTableData())
// because thats when the m_pRowLayoutData is built (in CEditBuffer::FixupTableData())
#if 0
for ( CEditElement* pChild = GetChild();
pChild;
@ -2385,16 +2408,16 @@ CEditTableCellElement* CEditTableElement::GetPreviousCellInRow(CEditTableCellEle
CEditTableCellElement* CEditTableElement::GetFirstCellAtColumnIndex(intn iIndex)
{
if( iIndex >= 0 && iIndex < m_ColumnLayoutData.Size() )
return m_ColumnLayoutData[iIndex]->pEdCell;
if( iIndex >= 0 && iIndex < m_iColumns )
return m_pColumnLayoutData[iIndex].pEdCell;
return NULL;
}
CEditTableCellElement* CEditTableElement::GetFirstCellAtRowIndex(intn iIndex)
{
if( iIndex >= 0 && iIndex < m_RowLayoutData.Size() )
return m_RowLayoutData[iIndex]->pEdCell;
if( iIndex >= 0 && iIndex < m_iRows )
return m_pRowLayoutData[iIndex].pEdCell;
return NULL;
}
@ -2402,16 +2425,16 @@ CEditTableCellElement* CEditTableElement::GetFirstCellAtRowIndex(intn iIndex)
// Get the defining left (for columns) and top (for rows) value from index
int32 CEditTableElement::GetColumnX(intn iIndex)
{
if( iIndex < m_ColumnLayoutData.Size() )
return m_ColumnLayoutData[iIndex]->X;
if( iIndex < m_iColumns )
return m_pColumnLayoutData[iIndex].X;
return 0;
}
int32 CEditTableElement::GetRowY(intn iIndex)
{
if( iIndex < m_RowLayoutData.Size() )
return m_RowLayoutData[iIndex]->Y;
if( iIndex < m_iRows )
return m_pRowLayoutData[iIndex].Y;
return 0;
}
@ -2419,10 +2442,9 @@ int32 CEditTableElement::GetRowY(intn iIndex)
// Get grid coordinates of a cell
intn CEditTableElement::GetColumnIndex(int32 X)
{
intn iCount = m_ColumnLayoutData.Size();
for( intn i=0; i < iCount; i++ )
for( intn i=0; i < m_iColumns; i++ )
{
if( m_ColumnLayoutData[i]->X == X )
if( m_pColumnLayoutData[i].X == X )
return i;
}
return -1;
@ -2430,10 +2452,9 @@ intn CEditTableElement::GetColumnIndex(int32 X)
intn CEditTableElement::GetRowIndex(int32 Y)
{
intn iCount = m_RowLayoutData.Size();
for( intn i=0; i < iCount; i++ )
for( intn i=0; i < m_iRows; i++ )
{
if( m_RowLayoutData[i]->Y == Y )
if( m_pRowLayoutData[i].Y == Y )
return i;
}
return -1;
@ -2536,36 +2557,34 @@ CEditTableCellElement* CEditTableElement::GetPreviousCellInColumn(CEditTableCell
CEditTableCellElement* CEditTableElement::GetFirstCellInNextColumn(int32 iCurrentColumnX)
{
intn iCount = m_ColumnLayoutData.Size();
intn i;
// Scan data to find current cell's column in our layout data
for( i = 0; i < iCount; i++ )
for( i = 0; i < m_iColumns; i++ )
{
if( iCurrentColumnX == m_ColumnLayoutData[i]->X )
if( iCurrentColumnX == m_pColumnLayoutData[i].X )
break;
}
if( i+1 >= iCount )
if( i+1 >= m_iColumns )
return NULL; // No cell is after the current column
return m_ColumnLayoutData[i+1]->pEdCell;
return m_pColumnLayoutData[i+1].pEdCell;
}
CEditTableCellElement* CEditTableElement::GetFirstCellInNextRow(int32 iCurrentRowY)
{
intn iCount = m_RowLayoutData.Size();
intn i;
// Scan data to find current cell's row in our layout data
for( i = 0; i < iCount; i++ )
for( i = 0; i < m_iRows; i++ )
{
if( iCurrentRowY == m_RowLayoutData[i]->Y )
if( iCurrentRowY == m_pRowLayoutData[i].Y )
break;
}
if( i+1 >= iCount )
if( i+1 >= m_iRows )
return NULL; // No cell is after the current row
return m_RowLayoutData[i+1]->pEdCell;
return m_pRowLayoutData[i+1].pEdCell;
}
// Figure out how many columns are included between given X values
@ -2575,10 +2594,9 @@ intn CEditTableElement::GetColumnsSpanned(int32 iStartX, int32 iEndX)
return 0;
intn iColumns = 0;
intn iTotalColumns = m_ColumnLayoutData.Size();
for( intn i = 0; i < iTotalColumns; i++ )
for( intn i = 0; i < m_iColumns; i++ )
{
int32 iColX = m_ColumnLayoutData[i]->X;
int32 iColX = m_pColumnLayoutData[i].X;
if( iStartX <= iColX && iEndX > iColX )
iColumns++;
}
@ -2638,15 +2656,15 @@ void CEditTableElement::FixupColumnsAndRows()
}
m_iColumns = X_Array.Size();
intn iColumns = CountColumns(); //m_ColumnLayoutData.Size();
intn iRows = CountRows(); //m_RowLayoutData.Size();
intn iColumns = CountColumns();
intn iRows = CountRows();
intn i, iMinSpan, iDecrease;
// We will find the maximum number of columns in all rows
m_iColumns = 0;
for ( i = 0; i < iColumns; i++ )
{
CEditTableCellElement *pFirstCellInCol = m_ColumnLayoutData[i]->pEdCell;
CEditTableCellElement *pFirstCellInCol = m_pColumnLayoutData[i].pEdCell;
pCell = pFirstCellInCol;
iMinSpan = 2;
@ -2675,7 +2693,7 @@ void CEditTableElement::FixupColumnsAndRows()
pCell = GetNextCellInColumn(pCell);
}
}
intn iCellsInRow = m_ColumnLayoutData[i]->iCellsInRow;
intn iCellsInRow = m_pColumnLayoutData[i].iCellsInRow;
CEditTableRowElement *pRow = (CEditTableRowElement*)pCell->GetParent();
if( pRow )
pRow->SetColumns(iCellsInRow);
@ -2687,7 +2705,7 @@ void CEditTableElement::FixupColumnsAndRows()
// Do the same for ROWSPAN
for ( i = 0; i < iRows; i++ )
{
CEditTableCellElement *pFirstCellInRow = m_RowLayoutData[i]->pEdCell;
CEditTableCellElement *pFirstCellInRow = m_pRowLayoutData[i].pEdCell;
pCell = pFirstCellInRow;
iMinSpan = 2;
@ -2868,7 +2886,7 @@ void CEditTableElement::InsertRows(int32 Y, int32 iNewY, intn number,
pNewCell->FinishedLoad(pBuffer);
}
}
pSourceRow = (CEditTableRowElement*)pSourceRow->GetNextSibling();
pSourceRow = pSourceRow->GetNextRow();
}
// Clear this so we don't touch empty cells
// from the paste source
@ -3311,12 +3329,12 @@ void CEditTableElement::DeleteRows(int32 Y, intn number,
}
// Delete the row if all cells were deleted (should always be true?)
// VERY IMPORTANT. Never call anything to cause
// relayout else our m_RowLayoutData and entire coordinate
// relayout else our m_pRowLayoutData and entire coordinate
// system will be altered
if( pRow && pRow->GetChild() == NULL )
{
// Get the next row if available before deleting this one
pLastRow = (CEditTableRowElement*)pRow->GetNextSibling();
pLastRow = pRow->GetNextRow();
#ifdef DEBUG
if( pLastRow )
XP_ASSERT(pLastRow->IsTableRow());
@ -3438,7 +3456,7 @@ void CEditTableElement::FinishedLoad( CEditBuffer* pBuffer ){
CEditTableRowElement* pRow = NULL;
CEditElement* pNext = 0;
// TODO: MAKE THIS WORK BEFORE LAYOUT HAPPENS (no m_ColumnLayoutData yet)
// TODO: MAKE THIS WORK BEFORE LAYOUT HAPPENS (no m_pColumnLayoutData yet)
//FixupColumnsAndRows();
// For efficiency, count rows only
@ -3555,7 +3573,6 @@ void CEditTableElement::SetData( EDT_TableData *pData ){
if ( pNew ) {
free(pNew); // XP_FREE?
}
// Save these since they are not saved in tag data if bWidthPercent = FALSE
m_iWidthPixels = pData->iWidthPixels;
m_iWidth = pData->iWidth;
m_bWidthPercent = pData->bWidthPercent;
@ -4015,6 +4032,9 @@ void CEditTableElement::SetSizeMode(MWContext *pContext, int iMode)
CEditTableCellElement *pCell = GetFirstCell();
if( pCell )
{
// Get current width and height
// (doesn't include amount we are changing
// during current resizing)
iParentWidth = pCell->GetParentWidth();
iParentHeight = pCell->GetParentHeight();
}
@ -4042,8 +4062,9 @@ void CEditTableElement::SetSizeMode(MWContext *pContext, int iMode)
// Save the current m_bWidthPercent, m_bHeightPercent, bWidthDefined, and bHeightDefined
pCell->SaveSizeMode(pCellData->bWidthDefined, pCellData->bHeightDefined);
if( (bCellPixels && pCellData->bWidthPercent) ||
(bCellPercent && !pCellData->bWidthPercent) )
if( bSetTableWidth &&
(bCellPixels && pCellData->bWidthPercent ||
bCellPercent && !pCellData->bWidthPercent) )
{
if( bCellPercent )
{
@ -4055,8 +4076,9 @@ void CEditTableElement::SetSizeMode(MWContext *pContext, int iMode)
}
bChanged = TRUE;
}
if( (bCellPixels && pCellData->bHeightPercent) ||
(bCellPercent && !pCellData->bHeightPercent) )
if( bSetTableHeight &&
(bCellPixels && pCellData->bHeightPercent ||
bCellPercent && !pCellData->bHeightPercent) )
{
if( bCellPercent )
{
@ -4122,27 +4144,15 @@ void CEditTableElement::RestoreSizeMode(MWContext *pContext)
}
}
// This should only be called before laying out a table and
// we expect to call AddLayoutData soon after to rebuild layout data and counters
void CEditTableElement::DeleteLayoutData()
{
intn i;
intn iColumns = m_ColumnLayoutData.Size();
intn iRows = m_RowLayoutData.Size();
for ( i = 0; i < iColumns; i++ )
{
if( m_ColumnLayoutData[i] )
delete m_ColumnLayoutData[i];
}
//Note: This does NOT free any memory,
// it just sets m_iSize = 0;
m_ColumnLayoutData.Empty();
for ( i = 0; i < iRows; i++ )
{
if( m_RowLayoutData[i] )
delete m_RowLayoutData[i];
}
m_RowLayoutData.Empty();
// Blank out current arrays and reset row and column counters
memset(m_pColumnLayoutData, 0, m_iColumnLayoutSize*sizeof(EDT_CellLayoutData));
memset(m_pRowLayoutData, 0, m_iRowLayoutSize*sizeof(EDT_CellLayoutData));
m_iColumns = 0;
m_iRows = 0;
}
// Store data for first cell in each column and row in growable arrays
@ -4155,25 +4165,23 @@ void CEditTableElement::AddLayoutData(CEditTableCellElement *pEdCell, LO_Element
EDT_CellLayoutData *pRowData;
intn i;
intn iCurrentColumns = m_ColumnLayoutData.Size();
intn iCurrentRows = m_RowLayoutData.Size();
// We always add the cell the first time here
XP_Bool bNewColumn = iCurrentColumns == 0;
XP_Bool bNewRow = iCurrentRows == 0;
XP_Bool bNewColumn = m_iColumns == 0;
XP_Bool bNewRow = m_iRows == 0;
for( i = 0; i < iCurrentColumns; i++ )
for( i = 0; i < m_iColumns; i++ )
{
if( pLoCell->lo_cell.x == m_ColumnLayoutData[i]->X )
if( pLoCell->lo_cell.x == m_pColumnLayoutData[i].X )
{
// We already have the first cell in this column
// Just increase the column count
// Note: We count geometric columns, so we must look at COLSPAN
m_ColumnLayoutData[i]->iCellsInColumn += lo_GetColSpan(pLoCell);
m_pColumnLayoutData[i].iCellsInColumn += lo_GetColSpan(pLoCell);
break;
}
else if( pLoCell->lo_cell.x > m_ColumnLayoutData[i]->X &&
( i+1 == iCurrentColumns ||
pLoCell->lo_cell.x < m_ColumnLayoutData[i+1]->X ) )
else if( pLoCell->lo_cell.x > m_pColumnLayoutData[i].X &&
( i+1 == m_iColumns ||
pLoCell->lo_cell.x < m_pColumnLayoutData[i+1].X ) )
{
// We are at the last existing cell in array or
// this cell's X is between current cell's and
@ -4188,9 +4196,26 @@ void CEditTableElement::AddLayoutData(CEditTableCellElement *pEdCell, LO_Element
if( bNewColumn )
{
pColData = new EDT_CellLayoutData;
if( !pColData )
return;
if( m_iColumns >= m_iColumnLayoutSize )
{
m_pColumnLayoutData = (EDT_CellLayoutData*)XP_REALLOC(m_pColumnLayoutData, (LAYOUT_ARRAY_SIZE+m_iColumnLayoutSize)*sizeof(EDT_CellLayoutData));
if( m_pColumnLayoutData )
{
m_iColumnLayoutSize += LAYOUT_ARRAY_SIZE;
}
else
{
m_iColumnLayoutSize = 0;
XP_TRACE(("Out of memory for ColumnLayout data"));
XP_ASSERT(FALSE);
return;
}
}
// Make room for inserted struct if not at end of current array
if( i < m_iColumns )
XP_MEMMOVE(&m_pColumnLayoutData[i+1], &m_pColumnLayoutData[i], (m_iColumns-i)*sizeof(EDT_CellLayoutData));
pColData = &m_pColumnLayoutData[i];
pColData->X = pLoCell->lo_cell.x;
pColData->Y = pLoCell->lo_cell.y;
pColData->pEdCell = pEdCell;
@ -4200,21 +4225,21 @@ void CEditTableElement::AddLayoutData(CEditTableCellElement *pEdCell, LO_Element
// These are ignored for column data
pColData->iCellsInRow = pColData->iRow = 0;
m_ColumnLayoutData.Insert(pColData, i);
m_iColumns++;
}
for( i = 0; i < iCurrentRows; i++ )
for( i = 0; i < m_iRows; i++ )
{
if( pLoCell->lo_cell.y == m_RowLayoutData[i]->Y )
if( pLoCell->lo_cell.y == m_pRowLayoutData[i].Y )
{
// We already have the first cell in this column
// We already have the first cell in this row
// Just increase the row count
m_RowLayoutData[i]->iCellsInRow += lo_GetRowSpan(pLoCell);
m_pRowLayoutData[i].iCellsInRow += lo_GetRowSpan(pLoCell);
break;
}
else if( pLoCell->lo_cell.y > m_RowLayoutData[i]->Y &&
( i+1 == iCurrentRows ||
pLoCell->lo_cell.y < m_RowLayoutData[i+1]->Y ) )
else if( pLoCell->lo_cell.y > m_pRowLayoutData[i].Y &&
( i+1 == m_iRows ||
pLoCell->lo_cell.y < m_pRowLayoutData[i+1].Y ) )
{
// We are at the last existing cell in array or
// this cell's Y is between current cell's and
@ -4229,9 +4254,26 @@ void CEditTableElement::AddLayoutData(CEditTableCellElement *pEdCell, LO_Element
if( bNewRow )
{
pRowData = new EDT_CellLayoutData;
if( !pRowData )
return;
if( m_iRows >= m_iRowLayoutSize )
{
m_pRowLayoutData = (EDT_CellLayoutData*)XP_REALLOC(m_pRowLayoutData, (LAYOUT_ARRAY_SIZE+m_iRowLayoutSize)*sizeof(EDT_CellLayoutData));
if( m_pRowLayoutData )
{
m_iRowLayoutSize += LAYOUT_ARRAY_SIZE;
}
else
{
m_iRowLayoutSize = 0;
XP_TRACE(("Out of memory for RowLayout data"));
XP_ASSERT(FALSE);
return;
}
}
// Make room for inserted struct if not at end of current array
if( i < m_iRows )
XP_MEMMOVE(&m_pRowLayoutData[i+1], &m_pRowLayoutData[i], (m_iRows-i)*sizeof(EDT_CellLayoutData));
pRowData = &m_pRowLayoutData[i];
pRowData->X = pLoCell->lo_cell.x;
pRowData->Y = pLoCell->lo_cell.y;
@ -4242,7 +4284,8 @@ void CEditTableElement::AddLayoutData(CEditTableCellElement *pEdCell, LO_Element
// These are ignored for row data
pRowData->iCellsInColumn = pRowData->iColumn = 0;
m_RowLayoutData.Insert(pRowData, i);
m_iRows++;
//m_pRowLayoutData.Insert(pRowData, i);
}
}
@ -4310,6 +4353,16 @@ CEditTableRowElement *CEditTableRowElement::GetNextRow()
{
return pRow->TableRow();
}
else if( pRow )
{
// Most likely we have a caption
XP_ASSERT(pRow->IsCaption());
// Can only have 1, so next one must
// be a row or we're at the end already
pRow = pRow->GetNextSibling();
if( pRow && pRow->IsTableRow() )
return pRow->TableRow();
}
return NULL;
}
@ -4591,7 +4644,7 @@ void CEditTableRowElement::InsertCells(int32 X, int32 iNewX, intn number, CEditT
// This is tough. We know we need to add cells, but how many?
// We can't be sure we had enough before so new cells end up
// at desired new column.
// TODO: USE pTable->m_ColumnLayoutData to figure out how
// TODO: USE pTable->m_pColumnLayoutData to figure out how
// many cells to add to bring us to desired X
// TRUE = insert after the cell found
edt_InsertCells(number, TRUE, pCellBefore, pSourceRow, &pCellForInsertPoint);
@ -4706,9 +4759,9 @@ void CEditTableRowElement::DeleteCells(int32 X, intn number, CEditTableCellEleme
int32 iCellX = pCell->GetX();
int32 iColSpan = pCell->GetColSpan();
if( X == iCellX )
if( iCellX >= X )
{
// Cell is in same column as delete column
// Cell is in same column as delete column or to the right of it
if( iColSpan <= iRemaining )
{
// Simplest case - just delete one cell
@ -4776,6 +4829,7 @@ void CEditTableRowElement::DeleteCells(int32 X, intn number, CEditTableCellEleme
CEditTableCellElement* CEditTableRowElement::FindCell(int32 X, XP_Bool bIncludeRightEdge)
{
CEditTableCellElement* pCell = NULL;
XP_Bool bQuitNextCycle = FALSE;
for ( CEditElement* pChild = GetChild();
pChild;
@ -4796,14 +4850,18 @@ CEditTableCellElement* CEditTableRowElement::FindCell(int32 X, XP_Bool bIncludeR
{
return pChild->TableCell();
} else {
// We are here whe we first find a cell
// Save it but continue to see if next cell's
// We are here when we first find a cell
// Save it but continue 1 more cycle to see if next cell's
// left edge matches - use that instead if it does
// (This nonsense is needed for 0 borders where
// (This is needed when border = 0, then the
// right edge of one cell = left edge of next)
pCell = pChild->TableCell();
bQuitNextCycle = TRUE;
continue; // Skip test just below
}
}
if( bQuitNextCycle )
break;
}
}
return pCell;
@ -5028,6 +5086,8 @@ CEditTableCellElement::CEditTableCellElement()
m_iHeightPixels(1),
m_bWidthPercent(FALSE),
m_bHeightPercent(FALSE),
m_bWidthDefined(FALSE),
m_bHeightDefined(FALSE),
m_iColSpan(1),
m_iRowSpan(1),
m_iRow(0),
@ -5056,6 +5116,8 @@ CEditTableCellElement::CEditTableCellElement(XP_Bool bIsHeader)
m_iHeightPixels(1),
m_bWidthPercent(FALSE),
m_bHeightPercent(FALSE),
m_bWidthDefined(FALSE),
m_bHeightDefined(FALSE),
m_iColSpan(1),
m_iRowSpan(1),
m_iRow(0),
@ -5084,6 +5146,8 @@ CEditTableCellElement::CEditTableCellElement(CEditElement *pParent, PA_Tag *pTag
m_iHeightPixels(1),
m_bWidthPercent(FALSE),
m_bHeightPercent(FALSE),
m_bWidthDefined(FALSE),
m_bHeightDefined(FALSE),
m_iColSpan(1),
m_iRowSpan(1),
m_iRow(0),
@ -5147,6 +5211,10 @@ CEditTableCellElement::CEditTableCellElement(IStreamIn *pStreamIn, CEditBuffer *
EDT_TableCellData *pData = ParseParams( pTag, pBuffer->GetRAMCharSetID() );
if(pData)
{
m_bWidthDefined = pData->bWidthDefined;
m_bHeightDefined = pData->bHeightDefined;
// Save these since they are not saved in tag data if bWidthPercent = FALSE
m_iWidth = pData->iWidth;
m_bWidthPercent = pData->bWidthPercent;
if( !m_bWidthPercent )
@ -5340,6 +5408,26 @@ void CEditTableCellElement::CalcPixelHeight(EDT_TableCellData *pData)
}
}
void CEditTableCellElement::SetSizeData(EDT_TableCellData * pData)
{
EDT_TableCellData * pCurrentData = GetData(0);
if( pData && pCurrentData )
{
pCurrentData->X = pData->X;
pCurrentData->iRow = pData->iRow;
pCurrentData->bWidthDefined = pData->bWidthDefined;
pCurrentData->bWidthPercent = pData->bWidthPercent;
pCurrentData->iWidthPixels = pData->iWidthPixels;
CalcPercentWidth(pCurrentData);
pCurrentData->bHeightDefined = pData->bHeightDefined;
pCurrentData->bHeightPercent = pData->bHeightPercent;
pCurrentData->iHeightPixels = pData->iHeightPixels;
CalcPercentHeight(pCurrentData);
SetData(pCurrentData);
EDT_FreeTableCellData(pCurrentData);
}
}
void CEditTableCellElement::SetWidth(XP_Bool bWidthDefined, XP_Bool bWidthPercent, int32 iWidthPixels)
{
EDT_TableCellData * pData = GetData(0);
@ -5574,6 +5662,9 @@ void CEditTableCellElement::SetData( EDT_TableCellData *pData ){
m_X = pData->X;
m_Y = pData->Y;
m_bWidthDefined = pData->bWidthDefined;
m_bHeightDefined = pData->bHeightDefined;
m_iWidthPixels = pData->iWidthPixels;
m_iHeightPixels = pData->iHeightPixels;
@ -5588,6 +5679,38 @@ void CEditTableCellElement::SetData( EDT_TableCellData *pData ){
m_iRowSpan = pData->iRowSpan;
}
// Since Getting/Setting data is costly (lots of string manipulation)
// use this when efficiency is important and you need just size data
// For even more efficiency, supply the TableCellData to avoid
// alloc/delete for large number of cells
EDT_TableCellData *CEditTableCellElement::GetSizeData(EDT_TableCellData *pData)
{
if( pData == NULL )
{
pData = XP_NEW( EDT_TableCellData );
if( pData )
XP_MEMSET( pData, 0, sizeof(EDT_TableCellData));
}
if( pData == 0 )
return NULL;
// Get just our member variables
pData->bWidthDefined = m_bWidthDefined;
pData->bHeightDefined = m_bHeightDefined;
pData->bWidthPercent = m_bWidthPercent;
pData->bHeightPercent = m_bHeightPercent;
pData->iWidth = m_iWidth;
pData->iWidthPixels = m_iWidthPixels;
pData->iHeight = m_iHeight;
pData->iHeightPixels = m_iHeightPixels;
pData->X = m_X;
pData->Y = m_Y;
pData->iRow = m_iRow;
return pData;
}
EDT_TableCellData* CEditTableCellElement::GetData( int16 csid )
{
//TODO: Account for interaction between default align and Header style
@ -6090,18 +6213,53 @@ XP_Bool CEditTableCellElement::IsEmpty()
return TRUE;
// We are empty if no more sibling containers
// and cell only has an empty string
if( GetChild()->GetNextSibling() == 0 && pElement->IsText() )
// and cell only has an empty string or
// a single space in the string (used to force showing borders in browser)
if( GetChild()->GetNextSibling() == 0 &&
pElement->IsText() && pElement->GetNextSibling() == 0 )
{
char *pText = pElement->Text()->GetText();
if( pText == 0 || XP_STRLEN(pText) == 0 )
{
// We should NEVER be missing text
if( !pText )
return TRUE;
}
int iLen = XP_STRLEN(pText);
if( iLen == 0 || (iLen == 1 && pText[0] == ' ') )
return TRUE;
}
return FALSE;
}
void CEditTableCellElement::SplitCell()
{
CEditBuffer *pBuffer = GetEditBuffer();
if( pBuffer == NULL || (m_iColSpan == 0 && m_iRowSpan == 0) )
return;
pBuffer->SetFillNewCellWithSpace();
CEditTableCellElement *pNewCell;
for( intn iRow = 0; iRow < m_iRowSpan; iRow++ )
{
for( intn iCol = 0; iCol < m_iColSpan; iCol++ )
{
pNewCell = new CEditTableCellElement;
pNewCell->InsertAfter(this);
pNewCell->FinishedLoad(pBuffer);
}
}
// Now reset values in current cell
EDT_TableCellData *pData = GetData();
if( pData )
{
pData->iColSpan = 1;
pData->iRowSpan = 1;
SetData(pData);
EDT_FreeTableCellData(pData);
}
pBuffer->ClearFillNewCellWithSpace();
}
// Move all contents of supplied cell into this cell
void CEditTableCellElement::MergeCells(CEditTableCellElement* pCell)
{

Просмотреть файл

@ -1021,7 +1021,7 @@ CEditSaveObject::~CEditSaveObject(){
if( m_status == ED_ERROR_NONE ){
// Save the last-used location into the history list
EDT_SyncPublishingHistory();
edt_SyncPublishingHistory(m_pBuffer->m_pContext);
} else {
// Save this URL so we can supply the "bad" location
// to user if they try to publish that URL again

Просмотреть файл

@ -5494,6 +5494,21 @@ char * EDT_GetDefaultPublishURL(MWContext * pMWContext, char **ppFilename, char
}
if( !bLastPublishFailed && !EDT_IS_NEW_DOCUMENT(pMWContext) ){
#if defined(SingleSignon)
// Check if we saved a username/password for this URL
char * pUserNameSingleSignon = NULL;
char * pPasswordSingleSignon = NULL;
SI_RestoreOldSignonDataFromBrowser(
pMWContext, pURL, FALSE, &pUserNameSingleSignon, &pPasswordSingleSignon);
if (pUserNameSingleSignon) {
*ppUserName = pUserNameSingleSignon;
*ppPassword = pPasswordSingleSignon;
// If we found a name, we assume the location part of
// URL is correct, so just return that
return EDT_ReplaceFilename(pURL, NULL, TRUE);
}
#endif
int iType = NET_URL_Type(pURL);
if( iType == FTP_TYPE_URL ||
iType == HTTP_TYPE_URL ||
@ -5605,8 +5620,7 @@ EDT_GetPublishingHistory(unsigned n,
return TRUE;
}
void
EDT_SyncPublishingHistory()
void edt_SyncPublishingHistory(MWContext *pMWContext)
{
char prefname[32];
char* prefvalue = NULL;
@ -5624,6 +5638,17 @@ EDT_SyncPublishingHistory()
return;
PREF_CopyCharPref("editor.publish_last_pass", &pLastPass);
#if defined(SingleSignon)
char *pLocation = NULL;
char *pUsername = NULL;
// Separate the location from the username
if( NET_ParseUploadURL( pLastLoc, &pLocation, &pUsername, NULL ))
{
SI_RememberSignonDataFromBrowser(
pMWContext, pLocation, pUsername, pLastPass);
}
#endif
/*
* First scan the list to find pref that matches new item
*/

Просмотреть файл

@ -459,7 +459,7 @@ lo_recolor_backgrounds(lo_DocState *state, LO_CellStruct *cell,
* never before payed attention to this attr
* so I'm guessing that it won't break anything :)
*/
tmp_attr.no_background = FALSE;
/* tmp_attr.no_background = FALSE; */
attr = lo_FetchTextAttr(state, &tmp_attr);
}

Просмотреть файл

@ -773,6 +773,8 @@ lo_DisplayElement(MWContext *context, LO_Element *tptr,
if (((LO_CellStruct*)tptr)->cell_inflow_layer)
break;
/* cmanske: reversed order so cell selection highlighing
shows up over text in the cell */
lo_DisplayCellContents(context, (LO_CellStruct *)tptr,
base_x, base_y, x, y, width, height);
lo_DisplayCell(context, (LO_CellStruct *)tptr);

Просмотреть файл

@ -698,8 +698,9 @@ void lo_MergeElements( MWContext *context, lo_DocState *old_state, int32 iStartL
}
else
{
#if 0
eptr = start_element;
//#if 0
eptr = /*start_element*/ old_line_array[iStartLine];
if( eptr )
{
*pRetHeight = eptr->lo_any.y - *pRetY + eptr->lo_any.line_height;
@ -708,7 +709,7 @@ void lo_MergeElements( MWContext *context, lo_DocState *old_state, int32 iStartL
{
*pRetHeight = -1;
}
#else
#if 0 //#else
XP_ASSERT(0);
*pRetHeight = -1;
#endif

Просмотреть файл

@ -723,7 +723,7 @@ lo_recolor_form_element_bg(lo_DocState *state, LO_FormElementStruct *form_ele,
/* removed by Lou 4-3-97. Allow text to
* overlap correctly in tables
*/
tmp_attr.no_background = FALSE;
/* tmp_attr.no_background = FALSE; */
attr = lo_FetchTextAttr(state, &tmp_attr);
}

Просмотреть файл

@ -3730,7 +3730,7 @@ XP_Bool LO_IsEmptyCell(LO_CellStruct *cell)
return TRUE;
}
/* The LO_CellStruct.width does not include border, cell padding etc and is complicated
/* The LO_CellStruct.width includes border, cell padding etc and is complicated
* by Column Span as well. Calculate the value to use for <TD WIDTH> param that
* would result in current pCellElement->lo_cell.width during the next layout
*/