4.5 实现其他菜单
void Spreadsheet::recalculate()
{
/* recalculate()槽能够对Tools->Recalculate菜单选项做出响应。
* 当必要时,它也会被Spreadsheet自动调用。
* 我们遍历每一个单元格,并且对每一个单元格调用setDirty()把它们标记为需要重新计算。
* 为了在电子制表软件中显示一个Cell对象的值,QTableWidget会再次对该对象调用text()以获得其值,从而使该值重新计算一次。
* 然后,对这个视口调用update()来重新绘制整个电子制表软件。
* QTableWidget 中的重绘代码就又会对每一个可见单元格调用text()来获得它们中要显示的值。
* 因为在每一个单元格上都调用了setDirty() ,所以这些对text()的调用将会使用重新计算过的值。
* 该计算可能需要重新计算那些不可见的单元格,这就会造成一个级联计算,直到每一个需要被重新计算的单元格能够在刚才刷新过的视口中重新得到计算,从而使它们也能够显示正确的文本。
* 这一计算是由Cell类执行的。
*/
for (int row = 0; row < RowCount; ++row) {
for (int column = 0; column < ColumnCount; ++column) {
if (cell(row, column))
cell(row, column)->setDirty();
}
}
viewport()->update();
}
void Spreadsheet::setAutoRecalculate(bool recalc)
{
/* setAutoRecalculate()槽对Options->Auto-Recalculate菜单选项做出响应。
* 如果启用了这个特性,则会立即重新计算整个电子制表软件以确保它是最新的,
* 然后,recalculate()会自动在somethingChanged()中得到调用。
* 因为QTableWidget已经提供了一个从QTableView 中继承而来的setShowGrid()槽,所以不需要再对Options->Show Grid菜单选项编写任何代码。
* 所有要保留的东西就是Spreadsheet:sort(),它会以在MainWindow::sort()中得到调用:
*/
autoRecalc = recalc;
if (autoRecalc)
recalculate();
}
void Spreadsheet::sort(const SpreadsheetCompare &compare)
{
/* 排序操作会对当前的选择进行,并且会根据存储在compare对象中的排序键和排序顺序重新排列这些行。
* 我们使用一个QStringList来重新表示每一行数据,并且把该选择存储在一个行列表中。
* 我们使用Qt的qStableSort()算法,并且根据公式而不是根据值来进行简单排序。
* 这一过程如下图所示。第11章中会讲述Qt的标准算法和数据结构。
* qStableSort()函数可以接受一个开始迭代器、一个终止迭代器和一个比较函数。
* 这个比较函数是一个带两个参数(两个QStringList)的函数,并且如果第一个参数“小于”第二个参数,它就返回true,否则返回falsle。
* 传递的作为比较函数的这个compare对象并不是一个真正的函数,但是它可以用作一个函数,将会很快看到这一点。
* 在执行完qStableSort()之后,我们把数据移回到这个表中,接着清空这一选择,并且调用somethingChanged()函数。
*/
QList<QStringList> rows;
QTableWidgetSelectionRange range = selectedRange();
int i;
for (i = 0; i < range.rowCount(); ++i) {
QStringList row;
for (int j = 0; j < range.columnCount(); ++j)
row.append(formula(range.topRow() + i,
range.leftColumn() + j));
rows.append(row);
}
qStableSort(rows.begin(), rows.end(), compare);
for (i = 0; i < range.rowCount(); ++i) {
for (int j = 0; j < range.columnCount(); ++j)
setFormula(range.topRow() + i, range.leftColumn() + j,
rows[i][j]);
}
clearSelection();
somethingChanged();
}
//spreadsheet.h
class SpreadsheetCompare
{
public:
bool operator()(const QStringList &row1,
const QStringList &row2) const;
enum {
KeyCount = 3 };
int keys[KeyCount];
bool ascending[KeyCount];
//在这个头文件的最后,给出了SpreadsheetCompare类的定义。