[qet] [1636] Title block templates: improved span management

[ Thread Index | Date Index | More lists.tuxfamily.org/qet Archives ]


Revision: 1636
Author:   xavier
Date:     2012-04-08 22:51:40 +0200 (Sun, 08 Apr 2012)
Log Message:
-----------
Title block templates: improved span management

Modified Paths:
--------------
    branches/0.3/sources/titleblock/templatecommands.cpp
    branches/0.3/sources/titleblock/templatecommands.h
    branches/0.3/sources/titleblock/templateview.cpp
    branches/0.3/sources/titleblockcell.cpp
    branches/0.3/sources/titleblockcell.h
    branches/0.3/sources/titleblocktemplate.cpp
    branches/0.3/sources/titleblocktemplate.h

Modified: branches/0.3/sources/titleblock/templatecommands.cpp
===================================================================
--- branches/0.3/sources/titleblock/templatecommands.cpp	2012-04-08 19:04:06 UTC (rev 1635)
+++ branches/0.3/sources/titleblock/templatecommands.cpp	2012-04-08 20:51:40 UTC (rev 1636)
@@ -608,6 +608,9 @@
 	// store the former values of the row_span and col_span attributes of the spanning cell
 	row_span_before_ = spanning_cell_ -> row_span;
 	col_span_before_ = spanning_cell_ -> col_span;
+	applied_row_span_before_ = spanning_cell_ -> applied_row_span;
+	applied_col_span_before_ = spanning_cell_ -> applied_col_span;
+	span_state_before_ = spanning_cell_ -> span_state;
 	
 	// calculate their new values after the merge operation
 	TitleBlockCell *bottom_right_cell = getBottomRightCell(merged_cells);
@@ -671,9 +674,12 @@
 		cell -> spanner_cell = spanner_cells_before_merge_[cell];
 	}
 	
-	// restore the row_span and col_span attributes of the spanning cell
+	// restore the span-related attributes of the spanning cell
 	spanning_cell_ -> row_span = row_span_before_;
 	spanning_cell_ -> col_span = col_span_before_;
+	spanning_cell_ -> applied_row_span = applied_row_span_before_;
+	spanning_cell_ -> applied_col_span = applied_col_span_before_;
+	spanning_cell_ -> span_state = span_state_before_;
 	
 	if (view_) view_ -> updateLayout();
 }
@@ -693,6 +699,9 @@
 	// set the new values of the row_span and col_span attributes
 	spanning_cell_ -> row_span = row_span_after_;
 	spanning_cell_ -> col_span = col_span_after_;
+	spanning_cell_ -> applied_row_span = row_span_after_;
+	spanning_cell_ -> applied_col_span = col_span_after_;
+	spanning_cell_ -> span_state = TitleBlockCell::Enabled;
 	
 	if (view_) view_ -> updateLayout();
 }
@@ -745,6 +754,9 @@
 	spanned_cells_ = tbtemplate_ -> spannedCells(spanning_cell_);
 	row_span_before_ = spanning_cell_ -> row_span;
 	col_span_before_ = spanning_cell_ -> col_span;
+	applied_row_span_before_ = spanning_cell_ -> row_span;
+	applied_col_span_before_ = spanning_cell_ -> col_span;
+	span_state_before_ = spanning_cell_ -> span_state;
 	
 	setText(
 		QString(
@@ -805,6 +817,9 @@
 	// the spanning cell span again
 	spanning_cell_ -> row_span = row_span_before_;
 	spanning_cell_ -> col_span = col_span_before_;
+	spanning_cell_ -> applied_row_span = applied_row_span_before_;
+	spanning_cell_ -> applied_col_span = applied_col_span_before_;
+	spanning_cell_ -> span_state = span_state_before_;
 	
 	if (view_) view_ -> updateLayout();
 }
@@ -823,6 +838,7 @@
 	// the spanning cell does not span anymore
 	spanning_cell_ -> row_span = 0;
 	spanning_cell_ -> col_span = 0;
+	tbtemplate_ -> checkCellSpan(spanning_cell_);
 	
 	if (view_) view_ -> updateLayout();
 }
@@ -989,13 +1005,14 @@
 			if ((pasted_cell.row_span != cell -> row_span) || (pasted_cell.col_span != cell -> col_span)) {
 				tbtemplate_ -> forgetSpanning(cell);
 				
+				// Note: the code below is similar to TitleBlockTemplate::checkCell() but is more aggressive (spans deletion).
 				// set the new/pasted span parameters
 				cell -> row_span = qBound(0, pasted_cell.row_span, tbtemplate_ -> rowsCount() - 1 - cell -> num_row);
 				cell -> col_span = qBound(0, pasted_cell.col_span, tbtemplate_ -> columnsCount() - 1 - cell -> num_col);
 				
 				if (cell -> row_span || cell -> col_span) {
 					// browse newly spanned cells...
-					foreach (TitleBlockCell *spanned_cell, tbtemplate_ -> spannedCells(cell)) {
+					foreach (TitleBlockCell *spanned_cell, tbtemplate_ -> spannedCells(cell, true)) {
 						// ... to ensure they are not already spanned by other cells
 						if (spanned_cell -> spanner_cell && spanned_cell -> spanner_cell != cell) {
 							// if so, simply cancel the whole spanning

Modified: branches/0.3/sources/titleblock/templatecommands.h
===================================================================
--- branches/0.3/sources/titleblock/templatecommands.h	2012-04-08 19:04:06 UTC (rev 1635)
+++ branches/0.3/sources/titleblock/templatecommands.h	2012-04-08 20:51:40 UTC (rev 1636)
@@ -198,6 +198,9 @@
 	QHash<TitleBlockCell *, TitleBlockCell *> spanner_cells_before_merge_;
 	int row_span_before_; ///< the row_span attribute of the spanning cell before the merge
 	int col_span_before_; ///< the col_span attribute of the spanning cell before the merge
+	int applied_row_span_before_; ///< the applied_row_span attribute of the spanning cell before the merge
+	int applied_col_span_before_; ///< the applied_col_span attribute of the spanning cell before the merge
+	int span_state_before_; ///< the span_state attribute of the spanning cell before the merge
 	int row_span_after_;  ///< the row_span attribute of the spanning cell after the merge
 	int col_span_after_;  ///< the col_span attribute of the spanning cell after the merge
 };
@@ -222,8 +225,11 @@
 	private:
 	TitleBlockCell *spanning_cell_;        ///< the cell spanning over the other ones
 	QSet<TitleBlockCell *> spanned_cells_; ///< the spanned cells
-	int row_span_before_;                  ///< the row_span attribute of the spanning cell after the merge
-	int col_span_before_;                  ///< the col_span attribute of the spanning cell after the merge
+	int row_span_before_;                  ///< the row_span attribute of the spanning cell before splitting
+	int col_span_before_;                  ///< the col_span attribute of the spanning cell before splitting
+	int applied_row_span_before_;          ///< the applied_row_span attribute of the spanning cell before splitting
+	int applied_col_span_before_;          ///< the applied_col_span attribute of the spanning cell before splitting
+	int span_state_before_;                ///< the span_state attribute of the spanning cell before splitting
 };
 
 /**

Modified: branches/0.3/sources/titleblock/templateview.cpp
===================================================================
--- branches/0.3/sources/titleblock/templateview.cpp	2012-04-08 19:04:06 UTC (rev 1635)
+++ branches/0.3/sources/titleblock/templateview.cpp	2012-04-08 20:51:40 UTC (rev 1636)
@@ -648,8 +648,10 @@
 	QList<int> heights = tbtemplate_ -> rowsHeights();
 	for (int i = 0 ; i < row_count ; ++ i) {
 		HelperCell *current_row_cell = static_cast<HelperCell *>(tbgrid_ -> itemAt(ROW_OFFSET + i, 0));
-		current_row_cell -> setType(QET::Absolute); // rows always have absolute heights
-		current_row_cell -> label = QString(tr("%1px", "format displayed in rows helper cells")).arg(heights.at(i));
+		if (current_row_cell) {
+			current_row_cell -> setType(QET::Absolute); // rows always have absolute heights
+			current_row_cell -> label = QString(tr("%1px", "format displayed in rows helper cells")).arg(heights.at(i));
+		}
 	}
 }
 
@@ -661,8 +663,10 @@
 	for (int i = 0 ; i < col_count ; ++ i) {
 		TitleBlockDimension current_col_dim = tbtemplate_ -> columnDimension(i);
 		HelperCell *current_col_cell = static_cast<HelperCell *>(tbgrid_ -> itemAt(1, COL_OFFSET + i));
-		current_col_cell -> setType(current_col_dim.type);
-		current_col_cell -> label = current_col_dim.toString();
+		if (current_col_cell) {
+			current_col_cell -> setType(current_col_dim.type);
+			current_col_cell -> label = current_col_dim.toString();
+		}
 	}
 }
 
@@ -673,7 +677,6 @@
 void TitleBlockTemplateView::addCells() {
 	int col_count = tbtemplate_ -> columnsCount();
 	int row_count = tbtemplate_ -> rowsCount();
-	if (row_count < 1 || col_count < 1) return;
 	
 	// we add a big cell to show the total width
 	total_width_helper_cell_ = new SplittedHelperCell();
@@ -725,7 +728,13 @@
 			if (cell -> spanner_cell) continue;
 			TitleBlockTemplateVisualCell *cell_item = new TitleBlockTemplateVisualCell();
 			cell_item -> setTemplateCell(tbtemplate_, cell);
-			tbgrid_ -> addItem(cell_item, ROW_OFFSET + j, COL_OFFSET + i, cell -> row_span + 1, cell -> col_span + 1);
+			
+			int row_span = 0, col_span = 0;
+			if (cell -> span_state != TitleBlockCell::Disabled) {
+				row_span = cell -> applied_row_span;
+				col_span = cell -> applied_col_span;
+			}
+			tbgrid_ -> addItem(cell_item, ROW_OFFSET + j, COL_OFFSET + i, row_span + 1, col_span + 1);
 		}
 	}
 }
@@ -773,7 +782,6 @@
 	for (int i = 0 ; i < col_count ; ++ i) {
 		for (int j = 0 ; j < row_count ; ++ j) {
 			if (tbgrid_ -> itemAt(ROW_OFFSET + j, COL_OFFSET + i)) continue;
-			qDebug() << Q_FUNC_INFO << "looks like there is nothing there (" << j << "," << i << ")";
 			TitleBlockTemplateVisualCell *cell_item = new TitleBlockTemplateVisualCell();
 			if (TitleBlockCell *target_cell = tbtemplate_ -> cell(j, i)) {
 				qDebug() << Q_FUNC_INFO << "target_cell" << target_cell;

Modified: branches/0.3/sources/titleblockcell.cpp
===================================================================
--- branches/0.3/sources/titleblockcell.cpp	2012-04-08 19:04:06 UTC (rev 1635)
+++ branches/0.3/sources/titleblockcell.cpp	2012-04-08 20:51:40 UTC (rev 1636)
@@ -7,6 +7,8 @@
 	cell_type = TitleBlockCell::EmptyCell;
 	num_row = num_col = -1;
 	row_span = col_span = 0;
+	applied_row_span = applied_col_span = 0;
+	span_state = TitleBlockCell::Enabled;
 	spanner_cell = 0;
 	display_label = true;
 	alignment = Qt::AlignCenter | Qt::AlignVCenter;

Modified: branches/0.3/sources/titleblockcell.h
===================================================================
--- branches/0.3/sources/titleblockcell.h	2012-04-08 19:04:06 UTC (rev 1635)
+++ branches/0.3/sources/titleblockcell.h	2012-04-08 20:51:40 UTC (rev 1636)
@@ -30,6 +30,11 @@
 		TextCell,
 		LogoCell
 	};
+	enum TemplateCellSpanState {
+		Disabled,     ///< the cell span parameters should not applied at all
+		Enabled,      ///< the cell span parameters should be applied without restriction
+		Restricted    ///< the cell span parameters should be applied with some restrictions
+	};
 	
 	// Constructor, destructor
 	public:
@@ -58,6 +63,9 @@
 	int num_col;                       ///< x coordinate of the cell within its parent title block template grid
 	int row_span;                      ///< number of extra rows spanned by this cell
 	int col_span;                      ///< number of extra columns spanned by this cell
+	int span_state;                    ///< how should row_span and col_span be applied given other cells in the parent template
+	int applied_row_span;              ///< Actually applied row span
+	int applied_col_span;              ///< Actually applied column span
 	TitleBlockCell *spanner_cell;      ///< Cell spanning this cell, if any
 	QString value_name;                ///< name of the cell; not displayed when the title block template is rendered
 	NamesList value;                   ///< Text displayed by the cell

Modified: branches/0.3/sources/titleblocktemplate.cpp
===================================================================
--- branches/0.3/sources/titleblocktemplate.cpp	2012-04-08 19:04:06 UTC (rev 1635)
+++ branches/0.3/sources/titleblocktemplate.cpp	2012-04-08 20:51:40 UTC (rev 1636)
@@ -154,8 +154,8 @@
 	@return true if the export succeeds, false otherwise
 */
 bool TitleBlockTemplate::saveToXmlElement(QDomElement &xml_element) const {
-	// we are supposed to have at least one row/column and a name
-	if (!columnsCount() || !rowsCount() || name_.isEmpty()) return(false);
+	// we are supposed to have at least a name
+	if (name_.isEmpty()) return(false);
 	
 	xml_element.setTagName("titleblocktemplate");
 	xml_element.setAttribute("name", name_);
@@ -538,8 +538,6 @@
 #endif
 	
 	int row_num, col_num, row_span, col_span;
-	bool has_row_span = false;
-	bool has_col_span = false;
 	row_num = col_num = -1;
 	row_span = col_span = 0;
 	
@@ -565,28 +563,15 @@
 	
 	// parse the rowspan and colspan attributes
 	if (QET::attributeIsAnInteger(xml_element, "rowspan", &row_span) && row_span > 0) {
-		if (row_num + row_span >= row_count) row_span = row_count - 1 - row_num;
-		has_row_span = true;
+		cell_ptr -> row_span = row_span;
 	}
 	
 	if (QET::attributeIsAnInteger(xml_element, "colspan", &col_span) && col_span > 0) {
-		if (col_num + col_span >= col_count) col_span = col_count - 1 - col_num;
-		has_col_span = true;
+		cell_ptr -> col_span = col_span;
 	}
+	// these attributes are stored "as is" -- whether they can be applied directly or must be restricted will be checked later
 	
-	// check if we can span on the required area
-	//if (!checkCellSpan(cell_ptr)) return(false);
-	
-	// at this point, the cell is ok - we fill the adequate cells in the matrix
-#ifdef TITLEBLOCK_TEMPLATE_DEBUG
-	qDebug() << Q_FUNC_INFO << "cell writing";
-#endif
-	if (has_row_span) cell_ptr -> row_span = row_span;
-	if (has_col_span) cell_ptr -> col_span = col_span;
 	if (titleblock_cell_ptr) *titleblock_cell_ptr = cell_ptr;
-	
-	//applyCellSpan(cell_ptr);
-	
 	return(true);
 }
 
@@ -1004,15 +989,23 @@
 
 /**
 	@param cell A cell belonging to this title block template
+	@param ignore_span_state (Optional, defaults to false) If true, will consider
+	cells theoretically spanned (i.e. row_span and col_span attributes).
+	Otherwise, will take span_state attribute into account.
 	@return the set of cells spanned by the provided cell
 	Note the returned set does not include the spanning, provided cell
 */
-QSet<TitleBlockCell *> TitleBlockTemplate::spannedCells(const TitleBlockCell *given_cell) const {
+QSet<TitleBlockCell *> TitleBlockTemplate::spannedCells(const TitleBlockCell *given_cell, bool ignore_span_state) const {
 	QSet<TitleBlockCell *> set;
-	if (!given_cell || !given_cell -> spans()) return(set);
+	if (!given_cell) return(set);
+	if (!ignore_span_state && given_cell -> span_state == TitleBlockCell::Disabled) return(set);
 	
-	for (int i = given_cell -> num_col ; i <= given_cell -> num_col + given_cell -> col_span ; ++ i) {
-		for (int j = given_cell -> num_row ; j <= given_cell -> num_row + given_cell -> row_span ; ++ j) {
+	int final_row_span = ignore_span_state ? given_cell -> row_span : given_cell -> applied_row_span;
+	int final_col_span = ignore_span_state ? given_cell -> col_span : given_cell -> applied_col_span;
+	if (!final_row_span && !final_col_span) return(set);
+	
+	for (int i = given_cell -> num_col ; i <= given_cell -> num_col + final_col_span ; ++ i) {
+		for (int j = given_cell -> num_row ; j <= given_cell -> num_row + final_row_span ; ++ j) {
 			if (i == given_cell -> num_col && j == given_cell -> num_row) continue;
 			TitleBlockCell *current_cell = cell(j, i);
 			if (current_cell) set << current_cell;
@@ -1241,8 +1234,14 @@
 			// calculate the border rect of the current cell
 			int x = lengthRange(0, cells_[i][j] -> num_col, widths);
 			int y = lengthRange(0, cells_[i][j] -> num_row, rows_heights_);
-			int w = lengthRange(cells_[i][j] -> num_col, cells_[i][j] -> num_col + 1 + cells_[i][j] -> col_span, widths);
-			int h = lengthRange(cells_[i][j] -> num_row, cells_[i][j] -> num_row + 1 + cells_[i][j] -> row_span, rows_heights_);
+			
+			int row_span = 0, col_span = 0;
+			if (cells_[i][j] -> span_state != TitleBlockCell::Disabled) {
+				row_span = cells_[i][j] -> applied_row_span;
+				col_span = cells_[i][j] -> applied_col_span;
+			}
+			int w = lengthRange(cells_[i][j] -> num_col, cells_[i][j] -> num_col + 1 + col_span, widths);
+			int h = lengthRange(cells_[i][j] -> num_row, cells_[i][j] -> num_row + 1 + row_span, rows_heights_);
 			QRect cell_rect(x, y, w, h);
 			
 			renderCell(painter, *cells_[i][j], diagram_context, cell_rect);
@@ -1374,6 +1373,9 @@
 	if (modify_cell) {
 		spanning_cell -> row_span = 0;
 		spanning_cell -> col_span = 0;
+		spanning_cell -> applied_row_span = 0;
+		spanning_cell -> applied_col_span = 0;
+		spanning_cell -> span_state = TitleBlockCell::Enabled;
 	}
 }
 
@@ -1385,39 +1387,54 @@
 	forgetSpanning();
 	for (int i = 0 ; i < columns_width_.count() ; ++ i) {
 		for (int j = 0 ; j < rows_heights_.count() ; ++ j) {
-			if (checkCellSpan(cells_[i][j])) {
-				applyCellSpan(cells_[i][j]);
-			}
+			checkCellSpan(cells_[i][j]);
+			applyCellSpan(cells_[i][j]);
 		}
 	}
 }
 
 /**
-	Check whether a given cell can be spanned according to its row_span and col_span attributes
+	Check whether a given cell can be spanned according to its row_span and
+	col_span attributes. the following attributes of \a cell are updated
+	according to what is really possible:
+	  * applied_col_span
+	  * applied_row_span
+	  * span_state
 	@param cell Cell we want to check
-	@return true if the spanned
+	@return false if no check could be performed, true otherwise
 */
-bool TitleBlockTemplate::checkCellSpan(TitleBlockCell *cell/*, int policy = TitleBlockTemplate::???*/) {
+bool TitleBlockTemplate::checkCellSpan(TitleBlockCell *cell) {
 	if (!cell) return(false);
-	if (!cell -> row_span && !cell -> col_span) return(true);
 	
+	cell -> span_state = TitleBlockCell::Enabled;
+	cell -> applied_row_span = cell -> row_span;
+	cell -> applied_col_span = cell -> col_span;
+	
 	// ensure the cell can span as far as required
-	if (cell -> num_col + cell -> col_span >= columnsCount()) return(false);
-	if (cell -> num_row + cell -> row_span >= rowsCount()) return(false);
+	if (cell -> num_col + cell -> col_span >= columnsCount()) {
+		cell -> applied_col_span = columnsCount() - 1 - cell -> num_col;
+		cell -> span_state = TitleBlockCell::Restricted;
+	}
+	if (cell -> num_row + cell -> row_span >= rowsCount()) {
+		cell -> applied_row_span = rowsCount() - 1 - cell -> num_row;
+		cell -> span_state = TitleBlockCell::Restricted;
+	}
 	
-	// ensure cells that will be spanned are free/empty
-	for (int i = cell -> num_col ; i <= cell -> num_col + cell -> col_span ; ++ i) {
-		for (int j = cell -> num_row ; j <= cell -> num_row + cell -> row_span ; ++ j) {
+	// ensure cells that will be spanned are either empty or free
+	for (int i = cell -> num_col ; i <= cell -> num_col + cell -> applied_col_span ; ++ i) {
+		for (int j = cell -> num_row ; j <= cell -> num_row + cell -> applied_row_span ; ++ j) {
 			if (i == cell -> num_col && j == cell -> num_row) continue;
 #ifdef TITLEBLOCK_TEMPLATE_DEBUG
 			qDebug() << Q_FUNC_INFO << "span check" << i << j;
 #endif
 			TitleBlockCell *current_cell = cells_[i][j];
 			if (current_cell -> cell_type != TitleBlockCell::EmptyCell || (current_cell -> spanner_cell && current_cell -> spanner_cell != cell)) {
-				return(false);
+				cell -> span_state = TitleBlockCell::Disabled;
+				return(true);
 			}
 		}
 	}
+	
 	return(true);
 }
 
@@ -1428,10 +1445,11 @@
 */
 void TitleBlockTemplate::applyCellSpan(TitleBlockCell *cell) {
 	if (!cell || (!cell -> row_span && !cell -> col_span)) return;
+	if (cell -> span_state == TitleBlockCell::Disabled) return;
 	
 	// goes through every spanned cell
-	for (int i = cell -> num_col ; i <= cell -> num_col + cell -> col_span ; ++ i) {
-		for (int j = cell -> num_row ; j <= cell -> num_row + cell -> row_span ; ++ j) {
+	for (int i = cell -> num_col ; i <= cell -> num_col + cell -> applied_col_span ; ++ i) {
+		for (int j = cell -> num_row ; j <= cell -> num_row + cell -> applied_row_span ; ++ j) {
 			// avoid the spanning cell itself
 			if (i == cell -> num_col && j == cell -> num_row) continue;
 #ifdef TITLEBLOCK_TEMPLATE_DEBUG

Modified: branches/0.3/sources/titleblocktemplate.h
===================================================================
--- branches/0.3/sources/titleblocktemplate.h	2012-04-08 19:04:06 UTC (rev 1635)
+++ branches/0.3/sources/titleblocktemplate.h	2012-04-08 20:51:40 UTC (rev 1636)
@@ -82,7 +82,7 @@
 	QList<TitleBlockCell *> createColumn();
 	
 	TitleBlockCell *cell(int, int) const;
-	QSet<TitleBlockCell *> spannedCells(const TitleBlockCell *) const;
+	QSet<TitleBlockCell *> spannedCells(const TitleBlockCell *, bool = false) const;
 	QHash<TitleBlockCell *, QPair<int, int> > getAllSpans() const;
 	void setAllSpans(const QHash<TitleBlockCell *, QPair<int, int> > &);
 	bool addLogo(const QString &, QByteArray *, const QString & = "svg", const QString & = "xml");


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/