Spreadsheet: Issue #2301: Handle enter/return and tab keys the same as e.g OpenOffice and Excel.

This commit is contained in:
Eivind Kvedalen 2015-11-08 11:15:20 +01:00 committed by wmayer
parent 2e5175c7be
commit b7480210fd
9 changed files with 192 additions and 12 deletions

View File

@ -16,6 +16,7 @@ set(SpreadsheetGui_LIBS
)
set(SpreadsheetGui_MOC_HDRS
LineEdit.h
SpreadsheetView.h
SheetModel.h
SheetTableView.h
@ -55,6 +56,8 @@ SET(SpreadsheetGui_SRCS
AppSpreadsheetGui.cpp
AppSpreadsheetGuiPy.cpp
Command.cpp
LineEdit.h
LineEdit.cpp
ViewProviderSpreadsheet.cpp
ViewProviderSpreadsheet.h
Resources/Spreadsheet.qrc

View File

@ -0,0 +1,93 @@
/***************************************************************************
* Copyright (c) Eivind Kvedalen (eivind@kvedalen.name) 2015 *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <QEvent>
# include <QKeyEvent>
#endif
#include "LineEdit.h"
using namespace SpreadsheetGui;
LineEdit::LineEdit(QWidget *parent)
: Gui::ExpressionLineEdit(parent)
, current()
, deltaCol(0)
, deltaRow(0)
{
}
bool LineEdit::event(QEvent *event)
{
if (event && event->type() == QEvent::KeyPress) {
QKeyEvent * kevent = static_cast<QKeyEvent*>(event);
if (kevent->key() == Qt::Key_Tab) {
if (kevent->modifiers() == 0) {
deltaCol = 1;
deltaRow = 0;
Q_EMIT returnPressed();
return true;
}
}
else if (kevent->key() == Qt::Key_Backtab) {
if (kevent->modifiers() == Qt::ShiftModifier) {
deltaCol = -1;
deltaRow = 0;
Q_EMIT returnPressed();
return true;
}
}
else if (kevent->key() == Qt::Key_Enter || kevent->key() == Qt::Key_Return) {
if (kevent->modifiers() == 0) {
deltaCol = 0;
deltaRow = 1;
Q_EMIT returnPressed();
return true;
}
else if (kevent->modifiers() == Qt::ShiftModifier) {
deltaCol = 0;
deltaRow = -1;
Q_EMIT returnPressed();
return true;
}
}
}
return Gui::ExpressionLineEdit::event(event);
}
void LineEdit::setIndex(QModelIndex _current)
{
current = _current;
}
QModelIndex LineEdit::next() const
{
const QAbstractItemModel * m = current.model();
return m->index(qMin(qMax(0, current.row() + deltaRow), m->rowCount() - 1 ),
qMin(qMax(0, current.column() + deltaCol), m->columnCount() - 1 ) );
}
#include "moc_LineEdit.cpp"

View File

@ -0,0 +1,28 @@
#ifndef LINEEDIT_H
#define LINEEDIT_H
#include <Gui/ExpressionCompleter.h>
#include <QWidget>
#include <QModelIndex>
namespace SpreadsheetGui {
class LineEdit : public Gui::ExpressionLineEdit
{
Q_OBJECT
public:
explicit LineEdit(QWidget *parent = 0);
bool event(QEvent *event);
void setIndex(QModelIndex _current);
QModelIndex next() const;
private:
QModelIndex current;
int deltaCol;
int deltaRow;
};
}
#endif // LINEEDIT_H

View File

@ -27,7 +27,7 @@
</widget>
</item>
<item>
<widget class="Gui::ExpressionLineEdit" name="cellContent">
<widget class="SpreadsheetGui::LineEdit" name="cellContent">
<property name="enabled">
<bool>false</bool>
</property>
@ -47,9 +47,9 @@
<header>SheetTableView.h</header>
</customwidget>
<customwidget>
<class>Gui::ExpressionLineEdit</class>
<class>SpreadsheetGui::LineEdit</class>
<extends>QLineEdit</extends>
<header location="global">Gui/ExpressionCompleter.h</header>
<header>SpreadsheetView.h</header>
</customwidget>
</customwidgets>
<tabstops>

View File

@ -413,7 +413,6 @@ bool SheetModel::setData(const QModelIndex & index, const QVariant & value, int
try {
std::string strAddress = address.toString();
std::string next_address = CellAddress(address.row() + 1, address.col()).toString();
QString str = value.toString();
std::string content;
Cell * cell = sheet->getCell(address);
@ -426,8 +425,6 @@ bool SheetModel::setData(const QModelIndex & index, const QVariant & value, int
Gui::Command::openCommand("Edit cell");
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.set('%s', '%s')", sheet->getNameInDocument(),
strAddress.c_str(), str.toUtf8().constData());
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.setPosition('%s')", sheet->getNameInDocument(),
next_address.c_str());
Gui::Command::commitCommand();
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.recompute()");
}

View File

@ -22,16 +22,17 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <QKeyEvent>
# include <QAction>
#endif
#include "SheetTableView.h"
#include <QKeyEvent>
#include <QAction>
#include <Gui/Command.h>
#include "PropertiesDialog.h"
#include <boost/bind.hpp>
#include "../App/Utils.h"
#include "../App/Range.h"
#include <boost/bind.hpp>
#include "SheetTableView.h"
#include "LineEdit.h"
#include "PropertiesDialog.h"
using namespace SpreadsheetGui;
using namespace Spreadsheet;
@ -70,6 +71,7 @@ SheetTableView::SheetTableView(QWidget *parent)
addAction(cellProperties);
setContextMenuPolicy(Qt::ActionsContextMenu);
setTabKeyNavigation(false);
connect(cellProperties, SIGNAL(triggered()), this, SLOT(cellProperties()));
}
@ -290,6 +292,53 @@ bool SheetTableView::edit ( const QModelIndex & index, EditTrigger trigger, QEve
return QTableView::edit(index, trigger, event);
}
bool SheetTableView::event(QEvent *event)
{
/* Catch key presses for navigating the table; Enter/Return (+Shift), and Tab (+Shift) */
if (event && event->type() == QEvent::KeyPress) {
QKeyEvent * kevent = static_cast<QKeyEvent*>(event);
if (kevent->key() == Qt::Key_Tab) {
QModelIndex c = currentIndex();
if (kevent->modifiers() == 0) {
setCurrentIndex(model()->index(c.row(), qMin(c.column() + 1, model()->columnCount() -1)));
return true;
}
}
else if (kevent->key() == Qt::Key_Backtab) {
QModelIndex c = currentIndex();
if (kevent->modifiers() == Qt::ShiftModifier) {
setCurrentIndex(model()->index(c.row(), qMax(c.column() - 1, 0)));
return true;
}
}
else if (kevent->key() == Qt::Key_Enter || kevent->key() == Qt::Key_Return) {
QModelIndex c = currentIndex();
if (kevent->modifiers() == 0) {
setCurrentIndex(model()->index(qMin(c.row() + 1, model()->rowCount() - 1), c.column()));
return true;
}
else if (kevent->modifiers() == Qt::ShiftModifier) {
setCurrentIndex(model()->index(qMax(c.row() - 1, 0), c.column()));
return true;
}
}
}
return QTableView::event(event);
}
void SheetTableView::closeEditor(QWidget * editor, QAbstractItemDelegate::EndEditHint hint)
{
SpreadsheetGui::LineEdit * le = qobject_cast<SpreadsheetGui::LineEdit*>(editor);
currentEditIndex = QModelIndex();
QTableView::closeEditor(editor, hint);
setCurrentIndex(le->next());
}
void SheetTableView::edit ( const QModelIndex & index )
{
currentEditIndex = index;

View File

@ -25,6 +25,7 @@
#include <QTableView>
#include <QHeaderView>
#include <QKeyEvent>
#include <boost/signals/connection.hpp>
#include "PreCompiled.h"
#include <Mod/Spreadsheet/App/Sheet.h>
@ -64,6 +65,8 @@ protected Q_SLOTS:
void cellProperties();
protected:
bool edit(const QModelIndex &index, EditTrigger trigger, QEvent *event);
bool event(QEvent *event);
void closeEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint);
QModelIndex currentEditIndex;
Spreadsheet::Sheet * sheet;

View File

@ -29,6 +29,7 @@
#endif
#include "SpreadsheetDelegate.h"
#include "LineEdit.h"
#include <App/DocumentObject.h>
#include <Mod/Spreadsheet/App/Sheet.h>
#include <Gui/ExpressionCompleter.h>
@ -45,7 +46,8 @@ QWidget *SpreadsheetDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem &,
const QModelIndex &index) const
{
Gui::ExpressionLineEdit *editor = new Gui::ExpressionLineEdit(parent);
SpreadsheetGui::LineEdit *editor = new SpreadsheetGui::LineEdit(parent);
editor->setIndex(index);
editor->setDocumentObject(sheet);
connect(editor, SIGNAL(returnPressed()), this, SLOT(commitAndCloseEditor()));

View File

@ -50,6 +50,7 @@
#include <boost/bind.hpp>
#include <Mod/Spreadsheet/App/Utils.h>
#include "qtcolorpicker.h"
#include <LineEdit.h>
#include "ui_Sheet.h"
@ -198,6 +199,7 @@ void SheetView::updateContentLine()
if (cell)
cell->getStringContent(str);
ui->cellContent->setText(QString::fromUtf8(str.c_str()));
ui->cellContent->setIndex(i);
ui->cellContent->setEnabled(true);
// Update completer model; for the time being, we do this by setting the document object of the input line.
@ -289,6 +291,9 @@ void SheetView::editingFinished()
// Update data in cell
ui->cells->model()->setData(i, QVariant(ui->cellContent->text()), Qt::EditRole);
ui->cells->setCurrentIndex(ui->cellContent->next());
ui->cells->setFocus();
}
void SheetView::currentChanged ( const QModelIndex & current, const QModelIndex & previous )