Code for Item View Chart Example
/****************************************************************************
**
** Copyright (C) 1992-2008 Nokia. All rights reserved.
**
** This file is part of Qt Jambi.
**
** * Commercial Usage
* Licensees holding valid Qt Commercial licenses may use this file in
* accordance with the Qt Commercial License Agreement provided with the
* Software or, alternatively, in accordance with the terms contained in
* a written agreement between you and Nokia.
*
*
* GNU General Public License Usage
* Alternatively, this file may be used under the terms of the GNU
* General Public License versions 2.0 or 3.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://www.fsf.org/licensing/licenses/info/GPLv2.html and
* http://www.gnu.org/copyleft/gpl.html. In addition, as a special
* exception, Nokia gives you certain additional rights. These rights
* are described in the Nokia Qt GPL Exception version 1.2, included in
* the file GPL_EXCEPTION.txt in this package.
*
* Qt for Windows(R) Licensees
* As a special exception, Nokia, 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.
*
*
* If you are unsure which license is appropriate for your use, please
* contact the sales department at qt-sales@nokia.com.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/
package com.trolltech.examples;
import com.trolltech.qt.core.*;
import com.trolltech.qt.gui.*;
import java.util.*;
@QtJambiExample(name = "Itemview Charts")
public class ItemviewChart extends QMainWindow {
private QAbstractItemModel model;
public static void main(String args[]) {
QApplication.initialize(args);
ItemviewChart mainW = new ItemviewChart();
mainW.show();
QApplication.exec();
}
public ItemviewChart() {
QMenu fileMenu = new QMenu(tr("&File"), this);
QAction openAction = new QAction(tr("&Open..."), this);
openAction.setShortcut(new QKeySequence(tr("Ctrl+O")));
openAction.triggered.connect(this, "openFile()");
fileMenu.addAction(openAction);
QAction saveAction = new QAction(tr("&Save As..."), this);
saveAction.setShortcut(new QKeySequence(tr("Ctrl+S")));
saveAction.triggered.connect(this, "saveFile()");
fileMenu.addAction(saveAction);
QAction quitAction = new QAction(tr("&Quit"), this);
quitAction.setShortcut(new QKeySequence(tr("Ctrl+Q")));
quitAction.triggered.connect(this, "close()");
fileMenu.addAction(quitAction);
setupModel();
setupViews();
menuBar().addMenu(fileMenu);
statusBar();
openFile("classpath:com/trolltech/examples/qtdata.cht");
setWindowTitle(tr("Chart"));
setWindowIcon(new QIcon("classpath:com/trolltech/images/qt-logo.png"));
resize(750, 500);
}
private void setupModel() {
model = new QStandardItemModel(8, 2, this);
model.setHeaderData(0, Qt.Orientation.Horizontal, tr("Label"));
model.setHeaderData(1, Qt.Orientation.Horizontal, tr("Quantity"));
}
private void setupViews() {
QSplitter splitter = new QSplitter();
QTableView table = new QTableView();
QAbstractItemView pieChart = new PieView(this);
splitter.addWidget(table);
splitter.addWidget(pieChart);
splitter.setStretchFactor(0, 0);
splitter.setStretchFactor(1, 1);
table.setModel(model);
pieChart.setModel(model);
QItemSelectionModel selectionModel = new QItemSelectionModel(model);
table.setSelectionModel(selectionModel);
pieChart.setSelectionModel(selectionModel);
setCentralWidget(splitter);
}
private void openFile() {
openFile("");
}
private void openFile(String path) {
String fileName;
if (path.equals(""))
fileName = QFileDialog.getOpenFileName(this, tr("Choose a data file"), "", new QFileDialog.Filter("*.cht"));
else
fileName = path;
if (!fileName.equals("")) {
QFile file = new QFile(fileName);
if (file.open(new QFile.OpenMode(QFile.OpenModeFlag.ReadOnly, QFile.OpenModeFlag.Text))) {
QTextStream stream = new QTextStream(file);
String line;
model.removeRows(0, model.rowCount(null), null);
int row = 0;
do {
line = stream.readLine();
if (!line.equals("")) {
model.insertRows(row, 1, null);
String[] pieces = line.split(",");
model.setData(model.index(row, 0, null), pieces[0].trim());
model.setData(model.index(row, 1, null), pieces[1].trim());
model.setData(model.index(row, 0, null), new QColor(pieces[2].trim()), Qt.ItemDataRole.DecorationRole);
row++;
}
} while (!line.equals(""));
file.close();
statusBar().showMessage(String.format(tr("Loaded %s"), fileName), 2000);
}
}
}
private void saveFile() {
String fileName = QFileDialog.getSaveFileName(this, tr("Save file as"), "", new QFileDialog.Filter("*.cht"));
if (!fileName.equals("")) {
QFile file = new QFile(fileName);
QTextStream stream = new QTextStream(file);
if (file.open(new QFile.OpenMode(QFile.OpenModeFlag.WriteOnly, QFile.OpenModeFlag.Text))) {
for (int row = 0; row < model.rowCount(null); ++row) {
stream.writeString(model.data(model.index(row, 0, null), Qt.ItemDataRole.DisplayRole).toString() + ",");
stream.writeString(model.data(model.index(row, 1, null), Qt.ItemDataRole.DisplayRole).toString() + ",");
stream.writeString(((QColor) model.data(model.index(row, 0, null), Qt.ItemDataRole.DecorationRole)).name());
stream.writeString("\n");
}
}
file.close();
statusBar().showMessage(String.format(tr("Saved %s"), fileName), 2000);
}
}
private class PieView extends QAbstractItemView {
private int margin;
private int totalSize;
private int pieSize;
private int validItems;
private double totalValue;
private QPoint origin;
private QRubberBand rubberBand;
public PieView(QWidget parent) {
super(parent);
horizontalScrollBar().setRange(0, 0);
verticalScrollBar().setRange(0, 0);
margin = 8;
totalSize = 300;
pieSize = totalSize - 2 * margin;
validItems = 0;
totalValue = 0.0;
}
@Override
protected void dataChanged(final QModelIndex topLeft, final QModelIndex bottomRight) {
super.dataChanged(topLeft, bottomRight);
validItems = 0;
totalValue = 0.0;
for (int row = 0; row < model().rowCount(rootIndex()); ++row) {
QModelIndex index = model().index(row, 1, rootIndex());
double value = toDouble(model().data(index));
if (value > 0.0) {
totalValue += value;
validItems++;
}
}
viewport().update();
}
@Override
protected boolean edit(final QModelIndex index, EditTrigger trigger, QEvent event) {
return false;
}
@Override
public QModelIndex indexAt(final QPoint point) {
if (validItems == 0)
return null;
int wx = point.x() + horizontalScrollBar().value();
int wy = point.y() + verticalScrollBar().value();
if (wx < totalSize) {
double cx = wx - totalSize / 2;
double cy = totalSize / 2 - wy;
double d = Math.pow(Math.pow(cx, 2) + Math.pow(cy, 2), 0.5);
if (d == 0 || d > pieSize / 2)
return null;
double angle = (180 / Math.PI) * Math.acos(cx / d);
if (cy < 0)
angle = 360 - angle;
double startAngle = 0.0;
for (int row = 0; row < model().rowCount(rootIndex()); ++row) {
QModelIndex index = model().index(row, 1, rootIndex());
double value = toDouble(model().data(index));
if (value > 0.0) {
double sliceAngle = 360 * value / totalValue;
if (angle >= startAngle && angle < (startAngle + sliceAngle))
return model().index(row, 1, rootIndex());
startAngle += sliceAngle;
}
}
}
return null;
}
@Override
protected boolean isIndexHidden(final QModelIndex index) {
return false;
}
QRect itemRect(final QModelIndex index) {
if (index == null)
return new QRect();
if (index.column() != 1)
return new QRect();
if (toDouble(model().data(index)) > 0.0) {
return new QRect(margin, margin, pieSize, pieSize);
}
return new QRect();
}
QRegion itemRegion(final QModelIndex index) {
if (index == null)
return null;
if (index.column() != 1)
return null;
if (toDouble(model().data(index)) <= 0.0)
return null;
double startAngle = 0.0;
for (int row = 0; row < model().rowCount(rootIndex()); ++row) {
QModelIndex sliceIndex = model().index(row, 1, rootIndex());
double value = toDouble(model().data(sliceIndex));
if (value > 0.0) {
double angle = 360 * value / totalValue;
if (sliceIndex.equals(index)) {
QPainterPath slicePath = new QPainterPath();
slicePath.moveTo(totalSize / 2, totalSize / 2);
slicePath.arcTo(margin, margin, margin + pieSize, margin + pieSize, startAngle, angle);
slicePath.closeSubpath();
return new QRegion(slicePath.toFillPolygon().toPolygon());
}
startAngle += angle;
}
}
return null;
}
@Override
protected int horizontalOffset() {
return horizontalScrollBar().value();
}
@Override
protected void mousePressEvent(QMouseEvent event) {
super.mousePressEvent(event);
origin = event.pos();
if (rubberBand == null)
rubberBand = new QRubberBand(QRubberBand.Shape.Rectangle, this);
rubberBand.setRubberBandGeometry(new QRect(origin, new QSize()));
rubberBand.show();
}
@Override
protected void mouseMoveEvent(QMouseEvent event) {
QRect rect = new QRect(origin, event.pos()).normalized();
rubberBand.setRubberBandGeometry(rect);
super.mouseMoveEvent(event);
QModelIndex underMouseIndex = indexAt(event.pos());
if (underMouseIndex == null)
setSelection(rect, selectionCommand(underMouseIndex, event));
viewport().update();
}
@Override
protected void mouseReleaseEvent(QMouseEvent event) {
super.mouseReleaseEvent(event);
rubberBand.hide();
viewport().update();
}
@Override
protected QModelIndex moveCursor(QAbstractItemView.CursorAction cursorAction, Qt.KeyboardModifiers modifiers) {
QModelIndex current = currentIndex();
switch (cursorAction) {
case MoveLeft:
case MoveUp:
if (current.row() > 0)
current = model().index(current.row() - 1, current.column(), rootIndex());
else
current = model().index(0, current.column(), rootIndex());
break;
case MoveRight:
case MoveDown:
if (current.row() < rows(current) - 1)
current = model().index(current.row() + 1, current.column(), rootIndex());
else
current = model().index(rows(current) - 1, current.column(), rootIndex());
break;
default:
break;
}
viewport().update();
return current;
}
@Override
protected void paintEvent(QPaintEvent event) {
QItemSelectionModel selections = selectionModel();
QStyleOptionViewItem option = viewOptions();
QBrush background = option.palette().base();
QPen foreground = new QPen(option.palette().color(QPalette.ColorRole.WindowText));
QPainter painter = new QPainter();
painter.begin(viewport());
painter.setRenderHint(QPainter.RenderHint.Antialiasing);
painter.fillRect(event.rect(), background);
painter.setPen(foreground);
QRect pieRect = new QRect(margin, margin, pieSize, pieSize);
if (validItems > 0) {
painter.save();
painter.translate(pieRect.x() - horizontalScrollBar().value(), pieRect.y() - verticalScrollBar().value());
painter.drawEllipse(0, 0, pieSize, pieSize);
double startAngle = 0.0;
int row;
for (row = 0; row < model().rowCount(rootIndex()); ++row) {
QModelIndex index = model().index(row, 1, rootIndex());
double value = toDouble(model().data(index));
if (value > 0.0) {
double angle = 360 * value / totalValue;
QModelIndex colorIndex = model().index(row, 0, rootIndex());
QColor color = (QColor) model().data(colorIndex, Qt.ItemDataRole.DecorationRole);
if (currentIndex() != null && currentIndex().equals(index) && selections.isSelected(index))
painter.setBrush(new QBrush(color, Qt.BrushStyle.Dense4Pattern));
else if (selections.isSelected(index))
painter.setBrush(new QBrush(color, Qt.BrushStyle.Dense3Pattern));
else
painter.setBrush(new QBrush(color));
painter.drawPie(0, 0, pieSize, pieSize, (int) (startAngle * 16), (int) (angle * 16));
startAngle += angle;
}
}
painter.restore();
}
painter.end();
}
@Override
protected void resizeEvent(QResizeEvent event) {
updateGeometries();
}
int rows(final QModelIndex index) {
return model().rowCount(model().parent(index));
}
@Override
protected void rowsInserted(final QModelIndex parent, int start, int end) {
for (int row = start; row <= end; ++row) {
QModelIndex index = model().index(row, 1, rootIndex());
double value = toDouble(model().data(index));
if (value > 0.0) {
totalValue += value;
validItems++;
}
}
super.rowsInserted(parent, start, end);
}
@Override
protected void rowsAboutToBeRemoved(final QModelIndex parent, int start, int end) {
for (int row = start; row <= end; ++row) {
QModelIndex index = model().index(row, 1, rootIndex());
double value = toDouble(model().data(index));
if (value > 0.0) {
totalValue -= value;
validItems--;
}
}
super.rowsAboutToBeRemoved(parent, start, end);
}
@Override
public void scrollTo(final QModelIndex index, ScrollHint hint) {
QRect area = viewport().rect();
QRect rect = visualRect(index);
if (rect.left() < area.left())
horizontalScrollBar().setValue(
horizontalScrollBar().value() + rect.left() - area.left());
else if (rect.right() > area.right())
horizontalScrollBar().setValue(
horizontalScrollBar().value() + Math.min(
rect.right() - area.right(), rect.left() - area.left()));
if (rect.top() < area.top())
verticalScrollBar().setValue(
verticalScrollBar().value() + rect.top() - area.top());
else if (rect.bottom() > area.bottom())
verticalScrollBar().setValue(
verticalScrollBar().value() + Math.min(
rect.bottom() - area.bottom(), rect.top() - area.top()));
update();
}
@Override
protected void setSelection(final QRect rect, QItemSelectionModel.SelectionFlags command) {
QRect contentsRect = rect.translated(horizontalScrollBar().value(), verticalScrollBar().value()).normalized();
int rows = model().rowCount(rootIndex());
int columns = model().columnCount(rootIndex());
Vector<QModelIndex> indexes = new Vector<QModelIndex>();
for (int row = 0; row < rows; ++row) {
for (int column = 0; column < columns; ++column) {
QModelIndex index = model().index(row, column, rootIndex());
QRegion region = itemRegion(index);
if (region != null && region.intersects(contentsRect))
indexes.add(index);
}
}
if (indexes.size() > 0) {
int firstRow = indexes.elementAt(0).row();
int lastRow = indexes.elementAt(0).row();
int firstColumn = indexes.elementAt(0).column();
int lastColumn = indexes.elementAt(0).column();
for (int i = 1; i < indexes.size(); ++i) {
firstRow = Math.min(firstRow, indexes.elementAt(i).row());
lastRow = Math.max(lastRow, indexes.elementAt(i).row());
firstColumn = Math.min(firstColumn, indexes.elementAt(i).column());
lastColumn = Math.max(lastColumn, indexes.elementAt(i).column());
}
QItemSelection selection = new QItemSelection(
model().index(firstRow, firstColumn, rootIndex()),
model().index(lastRow, lastColumn, rootIndex()));
selectionModel().select(selection, command);
} else {
QModelIndex noIndex = null;
QItemSelection selection = new QItemSelection(noIndex, noIndex);
selectionModel().select(selection, command);
}
update();
}
@Override
protected void updateGeometries() {
horizontalScrollBar().setPageStep(viewport().width());
horizontalScrollBar().setRange(0, Math.max(0, totalSize - viewport().width()));
verticalScrollBar().setPageStep(viewport().height());
verticalScrollBar().setRange(0, Math.max(0, totalSize - viewport().height()));
}
@Override
protected int verticalOffset() {
return verticalScrollBar().value();
}
@Override
public QRect visualRect(final QModelIndex index) {
QRect rect = itemRect(index);
if (rect.isValid())
return new QRect(rect.left() - horizontalScrollBar().value(), rect.top() - verticalScrollBar().value(), rect.width(), rect.height());
else
return rect;
}
@Override
protected QRegion visualRegionForSelection(final QItemSelection selection) {
int ranges = selection.size();
if (ranges == 0)
return new QRegion(new QRect());
QRegion region = new QRegion();
for (int i = 0; i < ranges; ++i) {
QItemSelectionRange range = selection.at(i);
for (int row = range.top(); row <= range.bottom(); ++row) {
for (int col = range.left(); col <= range.right(); ++col) {
QModelIndex index = model().index(row, col, rootIndex());
region = region.united(new QRegion(visualRect(index)));
}
}
}
return region;
}
}
private double toDouble(Object o) {
if (o instanceof String) {
try {
return Double.parseDouble((String) o);
} catch (NumberFormatException e) {
}
}
return 0;
}
}
Copyright © 2008 Nokia |
Trademarks |
Qt Jambi 4.4.3_01 |