labplot  2.8.2
About: LabPlot is an application for plotting and analysis of 2D and 3D functions and data. It is a complete rewrite of LabPlot1 and lacks in the first release a lot of features available in the predecessor. On the other hand, the GUI and the usability is more superior.
  Fossies Dox: labplot-2.8.2.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

Matrix.cpp
Go to the documentation of this file.
1 
2 /***************************************************************************
3  File : Matrix.cpp
4  Project : Matrix
5  Description : Spreadsheet with a MxN matrix data model
6  --------------------------------------------------------------------
7  Copyright : (C) 2008-2009 Tilman Benkert (thzs@gmx.net)
8  Copyright : (C) 2015-2017 Alexander Semke (alexander.semke@web.de)
9  Copyright : (C) 2017-2020 Stefan Gerlach (stefan.gerlach@uni.kn)
10 
11  ***************************************************************************/
12 
13 /***************************************************************************
14  * *
15  * This program is free software; you can redistribute it and/or modify *
16  * it under the terms of the GNU General Public License as published by *
17  * the Free Software Foundation; either version 2 of the License, or *
18  * (at your option) any later version. *
19  * *
20  * This program is distributed in the hope that it will be useful, *
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
23  * GNU General Public License for more details. *
24  * *
25  * You should have received a copy of the GNU General Public License *
26  * along with this program; if not, write to the Free Software *
27  * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
28  * Boston, MA 02110-1301 USA *
29  * *
30  ***************************************************************************/
31 
32 #include "Matrix.h"
33 #include "MatrixPrivate.h"
34 #include "matrixcommands.h"
36 #include "backend/core/Folder.h"
41 
42 #include <KLocalizedString>
43 #include <KConfig>
44 
45 #include <QHeaderView>
46 #include <QPrinter>
47 #include <QPrintDialog>
48 #include <QPrintPreviewDialog>
49 
50 /*!
51  This class manages matrix based data (i.e., mathematically
52  a MxN matrix with M rows, N columns). This data is typically
53  used to for 3D plots.
54 
55  The values of the matrix are stored as generic values. Each column
56  of the matrix is stored in a QVector<T> objects.
57 
58  \ingroup backend
59 */
60 Matrix::Matrix(int rows, int cols, const QString& name, const AbstractColumn::ColumnMode mode)
61  : AbstractDataSource(name, AspectType::Matrix), d(new MatrixPrivate(this, mode)) {
62 
63  //set initial number of rows and columns
64  appendColumns(cols);
65  appendRows(rows);
66 
67  init();
68 }
69 
70 Matrix::Matrix(const QString& name, bool loading, const AbstractColumn::ColumnMode mode)
71  : AbstractDataSource(name, AspectType::Matrix), d(new MatrixPrivate(this, mode)) {
72 
73  if (!loading)
74  init();
75 }
76 
78  delete d;
79 }
80 
81 void Matrix::init() {
82  KConfig config;
83  KConfigGroup group = config.group("Matrix");
84 
85  //matrix dimension
86  int rows = group.readEntry("RowCount", 10);
87  int cols = group.readEntry("ColumnCount", 10);
88  appendRows(rows);
89  appendColumns(cols);
90 
91  //mapping to logical x- and y-coordinates
92  d->xStart = group.readEntry("XStart", 0.0);
93  d->xEnd = group.readEntry("XEnd", 1.0);
94  d->yStart = group.readEntry("YStart", 0.0);
95  d->yEnd = group.readEntry("YEnd", 1.0);
96 
97  //format
98  QByteArray formatba = group.readEntry("NumericFormat", "f").toLatin1();
99  d->numericFormat = *formatba.data();
100  d->precision = group.readEntry("Precision", 3);
101  d->headerFormat = (Matrix::HeaderFormat)group.readEntry("HeaderFormat", static_cast<int>(HeaderFormat::HeaderRowsColumns));
102 }
103 
104 /*!
105  Returns an icon to be used for decorating my views.
106  */
107 QIcon Matrix::icon() const {
108  return QIcon::fromTheme("labplot-matrix");
109 }
110 
111 /*!
112  Returns a new context menu. The caller takes ownership of the menu.
113 */
115  QMenu* menu = AbstractPart::createContextMenu();
116  emit requestProjectContextMenu(menu);
117  return menu;
118 }
119 
120 QWidget* Matrix::view() const {
121  if (!m_partView) {
122  m_view = new MatrixView(const_cast<Matrix*>(this));
123  m_partView = m_view;
124  m_model = m_view->model();
125  }
126  return m_partView;
127 }
128 
129 bool Matrix::exportView() const {
130  auto* dlg = new ExportSpreadsheetDialog(m_view);
131  dlg->setFileName(name());
132  dlg->setMatrixMode(true);
133 
134  //TODO FITS filter to decide if it can be exported to both
135  dlg->setExportTo(QStringList() << i18n("FITS image") << i18n("FITS table"));
136  if (m_view->selectedColumnCount() == 0) {
137  dlg->setExportSelection(false);
138  }
139 
140  bool ret;
141  if ( (ret = (dlg->exec() == QDialog::Accepted)) ) {
142  const QString path = dlg->path();
143  WAIT_CURSOR;
144 
145  if (dlg->format() == ExportSpreadsheetDialog::Format::LaTeX) {
146  const bool verticalHeader = dlg->matrixVerticalHeader();
147  const bool horizontalHeader = dlg->matrixHorizontalHeader();
148  const bool latexHeader = dlg->exportHeader();
149  const bool gridLines = dlg->gridLines();
150  const bool entire = dlg->entireSpreadheet();
151  const bool captions = dlg->captions();
152  m_view->exportToLaTeX(path, verticalHeader, horizontalHeader,
153  latexHeader, gridLines, entire, captions);
154  } else if (dlg->format() == ExportSpreadsheetDialog::Format::FITS) {
155  const int exportTo = dlg->exportToFits();
156  m_view->exportToFits(path, exportTo );
157  } else {
158  const QString separator = dlg->separator();
159  const QLocale::Language format = dlg->numberFormat();
160  m_view->exportToFile(path, separator, format);
161  }
162  RESET_CURSOR;
163  }
164  delete dlg;
165 
166  return ret;
167 }
168 
170  QPrinter printer;
171  auto* dlg = new QPrintDialog(&printer, m_view);
172  bool ret;
173  dlg->setWindowTitle(i18nc("@title:window", "Print Matrix"));
174  if ( (ret = (dlg->exec() == QDialog::Accepted)) )
175  m_view->print(&printer);
176 
177  delete dlg;
178 
179  return ret;
180 }
181 
182 bool Matrix::printPreview() const {
183  auto* dlg = new QPrintPreviewDialog(m_view);
184  connect(dlg, &QPrintPreviewDialog::paintRequested, m_view, &MatrixView::print);
185  return dlg->exec();
186 }
187 
188 //##############################################################################
189 //########################## getter methods ##################################
190 //##############################################################################
191 void* Matrix::data() const {
192  return d->data;
193 }
194 
196 BASIC_D_READER_IMPL(Matrix, int, rowCount, rowCount)
197 BASIC_D_READER_IMPL(Matrix, int, columnCount, columnCount)
198 BASIC_D_READER_IMPL(Matrix, double, xStart, xStart)
199 BASIC_D_READER_IMPL(Matrix, double, xEnd, xEnd)
200 BASIC_D_READER_IMPL(Matrix, double, yStart, yStart)
201 BASIC_D_READER_IMPL(Matrix, double, yEnd, yEnd)
202 BASIC_D_READER_IMPL(Matrix, char, numericFormat, numericFormat)
204 BASIC_D_READER_IMPL(Matrix, Matrix::HeaderFormat, headerFormat, headerFormat)
205 CLASS_D_READER_IMPL(Matrix, QString, formula, formula)
206 
207 void Matrix::setSuppressDataChangedSignal(bool b) {
208  if (m_model)
209  m_model->setSuppressDataChangedSignal(b);
210 }
211 
213  if (m_model)
214  m_model->setChanged();
215 }
216 
217 //##############################################################################
218 //################# setter methods and undo commands ##########################
219 //##############################################################################
220 void Matrix::setRowCount(int count) {
221  if (count == d->rowCount)
222  return;
223 
224  const int diff = count - d->rowCount;
225  if (diff > 0)
226  appendRows(diff);
227  else if (diff < 0)
228  removeRows(rowCount() + diff, -diff);
229 }
230 
231 void Matrix::setColumnCount(int count) {
232  if (count == d->columnCount)
233  return;
234 
235  const int diff = count - columnCount();
236  if (diff > 0)
237  appendColumns(diff);
238  else if (diff < 0)
239  removeColumns(columnCount() + diff, -diff);
240 }
241 
242 STD_SETTER_CMD_IMPL_F_S(Matrix, SetXStart, double, xStart, updateViewHeader)
243 void Matrix::setXStart(double xStart) {
244  if (xStart != d->xStart)
245  exec(new MatrixSetXStartCmd(d, xStart, ki18n("%1: x-start changed")));
246 }
247 
248 STD_SETTER_CMD_IMPL_F_S(Matrix, SetXEnd, double, xEnd, updateViewHeader)
249 void Matrix::setXEnd(double xEnd) {
250  if (xEnd != d->xEnd)
251  exec(new MatrixSetXEndCmd(d, xEnd, ki18n("%1: x-end changed")));
252 }
253 
254 STD_SETTER_CMD_IMPL_F_S(Matrix, SetYStart, double, yStart, updateViewHeader)
255 void Matrix::setYStart(double yStart) {
256  if (yStart != d->yStart)
257  exec(new MatrixSetYStartCmd(d, yStart, ki18n("%1: y-start changed")));
258 }
259 
260 STD_SETTER_CMD_IMPL_F_S(Matrix, SetYEnd, double, yEnd, updateViewHeader)
261 void Matrix::setYEnd(double yEnd) {
262  if (yEnd != d->yEnd)
263  exec(new MatrixSetYEndCmd(d, yEnd, ki18n("%1: y-end changed")));
264 }
265 
266 STD_SETTER_CMD_IMPL_S(Matrix, SetNumericFormat, char, numericFormat)
267 void Matrix::setNumericFormat(char format) {
268  if (format != d->numericFormat)
269  exec(new MatrixSetNumericFormatCmd(d, format, ki18n("%1: numeric format changed")));
270 }
271 
272 STD_SETTER_CMD_IMPL_S(Matrix, SetPrecision, int, precision)
273 void Matrix::setPrecision(int precision) {
274  if (precision != d->precision)
275  exec(new MatrixSetPrecisionCmd(d, precision, ki18n("%1: precision changed")));
276 }
277 
278 //TODO: make this undoable?
279 void Matrix::setHeaderFormat(Matrix::HeaderFormat format) {
280  d->headerFormat = format;
282 
283  if (m_view)
285 
286  emit headerFormatChanged(format);
287 }
288 
289 //columns
290 void Matrix::insertColumns(int before, int count) {
291  if (count < 1 || before < 0 || before > columnCount()) return;
292  WAIT_CURSOR;
293  exec(new MatrixInsertColumnsCmd(d, before, count));
294  RESET_CURSOR;
295 }
296 
297 void Matrix::appendColumns(int count) {
298  insertColumns(columnCount(), count);
299 }
300 
301 void Matrix::removeColumns(int first, int count) {
302  if (count < 1 || first < 0 || first+count > columnCount()) return;
303  WAIT_CURSOR;
304  switch (d->mode) {
306  exec(new MatrixRemoveColumnsCmd<double>(d, first, count));
307  break;
309  exec(new MatrixRemoveColumnsCmd<QString>(d, first, count));
310  break;
312  exec(new MatrixRemoveColumnsCmd<int>(d, first, count));
313  break;
315  exec(new MatrixRemoveColumnsCmd<qint64>(d, first, count));
316  break;
320  exec(new MatrixRemoveColumnsCmd<QDateTime>(d, first, count));
321  break;
322  }
323  RESET_CURSOR;
324 }
325 
326 void Matrix::clearColumn(int c) {
327  WAIT_CURSOR;
328  switch (d->mode) {
331  break;
334  break;
337  break;
340  break;
345  break;
346  }
347  RESET_CURSOR;
348 }
349 
350 //rows
351 void Matrix::insertRows(int before, int count) {
352  if (count < 1 || before < 0 || before > rowCount()) return;
353  WAIT_CURSOR;
354  exec(new MatrixInsertRowsCmd(d, before, count));
355  RESET_CURSOR;
356 }
357 
358 void Matrix::appendRows(int count) {
359  insertRows(rowCount(), count);
360 }
361 
362 void Matrix::removeRows(int first, int count) {
363  if (count < 1 || first < 0 || first+count > rowCount()) return;
364  WAIT_CURSOR;
365  switch (d->mode) {
367  exec(new MatrixRemoveRowsCmd<double>(d, first, count));
368  break;
370  exec(new MatrixRemoveRowsCmd<QString>(d, first, count));
371  break;
373  exec(new MatrixRemoveRowsCmd<int>(d, first, count));
374  break;
376  exec(new MatrixRemoveRowsCmd<qint64>(d, first, count));
377  break;
381  exec(new MatrixRemoveRowsCmd<QDateTime>(d, first, count));
382  break;
383  }
384  RESET_CURSOR;
385 }
386 
387 void Matrix::clearRow(int r) {
388  switch (d->mode) {
390  for (int c = 0; c < columnCount(); ++c)
391  exec(new MatrixSetCellValueCmd<double>(d, r, c, 0.0));
392  break;
394  for (int c = 0; c < columnCount(); ++c)
395  exec(new MatrixSetCellValueCmd<QString>(d, r, c, QString()));
396  break;
398  for (int c = 0; c < columnCount(); ++c)
399  exec(new MatrixSetCellValueCmd<int>(d, r, c, 0));
400  break;
402  for (int c = 0; c < columnCount(); ++c)
403  exec(new MatrixSetCellValueCmd<qint64>(d, r, c, 0));
404  break;
408  for (int c = 0; c < columnCount(); ++c)
409  exec(new MatrixSetCellValueCmd<QDateTime>(d, r, c, QDateTime()));
410  break;
411  }
412 }
413 
414 //! Return the value in the given cell (needs explicit instantiation)
415 template <typename T>
416 T Matrix::cell(int row, int col) const {
417  return d->cell<T>(row, col);
418 }
419 template double Matrix::cell<double>(int row, int col) const;
420 template int Matrix::cell<int>(int row, int col) const;
421 template qint64 Matrix::cell<qint64>(int row, int col) const;
422 template QDateTime Matrix::cell<QDateTime>(int row, int col) const;
423 template QString Matrix::cell<QString>(int row, int col) const;
424 
425 //! Return the text displayed in the given cell (needs explicit instantiation)
426 template <typename T>
427 QString Matrix::text(int row, int col) {
429  return numberLocale.toString(cell<T>(row,col));
430 }
431 template <>
432 QString Matrix::text<double>(int row, int col) {
434  return numberLocale.toString(cell<double>(row,col), d->numericFormat, d->precision);
435 }
436 template <>
437 QString Matrix::text<QString>(int row, int col) {
438  return cell<QString>(row,col);
439 }
440 template QString Matrix::text<int>(int row, int col);
441 template QString Matrix::text<qint64>(int row, int col);
442 template QString Matrix::text<QDateTime>(int row, int col);
443 
444 //! Set the value of the cell (needs explicit instantiation)
445 template <typename T>
446 void Matrix::setCell(int row, int col, T value) {
447  if (row < 0 || row >= rowCount()) return;
448  if (col < 0 || col >= columnCount()) return;
449  exec(new MatrixSetCellValueCmd<T>(d, row, col, value));
450 }
451 template void Matrix::setCell<double>(int row, int col, double value);
452 template void Matrix::setCell<int>(int row, int col, int value);
453 template void Matrix::setCell<qint64>(int row, int col, qint64 value);
454 template void Matrix::setCell<QString>(int row, int col, QString value);
455 template void Matrix::setCell<QDateTime>(int row, int col, QDateTime value);
456 
457 void Matrix::clearCell(int row, int col) {
458  switch (d->mode) {
460  exec(new MatrixSetCellValueCmd<double>(d, row, col, 0.0));
461  break;
463  exec(new MatrixSetCellValueCmd<QString>(d, row, col, QString()));
464  break;
466  exec(new MatrixSetCellValueCmd<int>(d, row, col, 0));
467  break;
469  exec(new MatrixSetCellValueCmd<qint64>(d, row, col, 0));
470  break;
474  exec(new MatrixSetCellValueCmd<QDateTime>(d, row, col, QDateTime()));
475  break;
476  }
477 }
478 
479 void Matrix::setDimensions(int rows, int cols) {
480  if ( (rows < 0) || (cols < 0 ) || (rows == rowCount() && cols == columnCount()) )
481  return;
482 
483  WAIT_CURSOR;
484  beginMacro(i18n("%1: set matrix size to %2x%3", name(), rows, cols));
485 
486  int col_diff = cols - columnCount();
487  if (col_diff > 0)
488  insertColumns(columnCount(), col_diff);
489  else if (col_diff < 0)
490  removeColumns(columnCount() + col_diff, -col_diff);
491 
492  int row_diff = rows - rowCount();
493  if (row_diff > 0)
494  appendRows(row_diff);
495  else if (row_diff < 0)
496  removeRows(rowCount() + row_diff, -row_diff);
497 
498  endMacro();
499  RESET_CURSOR;
500 }
501 
502 void Matrix::copy(Matrix* other) {
503  WAIT_CURSOR;
504  beginMacro(i18n("%1: copy %2", name(), other->name()));
505 
506  int rows = other->rowCount();
507  int columns = other->columnCount();
508  setDimensions(rows, columns);
509 
510  for (int i = 0; i < rows; i++)
511  setRowHeight(i, other->rowHeight(i));
512 
513  for (int i = 0; i < columns; i++)
514  setColumnWidth(i, other->columnWidth(i));
515 
516  d->suppressDataChange = true;
517  switch (d->mode) {
519  for (int i = 0; i < columns; i++)
520  setColumnCells(i, 0, rows-1, other->columnCells<double>(i, 0, rows-1));
521  break;
523  for (int i = 0; i < columns; i++)
524  setColumnCells(i, 0, rows-1, other->columnCells<QString>(i, 0, rows-1));
525  break;
527  for (int i = 0; i < columns; i++)
528  setColumnCells(i, 0, rows-1, other->columnCells<int>(i, 0, rows-1));
529  break;
531  for (int i = 0; i < columns; i++)
532  setColumnCells(i, 0, rows-1, other->columnCells<qint64>(i, 0, rows-1));
533  break;
537  for (int i = 0; i < columns; i++)
538  setColumnCells(i, 0, rows-1, other->columnCells<QDateTime>(i, 0, rows-1));
539  break;
540  }
541 
542  setCoordinates(other->xStart(), other->xEnd(), other->yStart(), other->yEnd());
543  setNumericFormat(other->numericFormat());
544  setPrecision(other->precision());
545  d->formula = other->formula();
546  d->suppressDataChange = false;
547  emit dataChanged(0, 0, rows-1, columns-1);
548  if (m_view)
550 
551  endMacro();
552  RESET_CURSOR;
553 }
554 
555 //! Duplicate the matrix inside its folder
557  Matrix* matrix = new Matrix(rowCount(), columnCount(), name());
558  matrix->copy(this);
559  if (folder())
560  folder()->addChild(matrix);
561 }
562 
564  if (!m_view) return;
565  WAIT_CURSOR;
566  int count = m_view->selectedRowCount(false);
567  beginMacro(i18np("%1: add %2 rows", "%1: add %2 rows", name(), count));
568  exec(new MatrixInsertRowsCmd(d, rowCount(), count));
569  endMacro();
570  RESET_CURSOR;
571 }
572 
574  if (!m_view) return;
575  WAIT_CURSOR;
576  int count = m_view->selectedRowCount(false);
577  beginMacro(i18np("%1: add %2 column", "%1: add %2 columns", name(), count));
578  exec(new MatrixInsertColumnsCmd(d, columnCount(), count));
579  endMacro();
580  RESET_CURSOR;
581 }
582 
583 void Matrix::setCoordinates(double x1, double x2, double y1, double y2) {
584  exec(new MatrixSetCoordinatesCmd(d, x1, x2, y1, y2));
585 }
586 
587 void Matrix::setFormula(const QString& formula) {
588  exec(new MatrixSetFormulaCmd(d, formula));
589 }
590 
591 //! This method should only be called by the view.
592 /** This method does not change the view, it only changes the
593  * values that are saved when the matrix is saved. The view
594  * has to take care of reading and applying these values */
595 void Matrix::setRowHeight(int row, int height) {
596  d->setRowHeight(row, height);
597 }
598 
599 //! This method should only be called by the view.
600 /** This method does not change the view, it only changes the
601  * values that are saved when the matrix is saved. The view
602  * has to take care of reading and applying these values */
603 void Matrix::setColumnWidth(int col, int width) {
604  d->setColumnWidth(col, width);
605 }
606 
607 int Matrix::rowHeight(int row) const {
608  return d->rowHeight(row);
609 }
610 
611 int Matrix::columnWidth(int col) const {
612  return d->columnWidth(col);
613 }
614 
615 //! Return the values in the given cells as vector
616 template <typename T>
617 QVector<T> Matrix::columnCells(int col, int first_row, int last_row) {
618  return d->columnCells<T>(col, first_row, last_row);
619 }
620 
621 //! Set the values in the given cells from a type T vector
622 template <typename T>
623 void Matrix::setColumnCells(int col, int first_row, int last_row, const QVector<T>& values) {
624  WAIT_CURSOR;
625  exec(new MatrixSetColumnCellsCmd<T>(d, col, first_row, last_row, values));
626  RESET_CURSOR;
627 }
628 
629 //! Return the values in the given cells as vector (needs explicit instantiation)
630 template <typename T>
631 QVector<T> Matrix::rowCells(int row, int first_column, int last_column) {
632  return d->rowCells<T>(row, first_column, last_column);
633 }
634 template QVector<double> Matrix::rowCells<double>(int row, int first_column, int last_column);
635 template QVector<QString> Matrix::rowCells<QString>(int row, int first_column, int last_column);
636 template QVector<int> Matrix::rowCells<int>(int row, int first_column, int last_column);
637 template QVector<QDateTime> Matrix::rowCells<QDateTime>(int row, int first_column, int last_column);
638 
639 //! Set the values in the given cells from a type T vector
640 template <typename T>
641 void Matrix::setRowCells(int row, int first_column, int last_column, const QVector<T>& values) {
642  WAIT_CURSOR;
643  exec(new MatrixSetRowCellsCmd<T>(d, row, first_column, last_column, values));
644  RESET_CURSOR;
645 }
646 
647 void Matrix::setData(void* data) {
648  bool isEmpty = false;
649 
650  switch (d->mode) {
652  if (static_cast<QVector<QVector<double>>*>(data)->isEmpty())
653  isEmpty = true;
654  break;
656  if (static_cast<QVector<QVector<QString>>*>(data)->isEmpty())
657  isEmpty = true;
658  break;
660  if (static_cast<QVector<QVector<int>>*>(data)->isEmpty())
661  isEmpty = true;
662  break;
664  if (static_cast<QVector<QVector<qint64>>*>(data)->isEmpty())
665  isEmpty = true;
666  break;
670  if (static_cast<QVector<QVector<QDateTime>>*>(data)->isEmpty())
671  isEmpty = true;
672  break;
673  }
674 
675  if (!isEmpty)
677 }
678 
679 //##############################################################################
680 //######################### Public slots #####################################
681 //##############################################################################
682 //! Clear the whole matrix (i.e. reset all cells)
684  WAIT_CURSOR;
685  beginMacro(i18n("%1: clear", name()));
686  switch (d->mode) {
689  break;
692  break;
694  exec(new MatrixClearCmd<int>(d));
695  break;
698  break;
703  break;
704  }
705  endMacro();
706  RESET_CURSOR;
707 }
708 
710  WAIT_CURSOR;
711  switch (d->mode) {
714  break;
717  break;
720  break;
723  break;
728  break;
729  }
730  RESET_CURSOR;
731 }
732 
734  WAIT_CURSOR;
735  switch (d->mode) {
738  break;
741  break;
744  break;
747  break;
752  break;
753  }
754  RESET_CURSOR;
755 }
756 
758  WAIT_CURSOR;
759  switch (d->mode) {
762  break;
765  break;
768  break;
771  break;
776  break;
777  }
778  RESET_CURSOR;
779 }
780 
781 //##############################################################################
782 //###################### Private implementation ###############################
783 //##############################################################################
784 
786  : q(owner), data(nullptr), mode(m), rowCount(0), columnCount(0), suppressDataChange(false) {
787 
788  switch (mode) {
790  data = new QVector<QVector<double>>();
791  break;
794  break;
796  data = new QVector<QVector<int>>();
797  break;
799  data = new QVector<QVector<qint64>>();
800  break;
805  break;
806  }
807 }
808 
810  if (data) {
811  switch (mode) {
813  delete static_cast<QVector<QVector<double>>*>(data);
814  break;
816  delete static_cast<QVector<QVector<QString>>*>(data);
817  break;
819  delete static_cast<QVector<QVector<int>>*>(data);
820  break;
822  delete static_cast<QVector<QVector<qint64>>*>(data);
823  break;
827  delete static_cast<QVector<QVector<QDateTime>>*>(data);
828  break;
829  }
830  }
831 }
832 
834  q->m_view->model()->updateHeader();
835 }
836 
837 /*!
838  Insert \p count columns before column number \c before
839 */
840 void MatrixPrivate::insertColumns(int before, int count) {
841  Q_ASSERT(before >= 0);
842  Q_ASSERT(before <= columnCount);
843 
844  emit q->columnsAboutToBeInserted(before, count);
845  switch (mode) {
847  for (int i = 0; i < count; i++) {
848  static_cast<QVector<QVector<double>>*>(data)->insert(before+i, QVector<double>(rowCount));
849  columnWidths.insert(before+i, 0);
850  }
851  break;
853  for (int i = 0; i < count; i++) {
854  static_cast<QVector<QVector<QString>>*>(data)->insert(before+i, QVector<QString>(rowCount));
855  columnWidths.insert(before+i, 0);
856  }
857  break;
859  for (int i = 0; i < count; i++) {
860  static_cast<QVector<QVector<int>>*>(data)->insert(before+i, QVector<int>(rowCount));
861  columnWidths.insert(before+i, 0);
862  }
863  break;
865  for (int i = 0; i < count; i++) {
866  static_cast<QVector<QVector<qint64>>*>(data)->insert(before+i, QVector<qint64>(rowCount));
867  columnWidths.insert(before+i, 0);
868  }
869  break;
873  for (int i = 0; i < count; i++) {
874  static_cast<QVector<QVector<QDateTime>>*>(data)->insert(before+i, QVector<QDateTime>(rowCount));
875  columnWidths.insert(before+i, 0);
876  }
877  break;
878  }
879 
880  columnCount += count;
881  emit q->columnsInserted(before, count);
882 }
883 
884 /*!
885  Remove \c count columns starting with column index \c first
886 */
887 void MatrixPrivate::removeColumns(int first, int count) {
888  emit q->columnsAboutToBeRemoved(first, count);
889  Q_ASSERT(first >= 0);
890  Q_ASSERT(first + count <= columnCount);
891 
892  switch (mode) {
894  (static_cast<QVector<QVector<double>>*>(data))->remove(first, count);
895  break;
897  (static_cast<QVector<QVector<QString>>*>(data))->remove(first, count);
898  break;
900  (static_cast<QVector<QVector<int>>*>(data))->remove(first, count);
901  break;
903  (static_cast<QVector<QVector<qint64>>*>(data))->remove(first, count);
904  break;
908  (static_cast<QVector<QVector<QDateTime>>*>(data))->remove(first, count);
909  break;
910  }
911 
912  for (int i = 0; i < count; i++)
913  columnWidths.remove(first);
914  columnCount -= count;
915  emit q->columnsRemoved(first, count);
916 }
917 
918 /*!
919  Insert \c count rows before row with the index \c before
920 */
921 void MatrixPrivate::insertRows(int before, int count) {
922  emit q->rowsAboutToBeInserted(before, count);
923  Q_ASSERT(before >= 0);
924  Q_ASSERT(before <= rowCount);
925 
926  switch (mode) {
928  for (int col = 0; col < columnCount; col++)
929  for (int i = 0; i < count; i++)
930  (static_cast<QVector<QVector<double>>*>(data))->operator[](col).insert(before+i, 0.0);
931  break;
933  for (int col = 0; col < columnCount; col++)
934  for (int i = 0; i < count; i++)
935  (static_cast<QVector<QVector<QString>>*>(data))->operator[](col).insert(before+i, QString());
936  break;
938  for (int col = 0; col < columnCount; col++)
939  for (int i = 0; i < count; i++)
940  (static_cast<QVector<QVector<int>>*>(data))->operator[](col).insert(before+i, 0);
941  break;
943  for (int col = 0; col < columnCount; col++)
944  for (int i = 0; i < count; i++)
945  (static_cast<QVector<QVector<qint64>>*>(data))->operator[](col).insert(before+i, 0);
946  break;
950  for (int col = 0; col < columnCount; col++)
951  for (int i = 0; i < count; i++)
952  (static_cast<QVector<QVector<QDateTime>>*>(data))->operator[](col).insert(before+i, QDateTime());
953  }
954 
955  for (int i = 0; i < count; i++)
956  rowHeights.insert(before+i, 0);
957 
958  rowCount += count;
959  emit q->rowsInserted(before, count);
960 }
961 
962 /*!
963  Remove \c count columns starting from the column with index \c first
964 */
965 void MatrixPrivate::removeRows(int first, int count) {
966  emit q->rowsAboutToBeRemoved(first, count);
967  Q_ASSERT(first >= 0);
968  Q_ASSERT(first+count <= rowCount);
969 
970  switch (mode) {
972  for (int col = 0; col < columnCount; col++)
973  (static_cast<QVector<QVector<double>>*>(data))->operator[](col).remove(first, count);
974  break;
976  for (int col = 0; col < columnCount; col++)
977  (static_cast<QVector<QVector<QString>>*>(data))->operator[](col).remove(first, count);
978  break;
980  for (int col = 0; col < columnCount; col++)
981  (static_cast<QVector<QVector<int>>*>(data))->operator[](col).remove(first, count);
982  break;
984  for (int col = 0; col < columnCount; col++)
985  (static_cast<QVector<QVector<qint64>>*>(data))->operator[](col).remove(first, count);
986  break;
990  for (int col = 0; col < columnCount; col++)
991  (static_cast<QVector<QVector<QDateTime>>*>(data))->operator[](col).remove(first, count);
992  break;
993  }
994 
995  for (int i = 0; i < count; i++)
996  rowHeights.remove(first);
997 
998  rowCount -= count;
999  emit q->rowsRemoved(first, count);
1000 }
1001 
1002 //! Fill column with zeroes
1004  switch (mode) {
1006  static_cast<QVector<QVector<double>>*>(data)->operator[](col).fill(0.0);
1007  break;
1009  static_cast<QVector<QVector<QString>>*>(data)->operator[](col).fill(QString());
1010  break;
1012  static_cast<QVector<QVector<int>>*>(data)->operator[](col).fill(0);
1013  break;
1015  static_cast<QVector<QVector<qint64>>*>(data)->operator[](col).fill(0);
1016  break;
1020  static_cast<QVector<QVector<QDateTime>>*>(data)->operator[](col).fill(QDateTime());
1021  break;
1022  }
1023 
1024  if (!suppressDataChange)
1025  emit q->dataChanged(0, col, rowCount-1, col);
1026 }
1027 
1028 //##############################################################################
1029 //################## Serialization/Deserialization ###########################
1030 //##############################################################################
1031 void Matrix::save(QXmlStreamWriter* writer) const {
1032  DEBUG("Matrix::save()");
1033  writer->writeStartElement("matrix");
1034  writeBasicAttributes(writer);
1035  writeCommentElement(writer);
1036 
1037  //formula
1038  writer->writeStartElement("formula");
1039  writer->writeCharacters(d->formula);
1040  writer->writeEndElement();
1041 
1042  //format
1043  writer->writeStartElement("format");
1044  writer->writeAttribute("mode", QString::number(static_cast<int>(d->mode)));
1045  writer->writeAttribute("headerFormat", QString::number(static_cast<int>(d->headerFormat)));
1046  writer->writeAttribute("numericFormat", QString(QChar(d->numericFormat)));
1047  writer->writeAttribute("precision", QString::number(d->precision));
1048  writer->writeEndElement();
1049 
1050  //dimensions
1051  writer->writeStartElement("dimension");
1052  writer->writeAttribute("columns", QString::number(d->columnCount));
1053  writer->writeAttribute("rows", QString::number(d->rowCount));
1054  writer->writeAttribute("x_start", QString::number(d->xStart));
1055  writer->writeAttribute("x_end", QString::number(d->xEnd));
1056  writer->writeAttribute("y_start", QString::number(d->yStart));
1057  writer->writeAttribute("y_end", QString::number(d->yEnd));
1058  writer->writeEndElement();
1059 
1060  //vector with row heights
1061  writer->writeStartElement("row_heights");
1062  const char* data = reinterpret_cast<const char*>(d->rowHeights.constData());
1063  int size = d->rowHeights.size() * sizeof(int);
1064  writer->writeCharacters(QByteArray::fromRawData(data,size).toBase64());
1065  writer->writeEndElement();
1066 
1067  //vector with column widths
1068  writer->writeStartElement("column_widths");
1069  data = reinterpret_cast<const char*>(d->columnWidths.constData());
1070  size = d->columnWidths.size()*sizeof(int);
1071  writer->writeCharacters(QByteArray::fromRawData(data, size).toBase64());
1072  writer->writeEndElement();
1073 
1074  //columns
1075  DEBUG(" mode = " << static_cast<int>(d->mode));
1076  switch (d->mode) {
1078  size = d->rowCount*sizeof(double);
1079  for (int i = 0; i < d->columnCount; ++i) {
1080  data = reinterpret_cast<const char*>(static_cast<QVector<QVector<double>>*>(d->data)->at(i).constData());
1081  writer->writeStartElement("column");
1082  writer->writeCharacters(QByteArray::fromRawData(data, size).toBase64());
1083  writer->writeEndElement();
1084  }
1085  break;
1087  size = d->rowCount*sizeof(QString);
1088  for (int i = 0; i < d->columnCount; ++i) {
1089  QDEBUG(" string: " << static_cast<QVector<QVector<QString>>*>(d->data)->at(i));
1090  data = reinterpret_cast<const char*>(static_cast<QVector<QVector<QString>>*>(d->data)->at(i).constData());
1091  writer->writeStartElement("column");
1092  writer->writeCharacters(QByteArray::fromRawData(data, size).toBase64());
1093  writer->writeEndElement();
1094  }
1095  break;
1097  size = d->rowCount*sizeof(int);
1098  for (int i = 0; i < d->columnCount; ++i) {
1099  data = reinterpret_cast<const char*>(static_cast<QVector<QVector<int>>*>(d->data)->at(i).constData());
1100  writer->writeStartElement("column");
1101  writer->writeCharacters(QByteArray::fromRawData(data, size).toBase64());
1102  writer->writeEndElement();
1103  }
1104  break;
1106  size = d->rowCount*sizeof(qint64);
1107  for (int i = 0; i < d->columnCount; ++i) {
1108  data = reinterpret_cast<const char*>(static_cast<QVector<QVector<qint64>>*>(d->data)->at(i).constData());
1109  writer->writeStartElement("column");
1110  writer->writeCharacters(QByteArray::fromRawData(data, size).toBase64());
1111  writer->writeEndElement();
1112  }
1113  break;
1117  size = d->rowCount*sizeof(QDateTime);
1118  for (int i = 0; i < d->columnCount; ++i) {
1119  data = reinterpret_cast<const char*>(static_cast<QVector<QVector<QDateTime>>*>(d->data)->at(i).constData());
1120  writer->writeStartElement("column");
1121  writer->writeCharacters(QByteArray::fromRawData(data, size).toBase64());
1122  writer->writeEndElement();
1123  }
1124  break;
1125  }
1126 
1127  writer->writeEndElement(); // "matrix"
1128 }
1129 
1130 bool Matrix::load(XmlStreamReader* reader, bool preview) {
1131  DEBUG("Matrix::load()");
1132  if (!readBasicAttributes(reader))
1133  return false;
1134 
1135  KLocalizedString attributeWarning = ki18n("Attribute '%1' missing or empty, default value is used");
1136  QXmlStreamAttributes attribs;
1137  QString str;
1138 
1139  // read child elements
1140  while (!reader->atEnd()) {
1141  reader->readNext();
1142 
1143  if (reader->isEndElement() && reader->name() == "matrix")
1144  break;
1145 
1146  if (!reader->isStartElement())
1147  continue;
1148 
1149  if (reader->name() == "comment") {
1150  if (!readCommentElement(reader)) return false;
1151  } else if (!preview && reader->name() == "formula") {
1152  d->formula = reader->text().toString().trimmed();
1153  } else if (!preview && reader->name() == "format") {
1154  attribs = reader->attributes();
1155 
1156  str = attribs.value("mode").toString();
1157  if (str.isEmpty())
1158  reader->raiseWarning(attributeWarning.subs("mode").toString());
1159  else
1160  d->mode = AbstractColumn::ColumnMode(str.toInt());
1161 
1162  str = attribs.value("headerFormat").toString();
1163  if (str.isEmpty())
1164  reader->raiseWarning(attributeWarning.subs("headerFormat").toString());
1165  else
1166  d->headerFormat = Matrix::HeaderFormat(str.toInt());
1167 
1168  str = attribs.value("numericFormat").toString();
1169  if (str.isEmpty())
1170  reader->raiseWarning(attributeWarning.subs("numericFormat").toString());
1171  else {
1172  QByteArray formatba = str.toLatin1();
1173  d->numericFormat = *formatba.data();
1174  }
1175 
1176  str = attribs.value("precision").toString();
1177  if (str.isEmpty())
1178  reader->raiseWarning(attributeWarning.subs("precision").toString());
1179  else
1180  d->precision = str.toInt();
1181 
1182  } else if (!preview && reader->name() == "dimension") {
1183  attribs = reader->attributes();
1184 
1185  str = attribs.value("columns").toString();
1186  if (str.isEmpty())
1187  reader->raiseWarning(attributeWarning.subs("columns").toString());
1188  else
1189  d->columnCount = str.toInt();
1190 
1191  str = attribs.value("rows").toString();
1192  if (str.isEmpty())
1193  reader->raiseWarning(attributeWarning.subs("rows").toString());
1194  else
1195  d->rowCount = str.toInt();
1196 
1197  str = attribs.value("x_start").toString();
1198  if (str.isEmpty())
1199  reader->raiseWarning(attributeWarning.subs("x_start").toString());
1200  else
1201  d->xStart = str.toDouble();
1202 
1203  str = attribs.value("x_end").toString();
1204  if (str.isEmpty())
1205  reader->raiseWarning(attributeWarning.subs("x_end").toString());
1206  else
1207  d->xEnd = str.toDouble();
1208 
1209  str = attribs.value("y_start").toString();
1210  if (str.isEmpty())
1211  reader->raiseWarning(attributeWarning.subs("y_start").toString());
1212  else
1213  d->yStart = str.toDouble();
1214 
1215  str = attribs.value("y_end").toString();
1216  if (str.isEmpty())
1217  reader->raiseWarning(attributeWarning.subs("y_end").toString());
1218  else
1219  d->yEnd = str.toDouble();
1220  } else if (!preview && reader->name() == "row_heights") {
1221  reader->readNext();
1222  QString content = reader->text().toString().trimmed();
1223  QByteArray bytes = QByteArray::fromBase64(content.toLatin1());
1224  int count = bytes.size()/sizeof(int);
1225  d->rowHeights.resize(count);
1226  memcpy(d->rowHeights.data(), bytes.data(), count*sizeof(int));
1227  } else if (!preview && reader->name() == "column_widths") {
1228  reader->readNext();
1229  QString content = reader->text().toString().trimmed();
1230  QByteArray bytes = QByteArray::fromBase64(content.toLatin1());
1231  int count = bytes.size()/sizeof(int);
1232  d->columnWidths.resize(count);
1233  memcpy(d->columnWidths.data(), bytes.data(), count*sizeof(int));
1234  } else if (!preview && reader->name() == "column") {
1235  //TODO: parallelize reading of columns?
1236  reader->readNext();
1237  QString content = reader->text().toString().trimmed();
1238  QByteArray bytes = QByteArray::fromBase64(content.toLatin1());
1239 
1240  switch (d->mode) {
1242  int count = bytes.size()/sizeof(double);
1243  QVector<double> column;
1244  column.resize(count);
1245  memcpy(column.data(), bytes.data(), count*sizeof(double));
1246  static_cast<QVector<QVector<double>>*>(d->data)->append(column);
1247  break;
1248  }
1250  int count = bytes.size()/sizeof(char);
1251  QVector<QString> column;
1252  column.resize(count);
1253  //TODO: warning (GCC8): writing to an object of type 'class QString' with no trivial copy-assignment; use copy-assignment or copy-initialization instead
1254  //memcpy(column.data(), bytes.data(), count*sizeof(QString));
1255  //QDEBUG(" string: " << column.data());
1256  static_cast<QVector<QVector<QString>>*>(d->data)->append(column);
1257  break;
1258  }
1260  int count = bytes.size()/sizeof(int);
1261  QVector<int> column;
1262  column.resize(count);
1263  memcpy(column.data(), bytes.data(), count*sizeof(int));
1264  static_cast<QVector<QVector<int>>*>(d->data)->append(column);
1265  break;
1266  }
1268  int count = bytes.size()/sizeof(qint64);
1269  QVector<qint64> column;
1270  column.resize(count);
1271  memcpy(column.data(), bytes.data(), count*sizeof(qint64));
1272  static_cast<QVector<QVector<qint64>>*>(d->data)->append(column);
1273  break;
1274  }
1278  int count = bytes.size()/sizeof(QDateTime);
1279  QVector<QDateTime> column;
1280  column.resize(count);
1281  //TODO: warning (GCC8): writing to an object of type 'class QDateTime' with no trivial copy-assignment; use copy-assignment or copy-initialization instead
1282  //memcpy(column.data(), bytes.data(), count*sizeof(QDateTime));
1283  static_cast<QVector<QVector<QDateTime>>*>(d->data)->append(column);
1284  break;
1285  }
1286  }
1287  } else { // unknown element
1288  reader->raiseWarning(i18n("unknown element '%1'", reader->name().toString()));
1289  if (!reader->skipToEndElement())
1290  return false;
1291  }
1292  }
1293 
1294  return true;
1295 }
1296 
1297 //##############################################################################
1298 //######################## Data Import #######################################
1299 //##############################################################################
1300 int Matrix::prepareImport(std::vector<void*>& dataContainer, AbstractFileFilter::ImportMode mode,
1301  int actualRows, int actualCols, QStringList colNameList, QVector<AbstractColumn::ColumnMode> columnMode) {
1302  QDEBUG("prepareImport() rows =" << actualRows << " cols =" << actualCols);
1303  //QDEBUG(" column modes = " << columnMode);
1304  Q_UNUSED(colNameList);
1305  int columnOffset = 0;
1306  setUndoAware(false);
1307 
1309 
1310  // resize the matrix
1312  clear();
1313  setDimensions(actualRows, actualCols);
1314  } else {
1315  if (rowCount() < actualRows)
1316  setDimensions(actualRows, actualCols);
1317  else
1318  setDimensions(rowCount(), actualCols);
1319  }
1320 
1321  // data() returns a void* which is a pointer to a matrix of any data type (see ColumnPrivate.cpp)
1322  dataContainer.resize(actualCols);
1323  switch (columnMode[0]) { // only columnMode[0] is used
1325  for (int n = 0; n < actualCols; n++) {
1326  QVector<double>* vector = &(static_cast<QVector<QVector<double>>*>(data())->operator[](n));
1327  vector->resize(actualRows);
1328  dataContainer[n] = static_cast<void*>(vector);
1329  }
1331  break;
1333  for (int n = 0; n < actualCols; n++) {
1334  QVector<int>* vector = &(static_cast<QVector<QVector<int>>*>(data())->operator[](n));
1335  vector->resize(actualRows);
1336  dataContainer[n] = static_cast<void*>(vector);
1337  }
1339  break;
1341  for (int n = 0; n < actualCols; n++) {
1342  QVector<qint64>* vector = &(static_cast<QVector<QVector<qint64>>*>(data())->operator[](n));
1343  vector->resize(actualRows);
1344  dataContainer[n] = static_cast<void*>(vector);
1345  }
1347  break;
1349  for (int n = 0; n < actualCols; n++) {
1350  QVector<QString>* vector = &(static_cast<QVector<QVector<QString>>*>(data())->operator[](n));
1351  vector->resize(actualRows);
1352  dataContainer[n] = static_cast<void*>(vector);
1353  }
1355  break;
1359  for (int n = 0; n < actualCols; n++) {
1360  QVector<QDateTime>* vector = &(static_cast<QVector<QVector<QDateTime>>*>(data())->operator[](n));
1361  vector->resize(actualRows);
1362  dataContainer[n] = static_cast<void*>(vector);
1363  }
1365  break;
1366  }
1367 
1368  return columnOffset;
1369 }
1370 
1371 void Matrix::finalizeImport(int columnOffset, int startColumn, int endColumn, const QString& dateTimeFormat, AbstractFileFilter::ImportMode importMode) {
1372  DEBUG("Matrix::finalizeImport()");
1373  Q_UNUSED(columnOffset);
1374  Q_UNUSED(startColumn);
1375  Q_UNUSED(endColumn);
1376  Q_UNUSED(dateTimeFormat);
1377  Q_UNUSED(importMode);
1378 
1380  setChanged();
1381  setUndoAware(true);
1382  DEBUG("Matrix::finalizeImport() DONE");
1383 }
AspectType
void setUndoAware(bool)
bool readCommentElement(XmlStreamReader *)
Load comment from an XML element.
Folder * folder()
Return the folder the Aspect is contained in or 0 if there is none.
void addChild(AbstractAspect *)
Add the given Aspect to my list of children.
QString name() const
void writeBasicAttributes(QXmlStreamWriter *) const
Save name and creation time to XML.
void beginMacro(const QString &text)
Begin an undo stack macro (series of commands)
virtual QString path() const
Return the path that leads from the top-most Aspect (usually a Project) to me.
void exec(QUndoCommand *)
Execute the given command, pushing it on the undoStack() if available.
bool readBasicAttributes(XmlStreamReader *)
Load name and creation time from XML.
void writeCommentElement(QXmlStreamWriter *) const
Save the comment to XML.
void endMacro()
End the current undo stack macro.
Interface for the data sources.
QMenu * createContextMenu() override
Return AbstractAspect::createContextMenu() plus operations on the primary view.
QWidget * m_partView
Definition: AbstractPart.h:65
Dialog for exporting a spreadsheet to a file.
Clear matrix.
Clear matrix column.
Mirror the matrix horizontally.
void setChanged()
Definition: MatrixModel.cpp:67
void updateHeader()
void removeRows(int first, int count)
Definition: Matrix.cpp:965
void clearColumn(int col)
Fill column with zeroes.
Definition: Matrix.cpp:1003
Matrix::HeaderFormat headerFormat
void insertColumns(int before, int count)
Definition: Matrix.cpp:840
void removeColumns(int first, int count)
Definition: Matrix.cpp:887
QVector< T > columnCells(int col, int first_row, int last_row)
Definition: MatrixPrivate.h:70
T cell(int row, int col) const
Definition: MatrixPrivate.h:50
int precision
Number of significant digits.
QVector< T > rowCells(int row, int first_column, int last_column)
int rowHeight(int row) const
char numericFormat
Format code for displaying numbers.
QString formula
formula used to calculate the cells
QVector< int > columnWidths
Columns widths.
void setColumnWidth(int col, int width)
void setRowHeight(int row, int height)
int columnWidth(int col) const
void updateViewHeader()
Definition: Matrix.cpp:833
bool suppressDataChange
QVector< int > rowHeights
Row widths.
void insertRows(int before, int count)
Definition: Matrix.cpp:921
AbstractColumn::ColumnMode mode
MatrixPrivate(Matrix *, AbstractColumn::ColumnMode)
Definition: Matrix.cpp:785
Set matrix formula.
Set cell values for (a part of) a row at once.
Transpose the matrix.
void exportToFits(const QString &fileName, const int exportTo) const
void adjustHeaders()
Definition: MatrixView.cpp:383
void resizeHeaders()
Definition: MatrixView.cpp:415
int selectedRowCount(bool full=false) const
Definition: MatrixView.cpp:454
void exportToLaTeX(const QString &, const bool verticalHeaders, const bool horizontalHeaders, const bool latexHeaders, const bool gridLines, const bool entire, const bool captions) const
MatrixModel * model() const
Definition: MatrixView.cpp:90
int selectedColumnCount(bool full=false) const
Definition: MatrixView.cpp:431
void exportToFile(const QString &path, const QString &separator, QLocale::Language) const
void print(QPrinter *) const
Definition: MatrixView.cpp:980
Definition: Matrix.h:41
void setDimensions(int rows, int cols)
Definition: Matrix.cpp:479
void setData(void *)
Definition: Matrix.cpp:647
QMenu * createContextMenu() override
Definition: Matrix.cpp:114
void appendRows(int count)
Definition: Matrix.cpp:358
QVector< T > rowCells(int row, int first_column, int last_column)
Return the values in the given cells as vector (needs explicit instantiation)
Definition: Matrix.cpp:631
void duplicate()
Duplicate the matrix inside its folder.
Definition: Matrix.cpp:556
QVector< T > columnCells(int col, int first_row, int last_row)
Return the values in the given cells as vector.
Definition: Matrix.cpp:617
HeaderFormat
Definition: Matrix.h:46
bool printPreview() const override
Definition: Matrix.cpp:182
void insertRows(int before, int count)
Definition: Matrix.cpp:351
void setCoordinates(double x1, double x2, double y1, double y2)
Definition: Matrix.cpp:583
void columnsInserted(int first, int count)
void setRowCells(int row, int first_column, int last_column, const QVector< T > &values)
Set the values in the given cells from a type T vector.
Definition: Matrix.cpp:641
void addRows()
Definition: Matrix.cpp:563
Matrix(const QString &name, bool loading=false, const AbstractColumn::ColumnMode=AbstractColumn::ColumnMode::Numeric)
Definition: Matrix.cpp:70
QString text(int row, int col)
Return the text displayed in the given cell (needs explicit instantiation)
Definition: Matrix.cpp:427
MatrixView * m_view
Definition: Matrix.h:160
bool printView() override
Definition: Matrix.cpp:169
void setColumnCells(int col, int first_row, int last_row, const QVector< T > &values)
Set the values in the given cells from a type T vector.
Definition: Matrix.cpp:623
T cell(int row, int col) const
Return the value in the given cell (needs explicit instantiation)
Definition: Matrix.cpp:416
void init()
Definition: Matrix.cpp:81
void removeColumns(int first, int count)
Definition: Matrix.cpp:301
void mirrorHorizontally()
Definition: Matrix.cpp:733
void columnsRemoved(int first, int count)
void mirrorVertically()
Definition: Matrix.cpp:757
void save(QXmlStreamWriter *) const override
Save as XML.
Definition: Matrix.cpp:1031
void setColumnWidth(int col, int width)
This method should only be called by the view.
Definition: Matrix.cpp:603
QWidget * view() const override
Construct a primary view on me.
Definition: Matrix.cpp:120
bool exportView() const override
Definition: Matrix.cpp:129
void * data() const
Definition: Matrix.cpp:191
void dataChanged(int top, int left, int bottom, int right)
int rowHeight(int row) const
Definition: Matrix.cpp:607
void insertColumns(int before, int count)
Definition: Matrix.cpp:290
void columnsAboutToBeInserted(int before, int count)
MatrixPrivate *const d
Definition: Matrix.h:158
int columnWidth(int col) const
Definition: Matrix.cpp:611
void headerFormatChanged(Matrix::HeaderFormat)
void setChanged()
Definition: Matrix.cpp:212
void clearCell(int row, int col)
Definition: Matrix.cpp:457
MatrixModel * m_model
Definition: Matrix.h:159
void rowsRemoved(int first, int count)
void finalizeImport(int columnOffset, int startColumn, int endColumn, const QString &dateTimeFormat, AbstractFileFilter::ImportMode) override
Definition: Matrix.cpp:1371
int prepareImport(std::vector< void * > &dataContainer, AbstractFileFilter::ImportMode, int rows, int cols, QStringList colNameList, QVector< AbstractColumn::ColumnMode >) override
Definition: Matrix.cpp:1300
void transpose()
Definition: Matrix.cpp:709
void setRowHeight(int row, int height)
This method should only be called by the view.
Definition: Matrix.cpp:595
void setCell(int row, int col, T value)
Set the value of the cell (needs explicit instantiation)
Definition: Matrix.cpp:446
void rowsInserted(int first, int count)
void rowsAboutToBeRemoved(int first, int count)
void clearRow(int)
Definition: Matrix.cpp:387
void clear()
Clear the whole matrix (i.e. reset all cells)
Definition: Matrix.cpp:683
~Matrix() override
Definition: Matrix.cpp:77
void copy(Matrix *other)
Definition: Matrix.cpp:502
void setSuppressDataChangedSignal(bool)
Definition: Matrix.cpp:207
void requestProjectContextMenu(QMenu *)
void clearColumn(int)
Definition: Matrix.cpp:326
bool load(XmlStreamReader *, bool preview) override
Load from XML.
Definition: Matrix.cpp:1130
void addColumns()
Definition: Matrix.cpp:573
void appendColumns(int count)
Definition: Matrix.cpp:297
void columnsAboutToBeRemoved(int first, int count)
void removeRows(int first, int count)
Definition: Matrix.cpp:362
void rowsAboutToBeInserted(int before, int count)
QIcon icon() const override
Definition: Matrix.cpp:107
XML stream parser that supports errors as well as warnings. This class also adds line and column numb...
void raiseWarning(const QString &)
#define WAIT_CURSOR
Definition: macros.h:63
#define CLASS_D_READER_IMPL(classname, type, method, var)
Definition: macros.h:148
#define RESET_CURSOR
Definition: macros.h:64
#define DEBUG(x)
Definition: macros.h:50
#define SET_NUMBER_LOCALE
Definition: macros.h:75
#define STD_SETTER_CMD_IMPL_S(class_name, cmd_name, value_type, field_name)
Definition: macros.h:207
#define STD_SETTER_CMD_IMPL_F_S(class_name, cmd_name, value_type, field_name, finalize_method)
Definition: macros.h:215
#define QDEBUG(x)
Definition: macros.h:47
#define BASIC_D_READER_IMPL(classname, type, method, var)
Definition: macros.h:121
#define i18n(m)
Definition: nsl_common.h:38