📄 main.cpp
字号:
/******************************************************************************** Copyright (C) 2004-2007 Trolltech ASA. All rights reserved.**** This file is part of the demonstration applications of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include <QtGui>static QString encode_pos(int row, int col) { return QString(col + 'A') + QString::number(row + 1);}static void decode_pos(const QString &pos, int *row, int *col){ if (pos.isEmpty()) { *col = -1; *row = -1; } else { *col = pos.at(0).toLatin1() - 'A'; *row = pos.right(pos.size() - 1).toInt() - 1; }}class SpreadSheetDelegate : public QItemDelegate{ Q_OBJECTpublic: SpreadSheetDelegate(QObject *parent = 0); QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &index) const; void setEditorData(QWidget *editor, const QModelIndex &index) const; void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;private slots: void commitAndCloseEditor();};SpreadSheetDelegate::SpreadSheetDelegate(QObject *parent) : QItemDelegate(parent) {}QWidget *SpreadSheetDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem&, const QModelIndex &index) const{ if(index.column() == 1){ QDateTimeEdit *editor = new QDateTimeEdit(parent); editor->setDisplayFormat("dd/M/yyyy"); editor->setCalendarPopup(true); return editor; } QLineEdit *editor = new QLineEdit(parent); //create a completer with the strings in the column as model. QStringList allStrings; for(int i = 1; i<index.model()->rowCount(); i++){ QString strItem(index.model()->data(index.sibling(i, index.column()), Qt::EditRole).toString()); if(!allStrings.contains(strItem)) allStrings.append(strItem); } QCompleter *autoComplete = new QCompleter(allStrings); editor->setCompleter(autoComplete); connect(editor, SIGNAL(editingFinished()), this, SLOT(commitAndCloseEditor())); return editor;}void SpreadSheetDelegate::commitAndCloseEditor(){ QLineEdit *editor = qobject_cast<QLineEdit *>(sender()); emit commitData(editor); emit closeEditor(editor);}void SpreadSheetDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const{ QLineEdit *edit = qobject_cast<QLineEdit *>(editor); if (edit) { edit->setText(index.model()->data(index, Qt::EditRole).toString()); } else { QDateTimeEdit *dateEditor = qobject_cast<QDateTimeEdit *>(editor); if (dateEditor) { dateEditor->setDate(QDate::fromString(index.model()->data(index, Qt::EditRole).toString(), "d/M/yyyy")); } }}void SpreadSheetDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const{ QLineEdit *edit = qobject_cast<QLineEdit *>(editor); if (edit) { model->setData(index, edit->text()); } else { QDateTimeEdit *dateEditor = qobject_cast<QDateTimeEdit *>(editor); if (dateEditor) { model->setData(index, dateEditor->date().toString("dd/M/yyyy")); } }}class SpreadSheetItem : public QTableWidgetItem{public: SpreadSheetItem(); SpreadSheetItem(const QString &text); QTableWidgetItem *clone() const; QVariant data(int role) const; void setData(int role, const QVariant &value); QVariant display() const; inline QString formula() const { return QTableWidgetItem::data(Qt::DisplayRole).toString(); } static QVariant computeFormula(const QString &formula, const QTableWidget *widget, const QTableWidgetItem *self = 0);private: mutable bool isResolving;};SpreadSheetItem::SpreadSheetItem() : QTableWidgetItem(), isResolving(false) {}SpreadSheetItem::SpreadSheetItem(const QString &text) : QTableWidgetItem(text), isResolving(false) {}QTableWidgetItem *SpreadSheetItem::clone() const{ SpreadSheetItem *item = new SpreadSheetItem(); *item = *this; return item;}QVariant SpreadSheetItem::data(int role) const{ if (role == Qt::EditRole || role == Qt::StatusTipRole) return formula(); if (role == Qt::DisplayRole) return display(); QString t = display().toString(); bool isNumber = false; int number = t.toInt(&isNumber); if (role == Qt::TextColorRole) { if (!isNumber) return qVariantFromValue(QColor(Qt::black)); else if (number < 0) return qVariantFromValue(QColor(Qt::red)); return qVariantFromValue(QColor(Qt::blue)); } if (role == Qt::TextAlignmentRole) if (!t.isEmpty() && (t.at(0).isNumber() || t.at(0) == '-')) return (int)(Qt::AlignRight | Qt::AlignVCenter); return QTableWidgetItem::data(role);}void SpreadSheetItem::setData(int role, const QVariant &value){ QTableWidgetItem::setData(role, value); if (tableWidget()) tableWidget()->viewport()->update();}QVariant SpreadSheetItem::display() const{ // avoid circular dependencies if (isResolving) return QVariant(); isResolving = true; QVariant result = computeFormula(formula(), tableWidget(), this); isResolving = false; return result;}QVariant SpreadSheetItem::computeFormula(const QString &formula, const QTableWidget *widget, const QTableWidgetItem *self){ // check if the string is actually a formula or not QStringList list = formula.split(' '); if (list.isEmpty() || !widget) return formula; // its a normal string QString op = list.value(0).toLower(); int firstRow = -1; int firstCol = -1; int secondRow = -1; int secondCol = -1; if (list.count() > 1) decode_pos(list.value(1), &firstRow, &firstCol); if (list.count() > 2) decode_pos(list.value(2), &secondRow, &secondCol); const QTableWidgetItem *start = widget->item(firstRow, firstCol); const QTableWidgetItem *end = widget->item(secondRow, secondCol); int firstVal = start ? start->text().toInt() : 0; int secondVal = end ? end->text().toInt() : 0; QVariant result; if (op == "sum") { int sum = 0; for (int r = firstRow; r <= secondRow; ++r) { for (int c = firstCol; c <= secondCol; ++c) { const QTableWidgetItem *tableItem = widget->item(r, c); if (tableItem && tableItem != self) sum += tableItem->text().toInt(); } } result = sum; } else if (op == "+") { result = (firstVal + secondVal); } else if (op == "-") { result = (firstVal - secondVal); } else if (op == "*") { result = (firstVal * secondVal); } else if (op == "/") { if (secondVal == 0) result = QString("nan"); else result = (firstVal / secondVal); } else if (op == "=") { if (start) result = start->text(); } else { result = formula; } return result;}#if !defined(QT_NO_DBUS) && defined(Q_OS_UNIX)#include <QtDBus/QtDBus>class SpreadSheetAdaptor : public QDBusAbstractAdaptor{ Q_OBJECT Q_CLASSINFO("D-Bus Interface", "com.trolltech.DBus.SpreadSheetDemo")public: SpreadSheetAdaptor(QTableWidget *table) : QDBusAbstractAdaptor(table), table(table) { QDBusConnection::sessionBus().registerObject("/SpreadSheetDemo", table); }public slots: QString computeFormula(const QString &formula) { return SpreadSheetItem::computeFormula(formula, table).toString(); }private: QTableWidget *table;};#endif // QT_NO_DBUSclass SpreadSheet : public QMainWindow{ Q_OBJECTpublic: SpreadSheet(int rows, int cols, QWidget *parent = 0);public slots: void updateStatus(QTableWidgetItem *item); void updateColor(QTableWidgetItem *item); void updateLineEdit(QTableWidgetItem *item); void returnPressed(); void selectColor(); void selectFont(); void clear(); void showAbout(); void actionSum(); void actionSubtract(); void actionAdd(); void actionMultiply(); void actionDivide();protected: void setupContextMenu(); void setupContents(); void setupMenuBar(); void createActions(); void actionMath_helper(const QString &title, const QString &op); bool runInputDialog(const QString &title, const QString &c1Text, const QString &c2Text, const QString &opText, const QString &outText, QString *cell1, QString *cell2, QString *outCell);private: QToolBar *toolBar; QAction *colorAction; QAction *fontAction; QAction *firstSeparator; QAction *cell_sumAction; QAction *cell_addAction; QAction *cell_subAction; QAction *cell_mulAction; QAction *cell_divAction; QAction *secondSeparator; QAction *clearAction; QAction *aboutSpreadSheet; QAction *exitAction; QLabel *cellLabel; QTableWidget *table; QLineEdit *formulaInput;};SpreadSheet::SpreadSheet(int rows, int cols, QWidget *parent) : QMainWindow(parent){ addToolBar(toolBar = new QToolBar()); formulaInput = new QLineEdit(); cellLabel = new QLabel(toolBar); cellLabel->setMinimumSize(80, 0); toolBar->addWidget(cellLabel); toolBar->addWidget(formulaInput); table = new QTableWidget(rows, cols, this); for (int c = 0; c < cols; ++c) { QString character(QChar('A' + c)); table->setHorizontalHeaderItem(c, new QTableWidgetItem(character)); } table->setItemPrototype(table->item(rows - 1, cols - 1)); table->setItemDelegate(new SpreadSheetDelegate());#if !defined(QT_NO_DBUS) && defined(Q_OS_UNIX) new SpreadSheetAdaptor(table);#endif createActions(); updateColor(0); setupMenuBar(); setupContextMenu(); setupContents(); setCentralWidget(table); statusBar(); connect(table, SIGNAL(currentItemChanged(QTableWidgetItem*, QTableWidgetItem*)), this, SLOT(updateStatus(QTableWidgetItem*))); connect(table, SIGNAL(currentItemChanged(QTableWidgetItem*, QTableWidgetItem*)), this, SLOT(updateColor(QTableWidgetItem*))); connect(table, SIGNAL(currentItemChanged(QTableWidgetItem*, QTableWidgetItem*)), this, SLOT(updateLineEdit(QTableWidgetItem*))); connect(table, SIGNAL(itemChanged(QTableWidgetItem*)), this, SLOT(updateStatus(QTableWidgetItem*))); connect(formulaInput, SIGNAL(returnPressed()), this, SLOT(returnPressed())); connect(table, SIGNAL(itemChanged(QTableWidgetItem*)), this, SLOT(updateLineEdit(QTableWidgetItem*))); setWindowTitle(tr("Spreadsheet"));}void SpreadSheet::createActions(){ cell_sumAction = new QAction(tr("Sum"), this); connect(cell_sumAction, SIGNAL(triggered()), this, SLOT(actionSum())); cell_addAction = new QAction(tr("&Add"), this); cell_addAction->setShortcut(Qt::CTRL | Qt::Key_Plus); connect(cell_addAction, SIGNAL(triggered()), this, SLOT(actionAdd())); cell_subAction = new QAction(tr("&Subtract"), this); cell_subAction->setShortcut(Qt::CTRL | Qt::Key_Minus); connect(cell_subAction, SIGNAL(triggered()), this, SLOT(actionSubtract())); cell_mulAction = new QAction(tr("&Multiply"), this); cell_mulAction->setShortcut(Qt::CTRL | Qt::Key_multiply); connect(cell_mulAction, SIGNAL(triggered()), this, SLOT(actionMultiply())); cell_divAction = new QAction(tr("&Divide"), this); cell_divAction->setShortcut(Qt::CTRL | Qt::Key_division); connect(cell_divAction, SIGNAL(triggered()), this, SLOT(actionDivide())); fontAction = new QAction(tr("Font..."), this); fontAction->setShortcut(Qt::CTRL|Qt::Key_F); connect(fontAction, SIGNAL(triggered()), this, SLOT(selectFont())); colorAction = new QAction(QPixmap(16, 16), tr("Background &Color..."), this); connect(colorAction, SIGNAL(triggered()), this, SLOT(selectColor())); clearAction = new QAction(tr("Clear"), this); clearAction->setShortcut(Qt::Key_Delete); connect(clearAction, SIGNAL(triggered()), this, SLOT(clear())); aboutSpreadSheet = new QAction(tr("About Spreadsheet"), this); connect(aboutSpreadSheet, SIGNAL(triggered()), this, SLOT(showAbout())); exitAction = new QAction(tr("E&xit"), this); connect(exitAction, SIGNAL(triggered()), qApp, SLOT(quit())); firstSeparator = new QAction(this); firstSeparator->setSeparator(true); secondSeparator = new QAction(this); secondSeparator->setSeparator(true);}void SpreadSheet::setupMenuBar(){ QMenu *fileMenu = menuBar()->addMenu(tr("&File")); fileMenu->addAction(exitAction); QMenu *cellMenu = menuBar()->addMenu(tr("&Cell")); cellMenu->addAction(cell_addAction); cellMenu->addAction(cell_subAction); cellMenu->addAction(cell_mulAction); cellMenu->addAction(cell_divAction);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -