2 * Cueplot: a GUI front-end to gnuplot
3 * Copyright (C) 2007, 2008 Muneyuki Noguchi
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 #include "PlotDataWidget.h"
21 #include "PlotListModel.h"
22 #include "PlotListView.h"
23 #include "PlotOptionDialog.h"
25 #include <QtCore/QMimeData>
26 #include <QtGui/QApplication>
27 #include <QtGui/QClipboard>
28 #include <QtGui/QGridLayout>
29 #include <QtGui/QPushButton>
31 PlotDataWidget::PlotDataWidget(QWidget *parent)
34 addPushButton = new QPushButton;
35 addPushButton->setText(tr("&Add"));
36 addPushButton->setEnabled(false);
37 addPushButton->setIcon(QIcon(":/images/add.png"));
38 connect(addPushButton, SIGNAL(clicked()),
39 this, SIGNAL(dataAdded()));
41 optionPushButton = new QPushButton;
42 optionPushButton->setText(tr("O&ption..."));
43 optionPushButton->setEnabled(false);
44 optionPushButton->setSizePolicy(
45 QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
46 connect(optionPushButton, SIGNAL(clicked()),
47 this, SLOT(setPlotOptions()));
49 upPushButton = new QPushButton;
50 upPushButton->setText(tr("&Up"));
51 upPushButton->setEnabled(false);
52 upPushButton->setIcon(QIcon(":/images/up.png"));
53 connect(upPushButton, SIGNAL(clicked()),
54 this, SLOT(setDataUp()));
56 downPushButton = new QPushButton;
57 downPushButton->setText(tr("&Down"));
58 downPushButton->setEnabled(false);
59 downPushButton->setIcon(QIcon(":/images/down.png"));
60 connect(downPushButton, SIGNAL(clicked()),
61 this, SLOT(setDataDown()));
63 deletePushButton = new QPushButton;
64 deletePushButton->setText(tr("D&elete"));
65 deletePushButton->setEnabled(false);
66 deletePushButton->setIcon(QIcon(":/images/remove.png"));
67 deletePushButton->setSizePolicy(
68 QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
69 connect(deletePushButton, SIGNAL(clicked()),
70 this, SLOT(deleteData()));
72 plotListModel = new PlotListModel;
74 plotListView = new PlotListView;
75 plotListView->setModel(plotListModel);
76 // Task Tracker at trolltech.com
77 // #182440 items are removed when using InternalMove drag drop mode
78 #if !defined(Q_OS_DARWIN) || QT_VERSION >= 0x040400
79 plotListView->setDragEnabled(true);
81 plotListView->setAcceptDrops(true);
82 plotListView->setDropIndicatorShown(true);
83 plotListView->setSelectionMode(QAbstractItemView::ExtendedSelection);
84 connect(plotListModel,
85 SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)),
86 this, SLOT(changeDialog(const QModelIndex &, const QModelIndex &)));
87 connect(plotListModel, SIGNAL(rowsInserted(const QModelIndex &, int, int)),
88 this, SLOT(insertDialog(const QModelIndex &, int, int)));
89 connect(plotListModel, SIGNAL(rowsRemoved(const QModelIndex &, int, int)),
90 this, SLOT(removeDialog(const QModelIndex &, int, int)));
91 connect(plotListModel, SIGNAL(rowsMoved(int, int)),
92 this, SLOT(moveDialog(int, int)));
94 selectionModel = plotListView->selectionModel();
95 connect(selectionModel,
96 SIGNAL(selectionChanged(const QItemSelection &,
97 const QItemSelection &)), this, SLOT(setPushButton()));
99 // ----------- assemble layouts and widgets
100 // ------------------------ create layouts
102 QGridLayout *mainLayout = new QGridLayout;
103 mainLayout->setMargin(0);
104 mainLayout->addWidget(addPushButton, 0, 0);
105 mainLayout->addWidget(optionPushButton, 1, 0);
106 mainLayout->addWidget(upPushButton, 2, 0);
107 mainLayout->addWidget(downPushButton, 3, 0);
108 // ウィンドウを最大化したときのことを考えて、QSpacerItem を入れる
109 mainLayout->addItem(new QSpacerItem(0, 0,
110 QSizePolicy::Minimum, QSizePolicy::Expanding), 4, 0);
111 mainLayout->addItem(new QSpacerItem(0, 0,
112 QSizePolicy::Expanding, QSizePolicy::Minimum), 5, 0, 1, 2);
113 mainLayout->addWidget(deletePushButton, 5, 2);
114 mainLayout->addWidget(plotListView, 0, 1, 5, 2);
116 setLayout(mainLayout);
119 void PlotDataWidget::addData(const Plot &plot)
122 QModelIndexList list = selectionModel->selectedIndexes();
123 int row = list.size() ? list.last().row() + 1 : plotListModel->rowCount();
126 plotListModel->insertRow(row);
129 plotListModel->setPlot(plotListModel->index(row), plot);
132 void PlotDataWidget::setDataUp()
137 void PlotDataWidget::setDataDown()
142 void PlotDataWidget::moveData(bool up)
144 QModelIndexList list = selectionModel->selectedIndexes();
145 int size = list.size();
151 for (int i = 0; i < size; i++) {
152 int row = list[i].row();
153 // 一番上にある項目はこれ以上、上に動かせない
155 plotListModel->moveRow(row, row - 1);
159 for (int i = size - 1; i >= 0; i--) {
160 int row = list[i].row();
161 // 一番下にある項目はこれ以上、下に動かせない
162 if (row < plotListModel->rowCount() - 1) {
163 plotListModel->moveRow(row, row + 1);
170 void PlotDataWidget::deleteData()
172 for (int i = 0, j = selectionModel->selectedIndexes().size(); i < j; i++) {
173 // 項目が削除されるとselectionModel->selectedIndexes()の中身が変わる
174 plotListModel->removeRow(
175 selectionModel->selectedIndexes().first().row());
179 void PlotDataWidget::setPushButton()
182 // オプションボタンと削除ボタンを有効にする
183 QModelIndexList list = selectionModel->selectedIndexes();
184 bool isSelected = list.size();
185 optionPushButton->setEnabled(isSelected);
186 deletePushButton->setEnabled(isSelected);
188 // 選択された項目があり、複数の項目がリスト中にあれば、
190 int count = plotListModel->rowCount();
191 bool isMulti = isSelected && (count > 1);
197 for (int i = 0, j = list.size(); i < j; i++) {
198 int row = list.at(i).row();
207 // 選択された項目のうち一番上の項目が一番上にあるときは上ボタンを無効にする
208 upPushButton->setEnabled(isMulti && min != 0);
209 // 選択された項目のうち一番下の項目が一番下にあるときは下ボタンを無効にする
210 downPushButton->setEnabled(isMulti && max != count - 1);
213 void PlotDataWidget::changeOption(const PlotOptionDialog &dialog,
214 const QList<Plot> &list)
217 // オプションを変えたダイアログをリストの中から探す
218 for (int i = 0, j = dialogList.size(); i < j; i++) {
219 const PlotOptionDialog *d = dialogList.at(i);
221 plotListModel->setPlot(plotListModel->index(i), list[idx]);
227 void PlotDataWidget::setAdditionEnabled(bool enable)
229 addPushButton->setEnabled(enable);
232 void PlotDataWidget::setPlotOptions()
234 QModelIndexList list = selectionModel->selectedIndexes();
235 int size = list.size();
239 PlotOptionDialog *plotOptionDialog = dialogList.at(list[0].row());
240 // 新しいダイアログウィンドウを開くかどうかを示すフラグ
241 // i) 対応ダイアログを開いたことのない項目がある
242 // ii) 既存のダイアログの対応項目の数と選択項目の数が一致しない
243 bool flag = (!plotOptionDialog
244 || (size != dialogList.count(plotOptionDialog)));
246 for (int i = 0; i < size; i++) {
247 // iii) 既存のダイアログの対応項目と選択項目が一致しない
248 PlotOptionDialog *d = dialogList.at(list[i].row());
249 if (d != plotOptionDialog) {
256 // 選択項目に対応する既存のダイアログウィンドウをすべて閉じる
257 for (int i = 0; i < size; i++) {
258 PlotOptionDialog *dialog = dialogList.at(list[i].row());
262 if (dialog->canClose()) {
263 deleteDialog(*dialog);
269 plotOptionDialog = new PlotOptionDialog;
271 for (int i = 0; i < size; i++) {
272 plot.append(plotListModel->plot(list[i]));
273 dialogList[list[i].row()] = plotOptionDialog;
275 plotOptionDialog->setPlot(plot);
276 connect(plotOptionDialog,
277 SIGNAL(optionChanged(const PlotOptionDialog &,
278 const QList<Plot> &)),
280 SLOT(changeOption(const PlotOptionDialog &,
281 const QList<Plot> &)));
283 plotOptionDialog->show();
284 plotOptionDialog->raise();
285 plotOptionDialog->activateWindow();
288 void PlotDataWidget::changeDialog(const QModelIndex &topLeft,
289 const QModelIndex &bottomRight)
291 for (int i = topLeft.row(), j = bottomRight.row(); i <= j; i++) {
292 PlotOptionDialog *plotOptionDialog = dialogList.at(i);
293 if (plotOptionDialog) {
296 while ((idx = dialogList.indexOf(plotOptionDialog, idx)) >= 0) {
297 list.append(plotListModel->plot(plotListModel->index(idx)));
300 plotOptionDialog->setPlot(list);
306 void PlotDataWidget::insertDialog(const QModelIndex &/*parent*/,
309 selectionModel->clear();
310 for (int i = start; i <= end; i++) {
311 dialogList.insert(i, 0);
312 selectionModel->select(plotListModel->index(i),
313 QItemSelectionModel::Select);
315 selectionModel->setCurrentIndex(plotListModel->index(end),
316 QItemSelectionModel::Select);
320 void PlotDataWidget::removeDialog(const QModelIndex &/*parent*/,
323 for (int i = start; i <= end; i++) {
324 deleteDialog(*dialogList.takeAt(start));
330 void PlotDataWidget::moveDialog(int from, int to)
332 dialogList.move(from, to);
334 selectionModel->select(plotListModel->index(from),
335 QItemSelectionModel::Deselect);
337 QModelIndex modelIndex = plotListModel->index(to);
338 selectionModel->select(modelIndex, QItemSelectionModel::Select);
339 selectionModel->setCurrentIndex(modelIndex,
340 QItemSelectionModel::Select);
343 void PlotDataWidget::setAction()
345 // チェックされている項目があるか調べる
346 bool isChecked = false;
347 for (int i = 0, j = plotListModel->rowCount(); i < j; i++) {
348 if (plotListModel->data(plotListModel->index(i),
349 Qt::CheckStateRole) == Qt::Checked) {
354 emit setPlotEnabled(isChecked);
357 bool PlotDataWidget::hasItem() const
359 return plotListModel->rowCount() > 0;
362 QStringList PlotDataWidget::commandList() const
364 QStringList commandList;
365 for (int i = 0, j = plotListModel->rowCount(); i < j; i++) {
366 QModelIndex modelIndex = plotListModel->index(i);
367 if (plotListModel->data(modelIndex,
368 Qt::CheckStateRole) == Qt::Checked) {
369 commandList << plotListModel->plot(modelIndex).command();
375 void PlotDataWidget::closeDialog()
377 while (!dialogList.isEmpty()) {
378 deleteDialog(*dialogList.takeFirst());
382 void PlotDataWidget::deleteDialog(PlotOptionDialog &plotOptionDialog)
384 if (!(&plotOptionDialog)) {
389 while ((idx = dialogList.indexOf(&plotOptionDialog, idx)) >= 0) {
393 delete &plotOptionDialog;
396 void PlotDataWidget::copy()
398 if (QWidget::focusWidget() != plotListView) {
401 QApplication::clipboard()->setMimeData(plotListModel->mimeData(
402 selectionModel->selectedIndexes()));
405 void PlotDataWidget::cut()
407 if (QWidget::focusWidget() != plotListView) {
414 void PlotDataWidget::paste()
416 const QMimeData *data = QApplication::clipboard()->mimeData();
420 QWidget *widget = QWidget::focusWidget();
421 if (widget != plotListView) {
424 QModelIndexList list = selectionModel->selectedIndexes();
425 int row = list.size() ? list.last().row() + 1 : plotListModel->rowCount();
426 if (data->hasFormat("application/vnd.row.list")) {
427 plotListModel->decodePlot(data, row);
428 } else if (data->hasUrls()) {
429 plotListModel->decodeUrl(data, row);
430 } else if (data->hasText()) {
431 plotListModel->decodeText(data, row);