Engauge Digitizer  2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
WindowModelBase.cpp
Go to the documentation of this file.
1 /******************************************************************************************************
2  * (C) 2016 markummitchell@github.com. This file is part of Engauge Digitizer, which is released *
3  * under GNU General Public License version 2 (GPLv2) or (at your option) any later version. See file *
4  * LICENSE or go to gnu.org/licenses for details. Distribution requires prior written permission. *
5  ******************************************************************************************************/
6 
7 #include "EngaugeAssert.h"
8 #include "Logger.h"
9 #include <QItemSelectionModel>
10 #include <QMimeData>
11 #include <QTableView>
12 #include <QTextStream>
13 #include "WindowModelBase.h"
14 #include "WindowTable.h"
15 
17  m_view (nullptr)
18 {
19 }
20 
22 {
23 }
24 
25 int WindowModelBase::fold2dIndexes (int row,
26  int col,
27  int rowLow,
28  int colLow,
29  int colHigh) const
30 {
31  return (row - rowLow) * (colHigh - colLow + 1) + (col - colLow);
32 }
33 
34 QMimeData *WindowModelBase::mimeData(const QModelIndexList &indexes) const
35 {
36  if (indexes.isEmpty ()) {
37  return nullptr;
38  }
39 
40  QMimeData *data = new QMimeData ();
41 
42  data->setHtml (selectionAsHtml ());
43  data->setText (selectionAsText (m_delimiter));
44 
45  return data;
46 }
47 
49 {
50  ENGAUGE_CHECK_PTR (m_view);
51 
52  int rowLow, colLow, rowHigh, colHigh;
53  QVector<QString> table;
54 
55  // Get raw data as a rectangular table. Size may be zero
56  selectionAsTable (rowLow,
57  colLow,
58  rowHigh,
59  colHigh,
60  table);
61 
62  // Concatenate table into output string
63  QString html;
64  QTextStream str (&html);
65 
66  str << "<table>";
67  for (int row = rowLow; row <= rowHigh; row++) {
68  str << "<tr>";
69  for (int col = colLow; col <= colHigh; col++) {
70  str << "<td>" << table [fold2dIndexes (row, col, rowLow, colLow, colHigh)] << "</td>";
71  }
72  str << "<tr>\n";
73  }
74  str << "</table>";
75 
76  return html;
77 }
78 
79 void WindowModelBase::selectionAsTable (int &rowLow,
80  int &colLow,
81  int &rowHigh,
82  int &colHigh,
83  QVector<QString> &table) const
84 {
85  // This algorithm supports any arbitrary set of selected cells. Specifically, the cells do not need
86  // to be in a rectangular pattern. A rectangular grid that encompasses all selected cells will be created
87 
88  QItemSelectionModel *selectionModel = m_view->selectionModel ();
89  QModelIndexList selection = selectionModel->selectedIndexes ();
90 
91  if (selection.size () > 0) {
92 
93  // Gather input. Initialization of row/col limits is needed only to keep some compilers happy
94  rowLow = 0;
95  colLow = 0;
96  rowHigh = 0;
97  colHigh = 0;
98  bool isFirst = true;
99  for (QModelIndexList::const_iterator itr = selection.begin(); itr != selection.end(); itr++) {
100  QModelIndex index = *itr;
101  if (isFirst || index.row () < rowLow ) rowLow = index.row ();
102  if (isFirst || index.row () > rowHigh) rowHigh = index.row ();
103  if (isFirst || index.column () < colLow ) colLow = index.column ();
104  if (isFirst || index.column () > colHigh) colHigh = index.column ();
105  isFirst = false;
106  }
107 
108  int numRows = rowHigh - rowLow + 1;
109  int numCols = colHigh - colLow + 1;
110 
111  // Put data into two dimensional rowXcolumn table is handled as a flattened vector. Table is initialized
112  // with empty strings
113  table.resize (numRows * numCols);
114 
115  for (int i = 0; i < selection.size (); i++) {
116  QModelIndex index = selection [i];
117  QVariant d = data (index);
118  QString text = d.toString ();
119  table [fold2dIndexes (index.row(), index.column(), rowLow, colLow, colHigh)] = text;
120  }
121  } else {
122 
123  // Table has zero size
124  rowLow = 0;
125  colLow = 0;
126  rowHigh = -1;
127  colHigh = -1;
128 
129  }
130 }
131 
133 {
134  const bool NOT_GNUPLOT = false;
135 
136  ENGAUGE_CHECK_PTR (m_view);
137 
138  int rowLow, colLow, rowHigh, colHigh;
139  QVector<QString> table;
140 
141  // Get raw data as a rectangular table. Size may be zero
142  selectionAsTable (rowLow,
143  colLow,
144  rowHigh,
145  colHigh,
146  table);
147 
148  // Concatenate table into output string
149  QString text;
150  QTextStream str (&text);
151  for (int row = rowLow; row <= rowHigh; row++) {
152  QString delimiterStr;
153  for (int col = colLow; col <= colHigh; col++) {
154  str << delimiterStr << table [fold2dIndexes (row, col, rowLow, colLow, colHigh)];
155  delimiterStr = exportDelimiterToText (delimiter,
156  NOT_GNUPLOT);
157  }
158  str << "\n";
159  }
160 
161  return text;
162 }
163 
165 {
166  m_delimiter = delimiter;
167 }
168 
170 {
171  m_view = &view;
172 }
virtual ~WindowModelBase()
ExportDelimiter
Delimiter values that may or may not be overridden by DOCUMENT_SERIALIZE_EXPORT_DELIMITER_OVERRIDE_CS...
QString selectionAsHtml() const
Convert the selection into exportable html which is good for spreadsheets.
#define ENGAUGE_CHECK_PTR(ptr)
#endif
Definition: EngaugeAssert.h:27
QString selectionAsText(ExportDelimiter delimiter) const
Convert the selection into exportable text which is good for text editors.
void setView(WindowTable &view)
Save the view so this class can access the current selection.
void setDelimiter(ExportDelimiter delimiter)
Save output delimiter.
Table view class with support for both drag-and-drop and copy-and-paste.
Definition: WindowTable.h:17
QString exportDelimiterToText(ExportDelimiter exportDelimiter, bool isGnuplotDelimiter)
WindowModelBase()
Single constructor.
QMimeData * mimeData(const QModelIndexList &indexes) const
Support dragging of multiple cells.