Resolved issue #409. New feature: Export measurement file to Excel .csv.
--HG-- branch : develop
This commit is contained in:
parent
8e3f3a4cd8
commit
32d391c587
|
@ -24,6 +24,7 @@
|
||||||
- [#472] Add 'Full Name' column to Formula dialog.
|
- [#472] Add 'Full Name' column to Formula dialog.
|
||||||
- [#487] True dart point always goes to origin when the label is moved.
|
- [#487] True dart point always goes to origin when the label is moved.
|
||||||
- [#128] New Tool: Slash and Spread.
|
- [#128] New Tool: Slash and Spread.
|
||||||
|
- [#409] New feature: Export measurement file to Excel .csv.
|
||||||
|
|
||||||
# Version 0.4.5
|
# Version 0.4.5
|
||||||
- [#435] Valentina doesn't change the cursor.
|
- [#435] Valentina doesn't change the cursor.
|
||||||
|
|
|
@ -41,7 +41,7 @@ class DialogAboutTape : public QDialog
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit DialogAboutTape(QWidget *parent = 0);
|
explicit DialogAboutTape(QWidget *parent = 0);
|
||||||
~DialogAboutTape();
|
virtual ~DialogAboutTape();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void changeEvent(QEvent* event) Q_DECL_OVERRIDE;
|
virtual void changeEvent(QEvent* event) Q_DECL_OVERRIDE;
|
||||||
|
|
154
src/app/tape/dialogs/dialogexporttocsv.cpp
Normal file
154
src/app/tape/dialogs/dialogexporttocsv.cpp
Normal file
|
@ -0,0 +1,154 @@
|
||||||
|
/************************************************************************
|
||||||
|
**
|
||||||
|
** @file dialogexporttocsv.cpp
|
||||||
|
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
||||||
|
** @date 1 6, 2016
|
||||||
|
**
|
||||||
|
** @brief
|
||||||
|
** @copyright
|
||||||
|
** This source code is part of the Valentine project, a pattern making
|
||||||
|
** program, whose allow create and modeling patterns of clothing.
|
||||||
|
** Copyright (C) 2016 Valentina project
|
||||||
|
** <https://bitbucket.org/dismine/valentina> All Rights Reserved.
|
||||||
|
**
|
||||||
|
** Valentina is free software: you can redistribute it and/or modify
|
||||||
|
** it under the terms of the GNU General Public License as published by
|
||||||
|
** the Free Software Foundation, either version 3 of the License, or
|
||||||
|
** (at your option) any later version.
|
||||||
|
**
|
||||||
|
** Valentina 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 General Public License for more details.
|
||||||
|
**
|
||||||
|
** You should have received a copy of the GNU General Public License
|
||||||
|
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
**
|
||||||
|
*************************************************************************/
|
||||||
|
|
||||||
|
#include "dialogexporttocsv.h"
|
||||||
|
#include "ui_dialogexporttocsv.h"
|
||||||
|
|
||||||
|
#include "../vmisc/vtapesettings.h"
|
||||||
|
#include "../mapplication.h"
|
||||||
|
|
||||||
|
#include <QShowEvent>
|
||||||
|
#include <QTextCodec>
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
DialogExportToCSV::DialogExportToCSV(QWidget *parent)
|
||||||
|
: QDialog(parent),
|
||||||
|
ui(new Ui::DialogExportToCSV),
|
||||||
|
isInitialized(false)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
ui->checkBoxWithHeader->setChecked(qApp->TapeSettings()->GetCSVWithHeader());
|
||||||
|
|
||||||
|
foreach (int mib, QTextCodec::availableMibs())
|
||||||
|
{
|
||||||
|
ui->comboBoxCodec->addItem(QTextCodec::codecForMib(mib)->name(), mib);
|
||||||
|
}
|
||||||
|
|
||||||
|
ui->comboBoxCodec->setCurrentIndex(ui->comboBoxCodec->findData(qApp->TapeSettings()->GetCSVCodec()));
|
||||||
|
|
||||||
|
SetSeparator(qApp->TapeSettings()->GetCSVSeparator());
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
DialogExportToCSV::~DialogExportToCSV()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
bool DialogExportToCSV::WithHeader() const
|
||||||
|
{
|
||||||
|
return ui->checkBoxWithHeader->isChecked();
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
int DialogExportToCSV::SelectedMib() const
|
||||||
|
{
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK(5, 2, 0)
|
||||||
|
return ui->comboBoxCodec->itemData(ui->comboBoxCodec->currentIndex()).toInt();
|
||||||
|
#else
|
||||||
|
return ui->comboBoxCodec->currentData().toInt();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
QChar DialogExportToCSV::Separator() const
|
||||||
|
{
|
||||||
|
if (ui->radioButtonTab->isChecked())
|
||||||
|
{
|
||||||
|
return QChar('\t');
|
||||||
|
}
|
||||||
|
else if (ui->radioButtonSemicolon->isChecked())
|
||||||
|
{
|
||||||
|
return QChar(';');
|
||||||
|
}
|
||||||
|
else if (ui->radioButtonSpace->isChecked())
|
||||||
|
{
|
||||||
|
return QChar(' ');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return QChar(',');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void DialogExportToCSV::changeEvent(QEvent *event)
|
||||||
|
{
|
||||||
|
if (event->type() == QEvent::LanguageChange)
|
||||||
|
{
|
||||||
|
// retranslate designer form (single inheritance approach)
|
||||||
|
ui->retranslateUi(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// remember to call base class implementation
|
||||||
|
QDialog::changeEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void DialogExportToCSV::showEvent(QShowEvent *event)
|
||||||
|
{
|
||||||
|
QDialog::showEvent( event );
|
||||||
|
if ( event->spontaneous() )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isInitialized)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// do your init stuff here
|
||||||
|
|
||||||
|
setMaximumSize(size());
|
||||||
|
setMinimumSize(size());
|
||||||
|
|
||||||
|
isInitialized = true;//first show windows are held
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void DialogExportToCSV::SetSeparator(const QChar &separator)
|
||||||
|
{
|
||||||
|
switch(separator.toLatin1())
|
||||||
|
{
|
||||||
|
case '\t':
|
||||||
|
ui->radioButtonTab->setChecked(true);
|
||||||
|
break;
|
||||||
|
case ';':
|
||||||
|
ui->radioButtonSemicolon->setChecked(true);
|
||||||
|
break;
|
||||||
|
case ' ':
|
||||||
|
ui->radioButtonSpace->setChecked(true);
|
||||||
|
break;
|
||||||
|
case ',':
|
||||||
|
default:
|
||||||
|
ui->radioButtonComma->setChecked(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
62
src/app/tape/dialogs/dialogexporttocsv.h
Normal file
62
src/app/tape/dialogs/dialogexporttocsv.h
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
/************************************************************************
|
||||||
|
**
|
||||||
|
** @file dialogexporttocsv.h
|
||||||
|
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
||||||
|
** @date 1 6, 2016
|
||||||
|
**
|
||||||
|
** @brief
|
||||||
|
** @copyright
|
||||||
|
** This source code is part of the Valentine project, a pattern making
|
||||||
|
** program, whose allow create and modeling patterns of clothing.
|
||||||
|
** Copyright (C) 2016 Valentina project
|
||||||
|
** <https://bitbucket.org/dismine/valentina> All Rights Reserved.
|
||||||
|
**
|
||||||
|
** Valentina is free software: you can redistribute it and/or modify
|
||||||
|
** it under the terms of the GNU General Public License as published by
|
||||||
|
** the Free Software Foundation, either version 3 of the License, or
|
||||||
|
** (at your option) any later version.
|
||||||
|
**
|
||||||
|
** Valentina 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 General Public License for more details.
|
||||||
|
**
|
||||||
|
** You should have received a copy of the GNU General Public License
|
||||||
|
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
**
|
||||||
|
*************************************************************************/
|
||||||
|
|
||||||
|
#ifndef DIALOGEXPORTTOCSV_H
|
||||||
|
#define DIALOGEXPORTTOCSV_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class DialogExportToCSV;
|
||||||
|
}
|
||||||
|
|
||||||
|
class DialogExportToCSV : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit DialogExportToCSV(QWidget *parent = nullptr);
|
||||||
|
virtual ~DialogExportToCSV();
|
||||||
|
|
||||||
|
bool WithHeader() const;
|
||||||
|
int SelectedMib() const;
|
||||||
|
QChar Separator() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void changeEvent(QEvent* event) Q_DECL_OVERRIDE;
|
||||||
|
virtual void showEvent(QShowEvent *event) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Q_DISABLE_COPY(DialogExportToCSV)
|
||||||
|
Ui::DialogExportToCSV *ui;
|
||||||
|
bool isInitialized;
|
||||||
|
|
||||||
|
void SetSeparator(const QChar &separator);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // DIALOGEXPORTTOCSV_H
|
165
src/app/tape/dialogs/dialogexporttocsv.ui
Normal file
165
src/app/tape/dialogs/dialogexporttocsv.ui
Normal file
|
@ -0,0 +1,165 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>DialogExportToCSV</class>
|
||||||
|
<widget class="QDialog" name="DialogExportToCSV">
|
||||||
|
<property name="windowModality">
|
||||||
|
<enum>Qt::ApplicationModal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>298</width>
|
||||||
|
<height>292</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Export options</string>
|
||||||
|
</property>
|
||||||
|
<property name="windowIcon">
|
||||||
|
<iconset>
|
||||||
|
<normaloff>:/tapeicon/64x64/logo.png</normaloff>:/tapeicon/64x64/logo.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="modal">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBoxExport">
|
||||||
|
<property name="title">
|
||||||
|
<string>Export</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="checkBoxWithHeader">
|
||||||
|
<property name="text">
|
||||||
|
<string>With header</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Codec:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="comboBoxCodec"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBoxSeparator">
|
||||||
|
<property name="title">
|
||||||
|
<string>Separator</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="radioButtonTab">
|
||||||
|
<property name="text">
|
||||||
|
<string>Tab</string>
|
||||||
|
</property>
|
||||||
|
<attribute name="buttonGroup">
|
||||||
|
<string notr="true">buttonGroup</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="radioButtonComma">
|
||||||
|
<property name="text">
|
||||||
|
<string>Comma</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<attribute name="buttonGroup">
|
||||||
|
<string notr="true">buttonGroup</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="radioButtonSemicolon">
|
||||||
|
<property name="text">
|
||||||
|
<string>Semicolon</string>
|
||||||
|
</property>
|
||||||
|
<attribute name="buttonGroup">
|
||||||
|
<string notr="true">buttonGroup</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="radioButtonSpace">
|
||||||
|
<property name="text">
|
||||||
|
<string>Space</string>
|
||||||
|
</property>
|
||||||
|
<attribute name="buttonGroup">
|
||||||
|
<string notr="true">buttonGroup</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>DialogExportToCSV</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>248</x>
|
||||||
|
<y>254</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>157</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>DialogExportToCSV</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>316</x>
|
||||||
|
<y>260</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>286</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
<buttongroups>
|
||||||
|
<buttongroup name="buttonGroup"/>
|
||||||
|
</buttongroups>
|
||||||
|
</ui>
|
|
@ -11,6 +11,7 @@ SOURCES += \
|
||||||
$$PWD/dialogs/tapeconfigdialog.cpp \
|
$$PWD/dialogs/tapeconfigdialog.cpp \
|
||||||
$$PWD/dialogs/configpages/tapeconfigurationpage.cpp \
|
$$PWD/dialogs/configpages/tapeconfigurationpage.cpp \
|
||||||
$$PWD/dialogs/configpages/tapepathpage.cpp \
|
$$PWD/dialogs/configpages/tapepathpage.cpp \
|
||||||
|
$$PWD/dialogs/dialogexporttocsv.cpp \
|
||||||
$$PWD/vlitepattern.cpp \
|
$$PWD/vlitepattern.cpp \
|
||||||
$$PWD/vtablesearch.cpp
|
$$PWD/vtablesearch.cpp
|
||||||
|
|
||||||
|
@ -27,6 +28,7 @@ HEADERS += \
|
||||||
$$PWD/dialogs/tapeconfigdialog.h \
|
$$PWD/dialogs/tapeconfigdialog.h \
|
||||||
$$PWD/dialogs/configpages/tapeconfigurationpage.h \
|
$$PWD/dialogs/configpages/tapeconfigurationpage.h \
|
||||||
$$PWD/dialogs/configpages/tapepathpage.h \
|
$$PWD/dialogs/configpages/tapepathpage.h \
|
||||||
|
$$PWD/dialogs/dialogexporttocsv.h \
|
||||||
$$PWD/vlitepattern.h \
|
$$PWD/vlitepattern.h \
|
||||||
$$PWD/vtablesearch.h
|
$$PWD/vtablesearch.h
|
||||||
|
|
||||||
|
@ -34,4 +36,5 @@ FORMS += \
|
||||||
$$PWD/tmainwindow.ui \
|
$$PWD/tmainwindow.ui \
|
||||||
$$PWD/dialogs/dialogabouttape.ui \
|
$$PWD/dialogs/dialogabouttape.ui \
|
||||||
$$PWD/dialogs/dialognewmeasurements.ui \
|
$$PWD/dialogs/dialognewmeasurements.ui \
|
||||||
$$PWD/dialogs/dialogmdatabase.ui
|
$$PWD/dialogs/dialogmdatabase.ui \
|
||||||
|
$$PWD/dialogs/dialogexporttocsv.ui
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include "dialogs/dialognewmeasurements.h"
|
#include "dialogs/dialognewmeasurements.h"
|
||||||
#include "dialogs/dialogmdatabase.h"
|
#include "dialogs/dialogmdatabase.h"
|
||||||
#include "dialogs/tapeconfigdialog.h"
|
#include "dialogs/tapeconfigdialog.h"
|
||||||
|
#include "dialogs/dialogexporttocsv.h"
|
||||||
#include "../vpatterndb/calculator.h"
|
#include "../vpatterndb/calculator.h"
|
||||||
#include "../ifc/ifcdef.h"
|
#include "../ifc/ifcdef.h"
|
||||||
#include "../ifc/xml/vvitconverter.h"
|
#include "../ifc/xml/vvitconverter.h"
|
||||||
|
@ -39,6 +40,7 @@
|
||||||
#include "../ifc/xml/vpatternconverter.h"
|
#include "../ifc/xml/vpatternconverter.h"
|
||||||
#include "../vmisc/vlockguard.h"
|
#include "../vmisc/vlockguard.h"
|
||||||
#include "../vmisc/vsysexits.h"
|
#include "../vmisc/vsysexits.h"
|
||||||
|
#include "../vmisc/qxtcsvmodel.h"
|
||||||
#include "vlitepattern.h"
|
#include "vlitepattern.h"
|
||||||
#include "../qmuparser/qmudef.h"
|
#include "../qmuparser/qmudef.h"
|
||||||
#include "../vtools/dialogs/support/dialogeditwrongformula.h"
|
#include "../vtools/dialogs/support/dialogeditwrongformula.h"
|
||||||
|
@ -51,6 +53,7 @@
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
#include <QtNumeric>
|
#include <QtNumeric>
|
||||||
|
#include <QTextCodec>
|
||||||
|
|
||||||
#if defined(Q_OS_MAC)
|
#if defined(Q_OS_MAC)
|
||||||
#include <QMimeData>
|
#include <QMimeData>
|
||||||
|
@ -679,6 +682,80 @@ void TMainWindow::FileSaveAs()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void TMainWindow::ExportToCSV()
|
||||||
|
{
|
||||||
|
const QString filters = tr("Comma-Separated Values (*.cvs)");
|
||||||
|
const QString suffix("csv");
|
||||||
|
const QString path = QDir::homePath() + "/" + tr("measurements"); + "." + suffix;
|
||||||
|
|
||||||
|
QString fileName = QFileDialog::getSaveFileName(this, tr("Export to CSV"), path, filters);
|
||||||
|
|
||||||
|
if (fileName.isEmpty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QFileInfo f( fileName );
|
||||||
|
if (f.suffix().isEmpty() && f.suffix() != suffix)
|
||||||
|
{
|
||||||
|
fileName += "." + suffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
DialogExportToCSV dialog(this);
|
||||||
|
if (dialog.exec() == QDialog::Accepted)
|
||||||
|
{
|
||||||
|
QxtCsvModel csv;
|
||||||
|
const int columns = ui->tableWidget->columnCount();
|
||||||
|
{
|
||||||
|
int colCount = 0;
|
||||||
|
for (int column = 0; column < columns; ++column)
|
||||||
|
{
|
||||||
|
if (not ui->tableWidget->isColumnHidden(column))
|
||||||
|
{
|
||||||
|
csv.insertColumn(colCount++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dialog.WithHeader())
|
||||||
|
{
|
||||||
|
int colCount = 0;
|
||||||
|
for (int column = 0; column < columns; ++column)
|
||||||
|
{
|
||||||
|
if (not ui->tableWidget->isColumnHidden(column))
|
||||||
|
{
|
||||||
|
QTableWidgetItem *header = ui->tableWidget->horizontalHeaderItem(colCount);
|
||||||
|
csv.setHeaderText(colCount, header->text());
|
||||||
|
++colCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const int rows = ui->tableWidget->rowCount();
|
||||||
|
for (int row = 0; row < rows; ++row)
|
||||||
|
{
|
||||||
|
csv.insertRow(row);
|
||||||
|
int colCount = 0;
|
||||||
|
for (int column = 0; column < columns; ++column)
|
||||||
|
{
|
||||||
|
if (not ui->tableWidget->isColumnHidden(column))
|
||||||
|
{
|
||||||
|
QTableWidgetItem *item = ui->tableWidget->item(row, column);
|
||||||
|
csv.setText(row, colCount, item->text());
|
||||||
|
++colCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
csv.toCSV(fileName, dialog.WithHeader(), dialog.Separator(), QTextCodec::codecForMib(dialog.SelectedMib()));
|
||||||
|
|
||||||
|
qApp->TapeSettings()->SetCSVSeparator(dialog.Separator());
|
||||||
|
qApp->TapeSettings()->SetCSVCodec(dialog.SelectedMib());
|
||||||
|
qApp->TapeSettings()->SetCSVWithHeader(dialog.WithHeader());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
void TMainWindow::AboutToShowWindowMenu()
|
void TMainWindow::AboutToShowWindowMenu()
|
||||||
{
|
{
|
||||||
|
@ -863,6 +940,8 @@ void TMainWindow::Remove()
|
||||||
{
|
{
|
||||||
MFields(false);
|
MFields(false);
|
||||||
|
|
||||||
|
ui->actionExportToCSV->setEnabled(false);
|
||||||
|
|
||||||
ui->lineEditName->blockSignals(true);
|
ui->lineEditName->blockSignals(true);
|
||||||
ui->lineEditName->setText("");
|
ui->lineEditName->setText("");
|
||||||
ui->lineEditName->blockSignals(false);
|
ui->lineEditName->blockSignals(false);
|
||||||
|
@ -1060,13 +1139,15 @@ void TMainWindow::AddCustom()
|
||||||
|
|
||||||
ui->tableWidget->selectRow(currentRow);
|
ui->tableWidget->selectRow(currentRow);
|
||||||
|
|
||||||
|
ui->actionExportToCSV->setEnabled(true);
|
||||||
|
|
||||||
MeasurementsWasSaved(false);
|
MeasurementsWasSaved(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
void TMainWindow::AddKnown()
|
void TMainWindow::AddKnown()
|
||||||
{
|
{
|
||||||
DialogMDataBase *dialog = new DialogMDataBase(m->ListKnown(), this);
|
QScopedPointer<DialogMDataBase> dialog (new DialogMDataBase(m->ListKnown(), this));
|
||||||
if (dialog->exec() == QDialog::Accepted)
|
if (dialog->exec() == QDialog::Accepted)
|
||||||
{
|
{
|
||||||
qint32 currentRow;
|
qint32 currentRow;
|
||||||
|
@ -1114,9 +1195,10 @@ void TMainWindow::AddKnown()
|
||||||
|
|
||||||
ui->tableWidget->selectRow(currentRow);
|
ui->tableWidget->selectRow(currentRow);
|
||||||
|
|
||||||
|
ui->actionExportToCSV->setEnabled(true);
|
||||||
|
|
||||||
MeasurementsWasSaved(false);
|
MeasurementsWasSaved(false);
|
||||||
}
|
}
|
||||||
delete dialog;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -1732,6 +1814,7 @@ void TMainWindow::SetupMenu()
|
||||||
connect(ui->actionSaveAs, &QAction::triggered, this, &TMainWindow::FileSaveAs);
|
connect(ui->actionSaveAs, &QAction::triggered, this, &TMainWindow::FileSaveAs);
|
||||||
ui->actionSaveAs->setShortcuts(QKeySequence::SaveAs);
|
ui->actionSaveAs->setShortcuts(QKeySequence::SaveAs);
|
||||||
|
|
||||||
|
connect(ui->actionExportToCSV, &QAction::triggered, this, &TMainWindow::ExportToCSV);
|
||||||
connect(ui->actionReadOnly, &QAction::triggered, this, &TMainWindow::ReadOnly);
|
connect(ui->actionReadOnly, &QAction::triggered, this, &TMainWindow::ReadOnly);
|
||||||
connect(ui->actionPreferences, &QAction::triggered, this, &TMainWindow::Preferences);
|
connect(ui->actionPreferences, &QAction::triggered, this, &TMainWindow::Preferences);
|
||||||
|
|
||||||
|
@ -2302,6 +2385,11 @@ void TMainWindow::RefreshTable()
|
||||||
ui->tableWidget->resizeRowsToContents();
|
ui->tableWidget->resizeRowsToContents();
|
||||||
ui->tableWidget->horizontalHeader()->setStretchLastSection(true);
|
ui->tableWidget->horizontalHeader()->setStretchLastSection(true);
|
||||||
ui->tableWidget->blockSignals(false);
|
ui->tableWidget->blockSignals(false);
|
||||||
|
|
||||||
|
if (ui->tableWidget->rowCount() > 0)
|
||||||
|
{
|
||||||
|
ui->actionExportToCSV->setEnabled(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -79,6 +79,7 @@ protected:
|
||||||
private slots:
|
private slots:
|
||||||
void FileSave();
|
void FileSave();
|
||||||
void FileSaveAs();
|
void FileSaveAs();
|
||||||
|
void ExportToCSV();
|
||||||
void AboutToShowWindowMenu();
|
void AboutToShowWindowMenu();
|
||||||
void ShowWindow();
|
void ShowWindow();
|
||||||
void AboutApplication();
|
void AboutApplication();
|
||||||
|
|
|
@ -913,6 +913,7 @@
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
<addaction name="actionSave"/>
|
<addaction name="actionSave"/>
|
||||||
<addaction name="actionSaveAs"/>
|
<addaction name="actionSaveAs"/>
|
||||||
|
<addaction name="actionExportToCSV"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
<addaction name="actionReadOnly"/>
|
<addaction name="actionReadOnly"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
|
@ -1249,6 +1250,14 @@
|
||||||
<enum>QAction::NoRole</enum>
|
<enum>QAction::NoRole</enum>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="actionExportToCSV">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Export to CSV</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<layoutdefault spacing="6" margin="11"/>
|
<layoutdefault spacing="6" margin="11"/>
|
||||||
<resources>
|
<resources>
|
||||||
|
|
|
@ -632,4 +632,95 @@ static inline bool VFuzzyComparePossibleNulls(double p1, double p2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
** This file is derived from code bearing the following notice:
|
||||||
|
** The sole author of this file, Adam Higerd, has explicitly disclaimed all
|
||||||
|
** copyright interest and protection for the content within. This file has
|
||||||
|
** been placed in the public domain according to United States copyright
|
||||||
|
** statute and case law. In jurisdictions where this public domain dedication
|
||||||
|
** is not legally recognized, anyone who receives a copy of this file is
|
||||||
|
** permitted to use, modify, duplicate, and redistribute this file, in whole
|
||||||
|
** or in part, with no restrictions or conditions. In these jurisdictions,
|
||||||
|
** this file shall be copyright (C) 2006-2008 by Adam Higerd.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#define QXT_DECLARE_PRIVATE(PUB) friend class PUB##Private; QxtPrivateInterface<PUB, PUB##Private> qxt_d;
|
||||||
|
#define QXT_DECLARE_PUBLIC(PUB) friend class PUB;
|
||||||
|
#define QXT_INIT_PRIVATE(PUB) qxt_d.setPublic(this);
|
||||||
|
#define QXT_D(PUB) PUB##Private& d = qxt_d()
|
||||||
|
#define QXT_P(PUB) PUB& p = qxt_p()
|
||||||
|
|
||||||
|
template <typename PUB>
|
||||||
|
class QxtPrivate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QxtPrivate(): qxt_p_ptr(nullptr)
|
||||||
|
{}
|
||||||
|
virtual ~QxtPrivate()
|
||||||
|
{}
|
||||||
|
inline void QXT_setPublic(PUB* pub)
|
||||||
|
{
|
||||||
|
qxt_p_ptr = pub;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
inline PUB& qxt_p()
|
||||||
|
{
|
||||||
|
return *qxt_p_ptr;
|
||||||
|
}
|
||||||
|
inline const PUB& qxt_p() const
|
||||||
|
{
|
||||||
|
return *qxt_p_ptr;
|
||||||
|
}
|
||||||
|
inline PUB* qxt_ptr()
|
||||||
|
{
|
||||||
|
return qxt_p_ptr;
|
||||||
|
}
|
||||||
|
inline const PUB* qxt_ptr() const
|
||||||
|
{
|
||||||
|
return qxt_p_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Q_DISABLE_COPY(QxtPrivate)
|
||||||
|
PUB* qxt_p_ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename PUB, typename PVT>
|
||||||
|
class QxtPrivateInterface
|
||||||
|
{
|
||||||
|
friend class QxtPrivate<PUB>;
|
||||||
|
public:
|
||||||
|
QxtPrivateInterface() : pvt(new PVT)
|
||||||
|
{}
|
||||||
|
~QxtPrivateInterface()
|
||||||
|
{
|
||||||
|
delete pvt;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void setPublic(PUB* pub)
|
||||||
|
{
|
||||||
|
pvt->QXT_setPublic(pub);
|
||||||
|
}
|
||||||
|
inline PVT& operator()()
|
||||||
|
{
|
||||||
|
return *static_cast<PVT*>(pvt);
|
||||||
|
}
|
||||||
|
inline const PVT& operator()() const
|
||||||
|
{
|
||||||
|
return *static_cast<PVT*>(pvt);
|
||||||
|
}
|
||||||
|
inline PVT * operator->()
|
||||||
|
{
|
||||||
|
return static_cast<PVT*>(pvt);
|
||||||
|
}
|
||||||
|
inline const PVT * operator->() const
|
||||||
|
{
|
||||||
|
return static_cast<PVT*>(pvt);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
Q_DISABLE_COPY(QxtPrivateInterface)
|
||||||
|
QxtPrivate<PUB>* pvt;
|
||||||
|
};
|
||||||
|
|
||||||
#endif // DEF_H
|
#endif // DEF_H
|
||||||
|
|
729
src/libs/vmisc/qxtcsvmodel.cpp
Normal file
729
src/libs/vmisc/qxtcsvmodel.cpp
Normal file
|
@ -0,0 +1,729 @@
|
||||||
|
/****************************************************************************
|
||||||
|
** Copyright (c) 2006 - 2011, the LibQxt project.
|
||||||
|
** See the Qxt AUTHORS file for a list of authors and copyright holders.
|
||||||
|
** All rights reserved.
|
||||||
|
**
|
||||||
|
** Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in the
|
||||||
|
** documentation and/or other materials provided with the distribution.
|
||||||
|
** * Neither the name of the LibQxt project nor the
|
||||||
|
** names of its contributors may be used to endorse or promote products
|
||||||
|
** derived from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||||
|
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
**
|
||||||
|
** <http://libqxt.org> <foundation@libqxt.org>
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\class QxtCsvModel
|
||||||
|
\brief The QxtCsvModel class provides a QAbstractTableModel for CSV Files
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "qxtcsvmodel.h"
|
||||||
|
|
||||||
|
#include <QFile>
|
||||||
|
#include <QTextStream>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
class QxtCsvModelPrivate : public QxtPrivate<QxtCsvModel>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QxtCsvModelPrivate() : csvData(), header(), maxColumn(0), quoteMode(QxtCsvModel::DefaultQuoteMode)
|
||||||
|
{}
|
||||||
|
QXT_DECLARE_PUBLIC(QxtCsvModel)
|
||||||
|
|
||||||
|
QList<QStringList> csvData;
|
||||||
|
QStringList header;
|
||||||
|
int maxColumn;
|
||||||
|
QxtCsvModel::QuoteMode quoteMode;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef Q_CC_GNU
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Weffc++"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Creates an empty QxtCsvModel with parent \a parent.
|
||||||
|
*/
|
||||||
|
QxtCsvModel::QxtCsvModel(QObject *parent) : QAbstractTableModel(parent)
|
||||||
|
{
|
||||||
|
QXT_INIT_PRIVATE(QxtCsvModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Creates a QxtCsvModel with the parent \a parent and content loaded from \a file.
|
||||||
|
|
||||||
|
See \a setSource for information on the \a withHeader and \a separator properties, or
|
||||||
|
if you need control over the quoting method or codec used to parse the file.
|
||||||
|
|
||||||
|
\sa setSource
|
||||||
|
*/
|
||||||
|
QxtCsvModel::QxtCsvModel(QIODevice *file, QObject *parent, bool withHeader, QChar separator)
|
||||||
|
: QAbstractTableModel(parent)
|
||||||
|
{
|
||||||
|
QXT_INIT_PRIVATE(QxtCsvModel);
|
||||||
|
setSource(file, withHeader, separator);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\overload
|
||||||
|
|
||||||
|
Creates a QxtCsvModel with the parent \a parent and content loaded from \a file.
|
||||||
|
|
||||||
|
See \a setSource for information on the \a withHeader and \a separator properties, or
|
||||||
|
if you need control over the quoting method or codec used to parse the file.
|
||||||
|
|
||||||
|
\sa setSource
|
||||||
|
*/
|
||||||
|
QxtCsvModel::QxtCsvModel(const QString filename, QObject *parent, bool withHeader, QChar separator)
|
||||||
|
: QAbstractTableModel(parent)
|
||||||
|
{
|
||||||
|
QXT_INIT_PRIVATE(QxtCsvModel);
|
||||||
|
QFile src(filename);
|
||||||
|
setSource(&src, withHeader, separator);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef Q_CC_GNU
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QxtCsvModel::~QxtCsvModel()
|
||||||
|
{}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\reimp
|
||||||
|
*/
|
||||||
|
int QxtCsvModel::rowCount(const QModelIndex& parent) const
|
||||||
|
{
|
||||||
|
if (parent.row() != -1 && parent.column() != -1)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return qxt_d().csvData.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\reimp
|
||||||
|
*/
|
||||||
|
int QxtCsvModel::columnCount(const QModelIndex& parent) const
|
||||||
|
{
|
||||||
|
if (parent.row() != -1 && parent.column() != -1)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return qxt_d().maxColumn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\reimp
|
||||||
|
*/
|
||||||
|
QVariant QxtCsvModel::data(const QModelIndex& index, int role) const
|
||||||
|
{
|
||||||
|
if (index.parent() != QModelIndex())
|
||||||
|
{
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
if (role == Qt::DisplayRole || role == Qt::EditRole || role == Qt::UserRole)
|
||||||
|
{
|
||||||
|
if (index.row() < 0 || index.column() < 0 || index.row() >= rowCount())
|
||||||
|
{
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
const QStringList& row = qxt_d().csvData[index.row()];
|
||||||
|
if (index.column() >= row.length())
|
||||||
|
{
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
return row[index.column()];
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\reimp
|
||||||
|
*/
|
||||||
|
QVariant QxtCsvModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||||
|
{
|
||||||
|
if (section < qxt_d().header.count() && orientation == Qt::Horizontal && (role == Qt::DisplayRole
|
||||||
|
|| role == Qt::EditRole
|
||||||
|
|| role == Qt::UserRole))
|
||||||
|
{
|
||||||
|
return qxt_d().header[section];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return QAbstractTableModel::headerData(section, orientation, role);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\overload
|
||||||
|
|
||||||
|
Reads in a CSV file from the provided \a file using \a codec.
|
||||||
|
*/
|
||||||
|
void QxtCsvModel::setSource(const QString filename, bool withHeader, QChar separator, QTextCodec* codec)
|
||||||
|
{
|
||||||
|
QFile src(filename);
|
||||||
|
setSource(&src, withHeader, separator, codec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Reads in a CSV file from the provided \a file using \a codec.
|
||||||
|
|
||||||
|
The value of \a separator will be used to delimit fields, subject to the specified \a quoteMode.
|
||||||
|
If \a withHeader is set to true, the first line of the file will be used to populate the model's
|
||||||
|
horizontal header.
|
||||||
|
|
||||||
|
\sa quoteMode
|
||||||
|
*/
|
||||||
|
void QxtCsvModel::setSource(QIODevice *file, bool withHeader, QChar separator, QTextCodec* codec)
|
||||||
|
{
|
||||||
|
QxtCsvModelPrivate* d_ptr = &qxt_d();
|
||||||
|
bool headerSet = !withHeader;
|
||||||
|
if (not file->isOpen())
|
||||||
|
{
|
||||||
|
file->open(QIODevice::ReadOnly);
|
||||||
|
}
|
||||||
|
if (withHeader)
|
||||||
|
{
|
||||||
|
d_ptr->maxColumn = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
d_ptr->maxColumn = d_ptr->header.size();
|
||||||
|
}
|
||||||
|
d_ptr->csvData.clear();
|
||||||
|
QStringList row;
|
||||||
|
QString field;
|
||||||
|
QChar quote;
|
||||||
|
QChar ch, buffer(0);
|
||||||
|
bool readCR = false;
|
||||||
|
QTextStream stream(file);
|
||||||
|
if (codec)
|
||||||
|
{
|
||||||
|
stream.setCodec(codec);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stream.setAutoDetectUnicode(true);
|
||||||
|
}
|
||||||
|
while (not stream.atEnd())
|
||||||
|
{
|
||||||
|
if (buffer != QChar(0))
|
||||||
|
{
|
||||||
|
ch = buffer;
|
||||||
|
buffer = QChar(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stream >> ch;
|
||||||
|
}
|
||||||
|
if (ch == '\n' && readCR)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (ch == '\r')
|
||||||
|
{
|
||||||
|
readCR = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
readCR = false;
|
||||||
|
}
|
||||||
|
if (ch != separator && (ch.category() == QChar::Separator_Line || ch.category() == QChar::Separator_Paragraph
|
||||||
|
|| ch.category() == QChar::Other_Control))
|
||||||
|
{
|
||||||
|
row << field;
|
||||||
|
field.clear();
|
||||||
|
if (not row.isEmpty())
|
||||||
|
{
|
||||||
|
if (not headerSet)
|
||||||
|
{
|
||||||
|
d_ptr->header = row;
|
||||||
|
headerSet = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
d_ptr->csvData.append(row);
|
||||||
|
}
|
||||||
|
if (row.length() > d_ptr->maxColumn)
|
||||||
|
{
|
||||||
|
d_ptr->maxColumn = row.length();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
row.clear();
|
||||||
|
}
|
||||||
|
else if ((d_ptr->quoteMode & DoubleQuote && ch == '"') || (d_ptr->quoteMode & SingleQuote && ch == '\''))
|
||||||
|
{
|
||||||
|
quote = ch;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
stream >> ch;
|
||||||
|
if (ch == '\\' && d_ptr->quoteMode & BackslashEscape)
|
||||||
|
{
|
||||||
|
stream >> ch;
|
||||||
|
}
|
||||||
|
else if (ch == quote)
|
||||||
|
{
|
||||||
|
if (d_ptr->quoteMode & TwoQuoteEscape)
|
||||||
|
{
|
||||||
|
stream >> buffer;
|
||||||
|
if (buffer == quote)
|
||||||
|
{
|
||||||
|
buffer = QChar(0);
|
||||||
|
field.append(ch);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
field.append(ch);
|
||||||
|
} while (!stream.atEnd());
|
||||||
|
}
|
||||||
|
else if (ch == separator)
|
||||||
|
{
|
||||||
|
row << field;
|
||||||
|
field.clear();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
field.append(ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (not field.isEmpty())
|
||||||
|
{
|
||||||
|
row << field;
|
||||||
|
}
|
||||||
|
if (not row.isEmpty())
|
||||||
|
{
|
||||||
|
if (not headerSet)
|
||||||
|
{
|
||||||
|
d_ptr->header = row;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
d_ptr->csvData.append(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Sets the horizontal headers of the model to the values provided in \a data.
|
||||||
|
*/
|
||||||
|
void QxtCsvModel::setHeaderData(const QStringList& data)
|
||||||
|
{
|
||||||
|
qxt_d().header = data;
|
||||||
|
emit headerDataChanged(Qt::Horizontal, 0, data.count());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\reimp
|
||||||
|
*/
|
||||||
|
bool QxtCsvModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant& value, int role)
|
||||||
|
{
|
||||||
|
if (orientation != Qt::Horizontal)
|
||||||
|
{
|
||||||
|
return false; // We don't support the vertical header
|
||||||
|
}
|
||||||
|
|
||||||
|
if (role != Qt::DisplayRole && role != Qt::EditRole)
|
||||||
|
{
|
||||||
|
return false; // We don't support any other roles
|
||||||
|
}
|
||||||
|
|
||||||
|
if (section < 0)
|
||||||
|
{
|
||||||
|
return false; // Bogus input
|
||||||
|
}
|
||||||
|
|
||||||
|
while (section > qxt_d().header.size())
|
||||||
|
{
|
||||||
|
qxt_d().header << QString();
|
||||||
|
}
|
||||||
|
qxt_d().header[section] = value.toString();
|
||||||
|
emit headerDataChanged(Qt::Horizontal, section, section);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\reimp
|
||||||
|
*/
|
||||||
|
bool QxtCsvModel::setData(const QModelIndex& index, const QVariant& data, int role)
|
||||||
|
{
|
||||||
|
if (index.parent() != QModelIndex())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (role == Qt::DisplayRole || role == Qt::EditRole || role == Qt::UserRole)
|
||||||
|
{
|
||||||
|
if (index.row() >= rowCount() || index.column() >= columnCount() || index.row() < 0 || index.column() < 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
QStringList& row = qxt_d().csvData[index.row()];
|
||||||
|
while (row.length() <= index.column())
|
||||||
|
{
|
||||||
|
row << QString();
|
||||||
|
}
|
||||||
|
row[index.column()] = data.toString();
|
||||||
|
emit dataChanged(index, index);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\reimp
|
||||||
|
*/
|
||||||
|
bool QxtCsvModel::insertRow(int row, const QModelIndex& parent)
|
||||||
|
{
|
||||||
|
return insertRows(row, 1, parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\reimp
|
||||||
|
*/
|
||||||
|
bool QxtCsvModel::insertRows(int row, int count, const QModelIndex& parent)
|
||||||
|
{
|
||||||
|
if (parent != QModelIndex() || row < 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
emit beginInsertRows(parent, row, row + count);
|
||||||
|
QxtCsvModelPrivate& d_ptr = qxt_d();
|
||||||
|
if (row >= rowCount())
|
||||||
|
{
|
||||||
|
for(int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
d_ptr.csvData << QStringList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
d_ptr.csvData.insert(row, QStringList());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
emit endInsertRows();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\reimp
|
||||||
|
*/
|
||||||
|
bool QxtCsvModel::removeRow(int row, const QModelIndex& parent)
|
||||||
|
{
|
||||||
|
return removeRows(row, 1, parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\reimp
|
||||||
|
*/
|
||||||
|
bool QxtCsvModel::removeRows(int row, int count, const QModelIndex& parent)
|
||||||
|
{
|
||||||
|
if (parent != QModelIndex() || row < 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (row >= rowCount())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (row + count >= rowCount())
|
||||||
|
{
|
||||||
|
count = rowCount() - row;
|
||||||
|
}
|
||||||
|
emit beginRemoveRows(parent, row, row + count);
|
||||||
|
QxtCsvModelPrivate& d_ptr = qxt_d();
|
||||||
|
for (int i = 0;i < count;i++)
|
||||||
|
{
|
||||||
|
d_ptr.csvData.removeAt(row);
|
||||||
|
}
|
||||||
|
emit endRemoveRows();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\reimp
|
||||||
|
*/
|
||||||
|
bool QxtCsvModel::insertColumn(int col, const QModelIndex& parent)
|
||||||
|
{
|
||||||
|
return insertColumns(col, 1, parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\reimp
|
||||||
|
*/
|
||||||
|
bool QxtCsvModel::insertColumns(int col, int count, const QModelIndex& parent)
|
||||||
|
{
|
||||||
|
if (parent != QModelIndex() || col < 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
beginInsertColumns(parent, col, col + count - 1);
|
||||||
|
QxtCsvModelPrivate& d_ptr = qxt_d();
|
||||||
|
for (int i = 0; i < rowCount(); i++)
|
||||||
|
{
|
||||||
|
QStringList& row = d_ptr.csvData[i];
|
||||||
|
while (col >= row.length())
|
||||||
|
{
|
||||||
|
row.append(QString());
|
||||||
|
}
|
||||||
|
for (int j = 0; j < count; j++)
|
||||||
|
{
|
||||||
|
row.insert(col, QString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0; i < count ;i++)
|
||||||
|
{
|
||||||
|
d_ptr.header.insert(col, QString());
|
||||||
|
}
|
||||||
|
d_ptr.maxColumn += count;
|
||||||
|
endInsertColumns();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\reimp
|
||||||
|
*/
|
||||||
|
bool QxtCsvModel::removeColumn(int col, const QModelIndex& parent)
|
||||||
|
{
|
||||||
|
return removeColumns(col, 1, parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\reimp
|
||||||
|
*/
|
||||||
|
bool QxtCsvModel::removeColumns(int col, int count, const QModelIndex& parent)
|
||||||
|
{
|
||||||
|
if (parent != QModelIndex() || col < 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (col >= columnCount())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (col + count >= columnCount())
|
||||||
|
{
|
||||||
|
count = columnCount() - col;
|
||||||
|
}
|
||||||
|
emit beginRemoveColumns(parent, col, col + count);
|
||||||
|
QxtCsvModelPrivate& d_ptr = qxt_d();
|
||||||
|
QString before, after;
|
||||||
|
for (int i = 0; i < rowCount(); i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < count; j++)
|
||||||
|
{
|
||||||
|
d_ptr.csvData[i].removeAt(col);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
d_ptr.header.removeAt(col);
|
||||||
|
}
|
||||||
|
emit endRemoveColumns();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString qxt_addCsvQuotes(QxtCsvModel::QuoteMode mode, QString field)
|
||||||
|
{
|
||||||
|
bool addDoubleQuotes = ((mode & QxtCsvModel::DoubleQuote) && field.contains('"'));
|
||||||
|
bool addSingleQuotes = ((mode & QxtCsvModel::SingleQuote) && field.contains('\''));
|
||||||
|
bool quoteField = (mode & QxtCsvModel::AlwaysQuoteOutput) || addDoubleQuotes || addSingleQuotes;
|
||||||
|
if (quoteField && !addDoubleQuotes && !addSingleQuotes)
|
||||||
|
{
|
||||||
|
if (mode & QxtCsvModel::DoubleQuote)
|
||||||
|
{
|
||||||
|
addDoubleQuotes = true;
|
||||||
|
}
|
||||||
|
else if(mode & QxtCsvModel::SingleQuote)
|
||||||
|
{
|
||||||
|
addSingleQuotes = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mode & QxtCsvModel::BackslashEscape)
|
||||||
|
{
|
||||||
|
if (addDoubleQuotes)
|
||||||
|
{
|
||||||
|
return '"' + field.replace("\\", "\\\\").replace("\"", "\\\"") + '"';
|
||||||
|
}
|
||||||
|
if (addSingleQuotes)
|
||||||
|
{
|
||||||
|
return '\'' + field.replace("\\", "\\\\").replace("'", "\\'") + '\'';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (addDoubleQuotes)
|
||||||
|
{
|
||||||
|
return '"' + field.replace("\"", "\"\"") + '"';
|
||||||
|
}
|
||||||
|
if (addSingleQuotes)
|
||||||
|
{
|
||||||
|
return '\'' + field.replace("'", "''") + '\'';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Outputs the content of the model as a CSV file to the device \a dest using \a codec.
|
||||||
|
|
||||||
|
Fields in the output file will be separated by \a separator. Set \a withHeader to true
|
||||||
|
to output a row of headers at the top of the file.
|
||||||
|
*/
|
||||||
|
void QxtCsvModel::toCSV(QIODevice* dest, bool withHeader, QChar separator, QTextCodec* codec) const
|
||||||
|
{
|
||||||
|
const QxtCsvModelPrivate& d_ptr = qxt_d();
|
||||||
|
int row, col, rows, cols;
|
||||||
|
rows = rowCount();
|
||||||
|
cols = columnCount();
|
||||||
|
QString data;
|
||||||
|
if (not dest->isOpen())
|
||||||
|
{
|
||||||
|
dest->open(QIODevice::WriteOnly | QIODevice::Truncate);
|
||||||
|
}
|
||||||
|
QTextStream stream(dest);
|
||||||
|
if (codec)
|
||||||
|
{
|
||||||
|
stream.setCodec(codec);
|
||||||
|
}
|
||||||
|
if (withHeader)
|
||||||
|
{
|
||||||
|
data = "";
|
||||||
|
for (col = 0; col < cols; ++col)
|
||||||
|
{
|
||||||
|
if (col > 0)
|
||||||
|
{
|
||||||
|
data += separator;
|
||||||
|
}
|
||||||
|
data += qxt_addCsvQuotes(d_ptr.quoteMode, d_ptr.header.at(col));
|
||||||
|
}
|
||||||
|
stream << data << endl;
|
||||||
|
}
|
||||||
|
for (row = 0; row < rows; ++row)
|
||||||
|
{
|
||||||
|
const QStringList& rowData = d_ptr.csvData[row];
|
||||||
|
data = "";
|
||||||
|
for (col = 0; col < cols; ++col)
|
||||||
|
{
|
||||||
|
if (col > 0)
|
||||||
|
{
|
||||||
|
data += separator;
|
||||||
|
}
|
||||||
|
if (col < rowData.length())
|
||||||
|
{
|
||||||
|
data += qxt_addCsvQuotes(d_ptr.quoteMode, rowData.at(col));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data += qxt_addCsvQuotes(d_ptr.quoteMode, QString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stream << data << endl;
|
||||||
|
}
|
||||||
|
stream << flush;
|
||||||
|
dest->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\overload
|
||||||
|
|
||||||
|
Outputs the content of the model as a CSV file to the file specified by \a filename using \a codec.
|
||||||
|
|
||||||
|
Fields in the output file will be separated by \a separator. Set \a withHeader to true
|
||||||
|
to output a row of headers at the top of the file.
|
||||||
|
*/
|
||||||
|
void QxtCsvModel::toCSV(const QString filename, bool withHeader, QChar separator, QTextCodec* codec) const
|
||||||
|
{
|
||||||
|
QFile dest(filename);
|
||||||
|
toCSV(&dest, withHeader, separator, codec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\reimp
|
||||||
|
*/
|
||||||
|
Qt::ItemFlags QxtCsvModel::flags(const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
return Qt::ItemIsEditable | QAbstractTableModel::flags(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Returns the current quoting mode.
|
||||||
|
* \sa setQuoteMode
|
||||||
|
*/
|
||||||
|
QxtCsvModel::QuoteMode QxtCsvModel::quoteMode() const
|
||||||
|
{
|
||||||
|
return qxt_d().quoteMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Sets the current quoting mode. The default quoting mode is BothQuotes | BackslashEscape.
|
||||||
|
*
|
||||||
|
* The quoting mode determines what kinds of quoting is used for reading and writing CSV files.
|
||||||
|
* \sa quoteMode
|
||||||
|
* \sa QuoteOption
|
||||||
|
*/
|
||||||
|
void QxtCsvModel::setQuoteMode(QuoteMode mode)
|
||||||
|
{
|
||||||
|
qxt_d().quoteMode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Sets the content of the cell at row \a row and column \a column to \a value.
|
||||||
|
|
||||||
|
\sa text
|
||||||
|
*/
|
||||||
|
void QxtCsvModel::setText(int row, int column, const QString& value)
|
||||||
|
{
|
||||||
|
setData(index(row, column), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Fetches the content of the cell at row \a row and column \a column.
|
||||||
|
|
||||||
|
\sa setText
|
||||||
|
*/
|
||||||
|
QString QxtCsvModel::text(int row, int column) const
|
||||||
|
{
|
||||||
|
return data(index(row, column)).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Sets the content of the header for column \a column to \a value.
|
||||||
|
|
||||||
|
\sa headerText
|
||||||
|
*/
|
||||||
|
void QxtCsvModel::setHeaderText(int column, const QString& value)
|
||||||
|
{
|
||||||
|
setHeaderData(column, Qt::Horizontal, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Fetches the content of the cell at row \a row and column \a column.
|
||||||
|
|
||||||
|
\sa setText
|
||||||
|
*/
|
||||||
|
QString QxtCsvModel::headerText(int column) const
|
||||||
|
{
|
||||||
|
return headerData(column, Qt::Horizontal).toString();
|
||||||
|
}
|
113
src/libs/vmisc/qxtcsvmodel.h
Normal file
113
src/libs/vmisc/qxtcsvmodel.h
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
/****************************************************************************
|
||||||
|
** Copyright (c) 2006 - 2011, the LibQxt project.
|
||||||
|
** See the Qxt AUTHORS file for a list of authors and copyright holders.
|
||||||
|
** All rights reserved.
|
||||||
|
**
|
||||||
|
** Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in the
|
||||||
|
** documentation and/or other materials provided with the distribution.
|
||||||
|
** * Neither the name of the LibQxt project nor the
|
||||||
|
** names of its contributors may be used to endorse or promote products
|
||||||
|
** derived from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||||
|
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
**
|
||||||
|
** <http://libqxt.org> <foundation@libqxt.org>
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QXTCSVMODEL_H
|
||||||
|
#define QXTCSVMODEL_H
|
||||||
|
|
||||||
|
#include <QAbstractTableModel>
|
||||||
|
#include <QVariant>
|
||||||
|
#include <QIODevice>
|
||||||
|
#include <QChar>
|
||||||
|
#include <QString>
|
||||||
|
#include <QStringList>
|
||||||
|
#include <QModelIndex>
|
||||||
|
#include <def.h>
|
||||||
|
class QTextCodec;
|
||||||
|
|
||||||
|
class QxtCsvModelPrivate;
|
||||||
|
class QxtCsvModel : public QAbstractTableModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
QxtCsvModel(QObject *parent = nullptr);
|
||||||
|
explicit QxtCsvModel(QIODevice *file, QObject *parent = nullptr, bool withHeader = false, QChar separator = ',');
|
||||||
|
explicit QxtCsvModel(const QString filename, QObject *parent = nullptr, bool withHeader = false,
|
||||||
|
QChar separator = ',');
|
||||||
|
virtual ~QxtCsvModel();
|
||||||
|
|
||||||
|
virtual int rowCount(const QModelIndex& parent = QModelIndex()) const Q_DECL_OVERRIDE;
|
||||||
|
virtual int columnCount(const QModelIndex& parent = QModelIndex()) const Q_DECL_OVERRIDE;
|
||||||
|
virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
|
||||||
|
virtual bool setData(const QModelIndex& index, const QVariant& data, int role = Qt::EditRole) Q_DECL_OVERRIDE;
|
||||||
|
virtual QVariant headerData(int section, Qt::Orientation orientation,
|
||||||
|
int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
|
||||||
|
virtual bool setHeaderData(int section, Qt::Orientation orientation, const QVariant& value,
|
||||||
|
int role = Qt::DisplayRole) Q_DECL_OVERRIDE;
|
||||||
|
void setHeaderData(const QStringList& data);
|
||||||
|
|
||||||
|
QString text(int row, int column) const;
|
||||||
|
void setText(int row, int column, const QString& value);
|
||||||
|
|
||||||
|
QString headerText(int column) const;
|
||||||
|
void setHeaderText(int column, const QString& value);
|
||||||
|
|
||||||
|
|
||||||
|
bool insertRow(int row, const QModelIndex& parent = QModelIndex());
|
||||||
|
virtual bool insertRows(int row, int count, const QModelIndex& parent = QModelIndex()) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
bool removeRow(int row, const QModelIndex& parent = QModelIndex());
|
||||||
|
virtual bool removeRows(int row, int count, const QModelIndex& parent = QModelIndex()) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
bool insertColumn(int col, const QModelIndex& parent = QModelIndex());
|
||||||
|
virtual bool insertColumns(int col, int count, const QModelIndex& parent = QModelIndex()) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
bool removeColumn(int col, const QModelIndex& parent = QModelIndex());
|
||||||
|
virtual bool removeColumns(int col, int count, const QModelIndex& parent = QModelIndex()) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
void setSource(QIODevice *file, bool withHeader = false, QChar separator = ',', QTextCodec* codec = nullptr);
|
||||||
|
void setSource(const QString filename, bool withHeader = false, QChar separator = ',', QTextCodec* codec = nullptr);
|
||||||
|
|
||||||
|
void toCSV(QIODevice *file, bool withHeader = false, QChar separator = ',', QTextCodec* codec = nullptr) const;
|
||||||
|
void toCSV(const QString filename, bool withHeader = false, QChar separator = ',',
|
||||||
|
QTextCodec* codec = nullptr) const;
|
||||||
|
|
||||||
|
enum QuoteOption { NoQuotes = 0,
|
||||||
|
SingleQuote = 1,
|
||||||
|
DoubleQuote = 2,
|
||||||
|
BothQuotes = 3,
|
||||||
|
NoEscape = 0,
|
||||||
|
TwoQuoteEscape = 4,
|
||||||
|
BackslashEscape = 8,
|
||||||
|
AlwaysQuoteOutput = 16,
|
||||||
|
DefaultQuoteMode = BothQuotes | BackslashEscape | AlwaysQuoteOutput };
|
||||||
|
Q_DECLARE_FLAGS(QuoteMode, QuoteOption)
|
||||||
|
|
||||||
|
QuoteMode quoteMode() const;
|
||||||
|
void setQuoteMode(QuoteMode mode);
|
||||||
|
|
||||||
|
virtual Qt::ItemFlags flags(const QModelIndex& index) const Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Q_DISABLE_COPY(QxtCsvModel)
|
||||||
|
QXT_DECLARE_PRIVATE(QxtCsvModel)
|
||||||
|
};
|
||||||
|
Q_DECLARE_OPERATORS_FOR_FLAGS(QxtCsvModel::QuoteMode)
|
||||||
|
|
||||||
|
#endif // QXTCSVMODEL_H
|
|
@ -9,7 +9,8 @@ SOURCES += \
|
||||||
$$PWD/projectversion.cpp \
|
$$PWD/projectversion.cpp \
|
||||||
$$PWD/vcommonsettings.cpp \
|
$$PWD/vcommonsettings.cpp \
|
||||||
$$PWD/vtapesettings.cpp \
|
$$PWD/vtapesettings.cpp \
|
||||||
$$PWD/commandoptions.cpp
|
$$PWD/commandoptions.cpp \
|
||||||
|
$$PWD/qxtcsvmodel.cpp
|
||||||
|
|
||||||
win32-msvc*:SOURCES += $$PWD/stable.cpp
|
win32-msvc*:SOURCES += $$PWD/stable.cpp
|
||||||
|
|
||||||
|
@ -27,7 +28,8 @@ HEADERS += \
|
||||||
$$PWD/debugbreak.h \
|
$$PWD/debugbreak.h \
|
||||||
$$PWD/vlockguard.h \
|
$$PWD/vlockguard.h \
|
||||||
$$PWD/vsysexits.h \
|
$$PWD/vsysexits.h \
|
||||||
$$PWD/commandoptions.h
|
$$PWD/commandoptions.h \
|
||||||
|
$$PWD/qxtcsvmodel.h
|
||||||
|
|
||||||
# Qt's versions
|
# Qt's versions
|
||||||
# 5.0.0, 5.0.1, 5.0.2
|
# 5.0.0, 5.0.1, 5.0.2
|
||||||
|
|
|
@ -30,12 +30,17 @@
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
#include <QTextCodec>
|
||||||
|
|
||||||
const QString VTapeSettings::SettingDataBaseGeometry = QStringLiteral("database/geometry");
|
const QString VTapeSettings::SettingDataBaseGeometry = QStringLiteral("database/geometry");
|
||||||
|
|
||||||
const QString VTapeSettings::SettingDefHeight = QStringLiteral("gradation/defHeight");
|
const QString VTapeSettings::SettingDefHeight = QStringLiteral("gradation/defHeight");
|
||||||
const QString VTapeSettings::SettingDefSize = QStringLiteral("gradation/defHeight");
|
const QString VTapeSettings::SettingDefSize = QStringLiteral("gradation/defHeight");
|
||||||
|
|
||||||
|
const QString VTapeSettings::SettingCSVWithHeader = QStringLiteral("csv/withHeader");
|
||||||
|
const QString VTapeSettings::SettingCSVCodec = QStringLiteral("csv/withCodec");
|
||||||
|
const QString VTapeSettings::SettingCSVSeparator = QStringLiteral("csv/withSeparator");
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
VTapeSettings::VTapeSettings(Format format, Scope scope, const QString &organization, const QString &application,
|
VTapeSettings::VTapeSettings(Format format, Scope scope, const QString &organization, const QString &application,
|
||||||
QObject *parent)
|
QObject *parent)
|
||||||
|
@ -78,3 +83,70 @@ int VTapeSettings::GetDefSize() const
|
||||||
{
|
{
|
||||||
return value(SettingDefSize, 50).toInt();
|
return value(SettingDefSize, 50).toInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void VTapeSettings::SetCSVWithHeader(bool withHeader)
|
||||||
|
{
|
||||||
|
setValue(SettingCSVWithHeader, withHeader);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
bool VTapeSettings::GetCSVWithHeader() const
|
||||||
|
{
|
||||||
|
return value(SettingCSVWithHeader, false).toBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void VTapeSettings::SetCSVCodec(int mib)
|
||||||
|
{
|
||||||
|
setValue(SettingCSVCodec, mib);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
int VTapeSettings::GetCSVCodec() const
|
||||||
|
{
|
||||||
|
return value(SettingCSVCodec, QTextCodec::codecForLocale()->mibEnum()).toInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void VTapeSettings::SetCSVSeparator(const QChar &separator)
|
||||||
|
{
|
||||||
|
switch(separator.toLatin1())
|
||||||
|
{
|
||||||
|
case '\t':
|
||||||
|
setValue(SettingCSVSeparator, 0);
|
||||||
|
break;
|
||||||
|
case ';':
|
||||||
|
setValue(SettingCSVSeparator, 1);
|
||||||
|
break;
|
||||||
|
case ' ':
|
||||||
|
setValue(SettingCSVSeparator, 2);
|
||||||
|
break;
|
||||||
|
case ',':
|
||||||
|
default:
|
||||||
|
setValue(SettingCSVSeparator, 3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
QChar VTapeSettings::GetCSVSeparator() const
|
||||||
|
{
|
||||||
|
const quint8 separator = static_cast<quint8>(value(SettingCSVSeparator, 3).toUInt());
|
||||||
|
switch(separator)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
return QChar('\t');
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
return QChar(';');
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
return QChar(' ');
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
default:
|
||||||
|
return QChar(',');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -47,12 +47,24 @@ public:
|
||||||
void SetDefSize(int value);
|
void SetDefSize(int value);
|
||||||
int GetDefSize() const;
|
int GetDefSize() const;
|
||||||
|
|
||||||
|
void SetCSVWithHeader(bool withHeader);
|
||||||
|
bool GetCSVWithHeader() const;
|
||||||
|
|
||||||
|
void SetCSVCodec(int mib);
|
||||||
|
int GetCSVCodec() const;
|
||||||
|
|
||||||
|
void SetCSVSeparator(const QChar &separator);
|
||||||
|
QChar GetCSVSeparator() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Q_DISABLE_COPY(VTapeSettings)
|
Q_DISABLE_COPY(VTapeSettings)
|
||||||
|
|
||||||
static const QString SettingDataBaseGeometry;
|
static const QString SettingDataBaseGeometry;
|
||||||
static const QString SettingDefHeight;
|
static const QString SettingDefHeight;
|
||||||
static const QString SettingDefSize;
|
static const QString SettingDefSize;
|
||||||
|
static const QString SettingCSVWithHeader;
|
||||||
|
static const QString SettingCSVCodec;
|
||||||
|
static const QString SettingCSVSeparator;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // VTAPESETTINGS_H
|
#endif // VTAPESETTINGS_H
|
||||||
|
|
Loading…
Reference in New Issue
Block a user