[ref]同步 public
This commit is contained in:
parent
2a20810d1a
commit
0305921c3e
6
platform/src/public/pub_excel/excellib.cpp
Normal file
6
platform/src/public/pub_excel/excellib.cpp
Normal file
@ -0,0 +1,6 @@
|
||||
#include "excellib.h"
|
||||
|
||||
|
||||
ExcelLib::ExcelLib()
|
||||
{
|
||||
}
|
||||
51
platform/src/public/pub_excel/pub_excel.pro
Normal file
51
platform/src/public/pub_excel/pub_excel.pro
Normal file
@ -0,0 +1,51 @@
|
||||
#-------------------------------------------------
|
||||
#
|
||||
# Project created by QtCreator 2018-02-09T13:26:54
|
||||
#此处仅仅是简单将QtXlsx库封装
|
||||
#-------------------------------------------------
|
||||
|
||||
QT -= gui
|
||||
QT += core gui-private
|
||||
|
||||
TARGET = pub_excel
|
||||
TEMPLATE = lib
|
||||
|
||||
|
||||
DEFINES += QT_BUILD_XLSX_LIB
|
||||
include($$PWD/xlsx/qtxlsx.pri)
|
||||
|
||||
exists($$PWD/../../common.pri) {
|
||||
include($$PWD/../../common.pri)
|
||||
}else {
|
||||
error("FATAL error: connot find common.pri")
|
||||
}
|
||||
|
||||
|
||||
DEFINES += EXCELLIB_LIBRARY
|
||||
|
||||
# The following define makes your compiler emit warnings if you use
|
||||
# any feature of Qt which has been marked as deprecated (the exact warnings
|
||||
# depend on your compiler). Please consult the documentation of the
|
||||
# deprecated API in order to know how to port your code away from it.
|
||||
DEFINES += QT_DEPRECATED_WARNINGS
|
||||
|
||||
# You can also make your code fail to compile if you use deprecated APIs.
|
||||
# In order to do so, uncomment the following line.
|
||||
# You can also select to disable deprecated APIs only up to a certain version of Qt.
|
||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
INCLUDEPATH += $$PWD/../../include/public/pub_excel/xlsx \
|
||||
$$PWD/../../include/public/pub_excel
|
||||
|
||||
|
||||
SOURCES += \
|
||||
excellib.cpp
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/../../include/public/pub_excel/excellib.h \
|
||||
$$PWD/../../include/public/pub_excel/excellib_global.h
|
||||
|
||||
unix {
|
||||
target.path = /usr/lib
|
||||
INSTALLS += target
|
||||
}
|
||||
75
platform/src/public/pub_excel/xlsx/doc/qtxlsx.qdocconf
Normal file
75
platform/src/public/pub_excel/xlsx/doc/qtxlsx.qdocconf
Normal file
@ -0,0 +1,75 @@
|
||||
include($QT_INSTALL_DOCS/global/qt-html-templates-offline.qdocconf)
|
||||
include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf)
|
||||
|
||||
project = QtXlsx
|
||||
description = Qt Xlsx Reference Documentation
|
||||
url = http://qtxlsx.debao.me
|
||||
version = $QT_VERSION
|
||||
|
||||
qhp.projects = QtXlsx
|
||||
|
||||
qhp.QtXlsx.file = qtxlsx.qhp
|
||||
qhp.QtXlsx.namespace = me.debao.qtxlsx.$QT_VERSION_TAG
|
||||
qhp.QtXlsx.virtualFolder = qtxlsx
|
||||
qhp.QtXlsx.indexTitle = Qt Xlsx
|
||||
qhp.QtXlsx.indexRoot =
|
||||
|
||||
qhp.QtXlsx.filterAttributes = qtxlsx $QT_VERSION qtrefdoc
|
||||
qhp.QtXlsx.customFilters.Qt.name = QtXlsx $QT_VERSION
|
||||
qhp.QtXlsx.customFilters.Qt.filterAttributes = qtxlsx $QT_VERSION
|
||||
qhp.QtXlsx.subprojects = overviews classes qmltypes examples
|
||||
qhp.QtXlsx.subprojects.overviews.title = Overview
|
||||
qhp.QtXlsx.subprojects.overviews.indexTitle = Qt Xlsx
|
||||
qhp.QtXlsx.subprojects.overviews.selectors = fake:page,group,module
|
||||
qhp.QtXlsx.subprojects.classes.title = C++ Classes
|
||||
qhp.QtXlsx.subprojects.classes.indexTitle = Qt Xlsx C++ Classes
|
||||
qhp.QtXlsx.subprojects.classes.selectors = class fake:headerfile
|
||||
qhp.QtXlsx.subprojects.classes.sortPages = true
|
||||
qhp.QtXlsx.subprojects.examples.title = Examples
|
||||
qhp.QtXlsx.subprojects.examples.indexTitle = Qt Xlsx Examples
|
||||
qhp.QtXlsx.subprojects.examples.selectors = fake:example
|
||||
|
||||
tagfile = ../../../doc/qtxlsx/qtxlsx.tags
|
||||
|
||||
headerdirs += ..
|
||||
|
||||
sourcedirs += ..
|
||||
|
||||
exampledirs += ../../../examples/xlsx \
|
||||
snippets/
|
||||
|
||||
# Specify the install path under QT_INSTALL_EXAMPLES
|
||||
examplesinstallpath = xlsx
|
||||
|
||||
imagedirs += images
|
||||
|
||||
depends += qtcore qtdoc qtgui
|
||||
|
||||
HTML.footer = \
|
||||
" </div>\n" \
|
||||
" </div>\n" \
|
||||
" </div>\n" \
|
||||
" </div>\n" \
|
||||
"</div>\n" \
|
||||
"<div class=\"footer\">\n" \
|
||||
" <div class=\"qt13a-copyright\" id=\"copyright\">\n" \
|
||||
" <div class=\"qt13a-container\">\n" \
|
||||
" <p>\n" \
|
||||
" <acronym title=\"Copyright\">©</acronym> 2013-2014 Debao Zhang. \n" \
|
||||
" Documentation contributions included herein are the copyrights of\n" \
|
||||
" their respective owners.</p>\n" \
|
||||
" <p>\n" \
|
||||
" The documentation provided herein is licensed under the terms of the\n" \
|
||||
" <a href=\"http://www.gnu.org/licenses/fdl.html\">GNU Free Documentation\n" \
|
||||
" License version 1.3</a> as published by the Free Software Foundation.</p>\n" \
|
||||
" <p>\n" \
|
||||
" Documentation sources may be obtained from <a href=\"https://github.com/dbzhang800/QtXlsxWriter\">\n" \
|
||||
" github.com/dbzhang800</a>.</p>\n" \
|
||||
" <p>\n" \
|
||||
" Qt and their respective logos are trademarks of Digia Plc \n" \
|
||||
" in Finland and/or other countries worldwide. All other trademarks are property\n" \
|
||||
" of their respective owners. <a title=\"Privacy Policy\"\n" \
|
||||
" href=\"http://en.gitorious.org/privacy_policy/\">Privacy Policy</a></p>\n" \
|
||||
" </div>\n" \
|
||||
" </div>\n" \
|
||||
"</div>\n" \
|
||||
@ -0,0 +1,8 @@
|
||||
|
||||
//! [0]
|
||||
#include <QtXlsx>
|
||||
//! [0]
|
||||
|
||||
//! [1]
|
||||
#include <QtXlsx>
|
||||
//! [1]
|
||||
@ -0,0 +1,3 @@
|
||||
#! [1]
|
||||
QT += xlsx
|
||||
#! [1]
|
||||
8
platform/src/public/pub_excel/xlsx/doc/src/examples.qdoc
Normal file
8
platform/src/public/pub_excel/xlsx/doc/src/examples.qdoc
Normal file
@ -0,0 +1,8 @@
|
||||
/*!
|
||||
\group qtxlsx-examples
|
||||
\title Qt Xlsx Examples
|
||||
\brief Examples for the Qt Xlsx module
|
||||
\ingroup all-examples
|
||||
|
||||
Qt Xlsx comes with the following examples:
|
||||
*/
|
||||
72
platform/src/public/pub_excel/xlsx/doc/src/qtxlsx-index.qdoc
Normal file
72
platform/src/public/pub_excel/xlsx/doc/src/qtxlsx-index.qdoc
Normal file
@ -0,0 +1,72 @@
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2013 Debao Zhang <hello@debao.me>
|
||||
** All right reserved.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining
|
||||
** a copy of this software and associated documentation files (the
|
||||
** "Software"), to deal in the Software without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Software, and to
|
||||
** permit persons to whom the Software is furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be
|
||||
** included in all copies or substantial portions of the Software.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
/*!
|
||||
\title Qt Xlsx
|
||||
\page index.html
|
||||
\brief Qt Xlsx provides functionality for handling .xlsx files.
|
||||
|
||||
The \l{Qt Xlsx C++ Classes}{Qt Xlsx Module} provides a set of classes to read and write Excel files. It doesn't require
|
||||
Microsoft Excel and can be used in any platform that Qt5 supported. The library can be used to
|
||||
|
||||
\list
|
||||
\li \l{Hello QtXlsx Example}{Generate a new .xlsx file from scratch}
|
||||
\li \l{Extract Data Example}{Extract data from an existing .xlsx file}
|
||||
\li Edit an existing .xlsx file
|
||||
\endlist
|
||||
|
||||
\image xlsx_demo.gif
|
||||
|
||||
\table
|
||||
\row
|
||||
\li Source code: \li \l{https://github.com/dbzhang800/QtXlsxWriter}
|
||||
\row
|
||||
\li Issures: \li \l{https://github.com/dbzhang800/QtXlsxWriter/issues}
|
||||
\row
|
||||
\li License: \li MIT
|
||||
\endtable
|
||||
|
||||
\section1 Getting Started
|
||||
|
||||
To include the definitions of the module's classes, using the following directive:
|
||||
|
||||
\code
|
||||
#include <QtXlsx>
|
||||
\endcode
|
||||
|
||||
To link against the module, add this line to your qmake .pro file:
|
||||
|
||||
\code
|
||||
QT += xlsx
|
||||
\endcode
|
||||
|
||||
More information can be found in \l{Qt Xlsx Build} page.
|
||||
|
||||
\section1 Related information
|
||||
\list
|
||||
\li \l{Qt Xlsx C++ Classes}
|
||||
\li \l{Qt Xlsx Examples}
|
||||
\endlist
|
||||
*/
|
||||
36
platform/src/public/pub_excel/xlsx/doc/src/qtxlsx.qdoc
Normal file
36
platform/src/public/pub_excel/xlsx/doc/src/qtxlsx.qdoc
Normal file
@ -0,0 +1,36 @@
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2013 Debao Zhang <hello@debao.me>
|
||||
** All right reserved.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining
|
||||
** a copy of this software and associated documentation files (the
|
||||
** "Software"), to deal in the Software without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Software, and to
|
||||
** permit persons to whom the Software is furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be
|
||||
** included in all copies or substantial portions of the Software.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
/*!
|
||||
\module QtXlsx
|
||||
\title Qt Xlsx C++ Classes
|
||||
\ingroup modules
|
||||
|
||||
\brief The Qt Xlsx module provides functionality for handling .xlsx files.
|
||||
|
||||
.xlsx is a zipped, XML-based file format developed by Microsoft for
|
||||
representing spreadsheets.
|
||||
*/
|
||||
|
||||
83
platform/src/public/pub_excel/xlsx/doc/src/usage.qdoc
Normal file
83
platform/src/public/pub_excel/xlsx/doc/src/usage.qdoc
Normal file
@ -0,0 +1,83 @@
|
||||
/*!
|
||||
\page building
|
||||
\title Qt Xlsx Build
|
||||
|
||||
\note QZipWriter and QZipReader which live in gui-private is used in
|
||||
this library. For linux user, if your Qt is installed through package
|
||||
manager tools such "apt-get", make sure that you have installed the Qt5
|
||||
develop package *qtbase5-private-dev* ;
|
||||
if you Qt is built from source by yourself,
|
||||
or download from qt-project.org directly, nothing need to do.
|
||||
|
||||
\section1 Usage(1): Use Xlsx as Qt5's addon module
|
||||
|
||||
1. Download the source code from \l {https://github.com/dbzhang800/QtXlsxWriter/archive/master.zip} {github.com}.
|
||||
|
||||
2. Put the source code in any directory you like. At the toplevel directory run
|
||||
|
||||
\note Perl is needed in this step.
|
||||
|
||||
\code
|
||||
qmake
|
||||
make
|
||||
make install
|
||||
\endcode
|
||||
|
||||
The library, the header files, and others will be installed to your system.
|
||||
|
||||
3. Add following line to your qmake's project file:
|
||||
|
||||
\code
|
||||
QT += xlsx
|
||||
\endcode
|
||||
|
||||
4. Then, using Qt Xlsx in your code
|
||||
|
||||
\code
|
||||
#include "xlsxdocument.h"
|
||||
int main()
|
||||
{
|
||||
QXlsx::Document xlsx;
|
||||
xlsx.write("A1", "Hello Qt!");
|
||||
xlsx.saveAs("Test.xlsx");
|
||||
return 0;
|
||||
}
|
||||
\endcode
|
||||
|
||||
\section1 Usage(2): Use source code directly
|
||||
|
||||
The package contains a qtxlsx.pri file that allows you to integrate
|
||||
the component into applications that use qmake for the build step.
|
||||
|
||||
1. Download the source code from \l {https://github.com/dbzhang800/QtXlsxWriter/archive/master.zip} {github.com}
|
||||
|
||||
2. Put the source code in any directory you like. For example, 3rdparty:
|
||||
|
||||
\code
|
||||
|-- project.pro
|
||||
|-- ....
|
||||
|-- 3rdparty\
|
||||
| |-- qtxlsx\
|
||||
| |
|
||||
\endcode
|
||||
|
||||
3. Add following line to your qmake project file:
|
||||
|
||||
\code
|
||||
include(3rdparty/qtxlsx/src/xlsx/qtxlsx.pri)
|
||||
\endcode
|
||||
|
||||
\note If you like, you can copy all files from *src/xlsx* to your application's source path. Then add following line to your project file:
|
||||
|
||||
\code
|
||||
include(qtxlsx.pri)
|
||||
\endcode
|
||||
|
||||
\note If you do not use qmake, you need to define the following macro manually
|
||||
|
||||
\code
|
||||
XLSX_NO_LIB
|
||||
\endcode
|
||||
|
||||
4. Then, using Qt Xlsx in your code
|
||||
*/
|
||||
86
platform/src/public/pub_excel/xlsx/qtxlsx.pri
Normal file
86
platform/src/public/pub_excel/xlsx/qtxlsx.pri
Normal file
@ -0,0 +1,86 @@
|
||||
INCLUDEPATH += $$PWD
|
||||
DEPENDPATH += $$PWD
|
||||
|
||||
QT += core gui gui-private
|
||||
#!build_xlsx_lib:DEFINES += XLSX_NO_LIB
|
||||
|
||||
|
||||
|
||||
HEADERS += $$PWD/../../../include/public/pub_excel/xlsx/xlsxdocpropscore_p.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxdocpropsapp_p.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxrelationships_p.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxutility_p.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxsharedstrings_p.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxcontenttypes_p.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxtheme_p.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxformat.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxworkbook.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxstyles_p.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxabstractsheet.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxabstractsheet_p.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxworksheet.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxworksheet_p.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxchartsheet.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxchartsheet_p.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxzipwriter_p.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxworkbook_p.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxformat_p.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxglobal.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxdrawing_p.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxzipreader_p.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxdocument.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxdocument_p.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxcell.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxcell_p.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxdatavalidation.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxdatavalidation_p.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxcellreference.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxcellrange.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxrichstring_p.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxrichstring.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxconditionalformatting.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxconditionalformatting_p.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxcolor_p.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxnumformatparser_p.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxdrawinganchor_p.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxmediafile_p.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxabstractooxmlfile.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxabstractooxmlfile_p.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxchart.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxchart_p.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxsimpleooxmlfile_p.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxcellformula.h \
|
||||
$$PWD/../../../include/public/pub_excel/xlsx/xlsxcellformula_p.h
|
||||
|
||||
SOURCES += $$PWD/xlsxdocpropscore.cpp \
|
||||
$$PWD/xlsxdocpropsapp.cpp \
|
||||
$$PWD/xlsxrelationships.cpp \
|
||||
$$PWD/xlsxutility.cpp \
|
||||
$$PWD/xlsxsharedstrings.cpp \
|
||||
$$PWD/xlsxcontenttypes.cpp \
|
||||
$$PWD/xlsxtheme.cpp \
|
||||
$$PWD/xlsxformat.cpp \
|
||||
$$PWD/xlsxstyles.cpp \
|
||||
$$PWD/xlsxworkbook.cpp \
|
||||
$$PWD/xlsxabstractsheet.cpp \
|
||||
$$PWD/xlsxworksheet.cpp \
|
||||
$$PWD/xlsxchartsheet.cpp \
|
||||
$$PWD/xlsxzipwriter.cpp \
|
||||
$$PWD/xlsxdrawing.cpp \
|
||||
$$PWD/xlsxzipreader.cpp \
|
||||
$$PWD/xlsxdocument.cpp \
|
||||
$$PWD/xlsxcell.cpp \
|
||||
$$PWD/xlsxdatavalidation.cpp \
|
||||
$$PWD/xlsxcellreference.cpp \
|
||||
$$PWD/xlsxcellrange.cpp \
|
||||
$$PWD/xlsxrichstring.cpp \
|
||||
$$PWD/xlsxconditionalformatting.cpp \
|
||||
$$PWD/xlsxcolor.cpp \
|
||||
$$PWD/xlsxnumformatparser.cpp \
|
||||
$$PWD/xlsxdrawinganchor.cpp \
|
||||
$$PWD/xlsxmediafile.cpp \
|
||||
$$PWD/xlsxabstractooxmlfile.cpp \
|
||||
$$PWD/xlsxchart.cpp \
|
||||
$$PWD/xlsxsimpleooxmlfile.cpp \
|
||||
$$PWD/xlsxcellformula.cpp
|
||||
|
||||
17
platform/src/public/pub_excel/xlsx/xlsx.pro
Normal file
17
platform/src/public/pub_excel/xlsx/xlsx.pro
Normal file
@ -0,0 +1,17 @@
|
||||
TARGET = QtXlsx
|
||||
TEMPLATE = lib
|
||||
|
||||
QMAKE_DOCS = $$PWD/doc/qtxlsx.qdocconf
|
||||
|
||||
load(qt_module)
|
||||
|
||||
CONFIG += build_xlsx_lib
|
||||
include(qtxlsx.pri)
|
||||
|
||||
#Define this macro if you want to run tests, so more AIPs will get exported.
|
||||
#DEFINES += XLSX_TEST
|
||||
|
||||
QMAKE_TARGET_COMPANY = "Debao Zhang"
|
||||
QMAKE_TARGET_COPYRIGHT = "Copyright (C) 2013-2014 Debao Zhang <hello@debao.me>"
|
||||
QMAKE_TARGET_DESCRIPTION = ".Xlsx file wirter for Qt5"
|
||||
|
||||
119
platform/src/public/pub_excel/xlsx/xlsxabstractooxmlfile.cpp
Normal file
119
platform/src/public/pub_excel/xlsx/xlsxabstractooxmlfile.cpp
Normal file
@ -0,0 +1,119 @@
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2013-2014 Debao Zhang <hello@debao.me>
|
||||
** All right reserved.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining
|
||||
** a copy of this software and associated documentation files (the
|
||||
** "Software"), to deal in the Software without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Software, and to
|
||||
** permit persons to whom the Software is furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be
|
||||
** included in all copies or substantial portions of the Software.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "xlsxabstractooxmlfile.h"
|
||||
#include "xlsxabstractooxmlfile_p.h"
|
||||
|
||||
#include <QBuffer>
|
||||
#include <QByteArray>
|
||||
|
||||
QT_BEGIN_NAMESPACE_XLSX
|
||||
|
||||
AbstractOOXmlFilePrivate::AbstractOOXmlFilePrivate(AbstractOOXmlFile *q, AbstractOOXmlFile::CreateFlag flag=AbstractOOXmlFile::F_NewFromScratch)
|
||||
:relationships(new Relationships), flag(flag), q_ptr(q)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
AbstractOOXmlFilePrivate::~AbstractOOXmlFilePrivate()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*
|
||||
* \class AbstractOOXmlFile
|
||||
*
|
||||
* Base class of all the ooxml part file.
|
||||
*/
|
||||
|
||||
AbstractOOXmlFile::AbstractOOXmlFile(CreateFlag flag)
|
||||
:d_ptr(new AbstractOOXmlFilePrivate(this, flag))
|
||||
{
|
||||
}
|
||||
|
||||
AbstractOOXmlFile::AbstractOOXmlFile(AbstractOOXmlFilePrivate *d)
|
||||
:d_ptr(d)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
AbstractOOXmlFile::~AbstractOOXmlFile()
|
||||
{
|
||||
if (d_ptr->relationships)
|
||||
delete d_ptr->relationships;
|
||||
delete d_ptr;
|
||||
}
|
||||
|
||||
QByteArray AbstractOOXmlFile::saveToXmlData() const
|
||||
{
|
||||
QByteArray data;
|
||||
QBuffer buffer(&data);
|
||||
buffer.open(QIODevice::WriteOnly);
|
||||
saveToXmlFile(&buffer);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
bool AbstractOOXmlFile::loadFromXmlData(const QByteArray &data)
|
||||
{
|
||||
QBuffer buffer;
|
||||
buffer.setData(data);
|
||||
buffer.open(QIODevice::ReadOnly);
|
||||
|
||||
return loadFromXmlFile(&buffer);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
void AbstractOOXmlFile::setFilePath(const QString path)
|
||||
{
|
||||
Q_D(AbstractOOXmlFile);
|
||||
d->filePathInPackage = path;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
QString AbstractOOXmlFile::filePath() const
|
||||
{
|
||||
Q_D(const AbstractOOXmlFile);
|
||||
return d->filePathInPackage;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
Relationships *AbstractOOXmlFile::relationships() const
|
||||
{
|
||||
Q_D(const AbstractOOXmlFile);
|
||||
return d->relationships;
|
||||
}
|
||||
|
||||
|
||||
QT_END_NAMESPACE_XLSX
|
||||
206
platform/src/public/pub_excel/xlsx/xlsxabstractsheet.cpp
Normal file
206
platform/src/public/pub_excel/xlsx/xlsxabstractsheet.cpp
Normal file
@ -0,0 +1,206 @@
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2013-2014 Debao Zhang <hello@debao.me>
|
||||
** All right reserved.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining
|
||||
** a copy of this software and associated documentation files (the
|
||||
** "Software"), to deal in the Software without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Software, and to
|
||||
** permit persons to whom the Software is furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be
|
||||
** included in all copies or substantial portions of the Software.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
****************************************************************************/
|
||||
#include "xlsxabstractsheet.h"
|
||||
#include "xlsxabstractsheet_p.h"
|
||||
#include "xlsxworkbook.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE_XLSX
|
||||
|
||||
AbstractSheetPrivate::AbstractSheetPrivate(AbstractSheet *p, AbstractSheet::CreateFlag flag)
|
||||
: AbstractOOXmlFilePrivate(p, flag)
|
||||
{
|
||||
type = AbstractSheet::ST_WorkSheet;
|
||||
sheetState = AbstractSheet::SS_Visible;
|
||||
}
|
||||
|
||||
AbstractSheetPrivate::~AbstractSheetPrivate()
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
\class AbstractSheet
|
||||
\inmodule QtXlsx
|
||||
\brief Base class for worksheet, chartsheet, etc.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\enum AbstractSheet::SheetType
|
||||
|
||||
\value ST_WorkSheet
|
||||
\value ST_ChartSheet
|
||||
\omitvalue ST_DialogSheet
|
||||
\omitvalue ST_MacroSheet
|
||||
*/
|
||||
|
||||
/*!
|
||||
\enum AbstractSheet::SheetState
|
||||
|
||||
\value SS_Visible
|
||||
\value SS_Hidden
|
||||
\value SS_VeryHidden User cann't make a veryHidden sheet visible in normal way.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn AbstractSheet::copy(const QString &distName, int distId) const
|
||||
|
||||
Copies the current sheet to a sheet called \a distName with \a distId.
|
||||
Returns the new sheet.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
AbstractSheet::AbstractSheet(const QString &name, int id, Workbook *workbook, AbstractSheetPrivate *d) :
|
||||
AbstractOOXmlFile(d)
|
||||
{
|
||||
d_func()->name = name;
|
||||
d_func()->id = id;
|
||||
d_func()->workbook = workbook;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* Returns the name of the sheet.
|
||||
*/
|
||||
QString AbstractSheet::sheetName() const
|
||||
{
|
||||
Q_D(const AbstractSheet);
|
||||
return d->name;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
void AbstractSheet::setSheetName(const QString &sheetName)
|
||||
{
|
||||
Q_D(AbstractSheet);
|
||||
d->name = sheetName;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the type of the sheet.
|
||||
*/
|
||||
AbstractSheet::SheetType AbstractSheet::sheetType() const
|
||||
{
|
||||
Q_D(const AbstractSheet);
|
||||
return d->type;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
void AbstractSheet::setSheetType(SheetType type)
|
||||
{
|
||||
Q_D(AbstractSheet);
|
||||
d->type = type;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the state of the sheet.
|
||||
*
|
||||
* \sa isHidden(), isVisible(), setSheetState()
|
||||
*/
|
||||
AbstractSheet::SheetState AbstractSheet::sheetState() const
|
||||
{
|
||||
Q_D(const AbstractSheet);
|
||||
return d->sheetState;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Set the state of the sheet to \a state.
|
||||
*/
|
||||
void AbstractSheet::setSheetState(SheetState state)
|
||||
{
|
||||
Q_D(AbstractSheet);
|
||||
d->sheetState = state;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns true if the sheet is not visible, otherwise false will be returned.
|
||||
*
|
||||
* \sa sheetState(), setHidden()
|
||||
*/
|
||||
bool AbstractSheet::isHidden() const
|
||||
{
|
||||
Q_D(const AbstractSheet);
|
||||
return d->sheetState != SS_Visible;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns true if the sheet is visible.
|
||||
*/
|
||||
bool AbstractSheet::isVisible() const
|
||||
{
|
||||
return !isHidden();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Make the sheet hiden or visible based on \a hidden.
|
||||
*/
|
||||
void AbstractSheet::setHidden(bool hidden)
|
||||
{
|
||||
Q_D(AbstractSheet);
|
||||
if (hidden == isHidden())
|
||||
return;
|
||||
|
||||
d->sheetState = hidden ? SS_Hidden : SS_Visible;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Convenience function, equivalent to setHidden(! \a visible).
|
||||
*/
|
||||
void AbstractSheet::setVisible(bool visible)
|
||||
{
|
||||
setHidden(!visible);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
int AbstractSheet::sheetId() const
|
||||
{
|
||||
Q_D(const AbstractSheet);
|
||||
return d->id;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
Drawing *AbstractSheet::drawing() const
|
||||
{
|
||||
Q_D(const AbstractSheet);
|
||||
return d->drawing.data();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Return the workbook
|
||||
*/
|
||||
Workbook *AbstractSheet::workbook() const
|
||||
{
|
||||
Q_D(const AbstractSheet);
|
||||
return d->workbook;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE_XLSX
|
||||
178
platform/src/public/pub_excel/xlsx/xlsxcell.cpp
Normal file
178
platform/src/public/pub_excel/xlsx/xlsxcell.cpp
Normal file
@ -0,0 +1,178 @@
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2013-2014 Debao Zhang <hello@debao.me>
|
||||
** All right reserved.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining
|
||||
** a copy of this software and associated documentation files (the
|
||||
** "Software"), to deal in the Software without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Software, and to
|
||||
** permit persons to whom the Software is furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be
|
||||
** included in all copies or substantial portions of the Software.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
****************************************************************************/
|
||||
#include "xlsxcell.h"
|
||||
#include "xlsxcell_p.h"
|
||||
#include "xlsxformat.h"
|
||||
#include "xlsxformat_p.h"
|
||||
#include "xlsxutility_p.h"
|
||||
#include "xlsxworksheet.h"
|
||||
#include "xlsxworkbook.h"
|
||||
#include <QDateTime>
|
||||
|
||||
QT_BEGIN_NAMESPACE_XLSX
|
||||
|
||||
CellPrivate::CellPrivate(Cell *p) :
|
||||
q_ptr(p)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CellPrivate::CellPrivate(const CellPrivate * const cp)
|
||||
: value(cp->value), formula(cp->formula), cellType(cp->cellType)
|
||||
, format(cp->format), richString(cp->richString), parent(cp->parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
\class Cell
|
||||
\inmodule QtXlsx
|
||||
\brief The Cell class provides a API that is used to handle the worksheet cell.
|
||||
|
||||
*/
|
||||
|
||||
/*!
|
||||
\enum Cell::CellType
|
||||
\value BooleanType Boolean type
|
||||
\value NumberType Number type, can be blank or used with forumula
|
||||
\value ErrorType Error type
|
||||
\value SharedStringType Shared string type
|
||||
\value StringType String type, can be used with forumula
|
||||
\value InlineStringType Inline string type
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* Created by Worksheet only.
|
||||
*/
|
||||
Cell::Cell(const QVariant &data, CellType type, const Format &format, Worksheet *parent) :
|
||||
d_ptr(new CellPrivate(this))
|
||||
{
|
||||
d_ptr->value = data;
|
||||
d_ptr->cellType = type;
|
||||
d_ptr->format = format;
|
||||
d_ptr->parent = parent;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
Cell::Cell(const Cell * const cell):
|
||||
d_ptr(new CellPrivate(cell->d_ptr))
|
||||
{
|
||||
d_ptr->q_ptr = this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Destroys the Cell and cleans up.
|
||||
*/
|
||||
Cell::~Cell()
|
||||
{
|
||||
delete d_ptr;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Return the dataType of this Cell
|
||||
*/
|
||||
Cell::CellType Cell::cellType() const
|
||||
{
|
||||
Q_D(const Cell);
|
||||
return d->cellType;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Return the data content of this Cell
|
||||
*/
|
||||
QVariant Cell::value() const
|
||||
{
|
||||
Q_D(const Cell);
|
||||
return d->value;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Return the style used by this Cell. If no style used, 0 will be returned.
|
||||
*/
|
||||
Format Cell::format() const
|
||||
{
|
||||
Q_D(const Cell);
|
||||
return d->format;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns true if the cell has one formula.
|
||||
*/
|
||||
bool Cell::hasFormula() const
|
||||
{
|
||||
Q_D(const Cell);
|
||||
return d->formula.isValid();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Return the formula contents if the dataType is Formula
|
||||
*/
|
||||
CellFormula Cell::formula() const
|
||||
{
|
||||
Q_D(const Cell);
|
||||
return d->formula;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns whether the value is probably a dateTime or not
|
||||
*/
|
||||
bool Cell::isDateTime() const
|
||||
{
|
||||
Q_D(const Cell);
|
||||
if (d->cellType == NumberType && d->value.toDouble() >=0
|
||||
&& d->format.isValid() && d->format.isDateTimeFormat()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Return the data time value.
|
||||
*/
|
||||
QDateTime Cell::dateTime() const
|
||||
{
|
||||
Q_D(const Cell);
|
||||
if (!isDateTime())
|
||||
return QDateTime();
|
||||
return datetimeFromNumber(d->value.toDouble(), d->parent->workbook()->isDate1904());
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns whether the cell is probably a rich string or not
|
||||
*/
|
||||
bool Cell::isRichString() const
|
||||
{
|
||||
Q_D(const Cell);
|
||||
if (d->cellType != SharedStringType && d->cellType != InlineStringType
|
||||
&& d->cellType != StringType)
|
||||
return false;
|
||||
|
||||
return d->richString.isRichString();
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE_XLSX
|
||||
259
platform/src/public/pub_excel/xlsx/xlsxcellformula.cpp
Normal file
259
platform/src/public/pub_excel/xlsx/xlsxcellformula.cpp
Normal file
@ -0,0 +1,259 @@
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2013-2014 Debao Zhang <hello@debao.me>
|
||||
** All right reserved.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining
|
||||
** a copy of this software and associated documentation files (the
|
||||
** "Software"), to deal in the Software without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Software, and to
|
||||
** permit persons to whom the Software is furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be
|
||||
** included in all copies or substantial portions of the Software.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
****************************************************************************/
|
||||
#include "xlsxcellformula.h"
|
||||
#include "xlsxcellformula_p.h"
|
||||
#include "xlsxutility_p.h"
|
||||
|
||||
#include <QXmlStreamReader>
|
||||
#include <QXmlStreamWriter>
|
||||
|
||||
QT_BEGIN_NAMESPACE_XLSX
|
||||
|
||||
CellFormulaPrivate::CellFormulaPrivate(const QString &formula_, const CellRange &ref_, CellFormula::FormulaType type_)
|
||||
:formula(formula_), type(type_), reference(ref_), ca(false), si(0)
|
||||
{
|
||||
//Remove the formula '=' sign if exists
|
||||
if (formula.startsWith(QLatin1String("=")))
|
||||
formula.remove(0,1);
|
||||
else if (formula.startsWith(QLatin1String("{=")) && formula.endsWith(QLatin1String("}")))
|
||||
formula = formula.mid(2, formula.length()-3);
|
||||
}
|
||||
|
||||
CellFormulaPrivate::CellFormulaPrivate(const CellFormulaPrivate &other)
|
||||
: QSharedData(other)
|
||||
, formula(other.formula), type(other.type), reference(other.reference)
|
||||
, ca(other.ca), si(other.si)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CellFormulaPrivate::~CellFormulaPrivate()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
\class CellFormula
|
||||
\inmodule QtXlsx
|
||||
\brief The CellFormula class provides a API that is used to handle the cell formula.
|
||||
|
||||
*/
|
||||
|
||||
/*!
|
||||
\enum CellFormula::FormulaType
|
||||
\value NormalType
|
||||
\value ArrayType
|
||||
\value DataTableType
|
||||
\value SharedType
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Creates a new formula.
|
||||
*/
|
||||
CellFormula::CellFormula()
|
||||
{
|
||||
//The d pointer is initialized with a null pointer
|
||||
}
|
||||
|
||||
/*!
|
||||
* Creates a new formula with the given \a formula and \a type.
|
||||
*/
|
||||
CellFormula::CellFormula(const char *formula, FormulaType type)
|
||||
:d(new CellFormulaPrivate(QString::fromLatin1(formula), CellRange(), type))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
* Creates a new formula with the given \a formula and \a type.
|
||||
*/
|
||||
CellFormula::CellFormula(const QString &formula, FormulaType type)
|
||||
:d(new CellFormulaPrivate(formula, CellRange(), type))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
* Creates a new formula with the given \a formula, \a ref and \a type.
|
||||
*/
|
||||
CellFormula::CellFormula(const QString &formula, const CellRange &ref, FormulaType type)
|
||||
:d(new CellFormulaPrivate(formula, ref, type))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
Creates a new formula with the same attributes as the \a other formula.
|
||||
*/
|
||||
CellFormula::CellFormula(const CellFormula &other)
|
||||
:d(other.d)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
Assigns the \a other formula to this formula, and returns a
|
||||
reference to this formula.
|
||||
*/
|
||||
CellFormula &CellFormula::operator =(const CellFormula &other)
|
||||
{
|
||||
d = other.d;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Destroys this formula.
|
||||
*/
|
||||
CellFormula::~CellFormula()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the type of the formula.
|
||||
*/
|
||||
CellFormula::FormulaType CellFormula::formulaType() const
|
||||
{
|
||||
return d ? d->type : NormalType;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the contents of the formula.
|
||||
*/
|
||||
QString CellFormula::formulaText() const
|
||||
{
|
||||
return d ? d->formula : QString();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the reference cells of the formula. For normal formula,
|
||||
* this will return an invalid CellRange object.
|
||||
*/
|
||||
CellRange CellFormula::reference() const
|
||||
{
|
||||
return d ? d->reference : CellRange();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns whether the formula is valid.
|
||||
*/
|
||||
bool CellFormula::isValid() const
|
||||
{
|
||||
return d;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the shared index for shared formula.
|
||||
*/
|
||||
int CellFormula::sharedIndex() const
|
||||
{
|
||||
return d && d->type == SharedType ? d->si : -1;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
bool CellFormula::saveToXml(QXmlStreamWriter &writer) const
|
||||
{
|
||||
writer.writeStartElement(QStringLiteral("f"));
|
||||
QString t;
|
||||
switch (d->type) {
|
||||
case CellFormula::ArrayType:
|
||||
t = QStringLiteral("array");
|
||||
break;
|
||||
case CellFormula::SharedType:
|
||||
t = QStringLiteral("shared");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!t.isEmpty())
|
||||
writer.writeAttribute(QStringLiteral("t"), t);
|
||||
if (d->reference.isValid())
|
||||
writer.writeAttribute(QStringLiteral("ref"), d->reference.toString());
|
||||
if (d->ca)
|
||||
writer.writeAttribute(QStringLiteral("ca"), QStringLiteral("1"));
|
||||
if (d->type == CellFormula::SharedType)
|
||||
writer.writeAttribute(QStringLiteral("si"), QString::number(d->si));
|
||||
|
||||
if (!d->formula.isEmpty())
|
||||
writer.writeCharacters(d->formula);
|
||||
|
||||
writer.writeEndElement(); //f
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
bool CellFormula::loadFromXml(QXmlStreamReader &reader)
|
||||
{
|
||||
Q_ASSERT(reader.name() == QLatin1String("f"));
|
||||
if (!d)
|
||||
d = new CellFormulaPrivate(QString(), CellRange(), NormalType);
|
||||
|
||||
QXmlStreamAttributes attributes = reader.attributes();
|
||||
QString typeString = attributes.value(QLatin1String("t")).toString();
|
||||
if (typeString == QLatin1String("array"))
|
||||
d->type = ArrayType;
|
||||
else if (typeString == QLatin1String("shared"))
|
||||
d->type = SharedType;
|
||||
else
|
||||
d->type = NormalType;
|
||||
|
||||
if (attributes.hasAttribute(QLatin1String("ref"))) {
|
||||
QString refString = attributes.value(QLatin1String("ref")).toString();
|
||||
d->reference = CellRange(refString);
|
||||
}
|
||||
|
||||
QString ca = attributes.value(QLatin1String("si")).toString();
|
||||
d->ca = parseXsdBoolean(ca, false);
|
||||
|
||||
if (attributes.hasAttribute(QLatin1String("si")))
|
||||
d->si = attributes.value(QLatin1String("si")).toString().toInt();
|
||||
|
||||
d->formula = reader.readElementText();
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
bool CellFormula::operator ==(const CellFormula &formula) const
|
||||
{
|
||||
return d->formula == formula.d->formula && d->type == formula.d->type
|
||||
&& d->si ==formula.d->si;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
bool CellFormula::operator !=(const CellFormula &formula) const
|
||||
{
|
||||
return d->formula != formula.d->formula || d->type != formula.d->type
|
||||
|| d->si !=formula.d->si;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE_XLSX
|
||||
147
platform/src/public/pub_excel/xlsx/xlsxcellrange.cpp
Normal file
147
platform/src/public/pub_excel/xlsx/xlsxcellrange.cpp
Normal file
@ -0,0 +1,147 @@
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2013-2014 Debao Zhang <hello@debao.me>
|
||||
** All right reserved.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining
|
||||
** a copy of this software and associated documentation files (the
|
||||
** "Software"), to deal in the Software without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Software, and to
|
||||
** permit persons to whom the Software is furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be
|
||||
** included in all copies or substantial portions of the Software.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
****************************************************************************/
|
||||
#include "xlsxcellrange.h"
|
||||
#include "xlsxcellreference.h"
|
||||
#include <QString>
|
||||
#include <QPoint>
|
||||
#include <QStringList>
|
||||
|
||||
QT_BEGIN_NAMESPACE_XLSX
|
||||
|
||||
/*!
|
||||
\class CellRange
|
||||
\brief For a range "A1:B2" or single cell "A1"
|
||||
\inmodule QtXlsx
|
||||
|
||||
The CellRange class stores the top left and bottom
|
||||
right rows and columns of a range in a worksheet.
|
||||
*/
|
||||
|
||||
/*!
|
||||
Constructs an range, i.e. a range
|
||||
whose rowCount() and columnCount() are 0.
|
||||
*/
|
||||
CellRange::CellRange()
|
||||
: top(-1), left(-1), bottom(-2), right(-2)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
Constructs the range from the given \a top, \a
|
||||
left, \a bottom and \a right rows and columns.
|
||||
|
||||
\sa topRow(), leftColumn(), bottomRow(), rightColumn()
|
||||
*/
|
||||
CellRange::CellRange(int top, int left, int bottom, int right)
|
||||
: top(top), left(left), bottom(bottom), right(right)
|
||||
{
|
||||
}
|
||||
|
||||
CellRange::CellRange(const CellReference &topLeft, const CellReference &bottomRight)
|
||||
: top(topLeft.row()), left(topLeft.column())
|
||||
, bottom(bottomRight.row()), right(bottomRight.column())
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
\overload
|
||||
Constructs the range form the given \a range string.
|
||||
*/
|
||||
CellRange::CellRange(const QString &range)
|
||||
{
|
||||
init(range);
|
||||
}
|
||||
|
||||
/*!
|
||||
\overload
|
||||
Constructs the range form the given \a range string.
|
||||
*/
|
||||
CellRange::CellRange(const char *range)
|
||||
{
|
||||
init(QString::fromLatin1(range));
|
||||
}
|
||||
|
||||
void CellRange::init(const QString &range)
|
||||
{
|
||||
QStringList rs = range.split(QLatin1Char(':'));
|
||||
if (rs.size() == 2) {
|
||||
CellReference start(rs[0]);
|
||||
CellReference end(rs[1]);
|
||||
top = start.row();
|
||||
left = start.column();
|
||||
bottom = end.row();
|
||||
right = end.column();
|
||||
} else {
|
||||
CellReference p(rs[0]);
|
||||
top = p.row();
|
||||
left = p.column();
|
||||
bottom = p.row();
|
||||
right = p.column();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Constructs a the range by copying the given \a
|
||||
other range.
|
||||
*/
|
||||
CellRange::CellRange(const CellRange &other)
|
||||
: top(other.top), left(other.left), bottom(other.bottom), right(other.right)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
Destroys the range.
|
||||
*/
|
||||
CellRange::~CellRange()
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
Convert the range to string notation, such as "A1:B5".
|
||||
*/
|
||||
QString CellRange::toString(bool row_abs, bool col_abs) const
|
||||
{
|
||||
if (!isValid())
|
||||
return QString();
|
||||
|
||||
if (left == right && top == bottom) {
|
||||
//Single cell
|
||||
return CellReference(top, left).toString(row_abs, col_abs);
|
||||
}
|
||||
|
||||
QString cell_1 = CellReference(top, left).toString(row_abs, col_abs);
|
||||
QString cell_2 = CellReference(bottom, right).toString(row_abs, col_abs);
|
||||
return cell_1 + QLatin1String(":") + cell_2;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns true if the Range is valid.
|
||||
*/
|
||||
bool CellRange::isValid() const
|
||||
{
|
||||
return left <= right && top <= bottom;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE_XLSX
|
||||
174
platform/src/public/pub_excel/xlsx/xlsxcellreference.cpp
Normal file
174
platform/src/public/pub_excel/xlsx/xlsxcellreference.cpp
Normal file
@ -0,0 +1,174 @@
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2013-2014 Debao Zhang <hello@debao.me>
|
||||
** All right reserved.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining
|
||||
** a copy of this software and associated documentation files (the
|
||||
** "Software"), to deal in the Software without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Software, and to
|
||||
** permit persons to whom the Software is furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be
|
||||
** included in all copies or substantial portions of the Software.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
****************************************************************************/
|
||||
#include "xlsxcellreference.h"
|
||||
#include <QStringList>
|
||||
#include <QMap>
|
||||
#include <QRegularExpression>
|
||||
|
||||
QT_BEGIN_NAMESPACE_XLSX
|
||||
|
||||
namespace {
|
||||
|
||||
int intPow(int x, int p)
|
||||
{
|
||||
if (p == 0) return 1;
|
||||
if (p == 1) return x;
|
||||
|
||||
int tmp = intPow(x, p/2);
|
||||
if (p%2 == 0) return tmp * tmp;
|
||||
else return x * tmp * tmp;
|
||||
}
|
||||
|
||||
QString col_to_name(int col_num)
|
||||
{
|
||||
static QMap<int, QString> col_cache;
|
||||
|
||||
if (!col_cache.contains(col_num)) {
|
||||
QString col_str;
|
||||
int remainder;
|
||||
while (col_num) {
|
||||
remainder = col_num % 26;
|
||||
if (remainder == 0)
|
||||
remainder = 26;
|
||||
col_str.prepend(QChar('A'+remainder-1));
|
||||
col_num = (col_num - 1) / 26;
|
||||
}
|
||||
col_cache.insert(col_num, col_str);
|
||||
}
|
||||
|
||||
return col_cache[col_num];
|
||||
}
|
||||
|
||||
int col_from_name(const QString &col_str)
|
||||
{
|
||||
int col = 0;
|
||||
int expn = 0;
|
||||
for (int i=col_str.size()-1; i>-1; --i) {
|
||||
col += (col_str[i].unicode() - 'A' + 1) * intPow(26, expn);
|
||||
expn++;
|
||||
}
|
||||
|
||||
return col;
|
||||
}
|
||||
} //namespace
|
||||
|
||||
/*!
|
||||
\class CellReference
|
||||
\brief For one single cell such as "A1"
|
||||
\inmodule QtXlsx
|
||||
|
||||
The CellReference class stores the cell location in a worksheet.
|
||||
*/
|
||||
|
||||
/*!
|
||||
Constructs an invalid Cell Reference
|
||||
*/
|
||||
CellReference::CellReference()
|
||||
: _row(-1), _column(-1)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
Constructs the Reference from the given \a row, and \a column.
|
||||
*/
|
||||
CellReference::CellReference(int row, int column)
|
||||
: _row(row), _column(column)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
\overload
|
||||
Constructs the Reference form the given \a cell string.
|
||||
*/
|
||||
CellReference::CellReference(const QString &cell)
|
||||
{
|
||||
init(cell);
|
||||
}
|
||||
|
||||
/*!
|
||||
\overload
|
||||
Constructs the Reference form the given \a cell string.
|
||||
*/
|
||||
CellReference::CellReference(const char *cell)
|
||||
{
|
||||
init(QString::fromLatin1(cell));
|
||||
}
|
||||
|
||||
void CellReference::init(const QString &cell_str)
|
||||
{
|
||||
static QRegularExpression re(QStringLiteral("^\\$?([A-Z]{1,3})\\$?(\\d+)$"));
|
||||
QRegularExpressionMatch match = re.match(cell_str);
|
||||
if (match.hasMatch()) {
|
||||
const QString col_str = match.captured(1);
|
||||
const QString row_str = match.captured(2);
|
||||
_row = row_str.toInt();
|
||||
_column = col_from_name(col_str);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Constructs a Reference by copying the given \a
|
||||
other Reference.
|
||||
*/
|
||||
CellReference::CellReference(const CellReference &other)
|
||||
: _row(other._row), _column(other._column)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
Destroys the Reference.
|
||||
*/
|
||||
CellReference::~CellReference()
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
Convert the Reference to string notation, such as "A1" or "$A$1".
|
||||
If current object is invalid, an empty string will be returned.
|
||||
*/
|
||||
QString CellReference::toString(bool row_abs, bool col_abs) const
|
||||
{
|
||||
if (!isValid())
|
||||
return QString();
|
||||
|
||||
QString cell_str;
|
||||
if (col_abs)
|
||||
cell_str.append(QLatin1Char('$'));
|
||||
cell_str.append(col_to_name(_column));
|
||||
if (row_abs)
|
||||
cell_str.append(QLatin1Char('$'));
|
||||
cell_str.append(QString::number(_row));
|
||||
return cell_str;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns true if the Reference is valid.
|
||||
*/
|
||||
bool CellReference::isValid() const
|
||||
{
|
||||
return _row > 0 && _column > 0;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE_XLSX
|
||||
645
platform/src/public/pub_excel/xlsx/xlsxchart.cpp
Normal file
645
platform/src/public/pub_excel/xlsx/xlsxchart.cpp
Normal file
@ -0,0 +1,645 @@
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2013-2014 Debao Zhang <hello@debao.me>
|
||||
** All right reserved.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining
|
||||
** a copy of this software and associated documentation files (the
|
||||
** "Software"), to deal in the Software without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Software, and to
|
||||
** permit persons to whom the Software is furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be
|
||||
** included in all copies or substantial portions of the Software.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "xlsxchart_p.h"
|
||||
#include "xlsxworksheet.h"
|
||||
#include "xlsxcellrange.h"
|
||||
#include "xlsxutility_p.h"
|
||||
|
||||
#include <QIODevice>
|
||||
#include <QXmlStreamReader>
|
||||
#include <QXmlStreamWriter>
|
||||
#include <QDebug>
|
||||
|
||||
QT_BEGIN_NAMESPACE_XLSX
|
||||
|
||||
ChartPrivate::ChartPrivate(Chart *q, Chart::CreateFlag flag)
|
||||
:AbstractOOXmlFilePrivate(q, flag), chartType(static_cast<Chart::ChartType>(0))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ChartPrivate::~ChartPrivate()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
* \class Chart
|
||||
* \inmodule QtXlsx
|
||||
* \brief Main class for the charts.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\enum Chart::ChartType
|
||||
|
||||
\value CT_Area
|
||||
\value CT_Area3D,
|
||||
\value CT_Line,
|
||||
\value CT_Line3D,
|
||||
\value CT_Scatter,
|
||||
\value CT_Pie,
|
||||
\value CT_Pie3D,
|
||||
\value CT_Doughnut,
|
||||
\value CT_Bar,
|
||||
\value CT_Bar3D,
|
||||
|
||||
\omitvalue CT_Stock,
|
||||
\omitvalue CT_Radar,
|
||||
\omitvalue CT_OfPie,
|
||||
\omitvalue CT_Surface,
|
||||
\omitvalue CT_Surface3D,
|
||||
\omitvalue CT_Bubble
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
Chart::Chart(AbstractSheet *parent, CreateFlag flag)
|
||||
:AbstractOOXmlFile(new ChartPrivate(this, flag))
|
||||
{
|
||||
d_func()->sheet = parent;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Destroys the chart.
|
||||
*/
|
||||
Chart::~Chart()
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Add the data series which is in the range \a range of the \a sheet.
|
||||
*/
|
||||
void Chart::addSeries(const CellRange &range, AbstractSheet *sheet)
|
||||
{
|
||||
Q_D(Chart);
|
||||
if (!range.isValid())
|
||||
return;
|
||||
if (sheet && sheet->sheetType() != AbstractSheet::ST_WorkSheet)
|
||||
return;
|
||||
if (!sheet && d->sheet->sheetType() != AbstractSheet::ST_WorkSheet)
|
||||
return;
|
||||
|
||||
QString sheetName = sheet ? sheet->sheetName() : d->sheet->sheetName();
|
||||
//In case sheetName contains space or '
|
||||
sheetName = escapeSheetName(sheetName);
|
||||
|
||||
if (range.columnCount() == 1 || range.rowCount() == 1) {
|
||||
QSharedPointer<XlsxSeries> series = QSharedPointer<XlsxSeries>(new XlsxSeries);
|
||||
series->numberDataSource_numRef = sheetName + QLatin1String("!") + range.toString(true, true);
|
||||
d->seriesList.append(series);
|
||||
} else if (range.columnCount() < range.rowCount()) {
|
||||
//Column based series
|
||||
int firstDataColumn = range.firstColumn();
|
||||
QString axDataSouruce_numRef;
|
||||
if (d->chartType == CT_Scatter || d->chartType == CT_Bubble) {
|
||||
firstDataColumn += 1;
|
||||
CellRange subRange(range.firstRow(), range.firstColumn(), range.lastRow(), range.firstColumn());
|
||||
axDataSouruce_numRef = sheetName + QLatin1String("!") + subRange.toString(true, true);
|
||||
}
|
||||
|
||||
for (int col=firstDataColumn; col<=range.lastColumn(); ++col) {
|
||||
CellRange subRange(range.firstRow(), col, range.lastRow(), col);
|
||||
QSharedPointer<XlsxSeries> series = QSharedPointer<XlsxSeries>(new XlsxSeries);
|
||||
series->axDataSource_numRef = axDataSouruce_numRef;
|
||||
series->numberDataSource_numRef = sheetName + QLatin1String("!") + subRange.toString(true, true);
|
||||
d->seriesList.append(series);
|
||||
}
|
||||
|
||||
} else {
|
||||
//Row based series
|
||||
int firstDataRow = range.firstRow();
|
||||
QString axDataSouruce_numRef;
|
||||
if (d->chartType == CT_Scatter || d->chartType == CT_Bubble) {
|
||||
firstDataRow += 1;
|
||||
CellRange subRange(range.firstRow(), range.firstColumn(), range.firstRow(), range.lastColumn());
|
||||
axDataSouruce_numRef = sheetName + QLatin1String("!") + subRange.toString(true, true);
|
||||
}
|
||||
|
||||
for (int row=firstDataRow; row<=range.lastRow(); ++row) {
|
||||
CellRange subRange(row, range.firstColumn(), row, range.lastColumn());
|
||||
QSharedPointer<XlsxSeries> series = QSharedPointer<XlsxSeries>(new XlsxSeries);
|
||||
series->axDataSource_numRef = axDataSouruce_numRef;
|
||||
series->numberDataSource_numRef = sheetName + QLatin1String("!") + subRange.toString(true, true);
|
||||
d->seriesList.append(series);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Set the type of the chart to \a type
|
||||
*/
|
||||
void Chart::setChartType(ChartType type)
|
||||
{
|
||||
Q_D(Chart);
|
||||
d->chartType = type;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*
|
||||
*/
|
||||
void Chart::setChartStyle(int id)
|
||||
{
|
||||
Q_UNUSED(id)
|
||||
//!Todo
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
void Chart::saveToXmlFile(QIODevice *device) const
|
||||
{
|
||||
Q_D(const Chart);
|
||||
|
||||
QXmlStreamWriter writer(device);
|
||||
|
||||
writer.writeStartDocument(QStringLiteral("1.0"), true);
|
||||
writer.writeStartElement(QStringLiteral("c:chartSpace"));
|
||||
writer.writeAttribute(QStringLiteral("xmlns:c"), QStringLiteral("http://schemas.openxmlformats.org/drawingml/2006/chart"));
|
||||
writer.writeAttribute(QStringLiteral("xmlns:a"), QStringLiteral("http://schemas.openxmlformats.org/drawingml/2006/main"));
|
||||
writer.writeAttribute(QStringLiteral("xmlns:r"), QStringLiteral("http://schemas.openxmlformats.org/officeDocument/2006/relationships"));
|
||||
|
||||
d->saveXmlChart(writer);
|
||||
|
||||
writer.writeEndElement();//c:chartSpace
|
||||
writer.writeEndDocument();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
bool Chart::loadFromXmlFile(QIODevice *device)
|
||||
{
|
||||
Q_D(Chart);
|
||||
|
||||
QXmlStreamReader reader(device);
|
||||
while (!reader.atEnd()) {
|
||||
reader.readNextStartElement();
|
||||
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
||||
if (reader.name() == QLatin1String("chart")) {
|
||||
if (!d->loadXmlChart(reader))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChartPrivate::loadXmlChart(QXmlStreamReader &reader)
|
||||
{
|
||||
Q_ASSERT(reader.name() == QLatin1String("chart"));
|
||||
|
||||
while (!reader.atEnd()) {
|
||||
reader.readNextStartElement();
|
||||
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
||||
if (reader.name() == QLatin1String("plotArea")) {
|
||||
if (!loadXmlPlotArea(reader))
|
||||
return false;
|
||||
} else if (reader.name() == QLatin1String("legend")) {
|
||||
//!Todo
|
||||
}
|
||||
} else if (reader.tokenType() == QXmlStreamReader::EndElement &&
|
||||
reader.name() == QLatin1String("chart")) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChartPrivate::loadXmlPlotArea(QXmlStreamReader &reader)
|
||||
{
|
||||
Q_ASSERT(reader.name() == QLatin1String("plotArea"));
|
||||
|
||||
while (!reader.atEnd()) {
|
||||
reader.readNextStartElement();
|
||||
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
||||
if (reader.name() == QLatin1String("layout")) {
|
||||
//!ToDo
|
||||
} else if (reader.name().endsWith(QLatin1String("Chart"))) {
|
||||
//For pieChart, barChart, ...
|
||||
loadXmlXxxChart(reader);
|
||||
} else if (reader.name().endsWith(QLatin1String("Ax"))) {
|
||||
//For valAx, catAx, serAx, dateAx
|
||||
loadXmlAxis(reader);
|
||||
}
|
||||
|
||||
} else if (reader.tokenType() == QXmlStreamReader::EndElement &&
|
||||
reader.name() == QLatin1String("plotArea")) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChartPrivate::loadXmlXxxChart(QXmlStreamReader &reader)
|
||||
{
|
||||
QStringRef name = reader.name();
|
||||
if (name == QLatin1String("pieChart")) chartType = Chart::CT_Pie;
|
||||
else if (name == QLatin1String("pie3DChart")) chartType = Chart::CT_Pie3D;
|
||||
else if (name == QLatin1String("barChart")) chartType = Chart::CT_Bar;
|
||||
else if (name == QLatin1String("bar3DChart")) chartType = Chart::CT_Bar3D;
|
||||
else if (name == QLatin1String("lineChart")) chartType = Chart::CT_Line;
|
||||
else if (name == QLatin1String("line3DChart")) chartType = Chart::CT_Line3D;
|
||||
else if (name == QLatin1String("scatterChart")) chartType = Chart::CT_Scatter;
|
||||
else if (name == QLatin1String("areaChart")) chartType = Chart::CT_Area;
|
||||
else if (name == QLatin1String("area3DChart")) chartType = Chart::CT_Area3D;
|
||||
else if (name == QLatin1String("doughnutChart")) chartType = Chart::CT_Doughnut;
|
||||
else qDebug()<<"Cann't load chart: "<<name;
|
||||
|
||||
while (!reader.atEnd()) {
|
||||
reader.readNextStartElement();
|
||||
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
||||
if (reader.name() == QLatin1String("ser")) {
|
||||
loadXmlSer(reader);
|
||||
} else if (reader.name() == QLatin1String("axId")) {
|
||||
|
||||
}
|
||||
} else if (reader.tokenType() == QXmlStreamReader::EndElement
|
||||
&& reader.name() == name) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChartPrivate::loadXmlSer(QXmlStreamReader &reader)
|
||||
{
|
||||
Q_ASSERT(reader.name() == QLatin1String("ser"));
|
||||
|
||||
QSharedPointer<XlsxSeries> series = QSharedPointer<XlsxSeries>(new XlsxSeries);
|
||||
seriesList.append(series);
|
||||
|
||||
while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement
|
||||
&& reader.name() == QLatin1String("ser"))) {
|
||||
if (reader.readNextStartElement()) {
|
||||
QStringRef name = reader.name();
|
||||
if (name == QLatin1String("cat") || name == QLatin1String("xVal")) {
|
||||
while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement
|
||||
&& reader.name() == name)) {
|
||||
if (reader.readNextStartElement()) {
|
||||
if (reader.name() == QLatin1String("numRef"))
|
||||
series->axDataSource_numRef = loadXmlNumRef(reader);
|
||||
}
|
||||
}
|
||||
} else if (name == QLatin1String("val") || name == QLatin1String("yVal")) {
|
||||
while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement
|
||||
&& reader.name() == name)) {
|
||||
if (reader.readNextStartElement()) {
|
||||
if (reader.name() == QLatin1String("numRef"))
|
||||
series->numberDataSource_numRef = loadXmlNumRef(reader);
|
||||
}
|
||||
}
|
||||
} else if (name == QLatin1String("extLst")) {
|
||||
while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement
|
||||
&& reader.name() == name)) {
|
||||
reader.readNextStartElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
QString ChartPrivate::loadXmlNumRef(QXmlStreamReader &reader)
|
||||
{
|
||||
Q_ASSERT(reader.name() == QLatin1String("numRef"));
|
||||
|
||||
while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement
|
||||
&& reader.name() == QLatin1String("numRef"))) {
|
||||
if (reader.readNextStartElement()) {
|
||||
if (reader.name() == QLatin1String("f"))
|
||||
return reader.readElementText();
|
||||
}
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
void ChartPrivate::saveXmlChart(QXmlStreamWriter &writer) const
|
||||
{
|
||||
writer.writeStartElement(QStringLiteral("c:chart"));
|
||||
writer.writeStartElement(QStringLiteral("c:plotArea"));
|
||||
switch (chartType) {
|
||||
case Chart::CT_Pie:
|
||||
case Chart::CT_Pie3D:
|
||||
saveXmlPieChart(writer);
|
||||
break;
|
||||
case Chart::CT_Bar:
|
||||
case Chart::CT_Bar3D:
|
||||
saveXmlBarChart(writer);
|
||||
break;
|
||||
case Chart::CT_Line:
|
||||
case Chart::CT_Line3D:
|
||||
saveXmlLineChart(writer);
|
||||
break;
|
||||
case Chart::CT_Scatter:
|
||||
saveXmlScatterChart(writer);
|
||||
break;
|
||||
case Chart::CT_Area:
|
||||
case Chart::CT_Area3D:
|
||||
saveXmlAreaChart(writer);
|
||||
break;
|
||||
case Chart::CT_Doughnut:
|
||||
saveXmlDoughnutChart(writer);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
saveXmlAxes(writer);
|
||||
writer.writeEndElement(); //plotArea
|
||||
|
||||
// saveXmlLegend(writer);
|
||||
|
||||
writer.writeEndElement(); //chart
|
||||
}
|
||||
|
||||
void ChartPrivate::saveXmlPieChart(QXmlStreamWriter &writer) const
|
||||
{
|
||||
QString name = chartType==Chart::CT_Pie ? QStringLiteral("c:pieChart") : QStringLiteral("c:pie3DChart");
|
||||
|
||||
writer.writeStartElement(name);
|
||||
|
||||
//Do the same behavior as Excel, Pie prefer varyColors
|
||||
writer.writeEmptyElement(QStringLiteral("c:varyColors"));
|
||||
writer.writeAttribute(QStringLiteral("val"), QStringLiteral("1"));
|
||||
|
||||
for (int i=0; i<seriesList.size(); ++i)
|
||||
saveXmlSer(writer, seriesList[i].data(), i);
|
||||
|
||||
writer.writeEndElement(); //pieChart, pie3DChart
|
||||
}
|
||||
|
||||
void ChartPrivate::saveXmlBarChart(QXmlStreamWriter &writer) const
|
||||
{
|
||||
QString name = chartType==Chart::CT_Bar ? QStringLiteral("c:barChart") : QStringLiteral("c:bar3DChart");
|
||||
|
||||
writer.writeStartElement(name);
|
||||
|
||||
writer.writeEmptyElement(QStringLiteral("c:barDir"));
|
||||
writer.writeAttribute(QStringLiteral("val"), QStringLiteral("col"));
|
||||
|
||||
for (int i=0; i<seriesList.size(); ++i)
|
||||
saveXmlSer(writer, seriesList[i].data(), i);
|
||||
|
||||
if (axisList.isEmpty()) {
|
||||
//The order the axes??
|
||||
const_cast<ChartPrivate*>(this)->axisList.append(QSharedPointer<XlsxAxis>(new XlsxAxis(XlsxAxis::T_Cat, XlsxAxis::Bottom, 0, 1)));
|
||||
const_cast<ChartPrivate*>(this)->axisList.append(QSharedPointer<XlsxAxis>(new XlsxAxis(XlsxAxis::T_Val, XlsxAxis::Left, 1, 0)));
|
||||
}
|
||||
|
||||
//Note: Bar3D have 2~3 axes
|
||||
Q_ASSERT(axisList.size()==2 || (axisList.size()==3 && chartType==Chart::CT_Bar3D));
|
||||
|
||||
for (int i=0; i<axisList.size(); ++i) {
|
||||
writer.writeEmptyElement(QStringLiteral("c:axId"));
|
||||
writer.writeAttribute(QStringLiteral("val"), QString::number(axisList[i]->axisId));
|
||||
}
|
||||
|
||||
writer.writeEndElement(); //barChart, bar3DChart
|
||||
}
|
||||
|
||||
void ChartPrivate::saveXmlLineChart(QXmlStreamWriter &writer) const
|
||||
{
|
||||
QString name = chartType==Chart::CT_Line ? QStringLiteral("c:lineChart") : QStringLiteral("c:line3DChart");
|
||||
|
||||
writer.writeStartElement(name);
|
||||
|
||||
writer.writeEmptyElement(QStringLiteral("grouping"));
|
||||
|
||||
for (int i=0; i<seriesList.size(); ++i)
|
||||
saveXmlSer(writer, seriesList[i].data(), i);
|
||||
|
||||
if (axisList.isEmpty()) {
|
||||
const_cast<ChartPrivate*>(this)->axisList.append(QSharedPointer<XlsxAxis>(new XlsxAxis(XlsxAxis::T_Cat, XlsxAxis::Bottom, 0, 1)));
|
||||
const_cast<ChartPrivate*>(this)->axisList.append(QSharedPointer<XlsxAxis>(new XlsxAxis(XlsxAxis::T_Val, XlsxAxis::Left, 1, 0)));
|
||||
if (chartType==Chart::CT_Line3D)
|
||||
const_cast<ChartPrivate*>(this)->axisList.append(QSharedPointer<XlsxAxis>(new XlsxAxis(XlsxAxis::T_Ser, XlsxAxis::Bottom, 2, 0)));
|
||||
}
|
||||
|
||||
Q_ASSERT((axisList.size()==2||chartType==Chart::CT_Line)|| (axisList.size()==3 && chartType==Chart::CT_Line3D));
|
||||
|
||||
for (int i=0; i<axisList.size(); ++i) {
|
||||
writer.writeEmptyElement(QStringLiteral("c:axId"));
|
||||
writer.writeAttribute(QStringLiteral("val"), QString::number(axisList[i]->axisId));
|
||||
}
|
||||
|
||||
writer.writeEndElement(); //lineChart, line3DChart
|
||||
}
|
||||
|
||||
void ChartPrivate::saveXmlScatterChart(QXmlStreamWriter &writer) const
|
||||
{
|
||||
const QString name = QStringLiteral("c:scatterChart");
|
||||
|
||||
writer.writeStartElement(name);
|
||||
|
||||
writer.writeEmptyElement(QStringLiteral("c:scatterStyle"));
|
||||
|
||||
for (int i=0; i<seriesList.size(); ++i)
|
||||
saveXmlSer(writer, seriesList[i].data(), i);
|
||||
|
||||
if (axisList.isEmpty()) {
|
||||
const_cast<ChartPrivate*>(this)->axisList.append(QSharedPointer<XlsxAxis>(new XlsxAxis(XlsxAxis::T_Val, XlsxAxis::Bottom, 0, 1)));
|
||||
const_cast<ChartPrivate*>(this)->axisList.append(QSharedPointer<XlsxAxis>(new XlsxAxis(XlsxAxis::T_Val, XlsxAxis::Left, 1, 0)));
|
||||
}
|
||||
|
||||
Q_ASSERT(axisList.size()==2);
|
||||
|
||||
for (int i=0; i<axisList.size(); ++i) {
|
||||
writer.writeEmptyElement(QStringLiteral("c:axId"));
|
||||
writer.writeAttribute(QStringLiteral("val"), QString::number(axisList[i]->axisId));
|
||||
}
|
||||
|
||||
writer.writeEndElement(); //c:scatterChart
|
||||
}
|
||||
|
||||
void ChartPrivate::saveXmlAreaChart(QXmlStreamWriter &writer) const
|
||||
{
|
||||
QString name = chartType==Chart::CT_Area ? QStringLiteral("c:areaChart") : QStringLiteral("c:area3DChart");
|
||||
|
||||
writer.writeStartElement(name);
|
||||
|
||||
writer.writeEmptyElement(QStringLiteral("grouping"));
|
||||
|
||||
for (int i=0; i<seriesList.size(); ++i)
|
||||
saveXmlSer(writer, seriesList[i].data(), i);
|
||||
|
||||
if (axisList.isEmpty()) {
|
||||
const_cast<ChartPrivate*>(this)->axisList.append(QSharedPointer<XlsxAxis>(new XlsxAxis(XlsxAxis::T_Cat, XlsxAxis::Bottom, 0, 1)));
|
||||
const_cast<ChartPrivate*>(this)->axisList.append(QSharedPointer<XlsxAxis>(new XlsxAxis(XlsxAxis::T_Val, XlsxAxis::Left, 1, 0)));
|
||||
}
|
||||
|
||||
//Note: Area3D have 2~3 axes
|
||||
Q_ASSERT(axisList.size()==2 || (axisList.size()==3 && chartType==Chart::CT_Area3D));
|
||||
|
||||
for (int i=0; i<axisList.size(); ++i) {
|
||||
writer.writeEmptyElement(QStringLiteral("c:axId"));
|
||||
writer.writeAttribute(QStringLiteral("val"), QString::number(axisList[i]->axisId));
|
||||
}
|
||||
|
||||
writer.writeEndElement(); //lineChart, line3DChart
|
||||
}
|
||||
|
||||
void ChartPrivate::saveXmlDoughnutChart(QXmlStreamWriter &writer) const
|
||||
{
|
||||
QString name = QStringLiteral("c:doughnutChart");
|
||||
|
||||
writer.writeStartElement(name);
|
||||
|
||||
writer.writeEmptyElement(QStringLiteral("c:varyColors"));
|
||||
writer.writeAttribute(QStringLiteral("val"), QStringLiteral("1"));
|
||||
|
||||
for (int i=0; i<seriesList.size(); ++i)
|
||||
saveXmlSer(writer, seriesList[i].data(), i);
|
||||
|
||||
writer.writeStartElement(QStringLiteral("c:holeSize"));
|
||||
writer.writeAttribute(QStringLiteral("val"), QString::number(50));
|
||||
|
||||
writer.writeEndElement();
|
||||
}
|
||||
|
||||
void ChartPrivate::saveXmlSer(QXmlStreamWriter &writer, XlsxSeries *ser, int id) const
|
||||
{
|
||||
writer.writeStartElement(QStringLiteral("c:ser"));
|
||||
writer.writeEmptyElement(QStringLiteral("c:idx"));
|
||||
writer.writeAttribute(QStringLiteral("val"), QString::number(id));
|
||||
writer.writeEmptyElement(QStringLiteral("c:order"));
|
||||
writer.writeAttribute(QStringLiteral("val"), QString::number(id));
|
||||
|
||||
if (!ser->axDataSource_numRef.isEmpty()) {
|
||||
if (chartType == Chart::CT_Scatter || chartType == Chart::CT_Bubble)
|
||||
writer.writeStartElement(QStringLiteral("c:xVal"));
|
||||
else
|
||||
writer.writeStartElement(QStringLiteral("c:cat"));
|
||||
writer.writeStartElement(QStringLiteral("c:numRef"));
|
||||
writer.writeTextElement(QStringLiteral("c:f"), ser->axDataSource_numRef);
|
||||
writer.writeEndElement();//c:numRef
|
||||
writer.writeEndElement();//c:cat or c:xVal
|
||||
}
|
||||
|
||||
if (!ser->numberDataSource_numRef.isEmpty()) {
|
||||
if (chartType == Chart::CT_Scatter || chartType == Chart::CT_Bubble)
|
||||
writer.writeStartElement(QStringLiteral("c:yVal"));
|
||||
else
|
||||
writer.writeStartElement(QStringLiteral("c:val"));
|
||||
writer.writeStartElement(QStringLiteral("c:numRef"));
|
||||
writer.writeTextElement(QStringLiteral("c:f"), ser->numberDataSource_numRef);
|
||||
writer.writeEndElement();//c:numRef
|
||||
writer.writeEndElement();//c:val or c:yVal
|
||||
}
|
||||
|
||||
writer.writeEndElement();//c:ser
|
||||
}
|
||||
|
||||
bool ChartPrivate::loadXmlAxis(QXmlStreamReader &reader)
|
||||
{
|
||||
Q_ASSERT(reader.name().endsWith(QLatin1String("Ax")));
|
||||
QString name = reader.name().toString();
|
||||
|
||||
XlsxAxis *axis = new XlsxAxis;
|
||||
if (name == QLatin1String("valAx"))
|
||||
axis->type = XlsxAxis::T_Val;
|
||||
else if (name == QLatin1String("catAx"))
|
||||
axis->type = XlsxAxis::T_Cat;
|
||||
else if (name == QLatin1String("serAx"))
|
||||
axis->type = XlsxAxis::T_Ser;
|
||||
else
|
||||
axis->type = XlsxAxis::T_Date;
|
||||
|
||||
axisList.append(QSharedPointer<XlsxAxis>(axis));
|
||||
|
||||
while (!reader.atEnd()) {
|
||||
reader.readNextStartElement();
|
||||
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
||||
if (reader.name() == QLatin1String("axPos")) {
|
||||
QXmlStreamAttributes attrs = reader.attributes();
|
||||
QStringRef pos = attrs.value(QLatin1String("val"));
|
||||
if (pos==QLatin1String("l"))
|
||||
axis->axisPos = XlsxAxis::Left;
|
||||
else if (pos==QLatin1String("r"))
|
||||
axis->axisPos = XlsxAxis::Right;
|
||||
else if (pos==QLatin1String("b"))
|
||||
axis->axisPos = XlsxAxis::Bottom;
|
||||
else
|
||||
axis->axisPos = XlsxAxis::Top;
|
||||
} else if (reader.name() == QLatin1String("axId")) {
|
||||
axis->axisId = reader.attributes().value(QLatin1String("val")).toString().toInt();
|
||||
} else if (reader.name() == QLatin1String("crossAx")) {
|
||||
axis->crossAx = reader.attributes().value(QLatin1String("val")).toString().toInt();
|
||||
}
|
||||
} else if (reader.tokenType() == QXmlStreamReader::EndElement
|
||||
&& reader.name() == name) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ChartPrivate::saveXmlAxes(QXmlStreamWriter &writer) const
|
||||
{
|
||||
for (int i=0; i<axisList.size(); ++i) {
|
||||
XlsxAxis *axis = axisList[i].data();
|
||||
QString name;
|
||||
switch (axis->type) {
|
||||
case XlsxAxis::T_Cat: name = QStringLiteral("c:catAx"); break;
|
||||
case XlsxAxis::T_Val: name = QStringLiteral("c:valAx"); break;
|
||||
case XlsxAxis::T_Ser: name = QStringLiteral("c:serAx"); break;
|
||||
case XlsxAxis::T_Date: name = QStringLiteral("c:dateAx"); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
QString pos;
|
||||
switch (axis->axisPos) {
|
||||
case XlsxAxis::Top: pos = QStringLiteral("t"); break;
|
||||
case XlsxAxis::Bottom: pos = QStringLiteral("b"); break;
|
||||
case XlsxAxis::Left: pos = QStringLiteral("l"); break;
|
||||
case XlsxAxis::Right: pos = QStringLiteral("r"); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
writer.writeStartElement(name);
|
||||
writer.writeEmptyElement(QStringLiteral("c:axId"));
|
||||
writer.writeAttribute(QStringLiteral("val"), QString::number(axis->axisId));
|
||||
|
||||
writer.writeStartElement(QStringLiteral("c:scaling"));
|
||||
writer.writeEmptyElement(QStringLiteral("c:orientation"));
|
||||
writer.writeAttribute(QStringLiteral("val"), QStringLiteral("minMax"));
|
||||
writer.writeEndElement();//c:scaling
|
||||
|
||||
writer.writeEmptyElement(QStringLiteral("c:axPos"));
|
||||
writer.writeAttribute(QStringLiteral("val"), pos);
|
||||
|
||||
writer.writeEmptyElement(QStringLiteral("c:crossAx"));
|
||||
writer.writeAttribute(QStringLiteral("val"), QString::number(axis->crossAx));
|
||||
|
||||
writer.writeEndElement();//name
|
||||
}
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE_XLSX
|
||||
159
platform/src/public/pub_excel/xlsx/xlsxchartsheet.cpp
Normal file
159
platform/src/public/pub_excel/xlsx/xlsxchartsheet.cpp
Normal file
@ -0,0 +1,159 @@
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2013-2014 Debao Zhang <hello@debao.me>
|
||||
** All right reserved.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining
|
||||
** a copy of this software and associated documentation files (the
|
||||
** "Software"), to deal in the Software without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Software, and to
|
||||
** permit persons to whom the Software is furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be
|
||||
** included in all copies or substantial portions of the Software.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
****************************************************************************/
|
||||
#include "xlsxchartsheet.h"
|
||||
#include "xlsxchartsheet_p.h"
|
||||
#include "xlsxworkbook.h"
|
||||
#include "xlsxutility_p.h"
|
||||
#include "xlsxdrawing_p.h"
|
||||
#include "xlsxdrawinganchor_p.h"
|
||||
#include "xlsxchart.h"
|
||||
|
||||
#include <QXmlStreamReader>
|
||||
#include <QXmlStreamWriter>
|
||||
#include <QDir>
|
||||
|
||||
QT_BEGIN_NAMESPACE_XLSX
|
||||
|
||||
ChartsheetPrivate::ChartsheetPrivate(Chartsheet *p, Chartsheet::CreateFlag flag)
|
||||
: AbstractSheetPrivate(p, flag), chart(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ChartsheetPrivate::~ChartsheetPrivate()
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
\class Chartsheet
|
||||
\inmodule QtXlsx
|
||||
\brief Represent one chartsheet in the workbook.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
Chartsheet::Chartsheet(const QString &name, int id, Workbook *workbook, CreateFlag flag)
|
||||
:AbstractSheet(name, id, workbook, new ChartsheetPrivate(this, flag))
|
||||
{
|
||||
setSheetType(ST_ChartSheet);
|
||||
|
||||
if (flag == Chartsheet::F_NewFromScratch) {
|
||||
d_func()->drawing = QSharedPointer<Drawing>(new Drawing(this, flag));
|
||||
|
||||
DrawingAbsoluteAnchor *anchor = new DrawingAbsoluteAnchor(drawing(), DrawingAnchor::Picture);
|
||||
|
||||
anchor->pos = QPoint(0, 0);
|
||||
anchor->ext = QSize(9293679, 6068786);
|
||||
|
||||
QSharedPointer<Chart> chart = QSharedPointer<Chart>(new Chart(this, flag));
|
||||
chart->setChartType(Chart::CT_Bar);
|
||||
anchor->setObjectGraphicFrame(chart);
|
||||
|
||||
d_func()->chart = chart.data();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*
|
||||
* Make a copy of this sheet.
|
||||
*/
|
||||
|
||||
Chartsheet *Chartsheet::copy(const QString &distName, int distId) const
|
||||
{
|
||||
//:Todo
|
||||
Q_UNUSED(distName)
|
||||
Q_UNUSED(distId)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Destroys this workssheet.
|
||||
*/
|
||||
Chartsheet::~Chartsheet()
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the chart object of the sheet.
|
||||
*/
|
||||
Chart *Chartsheet::chart()
|
||||
{
|
||||
Q_D(Chartsheet);
|
||||
|
||||
return d->chart;
|
||||
}
|
||||
|
||||
void Chartsheet::saveToXmlFile(QIODevice *device) const
|
||||
{
|
||||
Q_D(const Chartsheet);
|
||||
d->relationships->clear();
|
||||
|
||||
QXmlStreamWriter writer(device);
|
||||
|
||||
writer.writeStartDocument(QStringLiteral("1.0"), true);
|
||||
writer.writeDefaultNamespace(QStringLiteral("http://schemas.openxmlformats.org/spreadsheetml/2006/main"));
|
||||
writer.writeNamespace(QStringLiteral("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), QStringLiteral("r"));
|
||||
writer.writeStartElement(QStringLiteral("chartsheet"));
|
||||
|
||||
writer.writeStartElement(QStringLiteral("sheetViews"));
|
||||
writer.writeEmptyElement(QStringLiteral("sheetView"));
|
||||
writer.writeAttribute(QStringLiteral("workbookViewId"), QString::number(0));
|
||||
writer.writeAttribute(QStringLiteral("zoomToFit"), QStringLiteral("1"));
|
||||
writer.writeEndElement(); //sheetViews
|
||||
|
||||
int idx = d->workbook->drawings().indexOf(d->drawing.data());
|
||||
d->relationships->addWorksheetRelationship(QStringLiteral("/drawing"), QStringLiteral("../drawings/drawing%1.xml").arg(idx+1));
|
||||
|
||||
writer.writeEmptyElement(QStringLiteral("drawing"));
|
||||
writer.writeAttribute(QStringLiteral("r:id"), QStringLiteral("rId%1").arg(d->relationships->count()));
|
||||
|
||||
writer.writeEndElement();//chartsheet
|
||||
writer.writeEndDocument();
|
||||
}
|
||||
|
||||
bool Chartsheet::loadFromXmlFile(QIODevice *device)
|
||||
{
|
||||
Q_D(Chartsheet);
|
||||
|
||||
QXmlStreamReader reader(device);
|
||||
while (!reader.atEnd()) {
|
||||
reader.readNextStartElement();
|
||||
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
||||
if (reader.name() == QLatin1String("drawing")) {
|
||||
QString rId = reader.attributes().value(QStringLiteral("r:id")).toString();
|
||||
QString name = d->relationships->getRelationshipById(rId).target;
|
||||
QString path = QDir::cleanPath(splitPath(filePath())[0] + QLatin1String("/") + name);
|
||||
d->drawing = QSharedPointer<Drawing>(new Drawing(this, F_LoadFromExists));
|
||||
d->drawing->setFilePath(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE_XLSX
|
||||
198
platform/src/public/pub_excel/xlsx/xlsxcolor.cpp
Normal file
198
platform/src/public/pub_excel/xlsx/xlsxcolor.cpp
Normal file
@ -0,0 +1,198 @@
|
||||
#include "xlsxcolor_p.h"
|
||||
#include "xlsxstyles_p.h"
|
||||
#include "xlsxutility_p.h"
|
||||
|
||||
#include <QDataStream>
|
||||
#include <QXmlStreamReader>
|
||||
#include <QXmlStreamWriter>
|
||||
#include <QDebug>
|
||||
|
||||
namespace QXlsx {
|
||||
|
||||
|
||||
XlsxColor::XlsxColor(const QColor &color)
|
||||
{
|
||||
if (color.isValid())
|
||||
val.setValue(color);
|
||||
}
|
||||
|
||||
XlsxColor::XlsxColor(const QString &theme, const QString &tint)
|
||||
:val(QStringList()<<theme<<tint)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
XlsxColor::XlsxColor(int index)
|
||||
:val(index)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool XlsxColor::isRgbColor() const
|
||||
{
|
||||
if (val.userType() == qMetaTypeId<QColor>() && val.value<QColor>().isValid())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool XlsxColor::isIndexedColor() const
|
||||
{
|
||||
return val.userType() == QMetaType::Int;
|
||||
}
|
||||
|
||||
bool XlsxColor::isThemeColor() const
|
||||
{
|
||||
return val.userType() == QMetaType::QStringList;
|
||||
}
|
||||
|
||||
bool XlsxColor::isInvalid() const
|
||||
{
|
||||
return !val.isValid();
|
||||
}
|
||||
|
||||
QColor XlsxColor::rgbColor() const
|
||||
{
|
||||
if (isRgbColor())
|
||||
return val.value<QColor>();
|
||||
return QColor();
|
||||
}
|
||||
|
||||
int XlsxColor::indexedColor() const
|
||||
{
|
||||
if (isIndexedColor())
|
||||
return val.toInt();
|
||||
return -1;
|
||||
}
|
||||
|
||||
QStringList XlsxColor::themeColor() const
|
||||
{
|
||||
if (isThemeColor())
|
||||
return val.toStringList();
|
||||
return QStringList();
|
||||
}
|
||||
|
||||
bool XlsxColor::saveToXml(QXmlStreamWriter &writer, const QString &node) const
|
||||
{
|
||||
if (!node.isEmpty())
|
||||
writer.writeEmptyElement(node); //color, bgColor, fgColor
|
||||
else
|
||||
writer.writeEmptyElement(QStringLiteral("color"));
|
||||
|
||||
if (val.userType() == qMetaTypeId<QColor>()) {
|
||||
writer.writeAttribute(QStringLiteral("rgb"), XlsxColor::toARGBString(val.value<QColor>()));
|
||||
} else if (val.userType() == QMetaType::QStringList) {
|
||||
QStringList themes = val.toStringList();
|
||||
writer.writeAttribute(QStringLiteral("theme"), themes[0]);
|
||||
if (!themes[1].isEmpty())
|
||||
writer.writeAttribute(QStringLiteral("tint"), themes[1]);
|
||||
} else if (val.userType() == QMetaType::Int) {
|
||||
writer.writeAttribute(QStringLiteral("indexed"), val.toString());
|
||||
} else {
|
||||
writer.writeAttribute(QStringLiteral("auto"), QStringLiteral("1"));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool XlsxColor::loadFromXml(QXmlStreamReader &reader)
|
||||
{
|
||||
QXmlStreamAttributes attributes = reader.attributes();
|
||||
|
||||
if (attributes.hasAttribute(QLatin1String("rgb"))) {
|
||||
QString colorString = attributes.value(QLatin1String("rgb")).toString();
|
||||
val.setValue(fromARGBString(colorString));
|
||||
} else if (attributes.hasAttribute(QLatin1String("indexed"))) {
|
||||
int index = attributes.value(QLatin1String("indexed")).toString().toInt();
|
||||
val.setValue(index);
|
||||
} else if (attributes.hasAttribute(QLatin1String("theme"))) {
|
||||
QString theme = attributes.value(QLatin1String("theme")).toString();
|
||||
QString tint = attributes.value(QLatin1String("tint")).toString();
|
||||
val.setValue(QStringList()<<theme<<tint);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
XlsxColor::operator QVariant() const
|
||||
{
|
||||
return QVariant(qMetaTypeId<XlsxColor>(), this);
|
||||
}
|
||||
|
||||
|
||||
QColor XlsxColor::fromARGBString(const QString &c)
|
||||
{
|
||||
Q_ASSERT(c.length() == 8);
|
||||
QColor color;
|
||||
color.setAlpha(c.mid(0, 2).toInt(0, 16));
|
||||
color.setRed(c.mid(2, 2).toInt(0, 16));
|
||||
color.setGreen(c.mid(4, 2).toInt(0, 16));
|
||||
color.setBlue(c.mid(6, 2).toInt(0, 16));
|
||||
return color;
|
||||
}
|
||||
|
||||
QString XlsxColor::toARGBString(const QColor &c)
|
||||
{
|
||||
QString color;
|
||||
color.sprintf("%02X%02X%02X%02X", c.alpha(), c.red(), c.green(), c.blue());
|
||||
return color;
|
||||
}
|
||||
|
||||
#if !defined(QT_NO_DATASTREAM)
|
||||
QDataStream &operator<<(QDataStream &s, const XlsxColor &color)
|
||||
{
|
||||
if (color.isInvalid())
|
||||
s<<0;
|
||||
else if (color.isRgbColor())
|
||||
s<<1<<color.rgbColor();
|
||||
else if (color.isIndexedColor())
|
||||
s<<2<<color.indexedColor();
|
||||
else if (color.isThemeColor())
|
||||
s<<3<<color.themeColor();
|
||||
else
|
||||
s<<4;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
QDataStream &operator>>(QDataStream &s, XlsxColor &color)
|
||||
{
|
||||
int marker(4);
|
||||
s>>marker;
|
||||
if (marker == 0) {
|
||||
color = XlsxColor();
|
||||
} else if (marker == 1) {
|
||||
QColor c;
|
||||
s>>c;
|
||||
color = XlsxColor(c);
|
||||
} else if (marker == 2) {
|
||||
int indexed;
|
||||
s>>indexed;
|
||||
color = XlsxColor(indexed);
|
||||
} else if (marker == 3) {
|
||||
QStringList list;
|
||||
s>>list;
|
||||
color = XlsxColor(list[0], list[1]);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
QDebug operator<<(QDebug dbg, const XlsxColor &c)
|
||||
{
|
||||
if (c.isInvalid())
|
||||
dbg.nospace() << "XlsxColor(invalid)";
|
||||
else if (c.isRgbColor())
|
||||
dbg.nospace() << c.rgbColor();
|
||||
else if (c.isIndexedColor())
|
||||
dbg.nospace() << "XlsxColor(indexed," << c.indexedColor() << ")";
|
||||
else if (c.isThemeColor())
|
||||
dbg.nospace() << "XlsxColor(theme," << c.themeColor().join(QLatin1Char(':')) << ")";
|
||||
|
||||
return dbg.space();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace QXlsx
|
||||
735
platform/src/public/pub_excel/xlsx/xlsxconditionalformatting.cpp
Normal file
735
platform/src/public/pub_excel/xlsx/xlsxconditionalformatting.cpp
Normal file
@ -0,0 +1,735 @@
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2013-2014 Debao Zhang <hello@debao.me>
|
||||
** All right reserved.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining
|
||||
** a copy of this software and associated documentation files (the
|
||||
** "Software"), to deal in the Software without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Software, and to
|
||||
** permit persons to whom the Software is furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be
|
||||
** included in all copies or substantial portions of the Software.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "xlsxconditionalformatting.h"
|
||||
#include "xlsxconditionalformatting_p.h"
|
||||
#include "xlsxworksheet.h"
|
||||
#include "xlsxcellrange.h"
|
||||
#include "xlsxstyles_p.h"
|
||||
|
||||
#include <QXmlStreamReader>
|
||||
#include <QXmlStreamWriter>
|
||||
#include <QDebug>
|
||||
|
||||
QT_BEGIN_NAMESPACE_XLSX
|
||||
|
||||
ConditionalFormattingPrivate::ConditionalFormattingPrivate()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ConditionalFormattingPrivate::ConditionalFormattingPrivate(const ConditionalFormattingPrivate &other)
|
||||
:QSharedData(other)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ConditionalFormattingPrivate::~ConditionalFormattingPrivate()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ConditionalFormattingPrivate::writeCfVo(QXmlStreamWriter &writer, const XlsxCfVoData &cfvo) const
|
||||
{
|
||||
writer.writeEmptyElement(QStringLiteral("cfvo"));
|
||||
QString type;
|
||||
switch(cfvo.type) {
|
||||
case ConditionalFormatting::VOT_Formula: type=QStringLiteral("formula"); break;
|
||||
case ConditionalFormatting::VOT_Max: type=QStringLiteral("max"); break;
|
||||
case ConditionalFormatting::VOT_Min: type=QStringLiteral("min"); break;
|
||||
case ConditionalFormatting::VOT_Num: type=QStringLiteral("num"); break;
|
||||
case ConditionalFormatting::VOT_Percent: type=QStringLiteral("percent"); break;
|
||||
case ConditionalFormatting::VOT_Percentile: type=QStringLiteral("percentile"); break;
|
||||
default: break;
|
||||
}
|
||||
writer.writeAttribute(QStringLiteral("type"), type);
|
||||
writer.writeAttribute(QStringLiteral("val"), cfvo.value);
|
||||
if (!cfvo.gte)
|
||||
writer.writeAttribute(QStringLiteral("gte"), QStringLiteral("0"));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \class ConditionalFormatting
|
||||
* \brief Conditional formatting for single cell or ranges
|
||||
* \inmodule QtXlsx
|
||||
*
|
||||
* The conditional formatting can be applied to a single cell or ranges of cells.
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\enum ConditionalFormatting::HighlightRuleType
|
||||
|
||||
\value Highlight_LessThan
|
||||
\value Highlight_LessThanOrEqual
|
||||
\value Highlight_Equal
|
||||
\value Highlight_NotEqual
|
||||
\value Highlight_GreaterThanOrEqual
|
||||
\value Highlight_GreaterThan
|
||||
\value Highlight_Between
|
||||
\value Highlight_NotBetween
|
||||
|
||||
\value Highlight_ContainsText
|
||||
\value Highlight_NotContainsText
|
||||
\value Highlight_BeginsWith
|
||||
\value Highlight_EndsWith
|
||||
|
||||
\value Highlight_TimePeriod
|
||||
|
||||
\value Highlight_Duplicate
|
||||
\value Highlight_Unique
|
||||
|
||||
\value Highlight_Blanks
|
||||
\value Highlight_NoBlanks
|
||||
\value Highlight_Errors
|
||||
\value Highlight_NoErrors
|
||||
|
||||
\value Highlight_Top
|
||||
\value Highlight_TopPercent
|
||||
\value Highlight_Bottom
|
||||
\value Highlight_BottomPercent
|
||||
|
||||
\value Highlight_AboveAverage
|
||||
\value Highlight_AboveOrEqualAverage
|
||||
\value Highlight_BelowAverage
|
||||
\value Highlight_BelowOrEqualAverage
|
||||
\value Highlight_AboveStdDev1
|
||||
\value Highlight_AboveStdDev2
|
||||
\value Highlight_AboveStdDev3
|
||||
\value Highlight_BelowStdDev1
|
||||
\value Highlight_BelowStdDev2
|
||||
\value Highlight_BelowStdDev3
|
||||
|
||||
\value Highlight_Expression
|
||||
*/
|
||||
|
||||
/*!
|
||||
\enum ConditionalFormatting::ValueObjectType
|
||||
|
||||
\value VOT_Formula
|
||||
\value VOT_Max
|
||||
\value VOT_Min
|
||||
\value VOT_Num
|
||||
\value VOT_Percent
|
||||
\value VOT_Percentile
|
||||
*/
|
||||
|
||||
/*!
|
||||
Construct a conditional formatting object
|
||||
*/
|
||||
ConditionalFormatting::ConditionalFormatting()
|
||||
:d(new ConditionalFormattingPrivate())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
Constructs a copy of \a other.
|
||||
*/
|
||||
ConditionalFormatting::ConditionalFormatting(const ConditionalFormatting &other)
|
||||
:d(other.d)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
Assigns \a other to this conditional formatting and returns a reference to
|
||||
this conditional formatting.
|
||||
*/
|
||||
ConditionalFormatting &ConditionalFormatting::operator=(const ConditionalFormatting &other)
|
||||
{
|
||||
this->d = other.d;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* Destroy the object.
|
||||
*/
|
||||
ConditionalFormatting::~ConditionalFormatting()
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Add a hightlight rule with the given \a type, \a formula1, \a formula2,
|
||||
* \a format and \a stopIfTrue.
|
||||
* Return false if failed.
|
||||
*/
|
||||
bool ConditionalFormatting::addHighlightCellsRule(HighlightRuleType type, const QString &formula1, const QString &formula2, const Format &format, bool stopIfTrue)
|
||||
{
|
||||
if (format.isEmpty())
|
||||
return false;
|
||||
|
||||
bool skipFormula = false;
|
||||
|
||||
QSharedPointer<XlsxCfRuleData> cfRule(new XlsxCfRuleData);
|
||||
if (type >= Highlight_LessThan && type <= Highlight_NotBetween) {
|
||||
cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("cellIs");
|
||||
QString op;
|
||||
switch (type) {
|
||||
case Highlight_Between: op = QStringLiteral("between"); break;
|
||||
case Highlight_Equal: op = QStringLiteral("equal"); break;
|
||||
case Highlight_GreaterThan: op = QStringLiteral("greaterThan"); break;
|
||||
case Highlight_GreaterThanOrEqual: op = QStringLiteral("greaterThanOrEqual"); break;
|
||||
case Highlight_LessThan: op = QStringLiteral("lessThan"); break;
|
||||
case Highlight_LessThanOrEqual: op = QStringLiteral("lessThanOrEqual"); break;
|
||||
case Highlight_NotBetween: op = QStringLiteral("notBetween"); break;
|
||||
case Highlight_NotEqual: op = QStringLiteral("notEqual"); break;
|
||||
default: break;
|
||||
}
|
||||
cfRule->attrs[XlsxCfRuleData::A_operator] = op;
|
||||
} else if (type >= Highlight_ContainsText && type <= Highlight_EndsWith) {
|
||||
if (type == Highlight_ContainsText) {
|
||||
cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("containsText");
|
||||
cfRule->attrs[XlsxCfRuleData::A_operator] = QStringLiteral("containsText");
|
||||
cfRule->attrs[XlsxCfRuleData::A_formula1_temp] = QStringLiteral("NOT(ISERROR(SEARCH(\"%1\",%2)))").arg(formula1);
|
||||
} else if (type == Highlight_NotContainsText) {
|
||||
cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("notContainsText");
|
||||
cfRule->attrs[XlsxCfRuleData::A_operator] = QStringLiteral("notContains");
|
||||
cfRule->attrs[XlsxCfRuleData::A_formula1_temp] = QStringLiteral("ISERROR(SEARCH(\"%2\",%1))").arg(formula1);
|
||||
} else if (type == Highlight_BeginsWith) {
|
||||
cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("beginsWith");
|
||||
cfRule->attrs[XlsxCfRuleData::A_operator] = QStringLiteral("beginsWith");
|
||||
cfRule->attrs[XlsxCfRuleData::A_formula1_temp] = QStringLiteral("LEFT(%2,LEN(\"%1\"))=\"%1\"").arg(formula1);
|
||||
} else {
|
||||
cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("endsWith");
|
||||
cfRule->attrs[XlsxCfRuleData::A_operator] = QStringLiteral("endsWith");
|
||||
cfRule->attrs[XlsxCfRuleData::A_formula1_temp] = QStringLiteral("RIGHT(%2,LEN(\"%1\"))=\"%1\"").arg(formula1);
|
||||
}
|
||||
cfRule->attrs[XlsxCfRuleData::A_text] = formula1;
|
||||
skipFormula = true;
|
||||
} else if (type == Highlight_TimePeriod) {
|
||||
cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("timePeriod");
|
||||
//:Todo
|
||||
return false;
|
||||
} else if (type == Highlight_Duplicate) {
|
||||
cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("duplicateValues");
|
||||
} else if (type == Highlight_Unique) {
|
||||
cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("uniqueValues");
|
||||
} else if (type == Highlight_Errors) {
|
||||
cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("containsErrors");
|
||||
cfRule->attrs[XlsxCfRuleData::A_formula1_temp] = QStringLiteral("ISERROR(%1)");
|
||||
skipFormula = true;
|
||||
} else if (type == Highlight_NoErrors) {
|
||||
cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("notContainsErrors");
|
||||
cfRule->attrs[XlsxCfRuleData::A_formula1_temp] = QStringLiteral("NOT(ISERROR(%1))");
|
||||
skipFormula = true;
|
||||
} else if (type == Highlight_Blanks) {
|
||||
cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("containsBlanks");
|
||||
cfRule->attrs[XlsxCfRuleData::A_formula1_temp] = QStringLiteral("LEN(TRIM(%1))=0");
|
||||
skipFormula = true;
|
||||
} else if (type == Highlight_NoBlanks) {
|
||||
cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("notContainsBlanks");
|
||||
cfRule->attrs[XlsxCfRuleData::A_formula1_temp] = QStringLiteral("LEN(TRIM(%1))>0");
|
||||
skipFormula = true;
|
||||
} else if (type >= Highlight_Top && type <= Highlight_BottomPercent) {
|
||||
cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("top10");
|
||||
if (type == Highlight_Bottom || type == Highlight_BottomPercent)
|
||||
cfRule->attrs[XlsxCfRuleData::A_bottom] = QStringLiteral("1");
|
||||
if (type == Highlight_TopPercent || type == Highlight_BottomPercent)
|
||||
cfRule->attrs[XlsxCfRuleData::A_percent] = QStringLiteral("1");
|
||||
cfRule->attrs[XlsxCfRuleData::A_rank] = !formula1.isEmpty() ? formula1 : QStringLiteral("10");
|
||||
skipFormula = true;
|
||||
} else if (type >= Highlight_AboveAverage && type <= Highlight_BelowStdDev3) {
|
||||
cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("aboveAverage");
|
||||
if (type >= Highlight_BelowAverage && type <= Highlight_BelowStdDev3)
|
||||
cfRule->attrs[XlsxCfRuleData::A_aboveAverage] = QStringLiteral("0");
|
||||
if (type == Highlight_AboveOrEqualAverage || type == Highlight_BelowOrEqualAverage)
|
||||
cfRule->attrs[XlsxCfRuleData::A_equalAverage] = QStringLiteral("1");
|
||||
if (type == Highlight_AboveStdDev1 || type == Highlight_BelowStdDev1)
|
||||
cfRule->attrs[XlsxCfRuleData::A_stdDev] = QStringLiteral("1");
|
||||
else if (type == Highlight_AboveStdDev2 || type == Highlight_BelowStdDev2)
|
||||
cfRule->attrs[XlsxCfRuleData::A_stdDev] = QStringLiteral("2");
|
||||
else if (type == Highlight_AboveStdDev3 || type == Highlight_BelowStdDev3)
|
||||
cfRule->attrs[XlsxCfRuleData::A_stdDev] = QStringLiteral("3");
|
||||
} else if (type == Highlight_Expression){
|
||||
cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("expression");
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
cfRule->dxfFormat = format;
|
||||
if (stopIfTrue)
|
||||
cfRule->attrs[XlsxCfRuleData::A_stopIfTrue] = true;
|
||||
if (!skipFormula) {
|
||||
if (!formula1.isEmpty())
|
||||
cfRule->attrs[XlsxCfRuleData::A_formula1] = formula1.startsWith(QLatin1String("=")) ? formula1.mid(1) : formula1;
|
||||
if (!formula2.isEmpty())
|
||||
cfRule->attrs[XlsxCfRuleData::A_formula2] = formula2.startsWith(QLatin1String("=")) ? formula2.mid(1) : formula2;
|
||||
}
|
||||
d->cfRules.append(cfRule);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \overload
|
||||
*
|
||||
* Add a hightlight rule with the given \a type \a format and \a stopIfTrue.
|
||||
*/
|
||||
bool ConditionalFormatting::addHighlightCellsRule(HighlightRuleType type, const Format &format, bool stopIfTrue)
|
||||
{
|
||||
if ((type >= Highlight_AboveAverage && type <= Highlight_BelowStdDev3)
|
||||
|| (type >= Highlight_Duplicate && type <= Highlight_NoErrors)) {
|
||||
return addHighlightCellsRule(type, QString(), QString(), format, stopIfTrue);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \overload
|
||||
*
|
||||
* Add a hightlight rule with the given \a type, \a formula, \a format and \a stopIfTrue.
|
||||
* Return false if failed.
|
||||
*/
|
||||
bool ConditionalFormatting::addHighlightCellsRule(HighlightRuleType type, const QString &formula, const Format &format, bool stopIfTrue)
|
||||
{
|
||||
if (type == Highlight_Between || type == Highlight_NotBetween)
|
||||
return false;
|
||||
|
||||
return addHighlightCellsRule(type, formula, QString(), format, stopIfTrue);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Add a dataBar rule with the given \a color, \a type1, \a val1
|
||||
* , \a type2, \a val2, \a showData and \a stopIfTrue.
|
||||
* Return false if failed.
|
||||
*/
|
||||
bool ConditionalFormatting::addDataBarRule(const QColor &color, ValueObjectType type1, const QString &val1, ValueObjectType type2, const QString &val2, bool showData, bool stopIfTrue)
|
||||
{
|
||||
QSharedPointer<XlsxCfRuleData> cfRule(new XlsxCfRuleData);
|
||||
|
||||
cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("dataBar");
|
||||
cfRule->attrs[XlsxCfRuleData::A_color1] = XlsxColor(color);
|
||||
if (stopIfTrue)
|
||||
cfRule->attrs[XlsxCfRuleData::A_stopIfTrue] = true;
|
||||
if (!showData)
|
||||
cfRule->attrs[XlsxCfRuleData::A_hideData] = true;
|
||||
|
||||
XlsxCfVoData cfvo1(type1, val1);
|
||||
XlsxCfVoData cfvo2(type2, val2);
|
||||
cfRule->attrs[XlsxCfRuleData::A_cfvo1] = QVariant::fromValue(cfvo1);
|
||||
cfRule->attrs[XlsxCfRuleData::A_cfvo2] = QVariant::fromValue(cfvo2);
|
||||
|
||||
d->cfRules.append(cfRule);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \overload
|
||||
* Add a dataBar rule with the given \a color, \a showData and \a stopIfTrue.
|
||||
*/
|
||||
bool ConditionalFormatting::addDataBarRule(const QColor &color, bool showData, bool stopIfTrue)
|
||||
{
|
||||
return addDataBarRule(color, VOT_Min, QStringLiteral("0"), VOT_Max, QStringLiteral("0"), showData, stopIfTrue);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Add a colorScale rule with the given \a minColor, \a maxColor and \a stopIfTrue.
|
||||
* Return false if failed.
|
||||
*/
|
||||
bool ConditionalFormatting::add2ColorScaleRule(const QColor &minColor, const QColor &maxColor, bool stopIfTrue)
|
||||
{
|
||||
ValueObjectType type1 = VOT_Min;
|
||||
ValueObjectType type2 = VOT_Max;
|
||||
QString val1 = QStringLiteral("0");
|
||||
QString val2 = QStringLiteral("0");
|
||||
|
||||
QSharedPointer<XlsxCfRuleData> cfRule(new XlsxCfRuleData);
|
||||
|
||||
cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("colorScale");
|
||||
cfRule->attrs[XlsxCfRuleData::A_color1] = XlsxColor(minColor);
|
||||
cfRule->attrs[XlsxCfRuleData::A_color2] = XlsxColor(maxColor);
|
||||
if (stopIfTrue)
|
||||
cfRule->attrs[XlsxCfRuleData::A_stopIfTrue] = true;
|
||||
|
||||
XlsxCfVoData cfvo1(type1, val1);
|
||||
XlsxCfVoData cfvo2(type2, val2);
|
||||
cfRule->attrs[XlsxCfRuleData::A_cfvo1] = QVariant::fromValue(cfvo1);
|
||||
cfRule->attrs[XlsxCfRuleData::A_cfvo2] = QVariant::fromValue(cfvo2);
|
||||
|
||||
d->cfRules.append(cfRule);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Add a colorScale rule with the given \a minColor, \a midColor, \a maxColor and \a stopIfTrue.
|
||||
* Return false if failed.
|
||||
*/
|
||||
bool ConditionalFormatting::add3ColorScaleRule(const QColor &minColor, const QColor &midColor, const QColor &maxColor, bool stopIfTrue)
|
||||
{
|
||||
ValueObjectType type1 = VOT_Min;
|
||||
ValueObjectType type2 = VOT_Percent;
|
||||
ValueObjectType type3 = VOT_Max;
|
||||
QString val1 = QStringLiteral("0");
|
||||
QString val2 = QStringLiteral("50");
|
||||
QString val3 = QStringLiteral("0");
|
||||
|
||||
QSharedPointer<XlsxCfRuleData> cfRule(new XlsxCfRuleData);
|
||||
|
||||
cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("colorScale");
|
||||
cfRule->attrs[XlsxCfRuleData::A_color1] = XlsxColor(minColor);
|
||||
cfRule->attrs[XlsxCfRuleData::A_color2] = XlsxColor(midColor);
|
||||
cfRule->attrs[XlsxCfRuleData::A_color3] = XlsxColor(maxColor);
|
||||
|
||||
if (stopIfTrue)
|
||||
cfRule->attrs[XlsxCfRuleData::A_stopIfTrue] = true;
|
||||
|
||||
XlsxCfVoData cfvo1(type1, val1);
|
||||
XlsxCfVoData cfvo2(type2, val2);
|
||||
XlsxCfVoData cfvo3(type3, val3);
|
||||
cfRule->attrs[XlsxCfRuleData::A_cfvo1] = QVariant::fromValue(cfvo1);
|
||||
cfRule->attrs[XlsxCfRuleData::A_cfvo2] = QVariant::fromValue(cfvo2);
|
||||
cfRule->attrs[XlsxCfRuleData::A_cfvo3] = QVariant::fromValue(cfvo3);
|
||||
|
||||
d->cfRules.append(cfRule);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the ranges on which the validation will be applied.
|
||||
*/
|
||||
QList<CellRange> ConditionalFormatting::ranges() const
|
||||
{
|
||||
return d->ranges;
|
||||
}
|
||||
|
||||
/*!
|
||||
Add the \a cell on which the conditional formatting will apply to.
|
||||
*/
|
||||
void ConditionalFormatting::addCell(const CellReference &cell)
|
||||
{
|
||||
d->ranges.append(CellRange(cell, cell));
|
||||
}
|
||||
|
||||
/*!
|
||||
\overload
|
||||
Add the cell(\a row, \a col) on which the conditional formatting will apply to.
|
||||
*/
|
||||
void ConditionalFormatting::addCell(int row, int col)
|
||||
{
|
||||
d->ranges.append(CellRange(row, col, row, col));
|
||||
}
|
||||
|
||||
/*!
|
||||
\overload
|
||||
Add the range(\a firstRow, \a firstCol, \a lastRow, \a lastCol) on
|
||||
which the conditional formatting will apply to.
|
||||
*/
|
||||
void ConditionalFormatting::addRange(int firstRow, int firstCol, int lastRow, int lastCol)
|
||||
{
|
||||
d->ranges.append(CellRange(firstRow, firstCol, lastRow, lastCol));
|
||||
}
|
||||
|
||||
/*!
|
||||
Add the \a range on which the conditional formatting will apply to.
|
||||
*/
|
||||
void ConditionalFormatting::addRange(const CellRange &range)
|
||||
{
|
||||
d->ranges.append(range);
|
||||
}
|
||||
|
||||
bool ConditionalFormattingPrivate::readCfRule(QXmlStreamReader &reader, XlsxCfRuleData *rule, Styles *styles)
|
||||
{
|
||||
Q_ASSERT(reader.name() == QLatin1String("cfRule"));
|
||||
QXmlStreamAttributes attrs = reader.attributes();
|
||||
if (attrs.hasAttribute(QLatin1String("type")))
|
||||
rule->attrs[XlsxCfRuleData::A_type] = attrs.value(QLatin1String("type")).toString();
|
||||
if (attrs.hasAttribute(QLatin1String("dxfId"))) {
|
||||
int id = attrs.value(QLatin1String("dxfId")).toString().toInt();
|
||||
if (styles)
|
||||
rule->dxfFormat = styles->dxfFormat(id);
|
||||
else
|
||||
rule->dxfFormat.setDxfIndex(id);
|
||||
}
|
||||
rule->priority = attrs.value(QLatin1String("priority")).toString().toInt();
|
||||
if (attrs.value(QLatin1String("stopIfTrue")) == QLatin1String("1")) {
|
||||
//default is false
|
||||
rule->attrs[XlsxCfRuleData::A_stopIfTrue] = QLatin1String("1");
|
||||
}
|
||||
if (attrs.value(QLatin1String("aboveAverage")) == QLatin1String("0")) {
|
||||
//default is true
|
||||
rule->attrs[XlsxCfRuleData::A_aboveAverage] = QLatin1String("0");
|
||||
}
|
||||
if (attrs.value(QLatin1String("percent")) == QLatin1String("1")) {
|
||||
//default is false
|
||||
rule->attrs[XlsxCfRuleData::A_percent] = QLatin1String("1");
|
||||
}
|
||||
if (attrs.value(QLatin1String("bottom")) == QLatin1String("1")) {
|
||||
//default is false
|
||||
rule->attrs[XlsxCfRuleData::A_bottom] = QLatin1String("1");
|
||||
}
|
||||
if (attrs.hasAttribute(QLatin1String("operator")))
|
||||
rule->attrs[XlsxCfRuleData::A_operator] = attrs.value(QLatin1String("operator")).toString();
|
||||
|
||||
if (attrs.hasAttribute(QLatin1String("text")))
|
||||
rule->attrs[XlsxCfRuleData::A_text] = attrs.value(QLatin1String("text")).toString();
|
||||
|
||||
if (attrs.hasAttribute(QLatin1String("timePeriod")))
|
||||
rule->attrs[XlsxCfRuleData::A_timePeriod] = attrs.value(QLatin1String("timePeriod")).toString();
|
||||
|
||||
if (attrs.hasAttribute(QLatin1String("rank")))
|
||||
rule->attrs[XlsxCfRuleData::A_rank] = attrs.value(QLatin1String("rank")).toString();
|
||||
|
||||
if (attrs.hasAttribute(QLatin1String("stdDev")))
|
||||
rule->attrs[XlsxCfRuleData::A_stdDev] = attrs.value(QLatin1String("stdDev")).toString();
|
||||
|
||||
if (attrs.value(QLatin1String("equalAverage")) == QLatin1String("1")) {
|
||||
//default is false
|
||||
rule->attrs[XlsxCfRuleData::A_equalAverage] = QLatin1String("1");
|
||||
}
|
||||
|
||||
while (!reader.atEnd()) {
|
||||
reader.readNextStartElement();
|
||||
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
||||
if (reader.name() == QLatin1String("formula")) {
|
||||
QString f = reader.readElementText();
|
||||
if (!rule->attrs.contains(XlsxCfRuleData::A_formula1))
|
||||
rule->attrs[XlsxCfRuleData::A_formula1] = f;
|
||||
else if (!rule->attrs.contains(XlsxCfRuleData::A_formula2))
|
||||
rule->attrs[XlsxCfRuleData::A_formula2] = f;
|
||||
else if (!rule->attrs.contains(XlsxCfRuleData::A_formula3))
|
||||
rule->attrs[XlsxCfRuleData::A_formula3] = f;
|
||||
} else if (reader.name() == QLatin1String("dataBar")) {
|
||||
readCfDataBar(reader, rule);
|
||||
} else if (reader.name() == QLatin1String("colorScale")) {
|
||||
readCfColorScale(reader, rule);
|
||||
}
|
||||
}
|
||||
if (reader.tokenType() == QXmlStreamReader::EndElement
|
||||
&& reader.name() == QStringLiteral("conditionalFormatting")) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ConditionalFormattingPrivate::readCfDataBar(QXmlStreamReader &reader, XlsxCfRuleData *rule)
|
||||
{
|
||||
Q_ASSERT(reader.name() == QLatin1String("dataBar"));
|
||||
QXmlStreamAttributes attrs = reader.attributes();
|
||||
if (attrs.value(QLatin1String("showValue")) == QLatin1String("0"))
|
||||
rule->attrs[XlsxCfRuleData::A_hideData] = QStringLiteral("1");
|
||||
|
||||
while (!reader.atEnd()) {
|
||||
reader.readNextStartElement();
|
||||
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
||||
if (reader.name() == QLatin1String("cfvo")) {
|
||||
XlsxCfVoData data;
|
||||
readCfVo(reader, data);
|
||||
if (!rule->attrs.contains(XlsxCfRuleData::A_cfvo1))
|
||||
rule->attrs[XlsxCfRuleData::A_cfvo1] = QVariant::fromValue(data);
|
||||
else
|
||||
rule->attrs[XlsxCfRuleData::A_cfvo2] = QVariant::fromValue(data);
|
||||
} else if (reader.name() == QLatin1String("color")) {
|
||||
XlsxColor color;
|
||||
color.loadFromXml(reader);
|
||||
rule->attrs[XlsxCfRuleData::A_color1] = color;
|
||||
}
|
||||
}
|
||||
if (reader.tokenType() == QXmlStreamReader::EndElement
|
||||
&& reader.name() == QStringLiteral("dataBar")) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ConditionalFormattingPrivate::readCfColorScale(QXmlStreamReader &reader, XlsxCfRuleData *rule)
|
||||
{
|
||||
Q_ASSERT(reader.name() == QLatin1String("colorScale"));
|
||||
|
||||
while (!reader.atEnd()) {
|
||||
reader.readNextStartElement();
|
||||
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
||||
if (reader.name() == QLatin1String("cfvo")) {
|
||||
XlsxCfVoData data;
|
||||
readCfVo(reader, data);
|
||||
if (!rule->attrs.contains(XlsxCfRuleData::A_cfvo1))
|
||||
rule->attrs[XlsxCfRuleData::A_cfvo1] = QVariant::fromValue(data);
|
||||
else if (!rule->attrs.contains(XlsxCfRuleData::A_cfvo2))
|
||||
rule->attrs[XlsxCfRuleData::A_cfvo2] = QVariant::fromValue(data);
|
||||
else
|
||||
rule->attrs[XlsxCfRuleData::A_cfvo2] = QVariant::fromValue(data);
|
||||
} else if (reader.name() == QLatin1String("color")) {
|
||||
XlsxColor color;
|
||||
color.loadFromXml(reader);
|
||||
if (!rule->attrs.contains(XlsxCfRuleData::A_color1))
|
||||
rule->attrs[XlsxCfRuleData::A_color1] = color;
|
||||
else if (!rule->attrs.contains(XlsxCfRuleData::A_color2))
|
||||
rule->attrs[XlsxCfRuleData::A_color2] = color;
|
||||
else
|
||||
rule->attrs[XlsxCfRuleData::A_color3] = color;
|
||||
}
|
||||
}
|
||||
if (reader.tokenType() == QXmlStreamReader::EndElement
|
||||
&& reader.name() == QStringLiteral("colorScale")) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ConditionalFormattingPrivate::readCfVo(QXmlStreamReader &reader, XlsxCfVoData &cfvo)
|
||||
{
|
||||
Q_ASSERT(reader.name() == QStringLiteral("cfvo"));
|
||||
|
||||
QXmlStreamAttributes attrs = reader.attributes();
|
||||
|
||||
QString type = attrs.value(QLatin1String("type")).toString();
|
||||
ConditionalFormatting::ValueObjectType t;
|
||||
if (type == QLatin1String("formula"))
|
||||
t = ConditionalFormatting::VOT_Formula;
|
||||
else if (type == QLatin1String("max"))
|
||||
t = ConditionalFormatting::VOT_Max;
|
||||
else if (type == QLatin1String("min"))
|
||||
t = ConditionalFormatting::VOT_Min;
|
||||
else if (type == QLatin1String("num"))
|
||||
t = ConditionalFormatting::VOT_Num;
|
||||
else if (type == QLatin1String("percent"))
|
||||
t = ConditionalFormatting::VOT_Percent;
|
||||
else //if (type == QLatin1String("percentile"))
|
||||
t = ConditionalFormatting::VOT_Percentile;
|
||||
|
||||
cfvo.type = t;
|
||||
cfvo.value = attrs.value(QLatin1String("val")).toString();
|
||||
if (attrs.value(QLatin1String("gte")) == QLatin1String("0")) {
|
||||
//default is true
|
||||
cfvo.gte = false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ConditionalFormatting::loadFromXml(QXmlStreamReader &reader, Styles *styles)
|
||||
{
|
||||
Q_ASSERT(reader.name() == QStringLiteral("conditionalFormatting"));
|
||||
|
||||
d->ranges.clear();
|
||||
d->cfRules.clear();
|
||||
QXmlStreamAttributes attrs = reader.attributes();
|
||||
QString sqref = attrs.value(QLatin1String("sqref")).toString();
|
||||
foreach (QString range, sqref.split(QLatin1Char(' ')))
|
||||
this->addRange(range);
|
||||
|
||||
while (!reader.atEnd()) {
|
||||
reader.readNextStartElement();
|
||||
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
||||
if (reader.name() == QLatin1String("cfRule")) {
|
||||
QSharedPointer<XlsxCfRuleData> cfRule(new XlsxCfRuleData);
|
||||
d->readCfRule(reader, cfRule.data(), styles);
|
||||
d->cfRules.append(cfRule);
|
||||
}
|
||||
}
|
||||
if (reader.tokenType() == QXmlStreamReader::EndElement
|
||||
&& reader.name() == QStringLiteral("conditionalFormatting")) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ConditionalFormatting::saveToXml(QXmlStreamWriter &writer) const
|
||||
{
|
||||
writer.writeStartElement(QStringLiteral("conditionalFormatting"));
|
||||
QStringList sqref;
|
||||
foreach (CellRange range, ranges())
|
||||
sqref.append(range.toString());
|
||||
writer.writeAttribute(QStringLiteral("sqref"), sqref.join(QLatin1Char(' ')));
|
||||
|
||||
for (int i=0; i<d->cfRules.size(); ++i) {
|
||||
const QSharedPointer<XlsxCfRuleData> &rule = d->cfRules[i];
|
||||
writer.writeStartElement(QStringLiteral("cfRule"));
|
||||
writer.writeAttribute(QStringLiteral("type"), rule->attrs[XlsxCfRuleData::A_type].toString());
|
||||
if (rule->dxfFormat.dxfIndexValid())
|
||||
writer.writeAttribute(QStringLiteral("dxfId"), QString::number(rule->dxfFormat.dxfIndex()));
|
||||
writer.writeAttribute(QStringLiteral("priority"), QString::number(rule->priority));
|
||||
if (rule->attrs.contains(XlsxCfRuleData::A_stopIfTrue))
|
||||
writer.writeAttribute(QStringLiteral("stopIfTrue"), rule->attrs[XlsxCfRuleData::A_stopIfTrue].toString());
|
||||
if (rule->attrs.contains(XlsxCfRuleData::A_aboveAverage))
|
||||
writer.writeAttribute(QStringLiteral("aboveAverage"), rule->attrs[XlsxCfRuleData::A_aboveAverage].toString());
|
||||
if (rule->attrs.contains(XlsxCfRuleData::A_percent))
|
||||
writer.writeAttribute(QStringLiteral("percent"), rule->attrs[XlsxCfRuleData::A_percent].toString());
|
||||
if (rule->attrs.contains(XlsxCfRuleData::A_bottom))
|
||||
writer.writeAttribute(QStringLiteral("bottom"), rule->attrs[XlsxCfRuleData::A_bottom].toString());
|
||||
if (rule->attrs.contains(XlsxCfRuleData::A_operator))
|
||||
writer.writeAttribute(QStringLiteral("operator"), rule->attrs[XlsxCfRuleData::A_operator].toString());
|
||||
if (rule->attrs.contains(XlsxCfRuleData::A_text))
|
||||
writer.writeAttribute(QStringLiteral("text"), rule->attrs[XlsxCfRuleData::A_text].toString());
|
||||
if (rule->attrs.contains(XlsxCfRuleData::A_timePeriod))
|
||||
writer.writeAttribute(QStringLiteral("timePeriod"), rule->attrs[XlsxCfRuleData::A_timePeriod].toString());
|
||||
if (rule->attrs.contains(XlsxCfRuleData::A_rank))
|
||||
writer.writeAttribute(QStringLiteral("rank"), rule->attrs[XlsxCfRuleData::A_rank].toString());
|
||||
if (rule->attrs.contains(XlsxCfRuleData::A_stdDev))
|
||||
writer.writeAttribute(QStringLiteral("stdDev"), rule->attrs[XlsxCfRuleData::A_stdDev].toString());
|
||||
if (rule->attrs.contains(XlsxCfRuleData::A_equalAverage))
|
||||
writer.writeAttribute(QStringLiteral("equalAverage"), rule->attrs[XlsxCfRuleData::A_equalAverage].toString());
|
||||
|
||||
if (rule->attrs[XlsxCfRuleData::A_type] == QLatin1String("dataBar")) {
|
||||
writer.writeStartElement(QStringLiteral("dataBar"));
|
||||
if (rule->attrs.contains(XlsxCfRuleData::A_hideData))
|
||||
writer.writeAttribute(QStringLiteral("showValue"), QStringLiteral("0"));
|
||||
d->writeCfVo(writer, rule->attrs[XlsxCfRuleData::A_cfvo1].value<XlsxCfVoData>());
|
||||
d->writeCfVo(writer, rule->attrs[XlsxCfRuleData::A_cfvo2].value<XlsxCfVoData>());
|
||||
rule->attrs[XlsxCfRuleData::A_color1].value<XlsxColor>().saveToXml(writer);
|
||||
writer.writeEndElement();//dataBar
|
||||
} else if (rule->attrs[XlsxCfRuleData::A_type] == QLatin1String("colorScale")) {
|
||||
writer.writeStartElement(QStringLiteral("colorScale"));
|
||||
d->writeCfVo(writer, rule->attrs[XlsxCfRuleData::A_cfvo1].value<XlsxCfVoData>());
|
||||
d->writeCfVo(writer, rule->attrs[XlsxCfRuleData::A_cfvo2].value<XlsxCfVoData>());
|
||||
if (rule->attrs.contains(XlsxCfRuleData::A_cfvo3))
|
||||
d->writeCfVo(writer, rule->attrs[XlsxCfRuleData::A_cfvo3].value<XlsxCfVoData>());
|
||||
|
||||
rule->attrs[XlsxCfRuleData::A_color1].value<XlsxColor>().saveToXml(writer);
|
||||
rule->attrs[XlsxCfRuleData::A_color2].value<XlsxColor>().saveToXml(writer);
|
||||
if (rule->attrs.contains(XlsxCfRuleData::A_color3))
|
||||
rule->attrs[XlsxCfRuleData::A_color3].value<XlsxColor>().saveToXml(writer);
|
||||
|
||||
writer.writeEndElement();//colorScale
|
||||
}
|
||||
|
||||
|
||||
if (rule->attrs.contains(XlsxCfRuleData::A_formula1_temp)) {
|
||||
QString startCell = ranges()[0].toString().split(QLatin1Char(':'))[0];
|
||||
writer.writeTextElement(QStringLiteral("formula"), rule->attrs[XlsxCfRuleData::A_formula1_temp].toString().arg(startCell));
|
||||
} else if (rule->attrs.contains(XlsxCfRuleData::A_formula1)) {
|
||||
writer.writeTextElement(QStringLiteral("formula"), rule->attrs[XlsxCfRuleData::A_formula1].toString());
|
||||
}
|
||||
if (rule->attrs.contains(XlsxCfRuleData::A_formula2))
|
||||
writer.writeTextElement(QStringLiteral("formula"), rule->attrs[XlsxCfRuleData::A_formula2].toString());
|
||||
if (rule->attrs.contains(XlsxCfRuleData::A_formula3))
|
||||
writer.writeTextElement(QStringLiteral("formula"), rule->attrs[XlsxCfRuleData::A_formula3].toString());
|
||||
|
||||
writer.writeEndElement(); //cfRule
|
||||
}
|
||||
|
||||
writer.writeEndElement(); //conditionalFormatting
|
||||
return true;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE_XLSX
|
||||
205
platform/src/public/pub_excel/xlsx/xlsxcontenttypes.cpp
Normal file
205
platform/src/public/pub_excel/xlsx/xlsxcontenttypes.cpp
Normal file
@ -0,0 +1,205 @@
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2013-2014 Debao Zhang <hello@debao.me>
|
||||
** All right reserved.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining
|
||||
** a copy of this software and associated documentation files (the
|
||||
** "Software"), to deal in the Software without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Software, and to
|
||||
** permit persons to whom the Software is furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be
|
||||
** included in all copies or substantial portions of the Software.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
****************************************************************************/
|
||||
#include "xlsxcontenttypes_p.h"
|
||||
#include <QXmlStreamWriter>
|
||||
#include <QXmlStreamReader>
|
||||
#include <QFile>
|
||||
#include <QMapIterator>
|
||||
#include <QBuffer>
|
||||
#include <QDebug>
|
||||
|
||||
namespace QXlsx {
|
||||
|
||||
ContentTypes::ContentTypes(CreateFlag flag)
|
||||
:AbstractOOXmlFile(flag)
|
||||
{
|
||||
m_package_prefix = QStringLiteral("application/vnd.openxmlformats-package.");
|
||||
m_document_prefix = QStringLiteral("application/vnd.openxmlformats-officedocument.");
|
||||
|
||||
m_defaults.insert(QStringLiteral("rels"), m_package_prefix + QStringLiteral("relationships+xml"));
|
||||
m_defaults.insert(QStringLiteral("xml"), QStringLiteral("application/xml"));
|
||||
}
|
||||
|
||||
void ContentTypes::addDefault(const QString &key, const QString &value)
|
||||
{
|
||||
m_defaults.insert(key, value);
|
||||
}
|
||||
|
||||
void ContentTypes::addOverride(const QString &key, const QString &value)
|
||||
{
|
||||
m_overrides.insert(key, value);
|
||||
}
|
||||
|
||||
void ContentTypes::addDocPropApp()
|
||||
{
|
||||
addOverride(QStringLiteral("/docProps/app.xml"), m_document_prefix + QStringLiteral("extended-properties+xml"));
|
||||
}
|
||||
|
||||
void ContentTypes::addDocPropCore()
|
||||
{
|
||||
addOverride(QStringLiteral("/docProps/core.xml"), m_package_prefix + QStringLiteral("core-properties+xml"));
|
||||
}
|
||||
|
||||
void ContentTypes::addStyles()
|
||||
{
|
||||
addOverride(QStringLiteral("/xl/styles.xml"), m_document_prefix + QStringLiteral("spreadsheetml.styles+xml"));
|
||||
}
|
||||
|
||||
void ContentTypes::addTheme()
|
||||
{
|
||||
addOverride(QStringLiteral("/xl/theme/theme1.xml"), m_document_prefix + QStringLiteral("theme+xml"));
|
||||
}
|
||||
|
||||
void ContentTypes::addWorkbook()
|
||||
{
|
||||
addOverride(QStringLiteral("/xl/workbook.xml"), m_document_prefix + QStringLiteral("spreadsheetml.sheet.main+xml"));
|
||||
}
|
||||
|
||||
void ContentTypes::addWorksheetName(const QString &name)
|
||||
{
|
||||
addOverride(QStringLiteral("/xl/worksheets/%1.xml").arg(name), m_document_prefix + QStringLiteral("spreadsheetml.worksheet+xml"));
|
||||
}
|
||||
|
||||
void ContentTypes::addChartsheetName(const QString &name)
|
||||
{
|
||||
addOverride(QStringLiteral("/xl/chartsheets/%1.xml").arg(name), m_document_prefix + QStringLiteral("spreadsheetml.chartsheet+xml"));
|
||||
}
|
||||
|
||||
void ContentTypes::addDrawingName(const QString &name)
|
||||
{
|
||||
addOverride(QStringLiteral("/xl/drawings/%1.xml").arg(name), m_document_prefix + QStringLiteral("drawing+xml"));
|
||||
}
|
||||
|
||||
void ContentTypes::addChartName(const QString &name)
|
||||
{
|
||||
addOverride(QStringLiteral("/xl/charts/%1.xml").arg(name), m_document_prefix + QStringLiteral("drawingml.chart+xml"));
|
||||
}
|
||||
|
||||
void ContentTypes::addCommentName(const QString &name)
|
||||
{
|
||||
addOverride(QStringLiteral("/xl/%1.xml").arg(name), m_document_prefix + QStringLiteral("spreadsheetml.comments+xml"));
|
||||
}
|
||||
|
||||
void ContentTypes::addTableName(const QString &name)
|
||||
{
|
||||
addOverride(QStringLiteral("/xl/tables/%1.xml").arg(name), m_document_prefix + QStringLiteral("spreadsheetml.table+xml"));
|
||||
}
|
||||
|
||||
void ContentTypes::addExternalLinkName(const QString &name)
|
||||
{
|
||||
addOverride(QStringLiteral("/xl/externalLinks/%1.xml").arg(name), m_document_prefix + QStringLiteral("spreadsheetml.externalLink+xml"));
|
||||
}
|
||||
|
||||
void ContentTypes::addSharedString()
|
||||
{
|
||||
addOverride(QStringLiteral("/xl/sharedStrings.xml"), m_document_prefix + QStringLiteral("spreadsheetml.sharedStrings+xml"));
|
||||
}
|
||||
|
||||
void ContentTypes::addVmlName()
|
||||
{
|
||||
addOverride(QStringLiteral("vml"), m_document_prefix + QStringLiteral("vmlDrawing"));
|
||||
}
|
||||
|
||||
void ContentTypes::addCalcChain()
|
||||
{
|
||||
addOverride(QStringLiteral("/xl/calcChain.xml"), m_document_prefix + QStringLiteral("spreadsheetml.calcChain+xml"));
|
||||
}
|
||||
|
||||
void ContentTypes::addVbaProject()
|
||||
{
|
||||
//:TODO
|
||||
addOverride(QStringLiteral("bin"), QStringLiteral("application/vnd.ms-office.vbaProject"));
|
||||
}
|
||||
|
||||
void ContentTypes::clearOverrides()
|
||||
{
|
||||
m_overrides.clear();
|
||||
}
|
||||
|
||||
void ContentTypes::saveToXmlFile(QIODevice *device) const
|
||||
{
|
||||
QXmlStreamWriter writer(device);
|
||||
|
||||
writer.writeStartDocument(QStringLiteral("1.0"), true);
|
||||
writer.writeStartElement(QStringLiteral("Types"));
|
||||
writer.writeAttribute(QStringLiteral("xmlns"), QStringLiteral("http://schemas.openxmlformats.org/package/2006/content-types"));
|
||||
|
||||
{
|
||||
QMapIterator<QString, QString> it(m_defaults);
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
writer.writeStartElement(QStringLiteral("Default"));
|
||||
writer.writeAttribute(QStringLiteral("Extension"), it.key());
|
||||
writer.writeAttribute(QStringLiteral("ContentType"), it.value());
|
||||
writer.writeEndElement();//Default
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
QMapIterator<QString, QString> it(m_overrides);
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
writer.writeStartElement(QStringLiteral("Override"));
|
||||
writer.writeAttribute(QStringLiteral("PartName"), it.key());
|
||||
writer.writeAttribute(QStringLiteral("ContentType"), it.value());
|
||||
writer.writeEndElement(); //Override
|
||||
}
|
||||
}
|
||||
|
||||
writer.writeEndElement();//Types
|
||||
writer.writeEndDocument();
|
||||
|
||||
}
|
||||
|
||||
bool ContentTypes::loadFromXmlFile(QIODevice *device)
|
||||
{
|
||||
m_defaults.clear();
|
||||
m_overrides.clear();
|
||||
|
||||
QXmlStreamReader reader(device);
|
||||
while (!reader.atEnd()) {
|
||||
QXmlStreamReader::TokenType token = reader.readNext();
|
||||
if (token == QXmlStreamReader::StartElement) {
|
||||
if (reader.name() == QLatin1String("Default")) {
|
||||
QXmlStreamAttributes attrs = reader.attributes();
|
||||
QString extension = attrs.value(QLatin1String("Extension")).toString();
|
||||
QString type = attrs.value(QLatin1String("ContentType")).toString();
|
||||
m_defaults.insert(extension, type);
|
||||
} else if (reader.name() == QLatin1String("Override")) {
|
||||
QXmlStreamAttributes attrs = reader.attributes();
|
||||
QString partName = attrs.value(QLatin1String("PartName")).toString();
|
||||
QString type = attrs.value(QLatin1String("ContentType")).toString();
|
||||
m_overrides.insert(partName, type);
|
||||
}
|
||||
}
|
||||
|
||||
if (reader.hasError()) {
|
||||
qDebug()<<reader.errorString();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} //namespace QXlsx
|
||||
552
platform/src/public/pub_excel/xlsx/xlsxdatavalidation.cpp
Normal file
552
platform/src/public/pub_excel/xlsx/xlsxdatavalidation.cpp
Normal file
@ -0,0 +1,552 @@
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2013-2014 Debao Zhang <hello@debao.me>
|
||||
** All right reserved.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining
|
||||
** a copy of this software and associated documentation files (the
|
||||
** "Software"), to deal in the Software without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Software, and to
|
||||
** permit persons to whom the Software is furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be
|
||||
** included in all copies or substantial portions of the Software.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "xlsxdatavalidation.h"
|
||||
#include "xlsxdatavalidation_p.h"
|
||||
#include "xlsxworksheet.h"
|
||||
#include "xlsxcellrange.h"
|
||||
|
||||
#include <QXmlStreamReader>
|
||||
#include <QXmlStreamWriter>
|
||||
|
||||
QT_BEGIN_NAMESPACE_XLSX
|
||||
|
||||
DataValidationPrivate::DataValidationPrivate()
|
||||
:validationType(DataValidation::None), validationOperator(DataValidation::Between)
|
||||
, errorStyle(DataValidation::Stop), allowBlank(false), isPromptMessageVisible(true)
|
||||
, isErrorMessageVisible(true)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
DataValidationPrivate::DataValidationPrivate(DataValidation::ValidationType type, DataValidation::ValidationOperator op, const QString &formula1, const QString &formula2, bool allowBlank)
|
||||
:validationType(type), validationOperator(op)
|
||||
, errorStyle(DataValidation::Stop), allowBlank(allowBlank), isPromptMessageVisible(true)
|
||||
, isErrorMessageVisible(true), formula1(formula1), formula2(formula2)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
DataValidationPrivate::DataValidationPrivate(const DataValidationPrivate &other)
|
||||
:QSharedData(other)
|
||||
, validationType(DataValidation::None), validationOperator(DataValidation::Between)
|
||||
, errorStyle(DataValidation::Stop), allowBlank(false), isPromptMessageVisible(true)
|
||||
, isErrorMessageVisible(true)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
DataValidationPrivate::~DataValidationPrivate()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
* \class DataValidation
|
||||
* \brief Data validation for single cell or a range
|
||||
* \inmodule QtXlsx
|
||||
*
|
||||
* The data validation can be applied to a single cell or a range of cells.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \enum DataValidation::ValidationType
|
||||
*
|
||||
* The enum type defines the type of data that you wish to validate.
|
||||
*
|
||||
* \value None the type of data is unrestricted. This is the same as not applying a data validation.
|
||||
* \value Whole restricts the cell to integer values. Means "Whole number"?
|
||||
* \value Decimal restricts the cell to decimal values.
|
||||
* \value List restricts the cell to a set of user specified values.
|
||||
* \value Date restricts the cell to date values.
|
||||
* \value Time restricts the cell to time values.
|
||||
* \value TextLength restricts the cell data based on an integer string length.
|
||||
* \value Custom restricts the cell based on an external Excel formula that returns a true/false value.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \enum DataValidation::ValidationOperator
|
||||
*
|
||||
* The enum type defines the criteria by which the data in the
|
||||
* cell is validated
|
||||
*
|
||||
* \value Between
|
||||
* \value NotBetween
|
||||
* \value Equal
|
||||
* \value NotEqual
|
||||
* \value LessThan
|
||||
* \value LessThanOrEqual
|
||||
* \value GreaterThan
|
||||
* \value GreaterThanOrEqual
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \enum DataValidation::ErrorStyle
|
||||
*
|
||||
* The enum type defines the type of error dialog that
|
||||
* is displayed.
|
||||
*
|
||||
* \value Stop
|
||||
* \value Warning
|
||||
* \value Information
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Construct a data validation object with the given \a type, \a op, \a formula1
|
||||
* \a formula2, and \a allowBlank.
|
||||
*/
|
||||
DataValidation::DataValidation(ValidationType type, ValidationOperator op, const QString &formula1, const QString &formula2, bool allowBlank)
|
||||
:d(new DataValidationPrivate(type, op, formula1, formula2, allowBlank))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
Construct a data validation object
|
||||
*/
|
||||
DataValidation::DataValidation()
|
||||
:d(new DataValidationPrivate())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
Constructs a copy of \a other.
|
||||
*/
|
||||
DataValidation::DataValidation(const DataValidation &other)
|
||||
:d(other.d)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
Assigns \a other to this validation and returns a reference to this validation.
|
||||
*/
|
||||
DataValidation &DataValidation::operator=(const DataValidation &other)
|
||||
{
|
||||
this->d = other.d;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* Destroy the object.
|
||||
*/
|
||||
DataValidation::~DataValidation()
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the validation type.
|
||||
*/
|
||||
DataValidation::ValidationType DataValidation::validationType() const
|
||||
{
|
||||
return d->validationType;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the validation operator.
|
||||
*/
|
||||
DataValidation::ValidationOperator DataValidation::validationOperator() const
|
||||
{
|
||||
return d->validationOperator;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the validation error style.
|
||||
*/
|
||||
DataValidation::ErrorStyle DataValidation::errorStyle() const
|
||||
{
|
||||
return d->errorStyle;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the formula1.
|
||||
*/
|
||||
QString DataValidation::formula1() const
|
||||
{
|
||||
return d->formula1;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the formula2.
|
||||
*/
|
||||
QString DataValidation::formula2() const
|
||||
{
|
||||
return d->formula2;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns whether blank is allowed.
|
||||
*/
|
||||
bool DataValidation::allowBlank() const
|
||||
{
|
||||
return d->allowBlank;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the error message.
|
||||
*/
|
||||
QString DataValidation::errorMessage() const
|
||||
{
|
||||
return d->errorMessage;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the error message title.
|
||||
*/
|
||||
QString DataValidation::errorMessageTitle() const
|
||||
{
|
||||
return d->errorMessageTitle;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the prompt message.
|
||||
*/
|
||||
QString DataValidation::promptMessage() const
|
||||
{
|
||||
return d->promptMessage;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the prompt message title.
|
||||
*/
|
||||
QString DataValidation::promptMessageTitle() const
|
||||
{
|
||||
return d->promptMessageTitle;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the whether prompt message is shown.
|
||||
*/
|
||||
bool DataValidation::isPromptMessageVisible() const
|
||||
{
|
||||
return d->isPromptMessageVisible;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the whether error message is shown.
|
||||
*/
|
||||
bool DataValidation::isErrorMessageVisible() const
|
||||
{
|
||||
return d->isErrorMessageVisible;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the ranges on which the validation will be applied.
|
||||
*/
|
||||
QList<CellRange> DataValidation::ranges() const
|
||||
{
|
||||
return d->ranges;
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the validation type to \a type.
|
||||
*/
|
||||
void DataValidation::setValidationType(DataValidation::ValidationType type)
|
||||
{
|
||||
d->validationType = type;
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the validation operator to \a op.
|
||||
*/
|
||||
void DataValidation::setValidationOperator(DataValidation::ValidationOperator op)
|
||||
{
|
||||
d->validationOperator = op;
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the error style to \a es.
|
||||
*/
|
||||
void DataValidation::setErrorStyle(DataValidation::ErrorStyle es)
|
||||
{
|
||||
d->errorStyle = es;
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the formula1 to \a formula.
|
||||
*/
|
||||
void DataValidation::setFormula1(const QString &formula)
|
||||
{
|
||||
if (formula.startsWith(QLatin1Char('=')))
|
||||
d->formula1 = formula.mid(1);
|
||||
else
|
||||
d->formula1 = formula;
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the formulas to \a formula.
|
||||
*/
|
||||
void DataValidation::setFormula2(const QString &formula)
|
||||
{
|
||||
if (formula.startsWith(QLatin1Char('=')))
|
||||
d->formula2 = formula.mid(1);
|
||||
else
|
||||
d->formula2 = formula;
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the error message to \a error with title \a title.
|
||||
*/
|
||||
void DataValidation::setErrorMessage(const QString &error, const QString &title)
|
||||
{
|
||||
d->errorMessage = error;
|
||||
d->errorMessageTitle = title;
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the prompt message to \a prompt with title \a title.
|
||||
*/
|
||||
void DataValidation::setPromptMessage(const QString &prompt, const QString &title)
|
||||
{
|
||||
d->promptMessage = prompt;
|
||||
d->promptMessageTitle = title;
|
||||
}
|
||||
|
||||
/*!
|
||||
Enable/disabe blank allow based on \a enable.
|
||||
*/
|
||||
void DataValidation::setAllowBlank(bool enable)
|
||||
{
|
||||
d->allowBlank = enable;
|
||||
}
|
||||
|
||||
/*!
|
||||
Enable/disabe prompt message visible based on \a visible.
|
||||
*/
|
||||
void DataValidation::setPromptMessageVisible(bool visible)
|
||||
{
|
||||
d->isPromptMessageVisible = visible;
|
||||
}
|
||||
|
||||
/*!
|
||||
Enable/disabe error message visible based on \a visible.
|
||||
*/
|
||||
void DataValidation::setErrorMessageVisible(bool visible)
|
||||
{
|
||||
d->isErrorMessageVisible = visible;
|
||||
}
|
||||
|
||||
/*!
|
||||
Add the \a cell on which the DataValidation will apply to.
|
||||
*/
|
||||
void DataValidation::addCell(const CellReference &cell)
|
||||
{
|
||||
d->ranges.append(CellRange(cell, cell));
|
||||
}
|
||||
|
||||
/*!
|
||||
\overload
|
||||
Add the cell(\a row, \a col) on which the DataValidation will apply to.
|
||||
*/
|
||||
void DataValidation::addCell(int row, int col)
|
||||
{
|
||||
d->ranges.append(CellRange(row, col, row, col));
|
||||
}
|
||||
|
||||
/*!
|
||||
\overload
|
||||
Add the range(\a firstRow, \a firstCol, \a lastRow, \a lastCol) on
|
||||
which the DataValidation will apply to.
|
||||
*/
|
||||
void DataValidation::addRange(int firstRow, int firstCol, int lastRow, int lastCol)
|
||||
{
|
||||
d->ranges.append(CellRange(firstRow, firstCol, lastRow, lastCol));
|
||||
}
|
||||
|
||||
/*!
|
||||
Add the \a range on which the DataValidation will apply to.
|
||||
*/
|
||||
void DataValidation::addRange(const CellRange &range)
|
||||
{
|
||||
d->ranges.append(range);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
bool DataValidation::saveToXml(QXmlStreamWriter &writer) const
|
||||
{
|
||||
static QMap<DataValidation::ValidationType, QString> typeMap;
|
||||
static QMap<DataValidation::ValidationOperator, QString> opMap;
|
||||
static QMap<DataValidation::ErrorStyle, QString> esMap;
|
||||
if (typeMap.isEmpty()) {
|
||||
typeMap.insert(DataValidation::None, QStringLiteral("none"));
|
||||
typeMap.insert(DataValidation::Whole, QStringLiteral("whole"));
|
||||
typeMap.insert(DataValidation::Decimal, QStringLiteral("decimal"));
|
||||
typeMap.insert(DataValidation::List, QStringLiteral("list"));
|
||||
typeMap.insert(DataValidation::Date, QStringLiteral("date"));
|
||||
typeMap.insert(DataValidation::Time, QStringLiteral("time"));
|
||||
typeMap.insert(DataValidation::TextLength, QStringLiteral("textLength"));
|
||||
typeMap.insert(DataValidation::Custom, QStringLiteral("custom"));
|
||||
|
||||
opMap.insert(DataValidation::Between, QStringLiteral("between"));
|
||||
opMap.insert(DataValidation::NotBetween, QStringLiteral("notBetween"));
|
||||
opMap.insert(DataValidation::Equal, QStringLiteral("equal"));
|
||||
opMap.insert(DataValidation::NotEqual, QStringLiteral("notEqual"));
|
||||
opMap.insert(DataValidation::LessThan, QStringLiteral("lessThan"));
|
||||
opMap.insert(DataValidation::LessThanOrEqual, QStringLiteral("lessThanOrEqual"));
|
||||
opMap.insert(DataValidation::GreaterThan, QStringLiteral("greaterThan"));
|
||||
opMap.insert(DataValidation::GreaterThanOrEqual, QStringLiteral("greaterThanOrEqual"));
|
||||
|
||||
esMap.insert(DataValidation::Stop, QStringLiteral("stop"));
|
||||
esMap.insert(DataValidation::Warning, QStringLiteral("warning"));
|
||||
esMap.insert(DataValidation::Information, QStringLiteral("information"));
|
||||
}
|
||||
|
||||
writer.writeStartElement(QStringLiteral("dataValidation"));
|
||||
if (validationType() != DataValidation::None)
|
||||
writer.writeAttribute(QStringLiteral("type"), typeMap[validationType()]);
|
||||
if (errorStyle() != DataValidation::Stop)
|
||||
writer.writeAttribute(QStringLiteral("errorStyle"), esMap[errorStyle()]);
|
||||
if (validationOperator() != DataValidation::Between)
|
||||
writer.writeAttribute(QStringLiteral("operator"), opMap[validationOperator()]);
|
||||
if (allowBlank())
|
||||
writer.writeAttribute(QStringLiteral("allowBlank"), QStringLiteral("1"));
|
||||
// if (dropDownVisible())
|
||||
// writer.writeAttribute(QStringLiteral("showDropDown"), QStringLiteral("1"));
|
||||
if (isPromptMessageVisible())
|
||||
writer.writeAttribute(QStringLiteral("showInputMessage"), QStringLiteral("1"));
|
||||
if (isErrorMessageVisible())
|
||||
writer.writeAttribute(QStringLiteral("showErrorMessage"), QStringLiteral("1"));
|
||||
if (!errorMessageTitle().isEmpty())
|
||||
writer.writeAttribute(QStringLiteral("errorTitle"), errorMessageTitle());
|
||||
if (!errorMessage().isEmpty())
|
||||
writer.writeAttribute(QStringLiteral("error"), errorMessage());
|
||||
if (!promptMessageTitle().isEmpty())
|
||||
writer.writeAttribute(QStringLiteral("promptTitle"), promptMessageTitle());
|
||||
if (!promptMessage().isEmpty())
|
||||
writer.writeAttribute(QStringLiteral("prompt"), promptMessage());
|
||||
|
||||
QStringList sqref;
|
||||
foreach (CellRange range, ranges())
|
||||
sqref.append(range.toString());
|
||||
writer.writeAttribute(QStringLiteral("sqref"), sqref.join(QLatin1Char(' ')));
|
||||
|
||||
if (!formula1().isEmpty())
|
||||
writer.writeTextElement(QStringLiteral("formula1"), formula1());
|
||||
if (!formula2().isEmpty())
|
||||
writer.writeTextElement(QStringLiteral("formula2"), formula2());
|
||||
|
||||
writer.writeEndElement(); //dataValidation
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
DataValidation DataValidation::loadFromXml(QXmlStreamReader &reader)
|
||||
{
|
||||
Q_ASSERT(reader.name() == QLatin1String("dataValidation"));
|
||||
|
||||
static QMap<QString, DataValidation::ValidationType> typeMap;
|
||||
static QMap<QString, DataValidation::ValidationOperator> opMap;
|
||||
static QMap<QString, DataValidation::ErrorStyle> esMap;
|
||||
if (typeMap.isEmpty()) {
|
||||
typeMap.insert(QStringLiteral("none"), DataValidation::None);
|
||||
typeMap.insert(QStringLiteral("whole"), DataValidation::Whole);
|
||||
typeMap.insert(QStringLiteral("decimal"), DataValidation::Decimal);
|
||||
typeMap.insert(QStringLiteral("list"), DataValidation::List);
|
||||
typeMap.insert(QStringLiteral("date"), DataValidation::Date);
|
||||
typeMap.insert(QStringLiteral("time"), DataValidation::Time);
|
||||
typeMap.insert(QStringLiteral("textLength"), DataValidation::TextLength);
|
||||
typeMap.insert(QStringLiteral("custom"), DataValidation::Custom);
|
||||
|
||||
opMap.insert(QStringLiteral("between"), DataValidation::Between);
|
||||
opMap.insert(QStringLiteral("notBetween"), DataValidation::NotBetween);
|
||||
opMap.insert(QStringLiteral("equal"), DataValidation::Equal);
|
||||
opMap.insert(QStringLiteral("notEqual"), DataValidation::NotEqual);
|
||||
opMap.insert(QStringLiteral("lessThan"), DataValidation::LessThan);
|
||||
opMap.insert(QStringLiteral("lessThanOrEqual"), DataValidation::LessThanOrEqual);
|
||||
opMap.insert(QStringLiteral("greaterThan"), DataValidation::GreaterThan);
|
||||
opMap.insert(QStringLiteral("greaterThanOrEqual"), DataValidation::GreaterThanOrEqual);
|
||||
|
||||
esMap.insert(QStringLiteral("stop"), DataValidation::Stop);
|
||||
esMap.insert(QStringLiteral("warning"), DataValidation::Warning);
|
||||
esMap.insert(QStringLiteral("information"), DataValidation::Information);
|
||||
}
|
||||
|
||||
DataValidation validation;
|
||||
QXmlStreamAttributes attrs = reader.attributes();
|
||||
|
||||
QString sqref = attrs.value(QLatin1String("sqref")).toString();
|
||||
foreach (QString range, sqref.split(QLatin1Char(' ')))
|
||||
validation.addRange(range);
|
||||
|
||||
if (attrs.hasAttribute(QLatin1String("type"))) {
|
||||
QString t = attrs.value(QLatin1String("type")).toString();
|
||||
validation.setValidationType(typeMap.contains(t) ? typeMap[t] : DataValidation::None);
|
||||
}
|
||||
if (attrs.hasAttribute(QLatin1String("errorStyle"))) {
|
||||
QString es = attrs.value(QLatin1String("errorStyle")).toString();
|
||||
validation.setErrorStyle(esMap.contains(es) ? esMap[es] : DataValidation::Stop);
|
||||
}
|
||||
if (attrs.hasAttribute(QLatin1String("operator"))) {
|
||||
QString op = attrs.value(QLatin1String("operator")).toString();
|
||||
validation.setValidationOperator(opMap.contains(op) ? opMap[op] : DataValidation::Between);
|
||||
}
|
||||
if (attrs.hasAttribute(QLatin1String("allowBlank"))) {
|
||||
validation.setAllowBlank(true);
|
||||
} else {
|
||||
validation.setAllowBlank(false);
|
||||
}
|
||||
if (attrs.hasAttribute(QLatin1String("showInputMessage"))) {
|
||||
validation.setPromptMessageVisible(true);
|
||||
} else {
|
||||
validation.setPromptMessageVisible(false);
|
||||
}
|
||||
if (attrs.hasAttribute(QLatin1String("showErrorMessage"))) {
|
||||
validation.setErrorMessageVisible(true);
|
||||
} else {
|
||||
validation.setErrorMessageVisible(false);
|
||||
}
|
||||
|
||||
QString et = attrs.value(QLatin1String("errorTitle")).toString();
|
||||
QString e = attrs.value(QLatin1String("error")).toString();
|
||||
if (!e.isEmpty() || !et.isEmpty())
|
||||
validation.setErrorMessage(e, et);
|
||||
|
||||
QString pt = attrs.value(QLatin1String("promptTitle")).toString();
|
||||
QString p = attrs.value(QLatin1String("prompt")).toString();
|
||||
if (!p.isEmpty() || !pt.isEmpty())
|
||||
validation.setPromptMessage(p, pt);
|
||||
|
||||
//find the end
|
||||
while(!(reader.name() == QLatin1String("dataValidation") && reader.tokenType() == QXmlStreamReader::EndElement)) {
|
||||
reader.readNextStartElement();
|
||||
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
||||
if (reader.name() == QLatin1String("formula1")) {
|
||||
validation.setFormula1(reader.readElementText());
|
||||
} else if (reader.name() == QLatin1String("formula2")) {
|
||||
validation.setFormula2(reader.readElementText());
|
||||
}
|
||||
}
|
||||
}
|
||||
return validation;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE_XLSX
|
||||
157
platform/src/public/pub_excel/xlsx/xlsxdocpropsapp.cpp
Normal file
157
platform/src/public/pub_excel/xlsx/xlsxdocpropsapp.cpp
Normal file
@ -0,0 +1,157 @@
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2013-2014 Debao Zhang <hello@debao.me>
|
||||
** All right reserved.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining
|
||||
** a copy of this software and associated documentation files (the
|
||||
** "Software"), to deal in the Software without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Software, and to
|
||||
** permit persons to whom the Software is furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be
|
||||
** included in all copies or substantial portions of the Software.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
****************************************************************************/
|
||||
#include "xlsxdocpropsapp_p.h"
|
||||
|
||||
#include <QXmlStreamWriter>
|
||||
#include <QXmlStreamReader>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QDateTime>
|
||||
#include <QVariant>
|
||||
#include <QBuffer>
|
||||
|
||||
namespace QXlsx {
|
||||
|
||||
DocPropsApp::DocPropsApp(CreateFlag flag)
|
||||
:AbstractOOXmlFile(flag)
|
||||
{
|
||||
}
|
||||
|
||||
void DocPropsApp::addPartTitle(const QString &title)
|
||||
{
|
||||
m_titlesOfPartsList.append(title);
|
||||
}
|
||||
|
||||
void DocPropsApp::addHeadingPair(const QString &name, int value)
|
||||
{
|
||||
m_headingPairsList.append(qMakePair(name, value));
|
||||
}
|
||||
|
||||
bool DocPropsApp::setProperty(const QString &name, const QString &value)
|
||||
{
|
||||
static QStringList validKeys;
|
||||
if (validKeys.isEmpty()) {
|
||||
validKeys << QStringLiteral("manager") << QStringLiteral("company");
|
||||
}
|
||||
|
||||
if (!validKeys.contains(name))
|
||||
return false;
|
||||
|
||||
if (value.isEmpty())
|
||||
m_properties.remove(name);
|
||||
else
|
||||
m_properties[name] = value;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QString DocPropsApp::property(const QString &name) const
|
||||
{
|
||||
if (m_properties.contains(name))
|
||||
return m_properties[name];
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
QStringList DocPropsApp::propertyNames() const
|
||||
{
|
||||
return m_properties.keys();
|
||||
}
|
||||
|
||||
void DocPropsApp::saveToXmlFile(QIODevice *device) const
|
||||
{
|
||||
QXmlStreamWriter writer(device);
|
||||
QString vt = QStringLiteral("http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes");
|
||||
|
||||
writer.writeStartDocument(QStringLiteral("1.0"), true);
|
||||
writer.writeStartElement(QStringLiteral("Properties"));
|
||||
writer.writeDefaultNamespace(QStringLiteral("http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"));
|
||||
writer.writeNamespace(vt, QStringLiteral("vt"));
|
||||
writer.writeTextElement(QStringLiteral("Application"), QStringLiteral("Microsoft Excel"));
|
||||
writer.writeTextElement(QStringLiteral("DocSecurity"), QStringLiteral("0"));
|
||||
writer.writeTextElement(QStringLiteral("ScaleCrop"), QStringLiteral("false"));
|
||||
|
||||
writer.writeStartElement(QStringLiteral("HeadingPairs"));
|
||||
writer.writeStartElement(vt, QStringLiteral("vector"));
|
||||
writer.writeAttribute(QStringLiteral("size"), QString::number(m_headingPairsList.size()*2));
|
||||
writer.writeAttribute(QStringLiteral("baseType"), QStringLiteral("variant"));
|
||||
typedef QPair<QString,int> PairType; //Make foreach happy
|
||||
foreach (PairType pair, m_headingPairsList) {
|
||||
writer.writeStartElement(vt, QStringLiteral("variant"));
|
||||
writer.writeTextElement(vt, QStringLiteral("lpstr"), pair.first);
|
||||
writer.writeEndElement(); //vt:variant
|
||||
writer.writeStartElement(vt, QStringLiteral("variant"));
|
||||
writer.writeTextElement(vt, QStringLiteral("i4"), QString::number(pair.second));
|
||||
writer.writeEndElement(); //vt:variant
|
||||
}
|
||||
writer.writeEndElement();//vt:vector
|
||||
writer.writeEndElement();//HeadingPairs
|
||||
|
||||
writer.writeStartElement(QStringLiteral("TitlesOfParts"));
|
||||
writer.writeStartElement(vt, QStringLiteral("vector"));
|
||||
writer.writeAttribute(QStringLiteral("size"), QString::number(m_titlesOfPartsList.size()));
|
||||
writer.writeAttribute(QStringLiteral("baseType"), QStringLiteral("lpstr"));
|
||||
foreach (QString title, m_titlesOfPartsList)
|
||||
writer.writeTextElement(vt, QStringLiteral("lpstr"), title);
|
||||
writer.writeEndElement();//vt:vector
|
||||
writer.writeEndElement();//TitlesOfParts
|
||||
|
||||
if (m_properties.contains(QStringLiteral("manager")))
|
||||
writer.writeTextElement(QStringLiteral("Manager"), m_properties[QStringLiteral("manager")]);
|
||||
//Not like "manager", "company" always exists for Excel generated file.
|
||||
writer.writeTextElement(QStringLiteral("Company"), m_properties.contains(QStringLiteral("company")) ? m_properties[QStringLiteral("company")]: QString());
|
||||
writer.writeTextElement(QStringLiteral("LinksUpToDate"), QStringLiteral("false"));
|
||||
writer.writeTextElement(QStringLiteral("SharedDoc"), QStringLiteral("false"));
|
||||
writer.writeTextElement(QStringLiteral("HyperlinksChanged"), QStringLiteral("false"));
|
||||
writer.writeTextElement(QStringLiteral("AppVersion"), QStringLiteral("12.0000"));
|
||||
|
||||
writer.writeEndElement(); //Properties
|
||||
writer.writeEndDocument();
|
||||
}
|
||||
|
||||
bool DocPropsApp::loadFromXmlFile(QIODevice *device)
|
||||
{
|
||||
QXmlStreamReader reader(device);
|
||||
while (!reader.atEnd()) {
|
||||
QXmlStreamReader::TokenType token = reader.readNext();
|
||||
if (token == QXmlStreamReader::StartElement) {
|
||||
if (reader.name() == QLatin1String("Properties"))
|
||||
continue;
|
||||
|
||||
if (reader.name() == QStringLiteral("Manager")) {
|
||||
setProperty(QStringLiteral("manager"), reader.readElementText());
|
||||
} else if (reader.name() == QStringLiteral("Company")) {
|
||||
setProperty(QStringLiteral("company"), reader.readElementText());
|
||||
}
|
||||
}
|
||||
|
||||
if (reader.hasError()) {
|
||||
qDebug("Error when read doc props app file.");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} //namespace
|
||||
168
platform/src/public/pub_excel/xlsx/xlsxdocpropscore.cpp
Normal file
168
platform/src/public/pub_excel/xlsx/xlsxdocpropscore.cpp
Normal file
@ -0,0 +1,168 @@
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2013-2014 Debao Zhang <hello@debao.me>
|
||||
** All right reserved.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining
|
||||
** a copy of this software and associated documentation files (the
|
||||
** "Software"), to deal in the Software without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Software, and to
|
||||
** permit persons to whom the Software is furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be
|
||||
** included in all copies or substantial portions of the Software.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
****************************************************************************/
|
||||
#include "xlsxdocpropscore_p.h"
|
||||
|
||||
#include <QXmlStreamWriter>
|
||||
#include <QXmlStreamReader>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QDateTime>
|
||||
#include <QDebug>
|
||||
#include <QBuffer>
|
||||
|
||||
namespace QXlsx {
|
||||
|
||||
DocPropsCore::DocPropsCore(CreateFlag flag)
|
||||
:AbstractOOXmlFile(flag)
|
||||
{
|
||||
}
|
||||
|
||||
bool DocPropsCore::setProperty(const QString &name, const QString &value)
|
||||
{
|
||||
static QStringList validKeys;
|
||||
if (validKeys.isEmpty()) {
|
||||
validKeys << QStringLiteral("title") << QStringLiteral("subject")
|
||||
<< QStringLiteral("keywords") << QStringLiteral("description")
|
||||
<< QStringLiteral("category") << QStringLiteral("status")
|
||||
<< QStringLiteral("created") << QStringLiteral("creator");
|
||||
}
|
||||
|
||||
if (!validKeys.contains(name))
|
||||
return false;
|
||||
|
||||
if (value.isEmpty())
|
||||
m_properties.remove(name);
|
||||
else
|
||||
m_properties[name] = value;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QString DocPropsCore::property(const QString &name) const
|
||||
{
|
||||
if (m_properties.contains(name))
|
||||
return m_properties[name];
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
QStringList DocPropsCore::propertyNames() const
|
||||
{
|
||||
return m_properties.keys();
|
||||
}
|
||||
|
||||
void DocPropsCore::saveToXmlFile(QIODevice *device) const
|
||||
{
|
||||
QXmlStreamWriter writer(device);
|
||||
const QString cp = QStringLiteral("http://schemas.openxmlformats.org/package/2006/metadata/core-properties");
|
||||
const QString dc = QStringLiteral("http://purl.org/dc/elements/1.1/");
|
||||
const QString dcterms = QStringLiteral("http://purl.org/dc/terms/");
|
||||
const QString dcmitype = QStringLiteral("http://purl.org/dc/dcmitype/");
|
||||
const QString xsi = QStringLiteral("http://www.w3.org/2001/XMLSchema-instance");
|
||||
writer.writeStartDocument(QStringLiteral("1.0"), true);
|
||||
writer.writeStartElement(QStringLiteral("cp:coreProperties"));
|
||||
writer.writeNamespace(cp, QStringLiteral("cp"));
|
||||
writer.writeNamespace(dc, QStringLiteral("dc"));
|
||||
writer.writeNamespace(dcterms, QStringLiteral("dcterms"));
|
||||
writer.writeNamespace(dcmitype, QStringLiteral("dcmitype"));
|
||||
writer.writeNamespace(xsi, QStringLiteral("xsi"));
|
||||
|
||||
if (m_properties.contains(QStringLiteral("title")))
|
||||
writer.writeTextElement(dc, QStringLiteral("title"), m_properties[QStringLiteral("title")]);
|
||||
|
||||
if (m_properties.contains(QStringLiteral("subject")))
|
||||
writer.writeTextElement(dc, QStringLiteral("subject"), m_properties[QStringLiteral("subject")]);
|
||||
|
||||
writer.writeTextElement(dc, QStringLiteral("creator"), m_properties.contains(QStringLiteral("creator")) ? m_properties[QStringLiteral("creator")] : QStringLiteral("Qt Xlsx Library"));
|
||||
|
||||
if (m_properties.contains(QStringLiteral("keywords")))
|
||||
writer.writeTextElement(cp, QStringLiteral("keywords"), m_properties[QStringLiteral("keywords")]);
|
||||
|
||||
if (m_properties.contains(QStringLiteral("description")))
|
||||
writer.writeTextElement(dc, QStringLiteral("description"), m_properties[QStringLiteral("description")]);
|
||||
|
||||
writer.writeTextElement(cp, QStringLiteral("lastModifiedBy"), m_properties.contains(QStringLiteral("creator")) ? m_properties[QStringLiteral("creator")] : QStringLiteral("Qt Xlsx Library"));
|
||||
|
||||
writer.writeStartElement(dcterms, QStringLiteral("created"));
|
||||
writer.writeAttribute(xsi, QStringLiteral("type"), QStringLiteral("dcterms:W3CDTF"));
|
||||
writer.writeCharacters(m_properties.contains(QStringLiteral("created")) ? m_properties[QStringLiteral("created")] : QDateTime::currentDateTime().toString(Qt::ISODate));
|
||||
writer.writeEndElement();//dcterms:created
|
||||
|
||||
writer.writeStartElement(dcterms, QStringLiteral("modified"));
|
||||
writer.writeAttribute(xsi, QStringLiteral("type"), QStringLiteral("dcterms:W3CDTF"));
|
||||
writer.writeCharacters(QDateTime::currentDateTime().toString(Qt::ISODate));
|
||||
writer.writeEndElement();//dcterms:created
|
||||
|
||||
if (m_properties.contains(QStringLiteral("category")))
|
||||
writer.writeTextElement(cp, QStringLiteral("category"), m_properties[QStringLiteral("category")]);
|
||||
|
||||
if (m_properties.contains(QStringLiteral("status")))
|
||||
writer.writeTextElement(cp, QStringLiteral("contentStatus"), m_properties[QStringLiteral("status")]);
|
||||
|
||||
writer.writeEndElement(); //cp:coreProperties
|
||||
writer.writeEndDocument();
|
||||
}
|
||||
|
||||
bool DocPropsCore::loadFromXmlFile(QIODevice *device)
|
||||
{
|
||||
QXmlStreamReader reader(device);
|
||||
|
||||
const QString cp = QStringLiteral("http://schemas.openxmlformats.org/package/2006/metadata/core-properties");
|
||||
const QString dc = QStringLiteral("http://purl.org/dc/elements/1.1/");
|
||||
const QString dcterms = QStringLiteral("http://purl.org/dc/terms/");
|
||||
|
||||
while (!reader.atEnd()) {
|
||||
QXmlStreamReader::TokenType token = reader.readNext();
|
||||
if (token == QXmlStreamReader::StartElement) {
|
||||
const QStringRef nsUri = reader.namespaceUri();
|
||||
const QStringRef name = reader.name();
|
||||
if (name == QStringLiteral("subject") && nsUri == dc) {
|
||||
setProperty(QStringLiteral("subject"), reader.readElementText());
|
||||
} else if (name == QStringLiteral("title") && nsUri == dc) {
|
||||
setProperty(QStringLiteral("title"), reader.readElementText());
|
||||
} else if (name == QStringLiteral("creator") && nsUri == dc) {
|
||||
setProperty(QStringLiteral("creator"), reader.readElementText());
|
||||
} else if (name == QStringLiteral("description") && nsUri == dc) {
|
||||
setProperty(QStringLiteral("description"), reader.readElementText());
|
||||
} else if (name == QStringLiteral("keywords") && nsUri == cp) {
|
||||
setProperty(QStringLiteral("keywords"), reader.readElementText());
|
||||
} else if (name == QStringLiteral("created") && nsUri == dcterms) {
|
||||
setProperty(QStringLiteral("created"), reader.readElementText());
|
||||
} else if (name == QStringLiteral("category") && nsUri == cp) {
|
||||
setProperty(QStringLiteral("category"), reader.readElementText());
|
||||
} else if (name == QStringLiteral("contentStatus") && nsUri == cp) {
|
||||
setProperty(QStringLiteral("status"), reader.readElementText());
|
||||
}
|
||||
}
|
||||
|
||||
if (reader.hasError()) {
|
||||
qDebug()<<"Error when read doc props core file."<<reader.errorString();
|
||||
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} //namespace
|
||||
1046
platform/src/public/pub_excel/xlsx/xlsxdocument.cpp
Normal file
1046
platform/src/public/pub_excel/xlsx/xlsxdocument.cpp
Normal file
File diff suppressed because it is too large
Load Diff
87
platform/src/public/pub_excel/xlsx/xlsxdrawing.cpp
Normal file
87
platform/src/public/pub_excel/xlsx/xlsxdrawing.cpp
Normal file
@ -0,0 +1,87 @@
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2013-2014 Debao Zhang <hello@debao.me>
|
||||
** All right reserved.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining
|
||||
** a copy of this software and associated documentation files (the
|
||||
** "Software"), to deal in the Software without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Software, and to
|
||||
** permit persons to whom the Software is furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be
|
||||
** included in all copies or substantial portions of the Software.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "xlsxdrawing_p.h"
|
||||
#include "xlsxdrawinganchor_p.h"
|
||||
#include "xlsxabstractsheet.h"
|
||||
|
||||
#include <QXmlStreamWriter>
|
||||
#include <QXmlStreamReader>
|
||||
#include <QBuffer>
|
||||
|
||||
namespace QXlsx {
|
||||
|
||||
Drawing::Drawing(AbstractSheet *sheet, CreateFlag flag)
|
||||
:AbstractOOXmlFile(flag), sheet(sheet)
|
||||
{
|
||||
workbook = sheet->workbook();
|
||||
}
|
||||
|
||||
Drawing::~Drawing()
|
||||
{
|
||||
qDeleteAll(anchors);
|
||||
}
|
||||
|
||||
void Drawing::saveToXmlFile(QIODevice *device) const
|
||||
{
|
||||
relationships()->clear();
|
||||
|
||||
QXmlStreamWriter writer(device);
|
||||
|
||||
writer.writeStartDocument(QStringLiteral("1.0"), true);
|
||||
writer.writeStartElement(QStringLiteral("xdr:wsDr"));
|
||||
writer.writeAttribute(QStringLiteral("xmlns:xdr"), QStringLiteral("http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing"));
|
||||
writer.writeAttribute(QStringLiteral("xmlns:a"), QStringLiteral("http://schemas.openxmlformats.org/drawingml/2006/main"));
|
||||
|
||||
foreach (DrawingAnchor *anchor, anchors)
|
||||
anchor->saveToXml(writer);
|
||||
|
||||
writer.writeEndElement();//xdr:wsDr
|
||||
writer.writeEndDocument();
|
||||
}
|
||||
|
||||
bool Drawing::loadFromXmlFile(QIODevice *device)
|
||||
{
|
||||
QXmlStreamReader reader(device);
|
||||
while (!reader.atEnd()) {
|
||||
reader.readNextStartElement();
|
||||
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
||||
if (reader.name() == QLatin1String("absoluteAnchor")) {
|
||||
DrawingAbsoluteAnchor * anchor = new DrawingAbsoluteAnchor(this);
|
||||
anchor->loadFromXml(reader);
|
||||
} else if (reader.name() == QLatin1String("oneCellAnchor")) {
|
||||
DrawingOneCellAnchor * anchor = new DrawingOneCellAnchor(this);
|
||||
anchor->loadFromXml(reader);
|
||||
} else if (reader.name() == QLatin1String("twoCellAnchor")) {
|
||||
DrawingTwoCellAnchor * anchor = new DrawingTwoCellAnchor(this);
|
||||
anchor->loadFromXml(reader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace QXlsx
|
||||
529
platform/src/public/pub_excel/xlsx/xlsxdrawinganchor.cpp
Normal file
529
platform/src/public/pub_excel/xlsx/xlsxdrawinganchor.cpp
Normal file
@ -0,0 +1,529 @@
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2013-2014 Debao Zhang <hello@debao.me>
|
||||
** All right reserved.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining
|
||||
** a copy of this software and associated documentation files (the
|
||||
** "Software"), to deal in the Software without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Software, and to
|
||||
** permit persons to whom the Software is furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be
|
||||
** included in all copies or substantial portions of the Software.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "xlsxdrawinganchor_p.h"
|
||||
#include "xlsxdrawing_p.h"
|
||||
#include "xlsxmediafile_p.h"
|
||||
#include "xlsxchart.h"
|
||||
#include "xlsxworkbook.h"
|
||||
#include "xlsxutility_p.h"
|
||||
|
||||
#include <QXmlStreamReader>
|
||||
#include <QXmlStreamWriter>
|
||||
#include <QBuffer>
|
||||
#include <QDir>
|
||||
|
||||
namespace QXlsx {
|
||||
|
||||
/*
|
||||
The vertices that define the position of a graphical object
|
||||
within the worksheet in pixels.
|
||||
|
||||
+------------+------------+
|
||||
| A | B |
|
||||
+-----+------------+------------+
|
||||
| |(x1,y1) | |
|
||||
| 1 |(A1)._______|______ |
|
||||
| | | | |
|
||||
| | | | |
|
||||
+-----+----| OBJECT |-----+
|
||||
| | | | |
|
||||
| 2 | |______________. |
|
||||
| | | (B2)|
|
||||
| | | (x2,y2)|
|
||||
+---- +------------+------------+
|
||||
|
||||
Example of an object that covers some of the area from cell A1 to B2.
|
||||
|
||||
Based on the width and height of the object we need to calculate 8 vars:
|
||||
|
||||
col_start, row_start, col_end, row_end, x1, y1, x2, y2.
|
||||
|
||||
We also calculate the absolute x and y position of the top left vertex of
|
||||
the object. This is required for images.
|
||||
|
||||
The width and height of the cells that the object occupies can be
|
||||
variable and have to be taken into account.
|
||||
*/
|
||||
|
||||
//anchor
|
||||
|
||||
DrawingAnchor::DrawingAnchor(Drawing *drawing, ObjectType objectType)
|
||||
:m_drawing(drawing), m_objectType(objectType)
|
||||
{
|
||||
m_drawing->anchors.append(this);
|
||||
m_id = m_drawing->anchors.size();//must be unique in one drawing{x}.xml file.
|
||||
}
|
||||
|
||||
DrawingAnchor::~DrawingAnchor()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void DrawingAnchor::setObjectPicture(const QImage &img)
|
||||
{
|
||||
QByteArray ba;
|
||||
QBuffer buffer(&ba);
|
||||
buffer.open(QIODevice::WriteOnly);
|
||||
img.save(&buffer, "PNG");
|
||||
|
||||
m_pictureFile = QSharedPointer<MediaFile>(new MediaFile(ba, QStringLiteral("png"), QStringLiteral("image/png")));
|
||||
m_drawing->workbook->addMediaFile(m_pictureFile);
|
||||
|
||||
m_objectType = Picture;
|
||||
}
|
||||
|
||||
void DrawingAnchor::setObjectGraphicFrame(QSharedPointer<Chart> chart)
|
||||
{
|
||||
m_chartFile = chart;
|
||||
m_drawing->workbook->addChartFile(chart);
|
||||
|
||||
m_objectType = GraphicFrame;
|
||||
}
|
||||
|
||||
QPoint DrawingAnchor::loadXmlPos(QXmlStreamReader &reader)
|
||||
{
|
||||
Q_ASSERT(reader.name() == QLatin1String("pos"));
|
||||
|
||||
QPoint pos;
|
||||
QXmlStreamAttributes attrs = reader.attributes();
|
||||
pos.setX(attrs.value(QLatin1String("x")).toString().toInt());
|
||||
pos.setY(attrs.value(QLatin1String("y")).toString().toInt());
|
||||
return pos;
|
||||
}
|
||||
|
||||
QSize DrawingAnchor::loadXmlExt(QXmlStreamReader &reader)
|
||||
{
|
||||
Q_ASSERT(reader.name() == QLatin1String("ext"));
|
||||
|
||||
QSize size;
|
||||
QXmlStreamAttributes attrs = reader.attributes();
|
||||
size.setWidth(attrs.value(QLatin1String("cx")).toString().toInt());
|
||||
size.setHeight(attrs.value(QLatin1String("cy")).toString().toInt());
|
||||
return size;
|
||||
}
|
||||
|
||||
XlsxMarker DrawingAnchor::loadXmlMarker(QXmlStreamReader &reader, const QString &node)
|
||||
{
|
||||
Q_ASSERT(reader.name() == node);
|
||||
|
||||
int col = 0;
|
||||
int colOffset = 0;
|
||||
int row = 0;
|
||||
int rowOffset = 0;
|
||||
while (!reader.atEnd()) {
|
||||
reader.readNextStartElement();
|
||||
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
||||
if (reader.name() == QLatin1String("col")) {
|
||||
col = reader.readElementText().toInt();
|
||||
} else if (reader.name() == QLatin1String("colOff")) {
|
||||
colOffset = reader.readElementText().toInt();
|
||||
} else if (reader.name() == QLatin1String("row")) {
|
||||
row = reader.readElementText().toInt();
|
||||
} else if (reader.name() == QLatin1String("rowOff")) {
|
||||
rowOffset = reader.readElementText().toInt();
|
||||
}
|
||||
} else if (reader.tokenType() == QXmlStreamReader::EndElement
|
||||
&& reader.name() == node) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return XlsxMarker(row, col, rowOffset, colOffset);
|
||||
}
|
||||
|
||||
void DrawingAnchor::loadXmlObject(QXmlStreamReader &reader)
|
||||
{
|
||||
if (reader.name() == QLatin1String("sp")) {
|
||||
//Shape
|
||||
m_objectType = Shape;
|
||||
loadXmlObjectShape(reader);
|
||||
} else if (reader.name() == QLatin1String("grpSp")) {
|
||||
//Group Shape
|
||||
m_objectType = GroupShape;
|
||||
loadXmlObjectGroupShape(reader);
|
||||
} else if (reader.name() == QLatin1String("graphicFrame")) {
|
||||
//Graphic Frame
|
||||
m_objectType = GraphicFrame;
|
||||
loadXmlObjectGraphicFrame(reader);
|
||||
} else if (reader.name() == QLatin1String("cxnSp")) {
|
||||
//Connection Shape
|
||||
m_objectType = ConnectionShape;
|
||||
loadXmlObjectConnectionShape(reader);
|
||||
} else if (reader.name() == QLatin1String("pic")) {
|
||||
//Picture
|
||||
m_objectType = Picture;
|
||||
loadXmlObjectPicture(reader);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawingAnchor::loadXmlObjectConnectionShape(QXmlStreamReader &reader)
|
||||
{
|
||||
Q_UNUSED(reader)
|
||||
}
|
||||
|
||||
void DrawingAnchor::loadXmlObjectGraphicFrame(QXmlStreamReader &reader)
|
||||
{
|
||||
Q_ASSERT(reader.name() == QLatin1String("graphicFrame"));
|
||||
|
||||
while (!reader.atEnd()) {
|
||||
reader.readNextStartElement();
|
||||
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
||||
if (reader.name() == QLatin1String("chart")) {
|
||||
QString rId = reader.attributes().value(QLatin1String("r:id")).toString();
|
||||
QString name = m_drawing->relationships()->getRelationshipById(rId).target;
|
||||
QString path = QDir::cleanPath(splitPath(m_drawing->filePath())[0] + QLatin1String("/") + name);
|
||||
|
||||
bool exist = false;
|
||||
QList<QSharedPointer<Chart> > cfs = m_drawing->workbook->chartFiles();
|
||||
for (int i=0; i<cfs.size(); ++i) {
|
||||
if (cfs[i]->filePath() == path) {
|
||||
//already exist
|
||||
exist = true;
|
||||
m_chartFile = cfs[i];
|
||||
}
|
||||
}
|
||||
if (!exist) {
|
||||
m_chartFile = QSharedPointer<Chart> (new Chart(m_drawing->sheet, Chart::F_LoadFromExists));
|
||||
m_chartFile->setFilePath(path);
|
||||
m_drawing->workbook->addChartFile(m_chartFile);
|
||||
}
|
||||
}
|
||||
} else if (reader.tokenType() == QXmlStreamReader::EndElement
|
||||
&& reader.name() == QLatin1String("graphicFrame")) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void DrawingAnchor::loadXmlObjectGroupShape(QXmlStreamReader &reader)
|
||||
{
|
||||
Q_UNUSED(reader)
|
||||
}
|
||||
|
||||
void DrawingAnchor::loadXmlObjectPicture(QXmlStreamReader &reader)
|
||||
{
|
||||
Q_ASSERT(reader.name() == QLatin1String("pic"));
|
||||
|
||||
while (!reader.atEnd()) {
|
||||
reader.readNextStartElement();
|
||||
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
||||
if (reader.name() == QLatin1String("blip")) {
|
||||
QString rId = reader.attributes().value(QLatin1String("r:embed")).toString();
|
||||
QString name = m_drawing->relationships()->getRelationshipById(rId).target;
|
||||
QString path = QDir::cleanPath(splitPath(m_drawing->filePath())[0] + QLatin1String("/") + name);
|
||||
|
||||
bool exist = false;
|
||||
QList<QSharedPointer<MediaFile> > mfs = m_drawing->workbook->mediaFiles();
|
||||
for (int i=0; i<mfs.size(); ++i) {
|
||||
if (mfs[i]->fileName() == path) {
|
||||
//already exist
|
||||
exist = true;
|
||||
m_pictureFile = mfs[i];
|
||||
}
|
||||
}
|
||||
if (!exist) {
|
||||
m_pictureFile = QSharedPointer<MediaFile> (new MediaFile(path));
|
||||
m_drawing->workbook->addMediaFile(m_pictureFile, true);
|
||||
}
|
||||
}
|
||||
} else if (reader.tokenType() == QXmlStreamReader::EndElement
|
||||
&& reader.name() == QLatin1String("pic")) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void DrawingAnchor::loadXmlObjectShape(QXmlStreamReader &reader)
|
||||
{
|
||||
Q_UNUSED(reader)
|
||||
}
|
||||
|
||||
void DrawingAnchor::saveXmlPos(QXmlStreamWriter &writer, const QPoint &pos) const
|
||||
{
|
||||
writer.writeEmptyElement(QStringLiteral("xdr:pos"));
|
||||
writer.writeAttribute(QStringLiteral("x"), QString::number(pos.x()));
|
||||
writer.writeAttribute(QStringLiteral("y"), QString::number(pos.y()));
|
||||
}
|
||||
|
||||
void DrawingAnchor::saveXmlExt(QXmlStreamWriter &writer, const QSize &ext) const
|
||||
{
|
||||
writer.writeStartElement(QStringLiteral("xdr:ext"));
|
||||
writer.writeAttribute(QStringLiteral("cx"), QString::number(ext.width()));
|
||||
writer.writeAttribute(QStringLiteral("cy"), QString::number(ext.height()));
|
||||
writer.writeEndElement(); //xdr:ext
|
||||
}
|
||||
|
||||
void DrawingAnchor::saveXmlMarker(QXmlStreamWriter &writer, const XlsxMarker &marker, const QString &node) const
|
||||
{
|
||||
writer.writeStartElement(node); //xdr:from or xdr:to
|
||||
writer.writeTextElement(QStringLiteral("xdr:col"), QString::number(marker.col()));
|
||||
writer.writeTextElement(QStringLiteral("xdr:colOff"), QString::number(marker.colOff()));
|
||||
writer.writeTextElement(QStringLiteral("xdr:row"), QString::number(marker.row()));
|
||||
writer.writeTextElement(QStringLiteral("xdr:rowOff"), QString::number(marker.rowOff()));
|
||||
writer.writeEndElement();
|
||||
}
|
||||
|
||||
void DrawingAnchor::saveXmlObject(QXmlStreamWriter &writer) const
|
||||
{
|
||||
if (m_objectType == Picture)
|
||||
saveXmlObjectPicture(writer);
|
||||
else if (m_objectType == ConnectionShape)
|
||||
saveXmlObjectConnectionShape(writer);
|
||||
else if (m_objectType == GraphicFrame)
|
||||
saveXmlObjectGraphicFrame(writer);
|
||||
else if (m_objectType == GroupShape)
|
||||
saveXmlObjectGroupShape(writer);
|
||||
else if (m_objectType == Shape)
|
||||
saveXmlObjectShape(writer);
|
||||
}
|
||||
|
||||
void DrawingAnchor::saveXmlObjectConnectionShape(QXmlStreamWriter &writer) const
|
||||
{
|
||||
Q_UNUSED(writer)
|
||||
}
|
||||
|
||||
void DrawingAnchor::saveXmlObjectGraphicFrame(QXmlStreamWriter &writer) const
|
||||
{
|
||||
writer.writeStartElement(QStringLiteral("xdr:graphicFrame"));
|
||||
writer.writeAttribute(QStringLiteral("macro"), QString());
|
||||
|
||||
writer.writeStartElement(QStringLiteral("xdr:nvGraphicFramePr"));
|
||||
writer.writeEmptyElement(QStringLiteral("xdr:cNvPr"));
|
||||
writer.writeAttribute(QStringLiteral("id"), QString::number(m_id));
|
||||
writer.writeAttribute(QStringLiteral("name"),QStringLiteral("Chart %1").arg(m_id));
|
||||
writer.writeEmptyElement(QStringLiteral("xdr:cNvGraphicFramePr"));
|
||||
writer.writeEndElement();//xdr:nvGraphicFramePr
|
||||
|
||||
writer.writeStartElement(QStringLiteral("xdr:xfrm"));
|
||||
writer.writeEndElement(); //xdr:xfrm
|
||||
|
||||
writer.writeStartElement(QStringLiteral("a:graphic"));
|
||||
writer.writeStartElement(QStringLiteral("a:graphicData"));
|
||||
writer.writeAttribute(QStringLiteral("uri"), QStringLiteral("http://schemas.openxmlformats.org/drawingml/2006/chart"));
|
||||
|
||||
int idx = m_drawing->workbook->chartFiles().indexOf(m_chartFile);
|
||||
m_drawing->relationships()->addDocumentRelationship(QStringLiteral("/chart"), QStringLiteral("../charts/chart%1.xml").arg(idx+1));
|
||||
|
||||
writer.writeEmptyElement(QStringLiteral("c:chart"));
|
||||
writer.writeAttribute(QStringLiteral("xmlns:c"), QStringLiteral("http://schemas.openxmlformats.org/drawingml/2006/chart"));
|
||||
writer.writeAttribute(QStringLiteral("xmlns:r"), QStringLiteral("http://schemas.openxmlformats.org/officeDocument/2006/relationships"));
|
||||
writer.writeAttribute(QStringLiteral("r:id"), QStringLiteral("rId%1").arg(m_drawing->relationships()->count()));
|
||||
|
||||
writer.writeEndElement(); //a:graphicData
|
||||
writer.writeEndElement(); //a:graphic
|
||||
writer.writeEndElement(); //xdr:graphicFrame
|
||||
}
|
||||
|
||||
void DrawingAnchor::saveXmlObjectGroupShape(QXmlStreamWriter &writer) const
|
||||
{
|
||||
Q_UNUSED(writer)
|
||||
}
|
||||
|
||||
void DrawingAnchor::saveXmlObjectPicture(QXmlStreamWriter &writer) const
|
||||
{
|
||||
Q_ASSERT(m_objectType == Picture && !m_pictureFile.isNull());
|
||||
|
||||
writer.writeStartElement(QStringLiteral("xdr:pic"));
|
||||
|
||||
writer.writeStartElement(QStringLiteral("xdr:nvPicPr"));
|
||||
writer.writeEmptyElement(QStringLiteral("xdr:cNvPr"));
|
||||
writer.writeAttribute(QStringLiteral("id"), QString::number(m_id));
|
||||
writer.writeAttribute(QStringLiteral("name"), QStringLiteral("Picture %1").arg(m_id));
|
||||
|
||||
writer.writeStartElement(QStringLiteral("xdr:cNvPicPr"));
|
||||
writer.writeEmptyElement(QStringLiteral("a:picLocks"));
|
||||
writer.writeAttribute(QStringLiteral("noChangeAspect"), QStringLiteral("1"));
|
||||
writer.writeEndElement(); //xdr:cNvPicPr
|
||||
|
||||
writer.writeEndElement(); //xdr:nvPicPr
|
||||
|
||||
m_drawing->relationships()->addDocumentRelationship(QStringLiteral("/image"), QStringLiteral("../media/image%1.%2")
|
||||
.arg(m_pictureFile->index()+1)
|
||||
.arg(m_pictureFile->suffix()));
|
||||
|
||||
writer.writeStartElement(QStringLiteral("xdr:blipFill"));
|
||||
writer.writeEmptyElement(QStringLiteral("a:blip"));
|
||||
writer.writeAttribute(QStringLiteral("xmlns:r"), QStringLiteral("http://schemas.openxmlformats.org/officeDocument/2006/relationships"));
|
||||
writer.writeAttribute(QStringLiteral("r:embed"), QStringLiteral("rId%1").arg(m_drawing->relationships()->count()));
|
||||
writer.writeStartElement(QStringLiteral("a:stretch"));
|
||||
writer.writeEmptyElement(QStringLiteral("a:fillRect"));
|
||||
writer.writeEndElement(); //a:stretch
|
||||
writer.writeEndElement();//xdr:blipFill
|
||||
|
||||
writer.writeStartElement(QStringLiteral("xdr:spPr"));
|
||||
|
||||
writer.writeStartElement(QStringLiteral("a:prstGeom"));
|
||||
writer.writeAttribute(QStringLiteral("prst"), QStringLiteral("rect"));
|
||||
writer.writeEmptyElement(QStringLiteral("a:avLst"));
|
||||
writer.writeEndElement(); //a:prstGeom
|
||||
|
||||
writer.writeEndElement(); //xdr:spPr
|
||||
|
||||
writer.writeEndElement(); //xdr:pic
|
||||
}
|
||||
|
||||
void DrawingAnchor::saveXmlObjectShape(QXmlStreamWriter &writer) const
|
||||
{
|
||||
Q_UNUSED(writer)
|
||||
}
|
||||
|
||||
//absolute anchor
|
||||
|
||||
DrawingAbsoluteAnchor::DrawingAbsoluteAnchor(Drawing *drawing, ObjectType objectType)
|
||||
:DrawingAnchor(drawing, objectType)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool DrawingAbsoluteAnchor::loadFromXml(QXmlStreamReader &reader)
|
||||
{
|
||||
Q_ASSERT(reader.name() == QLatin1String("absoluteAnchor"));
|
||||
|
||||
while (!reader.atEnd()) {
|
||||
reader.readNextStartElement();
|
||||
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
||||
if (reader.name() == QLatin1String("pos")) {
|
||||
pos = loadXmlPos(reader);
|
||||
} else if (reader.name() == QLatin1String("ext")) {
|
||||
ext = loadXmlExt(reader);
|
||||
} else {
|
||||
loadXmlObject(reader);
|
||||
}
|
||||
} else if (reader.tokenType() == QXmlStreamReader::EndElement
|
||||
&& reader.name() == QLatin1String("absoluteAnchor")) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void DrawingAbsoluteAnchor::saveToXml(QXmlStreamWriter &writer) const
|
||||
{
|
||||
writer.writeStartElement(QStringLiteral("xdr:absoluteAnchor"));
|
||||
saveXmlPos(writer, pos);
|
||||
saveXmlExt(writer, ext);
|
||||
|
||||
saveXmlObject(writer);
|
||||
|
||||
writer.writeEmptyElement(QStringLiteral("xdr:clientData"));
|
||||
writer.writeEndElement(); //xdr:absoluteAnchor
|
||||
}
|
||||
|
||||
//one cell anchor
|
||||
|
||||
DrawingOneCellAnchor::DrawingOneCellAnchor(Drawing *drawing, ObjectType objectType)
|
||||
:DrawingAnchor(drawing, objectType)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool DrawingOneCellAnchor::loadFromXml(QXmlStreamReader &reader)
|
||||
{
|
||||
Q_ASSERT(reader.name() == QLatin1String("oneCellAnchor"));
|
||||
while (!reader.atEnd()) {
|
||||
reader.readNextStartElement();
|
||||
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
||||
if (reader.name() == QLatin1String("from")) {
|
||||
from = loadXmlMarker(reader, QLatin1String("from"));
|
||||
} else if (reader.name() == QLatin1String("ext")) {
|
||||
ext = loadXmlExt(reader);
|
||||
} else {
|
||||
loadXmlObject(reader);
|
||||
}
|
||||
} else if (reader.tokenType() == QXmlStreamReader::EndElement
|
||||
&& reader.name() == QLatin1String("oneCellAnchor")) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void DrawingOneCellAnchor::saveToXml(QXmlStreamWriter &writer) const
|
||||
{
|
||||
writer.writeStartElement(QStringLiteral("xdr:oneCellAnchor"));
|
||||
|
||||
saveXmlMarker(writer, from, QStringLiteral("xdr:from"));
|
||||
saveXmlExt(writer, ext);
|
||||
|
||||
saveXmlObject(writer);
|
||||
|
||||
writer.writeEmptyElement(QStringLiteral("xdr:clientData"));
|
||||
writer.writeEndElement(); //xdr:oneCellAnchor
|
||||
}
|
||||
|
||||
/*
|
||||
Two cell anchor
|
||||
|
||||
This class specifies a two cell anchor placeholder for a group
|
||||
, a shape, or a drawing element. It moves with
|
||||
cells and its extents are in EMU units.
|
||||
*/
|
||||
DrawingTwoCellAnchor::DrawingTwoCellAnchor(Drawing *drawing, ObjectType objectType)
|
||||
:DrawingAnchor(drawing, objectType)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool DrawingTwoCellAnchor::loadFromXml(QXmlStreamReader &reader)
|
||||
{
|
||||
Q_ASSERT(reader.name() == QLatin1String("twoCellAnchor"));
|
||||
while (!reader.atEnd()) {
|
||||
reader.readNextStartElement();
|
||||
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
||||
if (reader.name() == QLatin1String("from")) {
|
||||
from = loadXmlMarker(reader, QLatin1String("from"));
|
||||
} else if (reader.name() == QLatin1String("to")) {
|
||||
to = loadXmlMarker(reader, QLatin1String("to"));
|
||||
} else {
|
||||
loadXmlObject(reader);
|
||||
}
|
||||
} else if (reader.tokenType() == QXmlStreamReader::EndElement
|
||||
&& reader.name() == QLatin1String("twoCellAnchor")) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void DrawingTwoCellAnchor::saveToXml(QXmlStreamWriter &writer) const
|
||||
{
|
||||
writer.writeStartElement(QStringLiteral("xdr:twoCellAnchor"));
|
||||
writer.writeAttribute(QStringLiteral("editAs"), QStringLiteral("oneCell"));
|
||||
|
||||
saveXmlMarker(writer, from, QStringLiteral("xdr:from"));
|
||||
saveXmlMarker(writer, to, QStringLiteral("xdr:to"));
|
||||
|
||||
saveXmlObject(writer);
|
||||
|
||||
writer.writeEmptyElement(QStringLiteral("xdr:clientData"));
|
||||
writer.writeEndElement(); //xdr:twoCellAnchor
|
||||
}
|
||||
|
||||
} // namespace QXlsx
|
||||
1432
platform/src/public/pub_excel/xlsx/xlsxformat.cpp
Normal file
1432
platform/src/public/pub_excel/xlsx/xlsxformat.cpp
Normal file
File diff suppressed because it is too large
Load Diff
99
platform/src/public/pub_excel/xlsx/xlsxmediafile.cpp
Normal file
99
platform/src/public/pub_excel/xlsx/xlsxmediafile.cpp
Normal file
@ -0,0 +1,99 @@
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2013-2014 Debao Zhang <hello@debao.me>
|
||||
** All right reserved.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining
|
||||
** a copy of this software and associated documentation files (the
|
||||
** "Software"), to deal in the Software without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Software, and to
|
||||
** permit persons to whom the Software is furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be
|
||||
** included in all copies or substantial portions of the Software.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "xlsxmediafile_p.h"
|
||||
#include <QCryptographicHash>
|
||||
|
||||
namespace QXlsx {
|
||||
|
||||
MediaFile::MediaFile(const QByteArray &bytes, const QString &suffix, const QString &mimeType)
|
||||
: m_contents(bytes), m_suffix(suffix), m_mimeType(mimeType)
|
||||
, m_index(0), m_indexValid(false)
|
||||
{
|
||||
m_hashKey = QCryptographicHash::hash(m_contents, QCryptographicHash::Md5);
|
||||
}
|
||||
|
||||
MediaFile::MediaFile(const QString &fileName)
|
||||
:m_fileName(fileName), m_index(0), m_indexValid(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void MediaFile::set(const QByteArray &bytes, const QString &suffix, const QString &mimeType)
|
||||
{
|
||||
m_contents = bytes;
|
||||
m_suffix = suffix;
|
||||
m_mimeType = mimeType;
|
||||
m_hashKey = QCryptographicHash::hash(m_contents, QCryptographicHash::Md5);
|
||||
m_indexValid = false;
|
||||
}
|
||||
|
||||
void MediaFile::setFileName(const QString &name)
|
||||
{
|
||||
m_fileName = name;
|
||||
}
|
||||
|
||||
QString MediaFile::fileName() const
|
||||
{
|
||||
return m_fileName;
|
||||
}
|
||||
|
||||
QString MediaFile::suffix() const
|
||||
{
|
||||
return m_suffix;
|
||||
}
|
||||
|
||||
QString MediaFile::mimeType() const
|
||||
{
|
||||
return m_mimeType;
|
||||
}
|
||||
|
||||
QByteArray MediaFile::contents() const
|
||||
{
|
||||
return m_contents;
|
||||
}
|
||||
|
||||
int MediaFile::index() const
|
||||
{
|
||||
return m_index;
|
||||
}
|
||||
|
||||
bool MediaFile::isIndexValid() const
|
||||
{
|
||||
return m_indexValid;
|
||||
}
|
||||
|
||||
void MediaFile::setIndex(int idx)
|
||||
{
|
||||
m_index = idx;
|
||||
m_indexValid = true;
|
||||
}
|
||||
|
||||
QByteArray MediaFile::hashKey() const
|
||||
{
|
||||
return m_hashKey;
|
||||
}
|
||||
|
||||
} // namespace QXlsx
|
||||
94
platform/src/public/pub_excel/xlsx/xlsxnumformatparser.cpp
Normal file
94
platform/src/public/pub_excel/xlsx/xlsxnumformatparser.cpp
Normal file
@ -0,0 +1,94 @@
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2013-2014 Debao Zhang <hello@debao.me>
|
||||
** All right reserved.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining
|
||||
** a copy of this software and associated documentation files (the
|
||||
** "Software"), to deal in the Software without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Software, and to
|
||||
** permit persons to whom the Software is furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be
|
||||
** included in all copies or substantial portions of the Software.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
****************************************************************************/
|
||||
#include "xlsxnumformatparser_p.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
namespace QXlsx {
|
||||
|
||||
bool NumFormatParser::isDateTime(const QString &formatCode)
|
||||
{
|
||||
for (int i = 0; i < formatCode.length(); ++i) {
|
||||
const QChar &c = formatCode[i];
|
||||
|
||||
switch (c.unicode()) {
|
||||
case '[':
|
||||
// [h], [m], [s] are valid format for time
|
||||
if (i < formatCode.length()-2 && formatCode[i+2] == QLatin1Char(']')) {
|
||||
const QChar cc = formatCode[i+1].toLower();
|
||||
if (cc == QLatin1Char('h') || cc == QLatin1Char('m') || cc == QLatin1Char('s'))
|
||||
return true;
|
||||
i+=2;
|
||||
break;
|
||||
} else {
|
||||
// condition or color: don't care, ignore
|
||||
while (i < formatCode.length() && formatCode[i] != QLatin1Char(']'))
|
||||
++i;
|
||||
break;
|
||||
}
|
||||
|
||||
// quoted plain text block: don't care, ignore
|
||||
case '"':
|
||||
while (i < formatCode.length()-1 && formatCode[++i] != QLatin1Char('"'))
|
||||
;
|
||||
break;
|
||||
|
||||
// escaped char: don't care, ignore
|
||||
case '\\':
|
||||
if (i < formatCode.length() - 1)
|
||||
++i;
|
||||
break;
|
||||
|
||||
// date/time can only be positive number,
|
||||
// so only the first section of the format make sense.
|
||||
case ';':
|
||||
return false;
|
||||
break;
|
||||
|
||||
// days
|
||||
case 'D':
|
||||
case 'd':
|
||||
// years
|
||||
case 'Y':
|
||||
case 'y':
|
||||
// hours
|
||||
case 'H':
|
||||
case 'h':
|
||||
// seconds
|
||||
case 'S':
|
||||
case 's':
|
||||
// minutes or months, depending on context
|
||||
case 'M':
|
||||
case 'm':
|
||||
return true;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace QXlsx
|
||||
189
platform/src/public/pub_excel/xlsx/xlsxrelationships.cpp
Normal file
189
platform/src/public/pub_excel/xlsx/xlsxrelationships.cpp
Normal file
@ -0,0 +1,189 @@
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2013-2014 Debao Zhang <hello@debao.me>
|
||||
** All right reserved.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining
|
||||
** a copy of this software and associated documentation files (the
|
||||
** "Software"), to deal in the Software without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Software, and to
|
||||
** permit persons to whom the Software is furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be
|
||||
** included in all copies or substantial portions of the Software.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
****************************************************************************/
|
||||
#include "xlsxrelationships_p.h"
|
||||
#include <QXmlStreamWriter>
|
||||
#include <QXmlStreamReader>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QBuffer>
|
||||
|
||||
namespace QXlsx {
|
||||
|
||||
const QString schema_doc = QStringLiteral("http://schemas.openxmlformats.org/officeDocument/2006/relationships");
|
||||
const QString schema_msPackage = QStringLiteral("http://schemas.microsoft.com/office/2006/relationships");
|
||||
const QString schema_package = QStringLiteral("http://schemas.openxmlformats.org/package/2006/relationships");
|
||||
//const QString schema_worksheet = QStringLiteral("http://schemas.openxmlformats.org/officeDocument/2006/relationships");
|
||||
Relationships::Relationships()
|
||||
{
|
||||
}
|
||||
|
||||
QList<XlsxRelationship> Relationships::documentRelationships(const QString &relativeType) const
|
||||
{
|
||||
return relationships(schema_doc + relativeType);
|
||||
}
|
||||
|
||||
void Relationships::addDocumentRelationship(const QString &relativeType, const QString &target)
|
||||
{
|
||||
addRelationship(schema_doc + relativeType, target);
|
||||
}
|
||||
|
||||
QList<XlsxRelationship> Relationships::msPackageRelationships(const QString &relativeType) const
|
||||
{
|
||||
return relationships(schema_msPackage + relativeType);
|
||||
}
|
||||
|
||||
void Relationships::addMsPackageRelationship(const QString &relativeType, const QString &target)
|
||||
{
|
||||
addRelationship(schema_msPackage + relativeType, target);
|
||||
}
|
||||
|
||||
QList<XlsxRelationship> Relationships::packageRelationships(const QString &relativeType) const
|
||||
{
|
||||
return relationships(schema_package + relativeType);
|
||||
}
|
||||
|
||||
void Relationships::addPackageRelationship(const QString &relativeType, const QString &target)
|
||||
{
|
||||
addRelationship(schema_package + relativeType, target);
|
||||
}
|
||||
|
||||
QList<XlsxRelationship> Relationships::worksheetRelationships(const QString &relativeType) const
|
||||
{
|
||||
return relationships(schema_doc + relativeType);
|
||||
}
|
||||
|
||||
void Relationships::addWorksheetRelationship(const QString &relativeType, const QString &target, const QString &targetMode)
|
||||
{
|
||||
addRelationship(schema_doc + relativeType, target, targetMode);
|
||||
}
|
||||
|
||||
QList<XlsxRelationship> Relationships::relationships(const QString &type) const
|
||||
{
|
||||
QList<XlsxRelationship> res;
|
||||
foreach (XlsxRelationship ship, m_relationships) {
|
||||
if (ship.type == type)
|
||||
res.append(ship);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void Relationships::addRelationship(const QString &type, const QString &target, const QString &targetMode)
|
||||
{
|
||||
XlsxRelationship relation;
|
||||
relation.id = QStringLiteral("rId%1").arg(m_relationships.size()+1);
|
||||
relation.type = type;
|
||||
relation.target = target;
|
||||
relation.targetMode = targetMode;
|
||||
|
||||
m_relationships.append(relation);
|
||||
}
|
||||
|
||||
void Relationships::saveToXmlFile(QIODevice *device) const
|
||||
{
|
||||
QXmlStreamWriter writer(device);
|
||||
|
||||
writer.writeStartDocument(QStringLiteral("1.0"), true);
|
||||
writer.writeStartElement(QStringLiteral("Relationships"));
|
||||
writer.writeAttribute(QStringLiteral("xmlns"), QStringLiteral("http://schemas.openxmlformats.org/package/2006/relationships"));
|
||||
foreach (XlsxRelationship relation, m_relationships) {
|
||||
writer.writeStartElement(QStringLiteral("Relationship"));
|
||||
writer.writeAttribute(QStringLiteral("Id"), relation.id);
|
||||
writer.writeAttribute(QStringLiteral("Type"), relation.type);
|
||||
writer.writeAttribute(QStringLiteral("Target"), relation.target);
|
||||
if (!relation.targetMode.isNull())
|
||||
writer.writeAttribute(QStringLiteral("TargetMode"), relation.targetMode);
|
||||
writer.writeEndElement();
|
||||
}
|
||||
writer.writeEndElement();//Relationships
|
||||
writer.writeEndDocument();
|
||||
}
|
||||
|
||||
QByteArray Relationships::saveToXmlData() const
|
||||
{
|
||||
QByteArray data;
|
||||
QBuffer buffer(&data);
|
||||
buffer.open(QIODevice::WriteOnly);
|
||||
saveToXmlFile(&buffer);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
bool Relationships::loadFromXmlFile(QIODevice *device)
|
||||
{
|
||||
clear();
|
||||
QXmlStreamReader reader(device);
|
||||
while (!reader.atEnd()) {
|
||||
QXmlStreamReader::TokenType token = reader.readNext();
|
||||
if (token == QXmlStreamReader::StartElement) {
|
||||
if (reader.name() == QStringLiteral("Relationship")) {
|
||||
QXmlStreamAttributes attributes = reader.attributes();
|
||||
XlsxRelationship relationship;
|
||||
relationship.id = attributes.value(QLatin1String("Id")).toString();
|
||||
relationship.type = attributes.value(QLatin1String("Type")).toString();
|
||||
relationship.target = attributes.value(QLatin1String("Target")).toString();
|
||||
relationship.targetMode = attributes.value(QLatin1String("TargetMode")).toString();
|
||||
m_relationships.append(relationship);
|
||||
}
|
||||
}
|
||||
|
||||
if (reader.hasError())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Relationships::loadFromXmlData(const QByteArray &data)
|
||||
{
|
||||
QBuffer buffer;
|
||||
buffer.setData(data);
|
||||
buffer.open(QIODevice::ReadOnly);
|
||||
return loadFromXmlFile(&buffer);
|
||||
}
|
||||
|
||||
XlsxRelationship Relationships::getRelationshipById(const QString &id) const
|
||||
{
|
||||
foreach (XlsxRelationship ship, m_relationships) {
|
||||
if (ship.id == id)
|
||||
return ship;
|
||||
}
|
||||
return XlsxRelationship();
|
||||
}
|
||||
|
||||
void Relationships::clear()
|
||||
{
|
||||
m_relationships.clear();
|
||||
}
|
||||
|
||||
int Relationships::count() const
|
||||
{
|
||||
return m_relationships.count();
|
||||
}
|
||||
|
||||
bool Relationships::isEmpty() const
|
||||
{
|
||||
return m_relationships.isEmpty();
|
||||
}
|
||||
|
||||
} //namespace
|
||||
343
platform/src/public/pub_excel/xlsx/xlsxrichstring.cpp
Normal file
343
platform/src/public/pub_excel/xlsx/xlsxrichstring.cpp
Normal file
@ -0,0 +1,343 @@
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2013-2014 Debao Zhang <hello@debao.me>
|
||||
** All right reserved.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining
|
||||
** a copy of this software and associated documentation files (the
|
||||
** "Software"), to deal in the Software without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Software, and to
|
||||
** permit persons to whom the Software is furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be
|
||||
** included in all copies or substantial portions of the Software.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
****************************************************************************/
|
||||
#include "xlsxrichstring.h"
|
||||
#include "xlsxrichstring_p.h"
|
||||
#include "xlsxformat_p.h"
|
||||
#include <QDebug>
|
||||
#include <QTextDocument>
|
||||
#include <QTextFragment>
|
||||
|
||||
QT_BEGIN_NAMESPACE_XLSX
|
||||
|
||||
RichStringPrivate::RichStringPrivate()
|
||||
:_dirty(true)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
RichStringPrivate::RichStringPrivate(const RichStringPrivate &other)
|
||||
:QSharedData(other), fragmentTexts(other.fragmentTexts)
|
||||
,fragmentFormats(other.fragmentFormats)
|
||||
, _idKey(other.idKey()), _dirty(other._dirty)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
RichStringPrivate::~RichStringPrivate()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
\class RichString
|
||||
\inmodule QtXlsx
|
||||
\brief This class add support for the rich text string of the cell.
|
||||
*/
|
||||
|
||||
/*!
|
||||
Constructs a null string.
|
||||
*/
|
||||
RichString::RichString()
|
||||
:d(new RichStringPrivate)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
Constructs a plain string with the given \a text.
|
||||
*/
|
||||
RichString::RichString(const QString text)
|
||||
:d(new RichStringPrivate)
|
||||
{
|
||||
addFragment(text, Format());
|
||||
}
|
||||
|
||||
/*!
|
||||
Constructs a copy of \a other.
|
||||
*/
|
||||
RichString::RichString(const RichString &other)
|
||||
:d(other.d)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
Destructs the string.
|
||||
*/
|
||||
RichString::~RichString()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
Assigns \a other to this string and returns a reference to this string
|
||||
*/
|
||||
RichString &RichString::operator =(const RichString &other)
|
||||
{
|
||||
this->d = other.d;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the rich string as a QVariant
|
||||
*/
|
||||
RichString::operator QVariant() const
|
||||
{
|
||||
return QVariant(qMetaTypeId<RichString>(), this);
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns true if this is rich text string.
|
||||
*/
|
||||
bool RichString::isRichString() const
|
||||
{
|
||||
if (fragmentCount() > 1) //Is this enough??
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns true is this is an Null string.
|
||||
*/
|
||||
bool RichString::isNull() const
|
||||
{
|
||||
return d->fragmentTexts.size() == 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns true is this is an empty string.
|
||||
*/
|
||||
bool RichString::isEmtpy() const
|
||||
{
|
||||
foreach (const QString str, d->fragmentTexts) {
|
||||
if (!str.isEmpty())
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
Converts to plain text string.
|
||||
*/
|
||||
QString RichString::toPlainString() const
|
||||
{
|
||||
if (isEmtpy())
|
||||
return QString();
|
||||
if (d->fragmentTexts.size() == 1)
|
||||
return d->fragmentTexts[0];
|
||||
|
||||
return d->fragmentTexts.join(QString());
|
||||
}
|
||||
|
||||
/*!
|
||||
Converts to html string
|
||||
*/
|
||||
QString RichString::toHtml() const
|
||||
{
|
||||
//: Todo
|
||||
return QString();
|
||||
}
|
||||
|
||||
/*!
|
||||
Replaces the entire contents of the document
|
||||
with the given HTML-formatted text in the \a text string
|
||||
*/
|
||||
void RichString::setHtml(const QString &text)
|
||||
{
|
||||
QTextDocument doc;
|
||||
doc.setHtml(text);
|
||||
QTextBlock block = doc.firstBlock();
|
||||
QTextBlock::iterator it;
|
||||
for (it = block.begin(); !(it.atEnd()); ++it) {
|
||||
QTextFragment textFragment = it.fragment();
|
||||
if (textFragment.isValid()) {
|
||||
Format fmt;
|
||||
fmt.setFont(textFragment.charFormat().font());
|
||||
fmt.setFontColor(textFragment.charFormat().foreground().color());
|
||||
addFragment(textFragment.text(), fmt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns fragment count.
|
||||
*/
|
||||
int RichString::fragmentCount() const
|
||||
{
|
||||
return d->fragmentTexts.size();
|
||||
}
|
||||
|
||||
/*!
|
||||
Appends a fragment with the given \a text and \a format.
|
||||
*/
|
||||
void RichString::addFragment(const QString &text, const Format &format)
|
||||
{
|
||||
d->fragmentTexts.append(text);
|
||||
d->fragmentFormats.append(format);
|
||||
d->_dirty = true;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns fragment text at the position \a index.
|
||||
*/
|
||||
QString RichString::fragmentText(int index) const
|
||||
{
|
||||
if (index < 0 || index >= fragmentCount())
|
||||
return QString();
|
||||
|
||||
return d->fragmentTexts[index];
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns fragment format at the position \a index.
|
||||
*/
|
||||
Format RichString::fragmentFormat(int index) const
|
||||
{
|
||||
if (index < 0 || index >= fragmentCount())
|
||||
return Format();
|
||||
|
||||
return d->fragmentFormats[index];
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
QByteArray RichStringPrivate::idKey() const
|
||||
{
|
||||
if (_dirty) {
|
||||
RichStringPrivate *rs = const_cast<RichStringPrivate *>(this);
|
||||
QByteArray bytes;
|
||||
if (fragmentTexts.size() == 1) {
|
||||
bytes = fragmentTexts[0].toUtf8();
|
||||
} else {
|
||||
//Generate a hash value base on QByteArray ?
|
||||
bytes.append("@@QtXlsxRichString=");
|
||||
for (int i=0; i<fragmentTexts.size(); ++i) {
|
||||
bytes.append("@Text");
|
||||
bytes.append(fragmentTexts[i].toUtf8());
|
||||
bytes.append("@Format");
|
||||
if (fragmentFormats[i].hasFontData())
|
||||
bytes.append(fragmentFormats[i].fontKey());
|
||||
}
|
||||
}
|
||||
rs->_idKey = bytes;
|
||||
rs->_dirty = false;
|
||||
}
|
||||
|
||||
return _idKey;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns true if this string \a rs1 is equal to string \a rs2;
|
||||
otherwise returns false.
|
||||
*/
|
||||
bool operator==(const RichString &rs1, const RichString &rs2)
|
||||
{
|
||||
if (rs1.fragmentCount() != rs2.fragmentCount())
|
||||
return false;
|
||||
|
||||
return rs1.d->idKey() == rs2.d->idKey();
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns true if this string \a rs1 is not equal to string \a rs2;
|
||||
otherwise returns false.
|
||||
*/
|
||||
bool operator!=(const RichString &rs1, const RichString &rs2)
|
||||
{
|
||||
if (rs1.fragmentCount() != rs2.fragmentCount())
|
||||
return true;
|
||||
|
||||
return rs1.d->idKey() != rs2.d->idKey();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
bool operator<(const RichString &rs1, const RichString &rs2)
|
||||
{
|
||||
return rs1.d->idKey() < rs2.d->idKey();
|
||||
}
|
||||
|
||||
/*!
|
||||
\overload
|
||||
Returns true if this string \a rs1 is equal to string \a rs2;
|
||||
otherwise returns false.
|
||||
*/
|
||||
bool operator ==(const RichString &rs1, const QString &rs2)
|
||||
{
|
||||
if (rs1.fragmentCount() == 1 && rs1.fragmentText(0) == rs2) //format == 0
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
\overload
|
||||
Returns true if this string \a rs1 is not equal to string \a rs2;
|
||||
otherwise returns false.
|
||||
*/
|
||||
bool operator !=(const RichString &rs1, const QString &rs2)
|
||||
{
|
||||
if (rs1.fragmentCount() == 1 && rs1.fragmentText(0) == rs2) //format == 0
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
\overload
|
||||
Returns true if this string \a rs1 is equal to string \a rs2;
|
||||
otherwise returns false.
|
||||
*/
|
||||
bool operator ==(const QString &rs1, const RichString &rs2)
|
||||
{
|
||||
return rs2 == rs1;
|
||||
}
|
||||
|
||||
/*!
|
||||
\overload
|
||||
Returns true if this string \a rs1 is not equal to string \a rs2;
|
||||
otherwise returns false.
|
||||
*/
|
||||
bool operator !=(const QString &rs1, const RichString &rs2)
|
||||
{
|
||||
return rs2 != rs1;
|
||||
}
|
||||
|
||||
uint qHash(const RichString &rs, uint seed) Q_DECL_NOTHROW
|
||||
{
|
||||
return qHash(rs.d->idKey(), seed);
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
QDebug operator<<(QDebug dbg, const RichString &rs)
|
||||
{
|
||||
dbg.nospace() << "QXlsx::RichString(" << rs.d->fragmentTexts << ")";
|
||||
return dbg.space();
|
||||
}
|
||||
#endif
|
||||
|
||||
QT_END_NAMESPACE_XLSX
|
||||
400
platform/src/public/pub_excel/xlsx/xlsxsharedstrings.cpp
Normal file
400
platform/src/public/pub_excel/xlsx/xlsxsharedstrings.cpp
Normal file
@ -0,0 +1,400 @@
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2013-2014 Debao Zhang <hello@debao.me>
|
||||
** All right reserved.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining
|
||||
** a copy of this software and associated documentation files (the
|
||||
** "Software"), to deal in the Software without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Software, and to
|
||||
** permit persons to whom the Software is furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be
|
||||
** included in all copies or substantial portions of the Software.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
****************************************************************************/
|
||||
#include "xlsxrichstring.h"
|
||||
#include "xlsxsharedstrings_p.h"
|
||||
#include "xlsxutility_p.h"
|
||||
#include "xlsxformat_p.h"
|
||||
#include "xlsxcolor_p.h"
|
||||
#include <QXmlStreamWriter>
|
||||
#include <QXmlStreamReader>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QDebug>
|
||||
#include <QBuffer>
|
||||
|
||||
namespace QXlsx {
|
||||
|
||||
/*
|
||||
* Note that, when we open an existing .xlsx file (broken file?),
|
||||
* duplicated string items may exist in the shared string table.
|
||||
*
|
||||
* In such case, the size of stringList will larger than stringTable.
|
||||
* Duplicated items can be removed once we loaded all the worksheets.
|
||||
*/
|
||||
|
||||
SharedStrings::SharedStrings(CreateFlag flag)
|
||||
:AbstractOOXmlFile(flag)
|
||||
{
|
||||
m_stringCount = 0;
|
||||
}
|
||||
|
||||
int SharedStrings::count() const
|
||||
{
|
||||
return m_stringCount;
|
||||
}
|
||||
|
||||
bool SharedStrings::isEmpty() const
|
||||
{
|
||||
return m_stringList.isEmpty();
|
||||
}
|
||||
|
||||
int SharedStrings::addSharedString(const QString &string)
|
||||
{
|
||||
return addSharedString(RichString(string));
|
||||
}
|
||||
|
||||
int SharedStrings::addSharedString(const RichString &string)
|
||||
{
|
||||
m_stringCount += 1;
|
||||
|
||||
if (m_stringTable.contains(string)) {
|
||||
XlsxSharedStringInfo &item = m_stringTable[string];
|
||||
item.count += 1;
|
||||
return item.index;
|
||||
}
|
||||
|
||||
int index = m_stringList.size();
|
||||
m_stringTable[string] = XlsxSharedStringInfo(index);
|
||||
m_stringList.append(string);
|
||||
return index;
|
||||
}
|
||||
|
||||
void SharedStrings::incRefByStringIndex(int idx)
|
||||
{
|
||||
if (idx <0 || idx >= m_stringList.size()) {
|
||||
qDebug("SharedStrings: invlid index");
|
||||
return;
|
||||
}
|
||||
|
||||
addSharedString(m_stringList[idx]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Broken, don't use.
|
||||
*/
|
||||
void SharedStrings::removeSharedString(const QString &string)
|
||||
{
|
||||
removeSharedString(RichString(string));
|
||||
}
|
||||
|
||||
/*
|
||||
* Broken, don't use.
|
||||
*/
|
||||
void SharedStrings::removeSharedString(const RichString &string)
|
||||
{
|
||||
if (!m_stringTable.contains(string))
|
||||
return;
|
||||
|
||||
m_stringCount -= 1;
|
||||
|
||||
XlsxSharedStringInfo &item = m_stringTable[string];
|
||||
item.count -= 1;
|
||||
|
||||
if (item.count <= 0) {
|
||||
for (int i=item.index+1; i<m_stringList.size(); ++i)
|
||||
m_stringTable[m_stringList[i]].index -= 1;
|
||||
|
||||
m_stringList.removeAt(item.index);
|
||||
m_stringTable.remove(string);
|
||||
}
|
||||
}
|
||||
|
||||
int SharedStrings::getSharedStringIndex(const QString &string) const
|
||||
{
|
||||
return getSharedStringIndex(RichString(string));
|
||||
}
|
||||
|
||||
int SharedStrings::getSharedStringIndex(const RichString &string) const
|
||||
{
|
||||
if (m_stringTable.contains(string))
|
||||
return m_stringTable[string].index;
|
||||
return -1;
|
||||
}
|
||||
|
||||
RichString SharedStrings::getSharedString(int index) const
|
||||
{
|
||||
if (index < m_stringList.count() && index >= 0)
|
||||
return m_stringList[index];
|
||||
return RichString();
|
||||
}
|
||||
|
||||
QList<RichString> SharedStrings::getSharedStrings() const
|
||||
{
|
||||
return m_stringList;
|
||||
}
|
||||
|
||||
void SharedStrings::writeRichStringPart_rPr(QXmlStreamWriter &writer, const Format &format) const
|
||||
{
|
||||
if (!format.hasFontData())
|
||||
return;
|
||||
|
||||
if (format.fontBold())
|
||||
writer.writeEmptyElement(QStringLiteral("b"));
|
||||
if (format.fontItalic())
|
||||
writer.writeEmptyElement(QStringLiteral("i"));
|
||||
if (format.fontStrikeOut())
|
||||
writer.writeEmptyElement(QStringLiteral("strike"));
|
||||
if (format.fontOutline())
|
||||
writer.writeEmptyElement(QStringLiteral("outline"));
|
||||
if (format.boolProperty(FormatPrivate::P_Font_Shadow))
|
||||
writer.writeEmptyElement(QStringLiteral("shadow"));
|
||||
if (format.hasProperty(FormatPrivate::P_Font_Underline)) {
|
||||
Format::FontUnderline u = format.fontUnderline();
|
||||
if (u != Format::FontUnderlineNone) {
|
||||
writer.writeEmptyElement(QStringLiteral("u"));
|
||||
if (u== Format::FontUnderlineDouble)
|
||||
writer.writeAttribute(QStringLiteral("val"), QStringLiteral("double"));
|
||||
else if (u == Format::FontUnderlineSingleAccounting)
|
||||
writer.writeAttribute(QStringLiteral("val"), QStringLiteral("singleAccounting"));
|
||||
else if (u == Format::FontUnderlineDoubleAccounting)
|
||||
writer.writeAttribute(QStringLiteral("val"), QStringLiteral("doubleAccounting"));
|
||||
}
|
||||
}
|
||||
if (format.hasProperty(FormatPrivate::P_Font_Script)) {
|
||||
Format::FontScript s = format.fontScript();
|
||||
if (s != Format::FontScriptNormal) {
|
||||
writer.writeEmptyElement(QStringLiteral("vertAlign"));
|
||||
if (s == Format::FontScriptSuper)
|
||||
writer.writeAttribute(QStringLiteral("val"), QStringLiteral("superscript"));
|
||||
else
|
||||
writer.writeAttribute(QStringLiteral("val"), QStringLiteral("subscript"));
|
||||
}
|
||||
}
|
||||
|
||||
if (format.hasProperty(FormatPrivate::P_Font_Size)) {
|
||||
writer.writeEmptyElement(QStringLiteral("sz"));
|
||||
writer.writeAttribute(QStringLiteral("val"), QString::number(format.fontSize()));
|
||||
}
|
||||
|
||||
if (format.hasProperty(FormatPrivate::P_Font_Color)) {
|
||||
XlsxColor color = format.property(FormatPrivate::P_Font_Color).value<XlsxColor>();
|
||||
color.saveToXml(writer);
|
||||
}
|
||||
|
||||
if (!format.fontName().isEmpty()) {
|
||||
writer.writeEmptyElement(QStringLiteral("rFont"));
|
||||
writer.writeAttribute(QStringLiteral("val"), format.fontName());
|
||||
}
|
||||
if (format.hasProperty(FormatPrivate::P_Font_Family)) {
|
||||
writer.writeEmptyElement(QStringLiteral("family"));
|
||||
writer.writeAttribute(QStringLiteral("val"), QString::number(format.intProperty(FormatPrivate::P_Font_Family)));
|
||||
}
|
||||
|
||||
if (format.hasProperty(FormatPrivate::P_Font_Scheme)) {
|
||||
writer.writeEmptyElement(QStringLiteral("scheme"));
|
||||
writer.writeAttribute(QStringLiteral("val"), format.stringProperty(FormatPrivate::P_Font_Scheme));
|
||||
}
|
||||
}
|
||||
|
||||
void SharedStrings::saveToXmlFile(QIODevice *device) const
|
||||
{
|
||||
QXmlStreamWriter writer(device);
|
||||
|
||||
if (m_stringList.size() != m_stringTable.size()) {
|
||||
//Duplicated string items exist in m_stringList
|
||||
//Clean up can not be done here, as the indices
|
||||
//have been used when we save the worksheets part.
|
||||
}
|
||||
|
||||
writer.writeStartDocument(QStringLiteral("1.0"), true);
|
||||
writer.writeStartElement(QStringLiteral("sst"));
|
||||
writer.writeAttribute(QStringLiteral("xmlns"), QStringLiteral("http://schemas.openxmlformats.org/spreadsheetml/2006/main"));
|
||||
writer.writeAttribute(QStringLiteral("count"), QString::number(m_stringCount));
|
||||
writer.writeAttribute(QStringLiteral("uniqueCount"), QString::number(m_stringList.size()));
|
||||
|
||||
foreach (RichString string, m_stringList) {
|
||||
writer.writeStartElement(QStringLiteral("si"));
|
||||
if (string.isRichString()) {
|
||||
//Rich text string
|
||||
for (int i=0; i<string.fragmentCount(); ++i) {
|
||||
writer.writeStartElement(QStringLiteral("r"));
|
||||
if (string.fragmentFormat(i).hasFontData()) {
|
||||
writer.writeStartElement(QStringLiteral("rPr"));
|
||||
writeRichStringPart_rPr(writer, string.fragmentFormat(i));
|
||||
writer.writeEndElement();// rPr
|
||||
}
|
||||
writer.writeStartElement(QStringLiteral("t"));
|
||||
if (isSpaceReserveNeeded(string.fragmentText(i)))
|
||||
writer.writeAttribute(QStringLiteral("xml:space"), QStringLiteral("preserve"));
|
||||
writer.writeCharacters(string.fragmentText(i));
|
||||
writer.writeEndElement();// t
|
||||
|
||||
writer.writeEndElement(); //r
|
||||
}
|
||||
} else {
|
||||
writer.writeStartElement(QStringLiteral("t"));
|
||||
QString pString = string.toPlainString();
|
||||
if (isSpaceReserveNeeded(pString))
|
||||
writer.writeAttribute(QStringLiteral("xml:space"), QStringLiteral("preserve"));
|
||||
writer.writeCharacters(pString);
|
||||
writer.writeEndElement();//t
|
||||
}
|
||||
writer.writeEndElement();//si
|
||||
}
|
||||
|
||||
writer.writeEndElement(); //sst
|
||||
writer.writeEndDocument();
|
||||
}
|
||||
|
||||
void SharedStrings::readString(QXmlStreamReader &reader)
|
||||
{
|
||||
Q_ASSERT(reader.name() == QLatin1String("si"));
|
||||
|
||||
RichString richString;
|
||||
|
||||
while (!reader.atEnd() && !(reader.name() == QLatin1String("si") && reader.tokenType() == QXmlStreamReader::EndElement)) {
|
||||
reader.readNextStartElement();
|
||||
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
||||
if (reader.name() == QLatin1String("r"))
|
||||
readRichStringPart(reader, richString);
|
||||
else if (reader.name() == QLatin1String("t"))
|
||||
readPlainStringPart(reader, richString);
|
||||
}
|
||||
}
|
||||
|
||||
int idx = m_stringList.size();
|
||||
m_stringTable[richString] = XlsxSharedStringInfo(idx, 0);
|
||||
m_stringList.append(richString);
|
||||
}
|
||||
|
||||
void SharedStrings::readRichStringPart(QXmlStreamReader &reader, RichString &richString)
|
||||
{
|
||||
Q_ASSERT(reader.name() == QLatin1String("r"));
|
||||
|
||||
QString text;
|
||||
Format format;
|
||||
while (!reader.atEnd() && !(reader.name() == QLatin1String("r") && reader.tokenType() == QXmlStreamReader::EndElement)) {
|
||||
reader.readNextStartElement();
|
||||
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
||||
if (reader.name() == QLatin1String("rPr")) {
|
||||
format = readRichStringPart_rPr(reader);
|
||||
} else if (reader.name() == QLatin1String("t")) {
|
||||
text = reader.readElementText();
|
||||
}
|
||||
}
|
||||
}
|
||||
richString.addFragment(text, format);
|
||||
}
|
||||
|
||||
void SharedStrings::readPlainStringPart(QXmlStreamReader &reader, RichString &richString)
|
||||
{
|
||||
Q_ASSERT(reader.name() == QLatin1String("t"));
|
||||
|
||||
//QXmlStreamAttributes attributes = reader.attributes();
|
||||
|
||||
QString text = reader.readElementText();
|
||||
richString.addFragment(text, Format());
|
||||
}
|
||||
|
||||
Format SharedStrings::readRichStringPart_rPr(QXmlStreamReader &reader)
|
||||
{
|
||||
Q_ASSERT(reader.name() == QLatin1String("rPr"));
|
||||
Format format;
|
||||
while (!reader.atEnd() && !(reader.name() == QLatin1String("rPr") && reader.tokenType() == QXmlStreamReader::EndElement)) {
|
||||
reader.readNextStartElement();
|
||||
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
||||
QXmlStreamAttributes attributes = reader.attributes();
|
||||
if (reader.name() == QLatin1String("rFont")) {
|
||||
format.setFontName(attributes.value(QLatin1String("val")).toString());
|
||||
} else if (reader.name() == QLatin1String("charset")) {
|
||||
format.setProperty(FormatPrivate::P_Font_Charset, attributes.value(QLatin1String("val")).toString().toInt());
|
||||
} else if (reader.name() == QLatin1String("family")) {
|
||||
format.setProperty(FormatPrivate::P_Font_Family, attributes.value(QLatin1String("val")).toString().toInt());
|
||||
} else if (reader.name() == QLatin1String("b")) {
|
||||
format.setFontBold(true);
|
||||
} else if (reader.name() == QLatin1String("i")) {
|
||||
format.setFontItalic(true);
|
||||
} else if (reader.name() == QLatin1String("strike")) {
|
||||
format.setFontStrikeOut(true);
|
||||
} else if (reader.name() == QLatin1String("outline")) {
|
||||
format.setFontOutline(true);
|
||||
} else if (reader.name() == QLatin1String("shadow")) {
|
||||
format.setProperty(FormatPrivate::P_Font_Shadow, true);
|
||||
} else if (reader.name() == QLatin1String("condense")) {
|
||||
format.setProperty(FormatPrivate::P_Font_Condense, attributes.value(QLatin1String("val")).toString().toInt());
|
||||
} else if (reader.name() == QLatin1String("extend")) {
|
||||
format.setProperty(FormatPrivate::P_Font_Extend, attributes.value(QLatin1String("val")).toString().toInt());
|
||||
} else if (reader.name() == QLatin1String("color")) {
|
||||
XlsxColor color;
|
||||
color.loadFromXml(reader);
|
||||
format.setProperty(FormatPrivate::P_Font_Color, color);
|
||||
} else if (reader.name() == QLatin1String("sz")) {
|
||||
format.setFontSize(attributes.value(QLatin1String("val")).toString().toInt());
|
||||
} else if (reader.name() == QLatin1String("u")) {
|
||||
QString value = attributes.value(QLatin1String("val")).toString();
|
||||
if (value == QLatin1String("double"))
|
||||
format.setFontUnderline(Format::FontUnderlineDouble);
|
||||
else if (value == QLatin1String("doubleAccounting"))
|
||||
format.setFontUnderline(Format::FontUnderlineDoubleAccounting);
|
||||
else if (value == QLatin1String("singleAccounting"))
|
||||
format.setFontUnderline(Format::FontUnderlineSingleAccounting);
|
||||
else
|
||||
format.setFontUnderline(Format::FontUnderlineSingle);
|
||||
} else if (reader.name() == QLatin1String("vertAlign")) {
|
||||
QString value = attributes.value(QLatin1String("val")).toString();
|
||||
if (value == QLatin1String("superscript"))
|
||||
format.setFontScript(Format::FontScriptSuper);
|
||||
else if (value == QLatin1String("subscript"))
|
||||
format.setFontScript(Format::FontScriptSub);
|
||||
} else if (reader.name() == QLatin1String("scheme")) {
|
||||
format.setProperty(FormatPrivate::P_Font_Scheme, attributes.value(QLatin1String("val")).toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
return format;
|
||||
}
|
||||
|
||||
bool SharedStrings::loadFromXmlFile(QIODevice *device)
|
||||
{
|
||||
QXmlStreamReader reader(device);
|
||||
int count = 0;
|
||||
bool hasUniqueCountAttr=true;
|
||||
while (!reader.atEnd()) {
|
||||
QXmlStreamReader::TokenType token = reader.readNext();
|
||||
if (token == QXmlStreamReader::StartElement) {
|
||||
if (reader.name() == QLatin1String("sst")) {
|
||||
QXmlStreamAttributes attributes = reader.attributes();
|
||||
if ((hasUniqueCountAttr = attributes.hasAttribute(QLatin1String("uniqueCount"))))
|
||||
count = attributes.value(QLatin1String("uniqueCount")).toString().toInt();
|
||||
} else if (reader.name() == QLatin1String("si")) {
|
||||
readString(reader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasUniqueCountAttr && m_stringList.size() != count) {
|
||||
qDebug("Error: Shared string count");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_stringList.size() != m_stringTable.size()) {
|
||||
//qDebug("Warning: Duplicated items exist in shared string table.");
|
||||
//Nothing we can do here, as indices of the strings will be used when loading sheets.
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} //namespace
|
||||
56
platform/src/public/pub_excel/xlsx/xlsxsimpleooxmlfile.cpp
Normal file
56
platform/src/public/pub_excel/xlsx/xlsxsimpleooxmlfile.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2013-2014 Debao Zhang <hello@debao.me>
|
||||
** All right reserved.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining
|
||||
** a copy of this software and associated documentation files (the
|
||||
** "Software"), to deal in the Software without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Software, and to
|
||||
** permit persons to whom the Software is furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be
|
||||
** included in all copies or substantial portions of the Software.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
****************************************************************************/
|
||||
#include "xlsxsimpleooxmlfile_p.h"
|
||||
#include <QIODevice>
|
||||
|
||||
namespace QXlsx {
|
||||
SimpleOOXmlFile::SimpleOOXmlFile(CreateFlag flag)
|
||||
:AbstractOOXmlFile(flag)
|
||||
{
|
||||
}
|
||||
|
||||
void SimpleOOXmlFile::saveToXmlFile(QIODevice *device) const
|
||||
{
|
||||
device->write(xmlData);
|
||||
}
|
||||
|
||||
QByteArray SimpleOOXmlFile::saveToXmlData() const
|
||||
{
|
||||
return xmlData;
|
||||
}
|
||||
|
||||
bool SimpleOOXmlFile::loadFromXmlData(const QByteArray &data)
|
||||
{
|
||||
xmlData = data;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SimpleOOXmlFile::loadFromXmlFile(QIODevice *device)
|
||||
{
|
||||
xmlData = device->readAll();
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
1334
platform/src/public/pub_excel/xlsx/xlsxstyles.cpp
Normal file
1334
platform/src/public/pub_excel/xlsx/xlsxstyles.cpp
Normal file
File diff suppressed because it is too large
Load Diff
237
platform/src/public/pub_excel/xlsx/xlsxtheme.cpp
Normal file
237
platform/src/public/pub_excel/xlsx/xlsxtheme.cpp
Normal file
@ -0,0 +1,237 @@
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2013-2014 Debao Zhang <hello@debao.me>
|
||||
** All right reserved.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining
|
||||
** a copy of this software and associated documentation files (the
|
||||
** "Software"), to deal in the Software without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Software, and to
|
||||
** permit persons to whom the Software is furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be
|
||||
** included in all copies or substantial portions of the Software.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
****************************************************************************/
|
||||
#include "xlsxtheme_p.h"
|
||||
#include <QIODevice>
|
||||
|
||||
namespace QXlsx {
|
||||
|
||||
const char *defaultXmlData =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"
|
||||
"<a:theme xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" name=\"Office \xe4\xb8\xbb\xe9\xa2\x98\">"
|
||||
"<a:themeElements>"
|
||||
"<a:clrScheme name=\"Office\">"
|
||||
"<a:dk1><a:sysClr val=\"windowText\" lastClr=\"000000\"/></a:dk1>"
|
||||
"<a:lt1><a:sysClr val=\"window\" lastClr=\"FFFFFF\"/></a:lt1>"
|
||||
"<a:dk2><a:srgbClr val=\"1F497D\"/></a:dk2>"
|
||||
"<a:lt2><a:srgbClr val=\"EEECE1\"/></a:lt2>"
|
||||
"<a:accent1><a:srgbClr val=\"4F81BD\"/></a:accent1>"
|
||||
"<a:accent2><a:srgbClr val=\"C0504D\"/></a:accent2>"
|
||||
"<a:accent3><a:srgbClr val=\"9BBB59\"/></a:accent3>"
|
||||
"<a:accent4><a:srgbClr val=\"8064A2\"/></a:accent4>"
|
||||
"<a:accent5><a:srgbClr val=\"4BACC6\"/></a:accent5>"
|
||||
"<a:accent6><a:srgbClr val=\"F79646\"/></a:accent6>"
|
||||
"<a:hlink><a:srgbClr val=\"0000FF\"/></a:hlink>"
|
||||
"<a:folHlink><a:srgbClr val=\"800080\"/></a:folHlink>"
|
||||
"</a:clrScheme>"
|
||||
"<a:fontScheme name=\"Office\">"
|
||||
"<a:majorFont>"
|
||||
"<a:latin typeface=\"Cambria\"/>"
|
||||
"<a:ea typeface=\"\"/>"
|
||||
"<a:cs typeface=\"\"/>"
|
||||
"<a:font script=\"Jpan\" typeface=\"\xef\xbc\xad\xef\xbc\xb3 \xef\xbc\xb0\xe3\x82\xb4\xe3\x82\xb7\xe3\x83\x83\xe3\x82\xaf\"/>"
|
||||
"<a:font script=\"Hang\" typeface=\"\xeb\xa7\x91\xec\x9d\x80 \xea\xb3\xa0\xeb\x94\x95\"/>"
|
||||
"<a:font script=\"Hans\" typeface=\"\xe5\xae\x8b\xe4\xbd\x93\"/>"
|
||||
"<a:font script=\"Hant\" typeface=\"\xe6\x96\xb0\xe7\xb4\xb0\xe6\x98\x8e\xe9\xab\x94\"/>"
|
||||
"<a:font script=\"Arab\" typeface=\"Times New Roman\"/>"
|
||||
"<a:font script=\"Hebr\" typeface=\"Times New Roman\"/>"
|
||||
"<a:font script=\"Thai\" typeface=\"Tahoma\"/>"
|
||||
"<a:font script=\"Ethi\" typeface=\"Nyala\"/>"
|
||||
"<a:font script=\"Beng\" typeface=\"Vrinda\"/>"
|
||||
"<a:font script=\"Gujr\" typeface=\"Shruti\"/>"
|
||||
"<a:font script=\"Khmr\" typeface=\"MoolBoran\"/>"
|
||||
"<a:font script=\"Knda\" typeface=\"Tunga\"/>"
|
||||
"<a:font script=\"Guru\" typeface=\"Raavi\"/>"
|
||||
"<a:font script=\"Cans\" typeface=\"Euphemia\"/>"
|
||||
"<a:font script=\"Cher\" typeface=\"Plantagenet Cherokee\"/>"
|
||||
"<a:font script=\"Yiii\" typeface=\"Microsoft Yi Baiti\"/>"
|
||||
"<a:font script=\"Tibt\" typeface=\"Microsoft Himalaya\"/>"
|
||||
"<a:font script=\"Thaa\" typeface=\"MV Boli\"/>"
|
||||
"<a:font script=\"Deva\" typeface=\"Mangal\"/>"
|
||||
"<a:font script=\"Telu\" typeface=\"Gautami\"/>"
|
||||
"<a:font script=\"Taml\" typeface=\"Latha\"/>"
|
||||
"<a:font script=\"Syrc\" typeface=\"Estrangelo Edessa\"/>"
|
||||
"<a:font script=\"Orya\" typeface=\"Kalinga\"/>"
|
||||
"<a:font script=\"Mlym\" typeface=\"Kartika\"/>"
|
||||
"<a:font script=\"Laoo\" typeface=\"DokChampa\"/>"
|
||||
"<a:font script=\"Sinh\" typeface=\"Iskoola Pota\"/>"
|
||||
"<a:font script=\"Mong\" typeface=\"Mongolian Baiti\"/>"
|
||||
"<a:font script=\"Viet\" typeface=\"Times New Roman\"/>"
|
||||
"<a:font script=\"Uigh\" typeface=\"Microsoft Uighur\"/>"
|
||||
"</a:majorFont>"
|
||||
"<a:minorFont>"
|
||||
"<a:latin typeface=\"Calibri\"/>"
|
||||
"<a:ea typeface=\"\"/>"
|
||||
"<a:cs typeface=\"\"/>"
|
||||
"<a:font script=\"Jpan\" typeface=\"\xef\xbc\xad\xef\xbc\xb3 \xef\xbc\xb0\xe3\x82\xb4\xe3\x82\xb7\xe3\x83\x83\xe3\x82\xaf\"/>"
|
||||
"<a:font script=\"Hang\" typeface=\"\xeb\xa7\x91\xec\x9d\x80 \xea\xb3\xa0\xeb\x94\x95\"/>"
|
||||
"<a:font script=\"Hans\" typeface=\"\xe5\xae\x8b\xe4\xbd\x93\"/>"
|
||||
"<a:font script=\"Hant\" typeface=\"\xe6\x96\xb0\xe7\xb4\xb0\xe6\x98\x8e\xe9\xab\x94\"/>"
|
||||
"<a:font script=\"Arab\" typeface=\"Arial\"/>"
|
||||
"<a:font script=\"Hebr\" typeface=\"Arial\"/>"
|
||||
"<a:font script=\"Thai\" typeface=\"Tahoma\"/>"
|
||||
"<a:font script=\"Ethi\" typeface=\"Nyala\"/>"
|
||||
"<a:font script=\"Beng\" typeface=\"Vrinda\"/>"
|
||||
"<a:font script=\"Gujr\" typeface=\"Shruti\"/>"
|
||||
"<a:font script=\"Khmr\" typeface=\"DaunPenh\"/>"
|
||||
"<a:font script=\"Knda\" typeface=\"Tunga\"/>"
|
||||
"<a:font script=\"Guru\" typeface=\"Raavi\"/>"
|
||||
"<a:font script=\"Cans\" typeface=\"Euphemia\"/>"
|
||||
"<a:font script=\"Cher\" typeface=\"Plantagenet Cherokee\"/>"
|
||||
"<a:font script=\"Yiii\" typeface=\"Microsoft Yi Baiti\"/>"
|
||||
"<a:font script=\"Tibt\" typeface=\"Microsoft Himalaya\"/>"
|
||||
"<a:font script=\"Thaa\" typeface=\"MV Boli\"/>"
|
||||
"<a:font script=\"Deva\" typeface=\"Mangal\"/>"
|
||||
"<a:font script=\"Telu\" typeface=\"Gautami\"/>"
|
||||
"<a:font script=\"Taml\" typeface=\"Latha\"/>"
|
||||
"<a:font script=\"Syrc\" typeface=\"Estrangelo Edessa\"/>"
|
||||
"<a:font script=\"Orya\" typeface=\"Kalinga\"/>"
|
||||
"<a:font script=\"Mlym\" typeface=\"Kartika\"/>"
|
||||
"<a:font script=\"Laoo\" typeface=\"DokChampa\"/>"
|
||||
"<a:font script=\"Sinh\" typeface=\"Iskoola Pota\"/>"
|
||||
"<a:font script=\"Mong\" typeface=\"Mongolian Baiti\"/>"
|
||||
"<a:font script=\"Viet\" typeface=\"Arial\"/>"
|
||||
"<a:font script=\"Uigh\" typeface=\"Microsoft Uighur\"/>"
|
||||
"</a:minorFont>"
|
||||
"</a:fontScheme>"
|
||||
"<a:fmtScheme name=\"Office\">"
|
||||
"<a:fillStyleLst>"
|
||||
"<a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill>"
|
||||
"<a:gradFill rotWithShape=\"1\">"
|
||||
"<a:gsLst>"
|
||||
"<a:gs pos=\"0\"><a:schemeClr val=\"phClr\"><a:tint val=\"50000\"/><a:satMod val=\"300000\"/></a:schemeClr></a:gs>"
|
||||
"<a:gs pos=\"35000\"><a:schemeClr val=\"phClr\"><a:tint val=\"37000\"/><a:satMod val=\"300000\"/></a:schemeClr></a:gs>"
|
||||
"<a:gs pos=\"100000\"><a:schemeClr val=\"phClr\"><a:tint val=\"15000\"/><a:satMod val=\"350000\"/></a:schemeClr></a:gs>"
|
||||
"</a:gsLst>"
|
||||
"<a:lin ang=\"16200000\" scaled=\"1\"/>"
|
||||
"</a:gradFill>"
|
||||
"<a:gradFill rotWithShape=\"1\">"
|
||||
"<a:gsLst>"
|
||||
"<a:gs pos=\"0\"><a:schemeClr val=\"phClr\"><a:shade val=\"51000\"/><a:satMod val=\"130000\"/></a:schemeClr></a:gs>"
|
||||
"<a:gs pos=\"80000\"><a:schemeClr val=\"phClr\"><a:shade val=\"93000\"/><a:satMod val=\"130000\"/></a:schemeClr></a:gs>"
|
||||
"<a:gs pos=\"100000\"><a:schemeClr val=\"phClr\"><a:shade val=\"94000\"/><a:satMod val=\"135000\"/></a:schemeClr></a:gs>"
|
||||
"</a:gsLst>"
|
||||
"<a:lin ang=\"16200000\" scaled=\"0\"/>"
|
||||
"</a:gradFill>"
|
||||
"</a:fillStyleLst>"
|
||||
"<a:lnStyleLst>"
|
||||
"<a:ln w=\"9525\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\">"
|
||||
"<a:solidFill><a:schemeClr val=\"phClr\"><a:shade val=\"95000\"/><a:satMod val=\"105000\"/></a:schemeClr></a:solidFill>"
|
||||
"<a:prstDash val=\"solid\"/>"
|
||||
"</a:ln>"
|
||||
"<a:ln w=\"25400\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\">"
|
||||
"<a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill>"
|
||||
"<a:prstDash val=\"solid\"/>"
|
||||
"</a:ln>"
|
||||
"<a:ln w=\"38100\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\">"
|
||||
"<a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill>"
|
||||
"<a:prstDash val=\"solid\"/>"
|
||||
"</a:ln>"
|
||||
"</a:lnStyleLst>"
|
||||
"<a:effectStyleLst>"
|
||||
"<a:effectStyle>"
|
||||
"<a:effectLst>"
|
||||
"<a:outerShdw blurRad=\"40000\" dist=\"20000\" dir=\"5400000\" rotWithShape=\"0\">"
|
||||
"<a:srgbClr val=\"000000\"><a:alpha val=\"38000\"/></a:srgbClr>"
|
||||
"</a:outerShdw>"
|
||||
"</a:effectLst>"
|
||||
"</a:effectStyle>"
|
||||
"<a:effectStyle>"
|
||||
"<a:effectLst>"
|
||||
"<a:outerShdw blurRad=\"40000\" dist=\"23000\" dir=\"5400000\" rotWithShape=\"0\">"
|
||||
"<a:srgbClr val=\"000000\"><a:alpha val=\"35000\"/></a:srgbClr>"
|
||||
"</a:outerShdw>"
|
||||
"</a:effectLst>"
|
||||
"</a:effectStyle>"
|
||||
"<a:effectStyle>"
|
||||
"<a:effectLst>"
|
||||
"<a:outerShdw blurRad=\"40000\" dist=\"23000\" dir=\"5400000\" rotWithShape=\"0\">"
|
||||
"<a:srgbClr val=\"000000\"><a:alpha val=\"35000\"/></a:srgbClr>"
|
||||
"</a:outerShdw>"
|
||||
"</a:effectLst>"
|
||||
"<a:scene3d>"
|
||||
"<a:camera prst=\"orthographicFront\"><a:rot lat=\"0\" lon=\"0\" rev=\"0\"/></a:camera>"
|
||||
"<a:lightRig rig=\"threePt\" dir=\"t\"><a:rot lat=\"0\" lon=\"0\" rev=\"1200000\"/></a:lightRig>"
|
||||
"</a:scene3d>"
|
||||
"<a:sp3d><a:bevelT w=\"63500\" h=\"25400\"/></a:sp3d>"
|
||||
"</a:effectStyle>"
|
||||
"</a:effectStyleLst>"
|
||||
"<a:bgFillStyleLst>"
|
||||
"<a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill>"
|
||||
"<a:gradFill rotWithShape=\"1\">"
|
||||
"<a:gsLst>"
|
||||
"<a:gs pos=\"0\"><a:schemeClr val=\"phClr\"><a:tint val=\"40000\"/><a:satMod val=\"350000\"/></a:schemeClr></a:gs>"
|
||||
"<a:gs pos=\"40000\"><a:schemeClr val=\"phClr\"><a:tint val=\"45000\"/><a:shade val=\"99000\"/><a:satMod val=\"350000\"/></a:schemeClr></a:gs>"
|
||||
"<a:gs pos=\"100000\"><a:schemeClr val=\"phClr\"><a:shade val=\"20000\"/><a:satMod val=\"255000\"/></a:schemeClr></a:gs></a:gsLst>"
|
||||
"<a:path path=\"circle\"><a:fillToRect l=\"50000\" t=\"-80000\" r=\"50000\" b=\"180000\"/></a:path>"
|
||||
"</a:gradFill>"
|
||||
"<a:gradFill rotWithShape=\"1\">"
|
||||
"<a:gsLst>"
|
||||
"<a:gs pos=\"0\"><a:schemeClr val=\"phClr\"><a:tint val=\"80000\"/><a:satMod val=\"300000\"/></a:schemeClr></a:gs>"
|
||||
"<a:gs pos=\"100000\"><a:schemeClr val=\"phClr\"><a:shade val=\"30000\"/><a:satMod val=\"200000\"/></a:schemeClr></a:gs>"
|
||||
"</a:gsLst>"
|
||||
"<a:path path=\"circle\"><a:fillToRect l=\"50000\" t=\"50000\" r=\"50000\" b=\"50000\"/></a:path>"
|
||||
"</a:gradFill>"
|
||||
"</a:bgFillStyleLst>"
|
||||
"</a:fmtScheme>"
|
||||
"</a:themeElements>"
|
||||
"<a:objectDefaults/>"
|
||||
"<a:extraClrSchemeLst/>"
|
||||
"</a:theme>"
|
||||
;
|
||||
|
||||
Theme::Theme(CreateFlag flag)
|
||||
:AbstractOOXmlFile(flag)
|
||||
{
|
||||
}
|
||||
|
||||
void Theme::saveToXmlFile(QIODevice *device) const
|
||||
{
|
||||
if (xmlData.isEmpty())
|
||||
device->write(defaultXmlData);
|
||||
else
|
||||
device->write(xmlData);
|
||||
}
|
||||
|
||||
QByteArray Theme::saveToXmlData() const
|
||||
{
|
||||
if (xmlData.isEmpty())
|
||||
return defaultXmlData;
|
||||
else
|
||||
return xmlData;
|
||||
}
|
||||
|
||||
bool Theme::loadFromXmlData(const QByteArray &data)
|
||||
{
|
||||
xmlData = data;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Theme::loadFromXmlFile(QIODevice *device)
|
||||
{
|
||||
xmlData = device->readAll();
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
276
platform/src/public/pub_excel/xlsx/xlsxutility.cpp
Normal file
276
platform/src/public/pub_excel/xlsx/xlsxutility.cpp
Normal file
@ -0,0 +1,276 @@
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2013-2014 Debao Zhang <hello@debao.me>
|
||||
** All right reserved.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining
|
||||
** a copy of this software and associated documentation files (the
|
||||
** "Software"), to deal in the Software without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Software, and to
|
||||
** permit persons to whom the Software is furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be
|
||||
** included in all copies or substantial portions of the Software.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
****************************************************************************/
|
||||
#include "xlsxutility_p.h"
|
||||
#include "xlsxcellreference.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QPoint>
|
||||
#include <QRegularExpression>
|
||||
#include <QMap>
|
||||
#include <QStringList>
|
||||
#include <QColor>
|
||||
#include <QDateTime>
|
||||
#include <QDebug>
|
||||
|
||||
namespace QXlsx {
|
||||
|
||||
bool parseXsdBoolean(const QString &value, bool defaultValue)
|
||||
{
|
||||
if (value == QLatin1String("1") || value == QLatin1String("true"))
|
||||
return true;
|
||||
if (value == QLatin1String("0") || value == QLatin1String("false"))
|
||||
return false;
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
QStringList splitPath(const QString &path)
|
||||
{
|
||||
int idx = path.lastIndexOf(QLatin1Char('/'));
|
||||
if (idx == -1)
|
||||
return QStringList()<<QStringLiteral(".")<<path;
|
||||
|
||||
return QStringList()<<path.left(idx)<<path.mid(idx+1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the .rel file path based on filePath
|
||||
*/
|
||||
QString getRelFilePath(const QString &filePath)
|
||||
{
|
||||
int idx = filePath.lastIndexOf(QLatin1Char('/'));
|
||||
if (idx == -1)
|
||||
return QString();
|
||||
|
||||
return QString(filePath.left(idx) + QLatin1String("/_rels/")
|
||||
+ filePath.mid(idx+1) + QLatin1String(".rels"));
|
||||
}
|
||||
|
||||
double datetimeToNumber(const QDateTime &dt, bool is1904)
|
||||
{
|
||||
//Note, for number 0, Excel2007 shown as 1900-1-0, which should be 1899-12-31
|
||||
QDateTime epoch(is1904 ? QDate(1904, 1, 1): QDate(1899, 12, 31), QTime(0,0));
|
||||
|
||||
double excel_time = epoch.msecsTo(dt) / (1000*60*60*24.0);
|
||||
|
||||
#if QT_VERSION >= 0x050200
|
||||
if (dt.isDaylightTime()) // Add one hour if the date is Daylight
|
||||
excel_time += 1.0 / 24.0;
|
||||
#endif
|
||||
|
||||
if (!is1904 && excel_time > 59) {//31+28
|
||||
//Account for Excel erroneously treating 1900 as a leap year.
|
||||
excel_time += 1;
|
||||
}
|
||||
|
||||
return excel_time;
|
||||
}
|
||||
|
||||
double timeToNumber(const QTime &time)
|
||||
{
|
||||
return QTime(0,0).msecsTo(time) / (1000*60*60*24.0);
|
||||
}
|
||||
|
||||
QDateTime datetimeFromNumber(double num, bool is1904)
|
||||
{
|
||||
if (!is1904 && num > 60)
|
||||
num = num - 1;
|
||||
|
||||
qint64 msecs = static_cast<qint64>(num * 1000*60*60*24.0 + 0.5);
|
||||
QDateTime epoch(is1904 ? QDate(1904, 1, 1): QDate(1899, 12, 31), QTime(0,0));
|
||||
|
||||
QDateTime dt = epoch.addMSecs(msecs);
|
||||
|
||||
#if QT_VERSION >= 0x050200
|
||||
// Remove one hour to see whether the date is Daylight
|
||||
QDateTime dt2 = dt.addMSecs(-3600);
|
||||
if (dt2.isDaylightTime())
|
||||
return dt2;
|
||||
#endif
|
||||
|
||||
return dt;
|
||||
}
|
||||
|
||||
/*
|
||||
Creates a valid sheet name
|
||||
minimum length is 1
|
||||
maximum length is 31
|
||||
doesn't contain special chars: / \ ? * ] [ :
|
||||
Sheet names must not begin or end with ' (apostrophe)
|
||||
|
||||
Invalid characters are replaced by one space character ' '.
|
||||
*/
|
||||
QString createSafeSheetName(const QString &nameProposal)
|
||||
{
|
||||
if (nameProposal.isEmpty())
|
||||
return QString();
|
||||
|
||||
QString ret = nameProposal;
|
||||
if (nameProposal.length() > 2 && nameProposal.startsWith(QLatin1Char('\'')) && nameProposal.endsWith(QLatin1Char('\'')))
|
||||
ret = unescapeSheetName(ret);
|
||||
|
||||
//Replace invalid chars with space.
|
||||
if (nameProposal.contains(QRegularExpression(QStringLiteral("[/\\\\?*\\][:]"))))
|
||||
ret.replace(QRegularExpression(QStringLiteral("[/\\\\?*\\][:]")), QStringLiteral(" "));
|
||||
if (ret.startsWith(QLatin1Char('\'')))
|
||||
ret[0] = QLatin1Char(' ');
|
||||
if (ret.endsWith(QLatin1Char('\'')))
|
||||
ret[ret.size()-1] = QLatin1Char(' ');
|
||||
|
||||
if (ret.size() > 31)
|
||||
ret = ret.left(31);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* When sheetName contains space or apostrophe, escaped is needed by cellFormula/definedName/chartSerials.
|
||||
*/
|
||||
QString escapeSheetName(const QString &sheetName)
|
||||
{
|
||||
//Already escaped.
|
||||
Q_ASSERT(!sheetName.startsWith(QLatin1Char('\'')) && !sheetName.endsWith(QLatin1Char('\'')));
|
||||
|
||||
//These is no need to escape
|
||||
if (!sheetName.contains(QRegularExpression(QStringLiteral("[ +\\-,%^=<>'&]"))))
|
||||
return sheetName;
|
||||
|
||||
//OK, escape is needed.
|
||||
QString name = sheetName;
|
||||
name.replace(QLatin1Char('\''), QLatin1String("\'\'"));
|
||||
return QLatin1Char('\'') + name + QLatin1Char('\'');
|
||||
}
|
||||
|
||||
/*
|
||||
*/
|
||||
QString unescapeSheetName(const QString &sheetName)
|
||||
{
|
||||
Q_ASSERT(sheetName.length() > 2 && sheetName.startsWith(QLatin1Char('\'')) && sheetName.endsWith(QLatin1Char('\'')));
|
||||
|
||||
QString name = sheetName.mid(1, sheetName.length()-2);
|
||||
name.replace(QLatin1String("\'\'"), QLatin1String("\'"));
|
||||
return name;
|
||||
}
|
||||
|
||||
/*
|
||||
* whether the string s starts or ends with space
|
||||
*/
|
||||
bool isSpaceReserveNeeded(const QString &s)
|
||||
{
|
||||
QString spaces(QStringLiteral(" \t\n\r"));
|
||||
return !s.isEmpty() && (spaces.contains(s.at(0))||spaces.contains(s.at(s.length()-1)));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert shared formula for non-root cells.
|
||||
*
|
||||
* For example, if "B1:B10" have shared formula "=A1*A1", this function will return "=A2*A2"
|
||||
* for "B2" cell, "=A3*A3" for "B3" cell, etc.
|
||||
*
|
||||
* Note, the formula "=A1*A1" for B1 can also be written as "=RC[-1]*RC[-1]", which is the same
|
||||
* for all other cells. In other words, this formula is shared.
|
||||
*
|
||||
* For long run, we need a formula parser.
|
||||
*/
|
||||
QString convertSharedFormula(const QString &rootFormula, const CellReference &rootCell, const CellReference &cell)
|
||||
{
|
||||
//Find all the "$?[A-Z]+$?[0-9]+" patterns in the rootFormula.
|
||||
QList<QPair<QString, int> > segments;
|
||||
|
||||
QString segment;
|
||||
bool inQuote = false;
|
||||
enum RefState{INVALID, PRE_AZ, AZ, PRE_09, _09};
|
||||
RefState refState = INVALID;
|
||||
int refFlag = 0; // 0x00, 0x01, 0x02, 0x03 ==> A1, $A1, A$1, $A$1
|
||||
foreach (QChar ch, rootFormula) {
|
||||
if (inQuote) {
|
||||
segment.append(ch);
|
||||
if (ch == QLatin1Char('"'))
|
||||
inQuote = false;
|
||||
} else {
|
||||
if (ch == QLatin1Char('"')) {
|
||||
inQuote = true;
|
||||
refState = INVALID;
|
||||
segment.append(ch);
|
||||
} else if (ch == QLatin1Char('$')) {
|
||||
if (refState == AZ) {
|
||||
segment.append(ch);
|
||||
refState = PRE_09;
|
||||
refFlag |= 0x02;
|
||||
} else {
|
||||
segments.append(qMakePair(segment, refState==_09 ? refFlag : -1));
|
||||
segment = QString(ch); //Start new segment.
|
||||
refState = PRE_AZ;
|
||||
refFlag = 0x01;
|
||||
}
|
||||
} else if (ch >= QLatin1Char('A') && ch <=QLatin1Char('Z')) {
|
||||
if (refState == PRE_AZ || refState == AZ) {
|
||||
segment.append(ch);
|
||||
} else {
|
||||
segments.append(qMakePair(segment, refState==_09 ? refFlag : -1));
|
||||
segment = QString(ch); //Start new segment.
|
||||
refFlag = 0x00;
|
||||
}
|
||||
refState = AZ;
|
||||
} else if (ch >= QLatin1Char('0') && ch <=QLatin1Char('9')) {
|
||||
segment.append(ch);
|
||||
|
||||
if (refState == AZ || refState == PRE_09 || refState == _09)
|
||||
refState = _09;
|
||||
else
|
||||
refState = INVALID;
|
||||
} else {
|
||||
if (refState == _09) {
|
||||
segments.append(qMakePair(segment, refFlag));
|
||||
segment = QString(ch); //Start new segment.
|
||||
} else {
|
||||
segment.append(ch);
|
||||
}
|
||||
refState = INVALID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!segment.isEmpty())
|
||||
segments.append(qMakePair(segment, refState==_09 ? refFlag : -1));
|
||||
|
||||
//Replace "A1", "$A1", "A$1" segment with proper one.
|
||||
QStringList result;
|
||||
typedef QPair<QString, int> PairType;
|
||||
foreach (PairType p, segments) {
|
||||
//qDebug()<<p.first<<p.second;
|
||||
if (p.second != -1 && p.second != 3) {
|
||||
CellReference oldRef(p.first);
|
||||
int row = p.second & 0x02 ? oldRef.row() : oldRef.row()-rootCell.row()+cell.row();
|
||||
int col = p.second & 0x01 ? oldRef.column() : oldRef.column()-rootCell.column()+cell.column();
|
||||
result.append(CellReference(row, col).toString(p.second & 0x02, p.second & 0x01));
|
||||
} else {
|
||||
result.append(p.first);
|
||||
}
|
||||
}
|
||||
|
||||
//OK
|
||||
return result.join(QString());
|
||||
}
|
||||
|
||||
} //namespace QXlsx
|
||||
693
platform/src/public/pub_excel/xlsx/xlsxworkbook.cpp
Normal file
693
platform/src/public/pub_excel/xlsx/xlsxworkbook.cpp
Normal file
@ -0,0 +1,693 @@
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2013-2014 Debao Zhang <hello@debao.me>
|
||||
** All right reserved.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining
|
||||
** a copy of this software and associated documentation files (the
|
||||
** "Software"), to deal in the Software without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Software, and to
|
||||
** permit persons to whom the Software is furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be
|
||||
** included in all copies or substantial portions of the Software.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
****************************************************************************/
|
||||
#include "xlsxworkbook.h"
|
||||
#include "xlsxworkbook_p.h"
|
||||
#include "xlsxsharedstrings_p.h"
|
||||
#include "xlsxworksheet.h"
|
||||
#include "xlsxchartsheet.h"
|
||||
#include "xlsxstyles_p.h"
|
||||
#include "xlsxformat.h"
|
||||
#include "xlsxworksheet_p.h"
|
||||
#include "xlsxformat_p.h"
|
||||
#include "xlsxmediafile_p.h"
|
||||
#include "xlsxutility_p.h"
|
||||
|
||||
#include <QXmlStreamWriter>
|
||||
#include <QXmlStreamReader>
|
||||
#include <QFile>
|
||||
#include <QBuffer>
|
||||
#include <QDir>
|
||||
|
||||
QT_BEGIN_NAMESPACE_XLSX
|
||||
|
||||
WorkbookPrivate::WorkbookPrivate(Workbook *q, Workbook::CreateFlag flag) :
|
||||
AbstractOOXmlFilePrivate(q, flag)
|
||||
{
|
||||
sharedStrings = QSharedPointer<SharedStrings> (new SharedStrings(flag));
|
||||
styles = QSharedPointer<Styles>(new Styles(flag));
|
||||
theme = QSharedPointer<Theme>(new Theme(flag));
|
||||
|
||||
x_window = 240;
|
||||
y_window = 15;
|
||||
window_width = 16095;
|
||||
window_height = 9660;
|
||||
|
||||
strings_to_numbers_enabled = false;
|
||||
strings_to_hyperlinks_enabled = true;
|
||||
html_to_richstring_enabled = false;
|
||||
date1904 = false;
|
||||
defaultDateFormat = QStringLiteral("yyyy-mm-dd");
|
||||
activesheetIndex = 0;
|
||||
firstsheet = 0;
|
||||
table_count = 0;
|
||||
|
||||
last_worksheet_index = 0;
|
||||
last_chartsheet_index = 0;
|
||||
last_sheet_id = 0;
|
||||
}
|
||||
|
||||
Workbook::Workbook(CreateFlag flag)
|
||||
: AbstractOOXmlFile(new WorkbookPrivate(this, flag))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Workbook::~Workbook()
|
||||
{
|
||||
}
|
||||
|
||||
bool Workbook::isDate1904() const
|
||||
{
|
||||
Q_D(const Workbook);
|
||||
return d->date1904;
|
||||
}
|
||||
|
||||
/*!
|
||||
Excel for Windows uses a default epoch of 1900 and Excel
|
||||
for Mac uses an epoch of 1904. However, Excel on either
|
||||
platform will convert automatically between one system
|
||||
and the other. Qt Xlsx stores dates in the 1900 format
|
||||
by default.
|
||||
|
||||
\note This function should be called before any date/time
|
||||
has been written.
|
||||
*/
|
||||
void Workbook::setDate1904(bool date1904)
|
||||
{
|
||||
Q_D(Workbook);
|
||||
d->date1904 = date1904;
|
||||
}
|
||||
|
||||
/*
|
||||
Enable the worksheet.write() method to convert strings
|
||||
to numbers, where possible, using float() in order to avoid
|
||||
an Excel warning about "Numbers Stored as Text".
|
||||
|
||||
The default is false
|
||||
*/
|
||||
void Workbook::setStringsToNumbersEnabled(bool enable)
|
||||
{
|
||||
Q_D(Workbook);
|
||||
d->strings_to_numbers_enabled = enable;
|
||||
}
|
||||
|
||||
bool Workbook::isStringsToNumbersEnabled() const
|
||||
{
|
||||
Q_D(const Workbook);
|
||||
return d->strings_to_numbers_enabled;
|
||||
}
|
||||
|
||||
void Workbook::setStringsToHyperlinksEnabled(bool enable)
|
||||
{
|
||||
Q_D(Workbook);
|
||||
d->strings_to_hyperlinks_enabled = enable;
|
||||
}
|
||||
|
||||
bool Workbook::isStringsToHyperlinksEnabled() const
|
||||
{
|
||||
Q_D(const Workbook);
|
||||
return d->strings_to_hyperlinks_enabled;
|
||||
}
|
||||
|
||||
void Workbook::setHtmlToRichStringEnabled(bool enable)
|
||||
{
|
||||
Q_D(Workbook);
|
||||
d->html_to_richstring_enabled = enable;
|
||||
}
|
||||
|
||||
bool Workbook::isHtmlToRichStringEnabled() const
|
||||
{
|
||||
Q_D(const Workbook);
|
||||
return d->html_to_richstring_enabled;
|
||||
}
|
||||
|
||||
QString Workbook::defaultDateFormat() const
|
||||
{
|
||||
Q_D(const Workbook);
|
||||
return d->defaultDateFormat;
|
||||
}
|
||||
|
||||
void Workbook::setDefaultDateFormat(const QString &format)
|
||||
{
|
||||
Q_D(Workbook);
|
||||
d->defaultDateFormat = format;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Create a defined name in the workbook.
|
||||
* \param name The defined name
|
||||
* \param formula The cell or range that the defined name refers to.
|
||||
* \param comment
|
||||
* \param scope The name of one worksheet, or empty which means golbal scope.
|
||||
* \return Return false if the name invalid.
|
||||
*/
|
||||
bool Workbook::defineName(const QString &name, const QString &formula, const QString &comment, const QString &scope)
|
||||
{
|
||||
Q_D(Workbook);
|
||||
|
||||
//Remove the = sign from the formula if it exists.
|
||||
QString formulaString = formula;
|
||||
if (formulaString.startsWith(QLatin1Char('=')))
|
||||
formulaString = formula.mid(1);
|
||||
|
||||
int id=-1;
|
||||
if (!scope.isEmpty()) {
|
||||
for (int i=0; i<d->sheets.size(); ++i) {
|
||||
if (d->sheets[i]->sheetName() == scope) {
|
||||
id = d->sheets[i]->sheetId();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
d->definedNamesList.append(XlsxDefineNameData(name, formulaString, comment, id));
|
||||
return true;
|
||||
}
|
||||
|
||||
AbstractSheet *Workbook::addSheet(const QString &name, AbstractSheet::SheetType type)
|
||||
{
|
||||
Q_D(Workbook);
|
||||
return insertSheet(d->sheets.size(), name, type);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
QStringList Workbook::worksheetNames() const
|
||||
{
|
||||
Q_D(const Workbook);
|
||||
return d->sheetNames;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* Used only when load the xlsx file!!
|
||||
*/
|
||||
AbstractSheet *Workbook::addSheet(const QString &name, int sheetId, AbstractSheet::SheetType type)
|
||||
{
|
||||
Q_D(Workbook);
|
||||
if (sheetId > d->last_sheet_id)
|
||||
d->last_sheet_id = sheetId;
|
||||
AbstractSheet *sheet=0;
|
||||
if (type == AbstractSheet::ST_WorkSheet) {
|
||||
sheet = new Worksheet(name, sheetId, this, F_LoadFromExists);
|
||||
} else if (type == AbstractSheet::ST_ChartSheet) {
|
||||
sheet = new Chartsheet(name, sheetId, this, F_LoadFromExists);
|
||||
} else {
|
||||
qWarning("unsupported sheet type.");
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
d->sheets.append(QSharedPointer<AbstractSheet>(sheet));
|
||||
d->sheetNames.append(name);
|
||||
return sheet;
|
||||
}
|
||||
|
||||
AbstractSheet *Workbook::insertSheet(int index, const QString &name, AbstractSheet::SheetType type)
|
||||
{
|
||||
Q_D(Workbook);
|
||||
QString sheetName = createSafeSheetName(name);
|
||||
if (!sheetName.isEmpty()) {
|
||||
//If user given an already in-used name, we should not continue any more!
|
||||
if (d->sheetNames.contains(sheetName))
|
||||
return 0;
|
||||
} else {
|
||||
if (type == AbstractSheet::ST_WorkSheet) {
|
||||
do {
|
||||
++d->last_worksheet_index;
|
||||
sheetName = QStringLiteral("Sheet%1").arg(d->last_worksheet_index);
|
||||
} while (d->sheetNames.contains(sheetName));
|
||||
} else if (type == AbstractSheet::ST_ChartSheet) {
|
||||
do {
|
||||
++d->last_chartsheet_index;
|
||||
sheetName = QStringLiteral("Chart%1").arg(d->last_chartsheet_index);
|
||||
} while (d->sheetNames.contains(sheetName));
|
||||
} else {
|
||||
qWarning("unsupported sheet type.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
++d->last_sheet_id;
|
||||
AbstractSheet *sheet;
|
||||
if (type == AbstractSheet::ST_WorkSheet)
|
||||
sheet = new Worksheet(sheetName, d->last_sheet_id, this, F_NewFromScratch);
|
||||
else
|
||||
sheet = new Chartsheet(sheetName, d->last_sheet_id, this, F_NewFromScratch);
|
||||
|
||||
d->sheets.insert(index, QSharedPointer<AbstractSheet>(sheet));
|
||||
d->sheetNames.insert(index, sheetName);
|
||||
d->activesheetIndex = index;
|
||||
return sheet;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns current active worksheet.
|
||||
*/
|
||||
AbstractSheet *Workbook::activeSheet() const
|
||||
{
|
||||
Q_D(const Workbook);
|
||||
if (d->sheets.isEmpty())
|
||||
const_cast<Workbook*>(this)->addSheet();
|
||||
return d->sheets[d->activesheetIndex].data();
|
||||
}
|
||||
|
||||
bool Workbook::setActiveSheet(int index)
|
||||
{
|
||||
Q_D(Workbook);
|
||||
if (index < 0 || index >= d->sheets.size()) {
|
||||
//warning
|
||||
return false;
|
||||
}
|
||||
d->activesheetIndex = index;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Rename the worksheet at the \a index to \a newName.
|
||||
*/
|
||||
bool Workbook::renameSheet(int index, const QString &newName)
|
||||
{
|
||||
Q_D(Workbook);
|
||||
QString name = createSafeSheetName(newName);
|
||||
if (index < 0 || index >= d->sheets.size())
|
||||
return false;
|
||||
|
||||
//If user given an already in-used name, return false
|
||||
for (int i=0; i<d->sheets.size(); ++i) {
|
||||
if (d->sheets[i]->sheetName() == name)
|
||||
return false;
|
||||
}
|
||||
|
||||
d->sheets[index]->setSheetName(name);
|
||||
d->sheetNames[index] = name;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Remove the worksheet at pos \a index.
|
||||
*/
|
||||
bool Workbook::deleteSheet(int index)
|
||||
{
|
||||
Q_D(Workbook);
|
||||
if (d->sheets.size() <= 1)
|
||||
return false;
|
||||
if (index < 0 || index >= d->sheets.size())
|
||||
return false;
|
||||
d->sheets.removeAt(index);
|
||||
d->sheetNames.removeAt(index);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Moves the worksheet form \a srcIndex to \a distIndex.
|
||||
*/
|
||||
bool Workbook::moveSheet(int srcIndex, int distIndex)
|
||||
{
|
||||
Q_D(Workbook);
|
||||
if (srcIndex == distIndex)
|
||||
return false;
|
||||
|
||||
if (srcIndex < 0 || srcIndex >= d->sheets.size())
|
||||
return false;
|
||||
|
||||
QSharedPointer<AbstractSheet> sheet = d->sheets.takeAt(srcIndex);
|
||||
d->sheetNames.takeAt(srcIndex);
|
||||
if (distIndex >= 0 || distIndex <= d->sheets.size()) {
|
||||
d->sheets.insert(distIndex, sheet);
|
||||
d->sheetNames.insert(distIndex, sheet->sheetName());
|
||||
} else {
|
||||
d->sheets.append(sheet);
|
||||
d->sheetNames.append(sheet->sheetName());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Workbook::copySheet(int index, const QString &newName)
|
||||
{
|
||||
Q_D(Workbook);
|
||||
if (index < 0 || index >= d->sheets.size())
|
||||
return false;
|
||||
|
||||
QString worksheetName = createSafeSheetName(newName);
|
||||
if (!newName.isEmpty()) {
|
||||
//If user given an already in-used name, we should not continue any more!
|
||||
if (d->sheetNames.contains(newName))
|
||||
return false;
|
||||
} else {
|
||||
int copy_index = 1;
|
||||
do {
|
||||
++copy_index;
|
||||
worksheetName = QStringLiteral("%1(%2)").arg(d->sheets[index]->sheetName()).arg(copy_index);
|
||||
} while (d->sheetNames.contains(worksheetName));
|
||||
}
|
||||
|
||||
++d->last_sheet_id;
|
||||
AbstractSheet *sheet = d->sheets[index]->copy(worksheetName, d->last_sheet_id);
|
||||
d->sheets.append(QSharedPointer<AbstractSheet> (sheet));
|
||||
d->sheetNames.append(sheet->sheetName());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns count of worksheets.
|
||||
*/
|
||||
int Workbook::sheetCount() const
|
||||
{
|
||||
Q_D(const Workbook);
|
||||
return d->sheets.count();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the sheet object at index \a sheetIndex.
|
||||
*/
|
||||
AbstractSheet *Workbook::sheet(int index) const
|
||||
{
|
||||
Q_D(const Workbook);
|
||||
if (index < 0 || index >= d->sheets.size())
|
||||
return 0;
|
||||
return d->sheets.at(index).data();
|
||||
}
|
||||
|
||||
SharedStrings *Workbook::sharedStrings() const
|
||||
{
|
||||
Q_D(const Workbook);
|
||||
return d->sharedStrings.data();
|
||||
}
|
||||
|
||||
Styles *Workbook::styles()
|
||||
{
|
||||
Q_D(Workbook);
|
||||
return d->styles.data();
|
||||
}
|
||||
|
||||
Theme *Workbook::theme()
|
||||
{
|
||||
Q_D(Workbook);
|
||||
return d->theme.data();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*
|
||||
* Unlike media files, drawing file is a property of the sheet.
|
||||
*/
|
||||
QList<Drawing *> Workbook::drawings()
|
||||
{
|
||||
Q_D(Workbook);
|
||||
QList<Drawing *> ds;
|
||||
for (int i=0; i<d->sheets.size(); ++i) {
|
||||
QSharedPointer<AbstractSheet> sheet = d->sheets[i];
|
||||
if (sheet->drawing())
|
||||
ds.append(sheet->drawing());
|
||||
}
|
||||
|
||||
return ds;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
QList<QSharedPointer<AbstractSheet> > Workbook::getSheetsByTypes(AbstractSheet::SheetType type) const
|
||||
{
|
||||
Q_D(const Workbook);
|
||||
QList<QSharedPointer<AbstractSheet> > list;
|
||||
for (int i=0; i<d->sheets.size(); ++i) {
|
||||
if (d->sheets[i]->sheetType() == type)
|
||||
list.append(d->sheets[i]);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
void Workbook::saveToXmlFile(QIODevice *device) const
|
||||
{
|
||||
Q_D(const Workbook);
|
||||
d->relationships->clear();
|
||||
if (d->sheets.isEmpty())
|
||||
const_cast<Workbook *>(this)->addSheet();
|
||||
|
||||
QXmlStreamWriter writer(device);
|
||||
|
||||
writer.writeStartDocument(QStringLiteral("1.0"), true);
|
||||
writer.writeStartElement(QStringLiteral("workbook"));
|
||||
writer.writeAttribute(QStringLiteral("xmlns"), QStringLiteral("http://schemas.openxmlformats.org/spreadsheetml/2006/main"));
|
||||
writer.writeAttribute(QStringLiteral("xmlns:r"), QStringLiteral("http://schemas.openxmlformats.org/officeDocument/2006/relationships"));
|
||||
|
||||
writer.writeEmptyElement(QStringLiteral("fileVersion"));
|
||||
writer.writeAttribute(QStringLiteral("appName"), QStringLiteral("xl"));
|
||||
writer.writeAttribute(QStringLiteral("lastEdited"), QStringLiteral("4"));
|
||||
writer.writeAttribute(QStringLiteral("lowestEdited"), QStringLiteral("4"));
|
||||
writer.writeAttribute(QStringLiteral("rupBuild"), QStringLiteral("4505"));
|
||||
// writer.writeAttribute(QStringLiteral("codeName"), QStringLiteral("{37E998C4-C9E5-D4B9-71C8-EB1FF731991C}"));
|
||||
|
||||
writer.writeEmptyElement(QStringLiteral("workbookPr"));
|
||||
if (d->date1904)
|
||||
writer.writeAttribute(QStringLiteral("date1904"), QStringLiteral("1"));
|
||||
writer.writeAttribute(QStringLiteral("defaultThemeVersion"), QStringLiteral("124226"));
|
||||
|
||||
writer.writeStartElement(QStringLiteral("bookViews"));
|
||||
writer.writeEmptyElement(QStringLiteral("workbookView"));
|
||||
writer.writeAttribute(QStringLiteral("xWindow"), QString::number(d->x_window));
|
||||
writer.writeAttribute(QStringLiteral("yWindow"), QString::number(d->y_window));
|
||||
writer.writeAttribute(QStringLiteral("windowWidth"), QString::number(d->window_width));
|
||||
writer.writeAttribute(QStringLiteral("windowHeight"), QString::number(d->window_height));
|
||||
//Store the firstSheet when it isn't the default
|
||||
//For example, when "the first sheet 0 is hidden", the first sheet will be 1
|
||||
if (d->firstsheet > 0)
|
||||
writer.writeAttribute(QStringLiteral("firstSheet"), QString::number(d->firstsheet + 1));
|
||||
//Store the activeTab when it isn't the first sheet
|
||||
if (d->activesheetIndex > 0)
|
||||
writer.writeAttribute(QStringLiteral("activeTab"), QString::number(d->activesheetIndex));
|
||||
writer.writeEndElement();//bookViews
|
||||
|
||||
writer.writeStartElement(QStringLiteral("sheets"));
|
||||
int worksheetIndex = 0;
|
||||
int chartsheetIndex = 0;
|
||||
for (int i=0; i<d->sheets.size(); ++i) {
|
||||
QSharedPointer<AbstractSheet> sheet = d->sheets[i];
|
||||
writer.writeEmptyElement(QStringLiteral("sheet"));
|
||||
writer.writeAttribute(QStringLiteral("name"), sheet->sheetName());
|
||||
writer.writeAttribute(QStringLiteral("sheetId"), QString::number(sheet->sheetId()));
|
||||
if (sheet->sheetState() == AbstractSheet::SS_Hidden)
|
||||
writer.writeAttribute(QStringLiteral("state"), QStringLiteral("hidden"));
|
||||
else if (sheet->sheetState() == AbstractSheet::SS_VeryHidden)
|
||||
writer.writeAttribute(QStringLiteral("state"), QStringLiteral("veryHidden"));
|
||||
|
||||
if (sheet->sheetType() == AbstractSheet::ST_WorkSheet)
|
||||
d->relationships->addDocumentRelationship(QStringLiteral("/worksheet"), QStringLiteral("worksheets/sheet%1.xml").arg(++worksheetIndex));
|
||||
else
|
||||
d->relationships->addDocumentRelationship(QStringLiteral("/chartsheet"), QStringLiteral("chartsheets/sheet%1.xml").arg(++chartsheetIndex));
|
||||
|
||||
writer.writeAttribute(QStringLiteral("r:id"), QStringLiteral("rId%1").arg(d->relationships->count()));
|
||||
}
|
||||
writer.writeEndElement();//sheets
|
||||
|
||||
if (d->externalLinks.size() > 0) {
|
||||
writer.writeStartElement(QStringLiteral("externalReferences"));
|
||||
for (int i=0; i<d->externalLinks.size(); ++i) {
|
||||
writer.writeEmptyElement(QStringLiteral("externalReference"));
|
||||
d->relationships->addDocumentRelationship(QStringLiteral("/externalLink"), QStringLiteral("externalLinks/externalLink%1.xml").arg(i+1));
|
||||
writer.writeAttribute(QStringLiteral("r:id"), QStringLiteral("rId%1").arg(d->relationships->count()));
|
||||
}
|
||||
writer.writeEndElement();//externalReferences
|
||||
}
|
||||
|
||||
if (!d->definedNamesList.isEmpty()) {
|
||||
writer.writeStartElement(QStringLiteral("definedNames"));
|
||||
foreach (XlsxDefineNameData data, d->definedNamesList) {
|
||||
writer.writeStartElement(QStringLiteral("definedName"));
|
||||
writer.writeAttribute(QStringLiteral("name"), data.name);
|
||||
if (!data.comment.isEmpty())
|
||||
writer.writeAttribute(QStringLiteral("comment"), data.comment);
|
||||
if (data.sheetId != -1) {
|
||||
//find the local index of the sheet.
|
||||
for (int i=0; i<d->sheets.size(); ++i) {
|
||||
if (d->sheets[i]->sheetId() == data.sheetId) {
|
||||
writer.writeAttribute(QStringLiteral("localSheetId"), QString::number(i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
writer.writeCharacters(data.formula);
|
||||
writer.writeEndElement();//definedName
|
||||
}
|
||||
writer.writeEndElement();//definedNames
|
||||
}
|
||||
|
||||
writer.writeStartElement(QStringLiteral("calcPr"));
|
||||
writer.writeAttribute(QStringLiteral("calcId"), QStringLiteral("124519"));
|
||||
writer.writeEndElement(); //calcPr
|
||||
|
||||
writer.writeEndElement();//workbook
|
||||
writer.writeEndDocument();
|
||||
|
||||
d->relationships->addDocumentRelationship(QStringLiteral("/theme"), QStringLiteral("theme/theme1.xml"));
|
||||
d->relationships->addDocumentRelationship(QStringLiteral("/styles"), QStringLiteral("styles.xml"));
|
||||
if (!sharedStrings()->isEmpty())
|
||||
d->relationships->addDocumentRelationship(QStringLiteral("/sharedStrings"), QStringLiteral("sharedStrings.xml"));
|
||||
}
|
||||
|
||||
bool Workbook::loadFromXmlFile(QIODevice *device)
|
||||
{
|
||||
Q_D(Workbook);
|
||||
|
||||
QXmlStreamReader reader(device);
|
||||
while (!reader.atEnd()) {
|
||||
QXmlStreamReader::TokenType token = reader.readNext();
|
||||
if (token == QXmlStreamReader::StartElement) {
|
||||
if (reader.name() == QLatin1String("sheet")) {
|
||||
QXmlStreamAttributes attributes = reader.attributes();
|
||||
const QString name = attributes.value(QLatin1String("name")).toString();
|
||||
int sheetId = attributes.value(QLatin1String("sheetId")).toString().toInt();
|
||||
const QString rId = attributes.value(QLatin1String("r:id")).toString();
|
||||
const QStringRef &stateString = attributes.value(QLatin1String("state"));
|
||||
AbstractSheet::SheetState state = AbstractSheet::SS_Visible;
|
||||
if (stateString == QLatin1String("hidden"))
|
||||
state = AbstractSheet::SS_Hidden;
|
||||
else if (stateString == QLatin1String("veryHidden"))
|
||||
state = AbstractSheet::SS_VeryHidden;
|
||||
|
||||
XlsxRelationship relationship = d->relationships->getRelationshipById(rId);
|
||||
|
||||
AbstractSheet::SheetType type = AbstractSheet::ST_WorkSheet;
|
||||
if (relationship.type.endsWith(QLatin1String("/worksheet")))
|
||||
type = AbstractSheet::ST_WorkSheet;
|
||||
else if (relationship.type.endsWith(QLatin1String("/chartsheet")))
|
||||
type = AbstractSheet::ST_ChartSheet;
|
||||
else if (relationship.type.endsWith(QLatin1String("/dialogsheet")))
|
||||
type = AbstractSheet::ST_DialogSheet;
|
||||
else if (relationship.type.endsWith(QLatin1String("/xlMacrosheet")))
|
||||
type = AbstractSheet::ST_MacroSheet;
|
||||
else
|
||||
qWarning("unknown sheet type");
|
||||
|
||||
AbstractSheet *sheet = addSheet(name, sheetId, type);
|
||||
sheet->setSheetState(state);
|
||||
const QString fullPath = QDir::cleanPath(splitPath(filePath())[0] +QLatin1String("/")+ relationship.target);
|
||||
sheet->setFilePath(fullPath);
|
||||
} else if (reader.name() == QLatin1String("workbookPr")) {
|
||||
QXmlStreamAttributes attrs = reader.attributes();
|
||||
if (attrs.hasAttribute(QLatin1String("date1904")))
|
||||
d->date1904 = true;
|
||||
} else if (reader.name() == QLatin1String("bookviews")) {
|
||||
while (!(reader.name() == QLatin1String("bookviews") && reader.tokenType() == QXmlStreamReader::EndElement)) {
|
||||
reader.readNextStartElement();
|
||||
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
||||
if (reader.name() == QLatin1String("workbookView")) {
|
||||
QXmlStreamAttributes attrs = reader.attributes();
|
||||
if (attrs.hasAttribute(QLatin1String("xWindow")))
|
||||
d->x_window = attrs.value(QLatin1String("xWindow")).toString().toInt();
|
||||
if (attrs.hasAttribute(QLatin1String("yWindow")))
|
||||
d->y_window = attrs.value(QLatin1String("yWindow")).toString().toInt();
|
||||
if (attrs.hasAttribute(QLatin1String("windowWidth")))
|
||||
d->window_width = attrs.value(QLatin1String("windowWidth")).toString().toInt();
|
||||
if (attrs.hasAttribute(QLatin1String("windowHeight")))
|
||||
d->window_height = attrs.value(QLatin1String("windowHeight")).toString().toInt();
|
||||
if (attrs.hasAttribute(QLatin1String("firstSheet")))
|
||||
d->firstsheet = attrs.value(QLatin1String("firstSheet")).toString().toInt();
|
||||
if (attrs.hasAttribute(QLatin1String("activeTab")))
|
||||
d->activesheetIndex = attrs.value(QLatin1String("activeTab")).toString().toInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (reader.name() == QLatin1String("externalReference")) {
|
||||
QXmlStreamAttributes attributes = reader.attributes();
|
||||
const QString rId = attributes.value(QLatin1String("r:id")).toString();
|
||||
XlsxRelationship relationship = d->relationships->getRelationshipById(rId);
|
||||
|
||||
QSharedPointer<SimpleOOXmlFile> link(new SimpleOOXmlFile(F_LoadFromExists));
|
||||
const QString fullPath = QDir::cleanPath(splitPath(filePath())[0] +QLatin1String("/")+ relationship.target);
|
||||
link->setFilePath(fullPath);
|
||||
d->externalLinks.append(link);
|
||||
} else if (reader.name() == QLatin1String("definedName")) {
|
||||
QXmlStreamAttributes attrs = reader.attributes();
|
||||
XlsxDefineNameData data;
|
||||
|
||||
data.name = attrs.value(QLatin1String("name")).toString();
|
||||
if (attrs.hasAttribute(QLatin1String("comment")))
|
||||
data.comment = attrs.value(QLatin1String("comment")).toString();
|
||||
if (attrs.hasAttribute(QLatin1String("localSheetId"))) {
|
||||
int localId = attrs.value(QLatin1String("localSheetId")).toString().toInt();
|
||||
int sheetId = d->sheets.at(localId)->sheetId();
|
||||
data.sheetId = sheetId;
|
||||
}
|
||||
data.formula = reader.readElementText();
|
||||
d->definedNamesList.append(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
QList<QSharedPointer<MediaFile> > Workbook::mediaFiles() const
|
||||
{
|
||||
Q_D(const Workbook);
|
||||
|
||||
return d->mediaFiles;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
void Workbook::addMediaFile(QSharedPointer<MediaFile> media, bool force)
|
||||
{
|
||||
Q_D(Workbook);
|
||||
if (!force) {
|
||||
for (int i=0; i<d->mediaFiles.size(); ++i) {
|
||||
if (d->mediaFiles[i]->hashKey() == media->hashKey()) {
|
||||
media->setIndex(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
media->setIndex(d->mediaFiles.size());
|
||||
d->mediaFiles.append(media);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
QList<QSharedPointer<Chart> > Workbook::chartFiles() const
|
||||
{
|
||||
Q_D(const Workbook);
|
||||
|
||||
return d->chartFiles;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
void Workbook::addChartFile(QSharedPointer<Chart> chart)
|
||||
{
|
||||
Q_D(Workbook);
|
||||
|
||||
if (!d->chartFiles.contains(chart))
|
||||
d->chartFiles.append(chart);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE_XLSX
|
||||
2342
platform/src/public/pub_excel/xlsx/xlsxworksheet.cpp
Normal file
2342
platform/src/public/pub_excel/xlsx/xlsxworksheet.cpp
Normal file
File diff suppressed because it is too large
Load Diff
75
platform/src/public/pub_excel/xlsx/xlsxzipreader.cpp
Normal file
75
platform/src/public/pub_excel/xlsx/xlsxzipreader.cpp
Normal file
@ -0,0 +1,75 @@
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2013-2014 Debao Zhang <hello@debao.me>
|
||||
** All right reserved.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining
|
||||
** a copy of this software and associated documentation files (the
|
||||
** "Software"), to deal in the Software without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Software, and to
|
||||
** permit persons to whom the Software is furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be
|
||||
** included in all copies or substantial portions of the Software.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "xlsxzipreader_p.h"
|
||||
|
||||
#include <private/qzipreader_p.h>
|
||||
#include <QVector>
|
||||
#include <QList>
|
||||
|
||||
namespace QXlsx {
|
||||
|
||||
ZipReader::ZipReader(const QString &filePath) :
|
||||
m_reader(new QZipReader(filePath))
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
ZipReader::ZipReader(QIODevice *device) :
|
||||
m_reader(new QZipReader(device))
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
ZipReader::~ZipReader()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ZipReader::init()
|
||||
{
|
||||
QList<QZipReader::FileInfo> allFiles = m_reader->fileInfoList().toList();
|
||||
foreach (const QZipReader::FileInfo &fi, allFiles) {
|
||||
if (fi.isFile)
|
||||
m_filePaths.append(fi.filePath);
|
||||
}
|
||||
}
|
||||
|
||||
bool ZipReader::exists() const
|
||||
{
|
||||
return m_reader->exists();
|
||||
}
|
||||
|
||||
QStringList ZipReader::filePaths() const
|
||||
{
|
||||
return m_filePaths;
|
||||
}
|
||||
|
||||
QByteArray ZipReader::fileData(const QString &fileName) const
|
||||
{
|
||||
return m_reader->fileData(fileName);
|
||||
}
|
||||
|
||||
} // namespace QXlsx
|
||||
68
platform/src/public/pub_excel/xlsx/xlsxzipwriter.cpp
Normal file
68
platform/src/public/pub_excel/xlsx/xlsxzipwriter.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2013-2014 Debao Zhang <hello@debao.me>
|
||||
** All right reserved.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining
|
||||
** a copy of this software and associated documentation files (the
|
||||
** "Software"), to deal in the Software without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Software, and to
|
||||
** permit persons to whom the Software is furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be
|
||||
** included in all copies or substantial portions of the Software.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
****************************************************************************/
|
||||
#include "xlsxzipwriter_p.h"
|
||||
#include <QDebug>
|
||||
#include <private/qzipwriter_p.h>
|
||||
|
||||
namespace QXlsx {
|
||||
|
||||
ZipWriter::ZipWriter(const QString &filePath)
|
||||
{
|
||||
m_writer = new QZipWriter(filePath, QIODevice::WriteOnly);
|
||||
m_writer->setCompressionPolicy(QZipWriter::AutoCompress);
|
||||
}
|
||||
|
||||
ZipWriter::ZipWriter(QIODevice *device)
|
||||
{
|
||||
m_writer = new QZipWriter(device);
|
||||
m_writer->setCompressionPolicy(QZipWriter::AutoCompress);
|
||||
}
|
||||
|
||||
ZipWriter::~ZipWriter()
|
||||
{
|
||||
delete m_writer;
|
||||
}
|
||||
|
||||
bool ZipWriter::error() const
|
||||
{
|
||||
return m_writer->status() != QZipWriter::NoError;
|
||||
}
|
||||
|
||||
void ZipWriter::addFile(const QString &filePath, QIODevice *device)
|
||||
{
|
||||
m_writer->addFile(filePath, device);
|
||||
}
|
||||
|
||||
void ZipWriter::addFile(const QString &filePath, const QByteArray &data)
|
||||
{
|
||||
m_writer->addFile(filePath, data);
|
||||
}
|
||||
|
||||
void ZipWriter::close()
|
||||
{
|
||||
m_writer->close();
|
||||
}
|
||||
|
||||
} // namespace QXlsx
|
||||
@ -11,7 +11,19 @@
|
||||
#include "log4cplus/asyncappender.h"
|
||||
#include "log4cplus/fileappender.h"
|
||||
#include "boost/filesystem.hpp"
|
||||
|
||||
//< 屏蔽xml_parser编译告警
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-copy"
|
||||
#endif
|
||||
|
||||
#include "boost/property_tree/xml_parser.hpp"
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#include "boost/typeof/typeof.hpp"
|
||||
#include "boost/thread/thread.hpp"
|
||||
|
||||
@ -212,7 +224,7 @@ bool searchLogger( const std::string& sPathFile )
|
||||
const bool bCreateDirs = true;
|
||||
const string sAppender = "RollingFileAppender";
|
||||
//const string sEncoding = "UTF-8";
|
||||
const string sConversionPattern = "%D{%y-%m-%d %H:%M:%S} [%t] %-5p %x %l - %m %n";
|
||||
const string sConversionPattern = "%D{%y-%m-%d %H:%M:%S.%q} %p %T %l - %m %n";
|
||||
const string sAppName = g_sAppName;
|
||||
const bool bAsync = false;
|
||||
const int nQueueSize = 100;
|
||||
@ -320,7 +332,7 @@ void addDefaultLogger()
|
||||
const int nMaxBackupIndex = 10;
|
||||
const string sFile = "default.log";
|
||||
const bool bCreateDirs = true;
|
||||
const string sConversionPattern = "%D{%y-%m-%d %H:%M:%S} [%t] %-5p %x %l - %m %n";
|
||||
const string sConversionPattern = "%D{%y-%m-%d %H:%M:%S.%q} %p %T %l - %m %n";
|
||||
const string sAppName = g_sAppName;
|
||||
|
||||
string sTmpFile = getLogFilePathName( sAppName, sFile );
|
||||
|
||||
@ -14,8 +14,20 @@
|
||||
#include "boost/lexical_cast.hpp"
|
||||
#include "boost/format.hpp"
|
||||
#include "boost/asio/ip/host_name.hpp"
|
||||
|
||||
//< 屏蔽xml_parser编译告警
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-copy"
|
||||
#endif
|
||||
|
||||
#include "boost/property_tree/xml_parser.hpp"
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
|
||||
#include "pub_logger_api/logger.h"
|
||||
#include "pub_utility_api/FileUtil.h"
|
||||
#include "SysInfoData.h"
|
||||
|
||||
@ -1027,7 +1027,7 @@ unsigned int CSysInfoImp::getUniqueIdOfNodeInfo()
|
||||
}
|
||||
|
||||
// 获取字符串crc
|
||||
nRet = calcCRC32( (unsigned char*)sInfo.c_str(), sInfo.size() );
|
||||
nRet = calcCRC32( (unsigned char*)sInfo.c_str(), static_cast<int>(sInfo.size()) );
|
||||
|
||||
// 基本不可能发生,以防万一,不,是以防43亿分之一
|
||||
if ( nRet == 0 )
|
||||
|
||||
@ -64,7 +64,7 @@ int iot_public::CProcessSharedMutex::init( char *cName, int nKey )
|
||||
pthread_mutexattr_init(&mutexAttr);/*初始化互斥锁的属性*/
|
||||
pthread_mutexattr_setpshared(&mutexAttr,PTHREAD_PROCESS_SHARED);/*设置互斥锁的属性*/
|
||||
pthread_mutexattr_setprotocol(&mutexAttr, PTHREAD_PRIO_INHERIT);
|
||||
pthread_mutexattr_setrobust_np(&mutexAttr,PTHREAD_MUTEX_ROBUST_NP);
|
||||
pthread_mutexattr_setrobust(&mutexAttr,PTHREAD_MUTEX_ROBUST_NP);
|
||||
if ( 0 != pthread_mutex_init(m_pLock,&mutexAttr) )/*互斥锁的初始化*/
|
||||
{
|
||||
LOGERROR("创建互斥锁 %s 时,初始化互斥锁失败,shmId=%d", m_cName, nShmId);
|
||||
@ -138,7 +138,7 @@ int iot_public::CProcessSharedMutex::lock()
|
||||
if ( nRet == EOWNERDEAD )
|
||||
{
|
||||
LOGERROR("互斥锁 %s 上次持有者异常退出", m_cName);
|
||||
nRet = pthread_mutex_consistent_np( m_pLock );
|
||||
nRet = pthread_mutex_consistent( m_pLock );
|
||||
if ( 0 == nRet )
|
||||
{
|
||||
LOGWARN("互斥锁 %s 从上次异常退出中恢复正常", m_cName);
|
||||
|
||||
@ -4,7 +4,19 @@
|
||||
@author 曹顶法
|
||||
*/
|
||||
#include "pub_utility_api/CommonConfigParse.h"
|
||||
|
||||
//< 屏蔽xml_parser编译告警
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-copy"
|
||||
#endif
|
||||
|
||||
#include "boost/property_tree/xml_parser.hpp"
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#include "boost/typeof/typeof.hpp"
|
||||
#include "boost/filesystem.hpp"
|
||||
#include "Common.h"
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
#include "pub_logger_api/logger.h"
|
||||
#include "pub_utility_api/FileUtil.h"
|
||||
#include "pub_utility_api/CommonConfigParse.h"
|
||||
|
||||
#include "pub_utility_api/I18N.h"
|
||||
#include "pub_utility_api/FileStyle.h"
|
||||
|
||||
namespace iot_public
|
||||
@ -40,27 +40,41 @@ std::string CFileStyle::getCurStyle( const std::string &strDefault )
|
||||
}
|
||||
|
||||
|
||||
std::string CFileStyle::getPathOfStyleFile( const std::string &strFileName, const std::string &strPlatOrProd,
|
||||
std::string CFileStyle::getPathOfStyleFile( const std::string &strFileName,
|
||||
const std::string &strDefaultLang,
|
||||
const std::string &strDefaultStyle )
|
||||
{
|
||||
boost::filesystem::path objFullPath = CFileUtil::getCurModuleDir();
|
||||
objFullPath /= "../../" + strPlatOrProd + "/common/style/" + getCurStyle() + "/" + strFileName;
|
||||
|
||||
if ( boost::filesystem::exists( objFullPath ))
|
||||
return objFullPath.string();
|
||||
|
||||
//< 如果样式配置文件配错,比如老工程有blue样式,当前是没有的
|
||||
std::string strCurLang;
|
||||
std::string strCurStyle;
|
||||
if(!strDefaultLang.empty())
|
||||
{
|
||||
LOGERROR( "getPathOfStyleFile(): 未找到样式文件[%s],尝试使用默认样式[%s]",
|
||||
objFullPath.c_str(), strDefaultStyle.c_str());
|
||||
objFullPath = CFileUtil::getCurModuleDir();
|
||||
objFullPath /= "../../" + strPlatOrProd + "/common/style/" + strDefaultStyle + "/" + strFileName;
|
||||
if ( boost::filesystem::exists( objFullPath ))
|
||||
return objFullPath.string();
|
||||
strCurLang = strDefaultLang;
|
||||
}
|
||||
else
|
||||
{
|
||||
strCurLang = getCurLanguage();
|
||||
}
|
||||
|
||||
LOGERROR( "getPathOfStyleFile(): 未找到样式文件[%s],返回空", objFullPath.c_str());
|
||||
return "";
|
||||
if(!strDefaultStyle.empty())
|
||||
{
|
||||
strCurStyle = strDefaultStyle;
|
||||
}
|
||||
else
|
||||
{
|
||||
strCurStyle = getCurStyle();
|
||||
}
|
||||
|
||||
boost::filesystem::path objFullPath = CFileUtil::getCurModuleDir();
|
||||
|
||||
if( objFullPath.string().empty() )
|
||||
{
|
||||
LOGERROR( "getPathOfStyleFile(): 未找到样式文件[%s],返回空", objFullPath.c_str());
|
||||
return "";
|
||||
}
|
||||
|
||||
objFullPath /= "../../resource/"+ strCurLang +"/style/" + strCurStyle + "/" + strFileName;
|
||||
|
||||
return objFullPath.string();
|
||||
}
|
||||
|
||||
} //namespace iot_public
|
||||
|
||||
@ -42,7 +42,13 @@ std::string CFileUtil::getCurModuleDir()
|
||||
|
||||
::memset( pcDirectory, 0, sizeof( pcDirectory ));
|
||||
#if defined(WIN32)
|
||||
::GetModuleFileNameA(NULL, pcDirectory, BUF_LEN);
|
||||
wchar_t pwcDirectory[BUF_LEN];
|
||||
::memset( pwcDirectory, 0, sizeof( pwcDirectory ));
|
||||
|
||||
::GetModuleFileNameW(NULL, pwcDirectory, BUF_LEN);
|
||||
|
||||
int len = WideCharToMultiByte(CP_UTF8, 0, pwcDirectory, -1, NULL, 0, NULL, NULL);
|
||||
WideCharToMultiByte(CP_UTF8, 0, pwcDirectory, -1, pcDirectory, (len > BUF_LEN ? BUF_LEN : len), NULL, NULL);
|
||||
#elif defined(__linux)
|
||||
readlink( "/proc/self/exe", pcDirectory, BUF_LEN );
|
||||
#elif defined(_AIX)
|
||||
@ -322,7 +328,7 @@ std::string CFileUtil::getPathOfCfgFile( const std::string &strFileName, const s
|
||||
//< 不判 boost::filesystem::is_regular_file( objFullPath ),允许传入目录名
|
||||
if ( boost::filesystem::exists( objFullPath ))
|
||||
{
|
||||
LOGINFO( "getPathOfCfgFile(): 使用data下配置文件[%s]", objFullPath.c_str());
|
||||
LOGINFO( "getPathOfCfgFile(): 使用data下配置文件[%s]", objFullPath.string().c_str());
|
||||
return objFullPath.string();
|
||||
}
|
||||
|
||||
@ -339,33 +345,30 @@ std::string CFileUtil::getPathOfCfgFile( const std::string &strFileName, const s
|
||||
|
||||
|
||||
std::string CFileUtil::getPathOfResFile( const std::string &strFileName,
|
||||
const std::string &strPlatOrProd,
|
||||
const std::string &strDefaultLang )
|
||||
{
|
||||
//< 获取一次开销相对较大,保存下来
|
||||
const std::string &&strCurDir = CFileUtil::getCurModuleDir();
|
||||
const std::string &&strCurLang = getCurLanguage( strDefaultLang );
|
||||
std::string strCurLang;
|
||||
if(strDefaultLang.empty())
|
||||
{
|
||||
strCurLang = getCurLanguage();
|
||||
}
|
||||
else
|
||||
{
|
||||
strCurLang = strDefaultLang;
|
||||
}
|
||||
|
||||
//< 判断是否存在,外部代码可省去判断,只需判断是否为空
|
||||
boost::filesystem::path objFullPath = strCurDir;
|
||||
objFullPath /= "../../" + strPlatOrProd + "/common/resource/" + strCurLang;
|
||||
objFullPath /= "../../resource/" + strCurLang;
|
||||
objFullPath /= strFileName;
|
||||
//< 不判 boost::filesystem::is_regular_file( objFullPath ),允许传入目录名
|
||||
if ( boost::filesystem::exists( objFullPath ))
|
||||
return objFullPath.string();
|
||||
|
||||
//< 如果默认语言和当前语言不一样,再尝试默认语言
|
||||
if ( strCurLang != strDefaultLang )
|
||||
{
|
||||
objFullPath = strCurDir;
|
||||
objFullPath /= "../../" + strPlatOrProd + "/common/resource/" + strDefaultLang;
|
||||
objFullPath /= strFileName;
|
||||
//< 不判 boost::filesystem::is_regular_file( objFullPath ),允许传入目录名
|
||||
if ( boost::filesystem::exists( objFullPath ))
|
||||
return objFullPath.string();
|
||||
}
|
||||
|
||||
LOGERROR( "getPathOfResFile(): 未找到资源文件[%s],返回空", strFileName.c_str());
|
||||
auto strFullPath=(objFullPath).string();
|
||||
LOGERROR( "parent[%s] getPathOfResFile(): 未找到资源文件[%s],返回空",strFullPath.c_str(), strFileName.c_str());
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
#include "boost/filesystem.hpp"
|
||||
|
||||
#include <boost/concept_check.hpp>
|
||||
#include "common/Common.h"
|
||||
#include "pub_logger_api/logger.h"
|
||||
#include "pub_utility_api/FileUtil.h"
|
||||
@ -29,12 +29,14 @@ std::string getCurLanguage( const std::string &strDefault )
|
||||
|
||||
std::string strLanguage = std::move( config.getStringWithDefault( "language", "language", strDefault ));
|
||||
LOGDEBUG( "getCurLanguage(): 获得的国际化语言是[%s]", strLanguage.c_str());
|
||||
return std::move( strLanguage );
|
||||
return strLanguage;
|
||||
}
|
||||
|
||||
|
||||
bool initI18N( const std::string &strRelativePath, const std::string &strFileName, const std::string &strPlatOrProd )
|
||||
{
|
||||
boost::ignore_unused_variable_warning(strPlatOrProd);
|
||||
|
||||
//获得国际化语言
|
||||
const std::string strLanguage = std::move( getCurLanguage());
|
||||
|
||||
@ -47,7 +49,7 @@ bool initI18N( const std::string &strRelativePath, const std::string &strFileNam
|
||||
return false;
|
||||
}
|
||||
boost::filesystem::path objPathTemp = strCurDir;
|
||||
objPathTemp /= "../../" + strPlatOrProd + "/common/resource/";
|
||||
objPathTemp /= "../../resource/";
|
||||
const std::string strRootPath = objPathTemp.string();
|
||||
|
||||
//设置boost messages_info
|
||||
@ -83,4 +85,4 @@ bool initI18N( const std::string &strRelativePath, const std::string &strFileNam
|
||||
}
|
||||
|
||||
|
||||
} //< namespace iot_public
|
||||
} //< namespace iot_public
|
||||
|
||||
@ -111,7 +111,7 @@ bool iot_public::CSingleProcInstance::hasInstanceRunning(const string& strUnique
|
||||
{
|
||||
std::transform(strName.begin(), strName.end(), strName.begin(), ::tolower);
|
||||
}
|
||||
strName = "__kbdct_" + strName;
|
||||
strName = "__iot_" + strName;
|
||||
if (!g_objGlobalMutex_.create(strName.c_str()))
|
||||
{
|
||||
//_assert(false);
|
||||
@ -143,7 +143,7 @@ bool iot_public::CSingleProcInstance::hasInstanceRunning(const string& strUnique
|
||||
{
|
||||
std::transform(strName.begin(), strName.end(), strName.begin(), ::tolower);
|
||||
}
|
||||
strName = TMPDIR"/__kbdct_" + strName;
|
||||
strName = TMPDIR"/__iot_" + strName;
|
||||
int fdLockFile;
|
||||
struct flock fl;
|
||||
/* 打开锁文件 */
|
||||
|
||||
@ -10,12 +10,10 @@ win32{
|
||||
}
|
||||
|
||||
# arm下的release版本关闭死锁检测,节省资源开销
|
||||
contains(QMAKE_HOST.arch, aarch64)
|
||||
{
|
||||
CONFIG(release, debug|release)
|
||||
{
|
||||
DEFINES += ISCS_DISABLE_DEADLOCK_CHECK
|
||||
}
|
||||
contains(QMAKE_HOST.arch, aarch64) | linux-aarch64* {
|
||||
CONFIG(release, debug|release) {
|
||||
DEFINES += ISCS_DISABLE_DEADLOCK_CHECK
|
||||
}
|
||||
}
|
||||
|
||||
# Input
|
||||
|
||||
204
platform/src/public/pub_widget/AlertMessageBox.cpp
Normal file
204
platform/src/public/pub_widget/AlertMessageBox.cpp
Normal file
@ -0,0 +1,204 @@
|
||||
#include "pub_widget/AlertMessageBox.h"
|
||||
#include <QLabel>
|
||||
#include <QResizeEvent>
|
||||
#include <QDesktopWidget>
|
||||
#include <QApplication>
|
||||
#include <QDebug>
|
||||
|
||||
AlertMessageBox* AlertMessageBox::m_handle = 0;
|
||||
AlertMessageBox::AlertMessageBox( QWidget *parent ) :
|
||||
QMenu( parent )
|
||||
, m_hideCount( 0 )
|
||||
, m_hideTransparent(10)
|
||||
, m_hideTotal( 18 )
|
||||
{
|
||||
setWindowFlags( windowFlags() | Qt::FramelessWindowHint );
|
||||
setAttribute( Qt::WA_TranslucentBackground );//设置背景透明
|
||||
|
||||
m_showIcon = new AdaptImage( this );
|
||||
m_showIcon->setMouseTracking( true );
|
||||
m_showText = new QLabel( this );
|
||||
m_showText->setMouseTracking( true );
|
||||
m_showText->setAlignment( Qt::AlignCenter );
|
||||
m_showText->setWordWrap(true);
|
||||
|
||||
m_stayTimer = new QTimer( this );
|
||||
m_hideTimer = new QTimer( this );
|
||||
|
||||
connect( m_stayTimer, SIGNAL( timeout() ), this, SLOT( slot_stay() ) );
|
||||
connect( m_hideTimer, SIGNAL( timeout() ), this, SLOT( slot_hide() ) );
|
||||
|
||||
setMouseTracking( true );
|
||||
}
|
||||
|
||||
void AlertMessageBox::resizeEvent( QResizeEvent *ev )
|
||||
{
|
||||
QMenu::resizeEvent( ev );
|
||||
const int w = ev->size().width();
|
||||
const int h = ev->size().height();
|
||||
|
||||
m_showIcon->setGeometry( 30, (h-42)/2, 42, 42 );
|
||||
m_showText->setGeometry( 30+42+10, 0, w - (30+42+10+10), h );
|
||||
}
|
||||
|
||||
void AlertMessageBox::showEvent( QShowEvent *ev )
|
||||
{
|
||||
m_pos = QCursor::pos();
|
||||
m_hideCount = 0;
|
||||
setWindowOpacity( 1 );
|
||||
m_hideTimer->stop();
|
||||
m_stayTimer->start( 1000 );
|
||||
QMenu::showEvent( ev );
|
||||
|
||||
}
|
||||
|
||||
void AlertMessageBox::hideEvent( QHideEvent *ev )
|
||||
{
|
||||
m_hideCount = 0;
|
||||
setWindowOpacity( 1 );
|
||||
m_stayTimer->stop();
|
||||
m_hideTimer->stop();
|
||||
m_showText->clear();
|
||||
QMenu::hideEvent( ev );
|
||||
|
||||
}
|
||||
|
||||
void AlertMessageBox::mousePressEvent( QMouseEvent *ev )
|
||||
{
|
||||
hide();
|
||||
QMenu::mousePressEvent( ev );
|
||||
}
|
||||
|
||||
void AlertMessageBox::mouseMoveEvent(QMouseEvent *ev)
|
||||
{
|
||||
QMenu::mouseMoveEvent( ev );
|
||||
/* 鼠标移动即开始隐藏窗口 */
|
||||
if ( m_pos != QCursor::pos() )
|
||||
{
|
||||
m_stayTimer->stop();
|
||||
if ( !m_hideTimer->isActive() )
|
||||
{
|
||||
m_hideTimer->start( 100 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AlertMessageBox::setIcon( N_MSG_BOX_ICON icon )
|
||||
{
|
||||
switch ( icon )//初始化图标
|
||||
{
|
||||
case ICON_WARNING:
|
||||
{
|
||||
m_showIcon->setProperty("MSG_TYPE","ICON_WARNING");
|
||||
}
|
||||
break;
|
||||
case ICON_ERROR:
|
||||
{
|
||||
m_showIcon->setProperty("MSG_TYPE","ICON_ERROR");
|
||||
}
|
||||
break;
|
||||
case ICON_INFORMATION:
|
||||
{
|
||||
m_showIcon->setProperty("MSG_TYPE","ICON_INFORMATION");
|
||||
}
|
||||
break;
|
||||
case ICON_QUESTION:
|
||||
{
|
||||
m_showIcon->setProperty("MSG_TYPE","ICON_QUESTION");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
m_showIcon->setProperty("MSG_TYPE","ICON_DEFAULT");
|
||||
break;
|
||||
}
|
||||
|
||||
m_showIcon->style()->polish(m_showIcon);
|
||||
|
||||
}
|
||||
|
||||
void AlertMessageBox::setText( const QString &text )
|
||||
{
|
||||
m_showText->setText( text );
|
||||
adjustTextToFixWidth( text );
|
||||
}
|
||||
|
||||
void AlertMessageBox::adjustTextToFixWidth( const QString & text )
|
||||
{
|
||||
QFontMetrics fm ( m_showText->font() );
|
||||
int textWidth = fm.width( text );
|
||||
int nWidth = this->width() - 160;
|
||||
if ( nWidth < textWidth )
|
||||
{
|
||||
m_showText->setAlignment( Qt::AlignVCenter| Qt::AlignLeft );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_showText->setAlignment( Qt::AlignCenter );
|
||||
}
|
||||
}
|
||||
|
||||
void AlertMessageBox::ReleaseInstance()
|
||||
{
|
||||
if ( m_handle )
|
||||
{
|
||||
delete m_handle;
|
||||
m_handle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void AlertMessageBox::Warning(QWidget *parent, const QString &msg )
|
||||
{
|
||||
message(parent, msg ,ICON_WARNING );
|
||||
}
|
||||
|
||||
void AlertMessageBox::Error(QWidget *parent, const QString &msg )
|
||||
{
|
||||
message(parent, msg,ICON_ERROR );
|
||||
}
|
||||
|
||||
void AlertMessageBox::Information(QWidget *parent, const QString &msg )
|
||||
{
|
||||
message(parent, msg ,ICON_INFORMATION);
|
||||
}
|
||||
|
||||
void AlertMessageBox::message(QWidget *parent,const QString &msg ,N_MSG_BOX_ICON icon )
|
||||
{
|
||||
if ( 0 == m_handle )
|
||||
{
|
||||
m_handle = new AlertMessageBox(parent);
|
||||
}
|
||||
|
||||
m_handle->setIcon( icon );
|
||||
m_handle->setText( msg );
|
||||
QDesktopWidget *deskTop = QApplication::desktop();
|
||||
QRect deskRect = deskTop->availableGeometry();
|
||||
m_handle->move(( deskRect.width() - m_handle->width() ) / 2, ( deskRect.height() - m_handle->height() ) / 2 );
|
||||
m_handle->show();
|
||||
}
|
||||
|
||||
void AlertMessageBox::slot_stay()
|
||||
{
|
||||
m_stayTimer->stop();
|
||||
if ( !m_hideTimer->isActive() )
|
||||
{
|
||||
m_hideTimer->start( 100 );
|
||||
}
|
||||
}
|
||||
|
||||
/*!Note that under X11 you need to have a composite manager running, and the X11 specific _NET_WM_WINDOW_OPACITY atom
|
||||
**needs to be supported by the window manager you are using.注意:远程桌面里用不了混成管理器,在本机透明度没有问题。
|
||||
*/
|
||||
void AlertMessageBox::slot_hide()
|
||||
{
|
||||
m_hideCount += 1;
|
||||
if ( m_hideCount > m_hideTransparent )
|
||||
{
|
||||
if ( m_hideCount >= m_hideTotal )
|
||||
{
|
||||
m_hideTimer->stop();
|
||||
hide();
|
||||
}
|
||||
else
|
||||
setWindowOpacity( ((double)m_hideTotal - m_hideCount)/(m_hideTotal-m_hideTransparent) );
|
||||
}
|
||||
}
|
||||
722
platform/src/public/pub_widget/Calendar.cpp
Normal file
722
platform/src/public/pub_widget/Calendar.cpp
Normal file
@ -0,0 +1,722 @@
|
||||
#include "Calendar.h"
|
||||
#include "LanguageSrc.h"
|
||||
#include <QButtonGroup>
|
||||
#include <QDate>
|
||||
|
||||
/***************************************************************************************************/
|
||||
CalendarButton::CalendarButton( const QString &text, QWidget *parent )
|
||||
: TVTButton( parent )
|
||||
{
|
||||
m_number = new QLabel( this );
|
||||
m_text = new QLabel( text, this );
|
||||
|
||||
m_number->setStyleSheet( " QLabel {background: transparent; font: bold 42px; color: rgb(216,216,216);} " );
|
||||
m_number->setAlignment( Qt::AlignCenter );
|
||||
m_text->setStyleSheet( " QLabel {background: transparent; font: 16px; color: rgb(209,209,209);} " );
|
||||
m_text->setAlignment( Qt::AlignCenter );
|
||||
|
||||
setStyleSheet( " CalendarButton { background: rgb(45,45,45); border-radius: 4px;}" );
|
||||
}
|
||||
|
||||
void CalendarButton::setCurrentValue( int value )
|
||||
{
|
||||
m_number->setText( QString::number( value ) );
|
||||
}
|
||||
|
||||
void CalendarButton::resizeEvent( QResizeEvent *e )
|
||||
{
|
||||
TVTButton::resizeEvent( e );
|
||||
const int w = e->size().width();
|
||||
const int h = e->size().height();
|
||||
|
||||
m_number->setGeometry( 10, 00, w - 40, h );
|
||||
m_text->setGeometry( w - 30, 0, 30, h );
|
||||
}
|
||||
/***************************************************************************************************/
|
||||
CalendarAssistButton::CalendarAssistButton( QWidget *parent )
|
||||
: TVTButton( parent )
|
||||
{
|
||||
}
|
||||
|
||||
void CalendarAssistButton::setEnterStyle( const QString &strStyle )
|
||||
{
|
||||
m_strEnterStyle = strStyle;
|
||||
}
|
||||
|
||||
void CalendarAssistButton::setLeaveStyle( const QString &strStyle )
|
||||
{
|
||||
m_strLeaveStyle = strStyle;
|
||||
setStyleSheet( m_strLeaveStyle );
|
||||
}
|
||||
|
||||
void CalendarAssistButton::enterEvent( QEvent *e )
|
||||
{
|
||||
TVTButton::enterEvent( e );
|
||||
if ( isEnabled() )
|
||||
{
|
||||
setCursor( Qt::PointingHandCursor );
|
||||
setStyleSheet( m_strEnterStyle );
|
||||
}
|
||||
}
|
||||
|
||||
void CalendarAssistButton::leaveEvent( QEvent *e )
|
||||
{
|
||||
TVTButton::leaveEvent( e );
|
||||
if ( isEnabled() )
|
||||
{
|
||||
setCursor( Qt::ArrowCursor );
|
||||
setStyleSheet( m_strLeaveStyle );
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************************************/
|
||||
CalendarItem::CalendarItem( const QString &text, QWidget *parent )
|
||||
: QLabel( parent )
|
||||
{
|
||||
m_label1 = new CalendarAssistButton( this );
|
||||
m_label2 = new CalendarAssistButton( this );
|
||||
m_calendarButton = new CalendarButton( text, this );
|
||||
m_label3 = new CalendarAssistButton( this );
|
||||
m_label4 = new CalendarAssistButton( this );
|
||||
|
||||
QString strEnterStyle = " CalendarAssistButton {background: transparent; border: 0px; color: rgb(216, 216, 216); font: bold %1px;} ";
|
||||
QString strLeaveStyle = " CalendarAssistButton {background: transparent; border: 0px; color: rgb(138, 138, 138); font: %1px;} ";
|
||||
m_label1->setEnterStyle( strEnterStyle.arg( 22 ) );
|
||||
m_label1->setLeaveStyle( strLeaveStyle.arg( 22 ) );
|
||||
m_label2->setEnterStyle( strEnterStyle.arg( 32 ) );
|
||||
m_label2->setLeaveStyle( strLeaveStyle.arg( 32 ) );
|
||||
m_label3->setEnterStyle( strEnterStyle.arg( 32 ) );
|
||||
m_label3->setLeaveStyle( strLeaveStyle.arg( 32 ) );
|
||||
m_label4->setEnterStyle( strEnterStyle.arg( 22 ) );
|
||||
m_label4->setLeaveStyle( strLeaveStyle.arg( 22 ) );
|
||||
|
||||
QButtonGroup *btnGroup = new QButtonGroup( this );
|
||||
btnGroup->addButton( m_label1 );
|
||||
btnGroup->addButton( m_label2 );
|
||||
btnGroup->addButton( m_label3 );
|
||||
btnGroup->addButton( m_label4 );
|
||||
|
||||
m_value = 0;
|
||||
m_maxValue = 0;
|
||||
m_minValue = 0;
|
||||
memset(m_variableValue, 0, sizeof(m_variableValue));
|
||||
|
||||
connect( btnGroup, SIGNAL( buttonClicked( QAbstractButton* ) ), this, SLOT( slot_buttonClicked( QAbstractButton* ) ) );
|
||||
}
|
||||
|
||||
void CalendarItem::slot_buttonClicked( QAbstractButton* btn )
|
||||
{
|
||||
int value = btn->text().toInt();
|
||||
m_calendarButton->setCurrentValue( value );
|
||||
|
||||
setCurrentValue( value, false );
|
||||
}
|
||||
|
||||
void CalendarItem::setValueRange( int min, int max )
|
||||
{
|
||||
m_minValue = min;
|
||||
m_maxValue = max;
|
||||
|
||||
if ( m_value > m_maxValue )
|
||||
{
|
||||
m_value = m_maxValue;
|
||||
}
|
||||
setCurrentValue( m_value, false );
|
||||
}
|
||||
|
||||
void CalendarItem::setCurrentValue( int value , bool blockSignals )
|
||||
{
|
||||
m_value = value;
|
||||
m_calendarButton->setCurrentValue( m_value );
|
||||
|
||||
m_variableValue[0] = m_value - 2;
|
||||
m_variableValue[1] = m_value - 1;
|
||||
m_variableValue[2] = m_value + 1;
|
||||
m_variableValue[3] = m_value + 2;
|
||||
|
||||
adjustValue();
|
||||
|
||||
if ( !blockSignals )
|
||||
{
|
||||
emit sig_value( m_value );
|
||||
}
|
||||
}
|
||||
|
||||
int CalendarItem::value()
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
|
||||
void CalendarItem::adjustValue()
|
||||
{
|
||||
for ( int i = 0; i < sizeof( m_variableValue ) / sizeof( m_variableValue[0] ); i++ )
|
||||
{
|
||||
if ( m_variableValue[i] > m_maxValue )
|
||||
{
|
||||
m_variableValue[i] -= ( m_maxValue - m_minValue + 1 );
|
||||
}
|
||||
else if ( m_variableValue[i] < m_minValue )
|
||||
{
|
||||
m_variableValue[i] += ( m_maxValue - m_minValue + 1 );
|
||||
}
|
||||
}
|
||||
|
||||
m_label1->setText( QString::number( m_variableValue[0] ) );
|
||||
m_label2->setText( QString::number( m_variableValue[1] ) );
|
||||
m_label3->setText( QString::number( m_variableValue[2] ) );
|
||||
m_label4->setText( QString::number( m_variableValue[3] ) );
|
||||
}
|
||||
|
||||
void CalendarItem::enterEvent( QEvent *e )
|
||||
{
|
||||
QLabel::enterEvent( e );
|
||||
m_calendarButton->setStyleSheet( " CalendarButton {background: rgb(0, 31, 36);border: 1px solid rgb(56, 145, 180); border-radius: 4px;} " );
|
||||
|
||||
}
|
||||
|
||||
void CalendarItem::leaveEvent( QEvent *e )
|
||||
{
|
||||
QLabel::leaveEvent( e );
|
||||
m_calendarButton->setStyleSheet( " CalendarButton { background: rgb(45,45,45); border-radius: 4px;} " );
|
||||
}
|
||||
|
||||
void CalendarItem::wheelEvent( QWheelEvent *e )
|
||||
{
|
||||
QLabel::wheelEvent( e );
|
||||
int degree = e->delta() / 8;
|
||||
int steps = degree / 15;
|
||||
m_value -= steps;
|
||||
|
||||
if ( m_value > m_maxValue )
|
||||
{
|
||||
m_value -= ( m_maxValue - m_minValue + 1 );
|
||||
}
|
||||
else if ( m_value < m_minValue )
|
||||
{
|
||||
m_value += ( m_maxValue - m_minValue + 1 );
|
||||
}
|
||||
m_calendarButton->setCurrentValue( m_value );
|
||||
|
||||
m_variableValue[0] = m_value - 2;
|
||||
m_variableValue[1] = m_value - 1;
|
||||
m_variableValue[2] = m_value + 1;
|
||||
m_variableValue[3] = m_value + 2;
|
||||
|
||||
adjustValue();
|
||||
|
||||
emit sig_value( m_value );
|
||||
}
|
||||
|
||||
void CalendarItem::resizeEvent( QResizeEvent *e )
|
||||
{
|
||||
QLabel::resizeEvent( e );
|
||||
const int w = e->size().width();
|
||||
const int h = e->size().height();
|
||||
|
||||
QFontMetrics fm( m_label1->font() );
|
||||
int width = fm.width( m_label1->text() ) + 20;
|
||||
m_label1->setGeometry(( w - 20 - width ) / 2, 0, width, 50 );
|
||||
|
||||
fm = QFontMetrics( m_label2->font() );
|
||||
width = fm.width( m_label2->text() ) + 20;
|
||||
m_label2->setGeometry(( w - 20 - width ) / 2, 50, width, 60 );
|
||||
m_calendarButton->setGeometry( 0, 110, w, 60 );
|
||||
|
||||
fm = QFontMetrics( m_label3->font() );
|
||||
width = fm.width( m_label3->text() ) + 20;
|
||||
m_label3->setGeometry(( w - 20 - width ) / 2, 170, width, 60 );
|
||||
|
||||
fm = QFontMetrics( m_label4->font() );
|
||||
width = fm.width( m_label4->text() ) + 20;
|
||||
m_label4->setGeometry(( w - 20 - width ) / 2, 230, width, 50 );
|
||||
}
|
||||
|
||||
/***************************************************************************************************/
|
||||
Calendar::Calendar( QWidget *parent ) :
|
||||
QLabel( parent )
|
||||
{
|
||||
m_yearItem = new CalendarItem( GET_TXT( "IDCS_YEAR" ), this );
|
||||
m_yearItem->setValueRange( 2010, 2037 ); //2038-01-19T03:14:06
|
||||
m_monthItem = new CalendarItem( GET_TXT( "IDCS_MONTH" ), this );
|
||||
m_monthItem->setValueRange( 1, 12 );
|
||||
m_dayItem = new CalendarItem( GET_TXT( "IDCS_DAY" ), this );
|
||||
m_dayItem->setValueRange( 1, 31 );
|
||||
m_hourItem = new CalendarItem( GET_TXT( "IDCS_HOUR" ), this );
|
||||
m_hourItem->setValueRange( 0, 23 );
|
||||
m_minuteItem = new CalendarItem( GET_TXT( "IDCS_MINUTE" ), this );
|
||||
m_minuteItem->setValueRange( 0, 59 );
|
||||
m_secondItem = new CalendarItem( GET_TXT( "IDCS_SECOND" ), this );
|
||||
m_secondItem->setValueRange( 0, 59 );
|
||||
|
||||
connect( m_yearItem, SIGNAL( sig_value( int ) ), this, SLOT( slot_yearChange( int ) ) );
|
||||
connect( m_monthItem, SIGNAL( sig_value( int ) ), this, SLOT( slot_monthChange( int ) ) );
|
||||
connect( m_dayItem, SIGNAL( sig_value( int ) ), this, SLOT( slot_dayChange( int ) ) );
|
||||
connect( m_hourItem, SIGNAL( sig_value( int ) ), this, SLOT( slot_hourChange( int ) ) );
|
||||
connect( m_minuteItem, SIGNAL( sig_value( int ) ), this, SLOT( slot_minuteChange( int ) ) );
|
||||
connect( m_secondItem, SIGNAL( sig_value( int ) ), this, SLOT( slot_secondChange( int ) ) );
|
||||
|
||||
setFixedSize( 685, 280 );
|
||||
//setAttribute( Qt::WA_TranslucentBackground );
|
||||
}
|
||||
|
||||
void Calendar::slot_yearChange( int value )
|
||||
{
|
||||
if ( m_minDateTime.isValid() )
|
||||
{
|
||||
changeTime( COMPARE_MIN, YEAR );
|
||||
}
|
||||
else if ( m_maxDateTime.isValid() )
|
||||
{
|
||||
changeTime( COMPARE_MAX, YEAR );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_currentYear = value;
|
||||
|
||||
QDate date;
|
||||
date.setDate( m_currentYear, m_currentMonth, 1 );
|
||||
|
||||
/* 根据年份和月份调整日期的最大最小值 */
|
||||
m_dayItem->setValueRange( 1, date.daysInMonth() );
|
||||
}
|
||||
}
|
||||
|
||||
void Calendar::slot_monthChange( int value )
|
||||
{
|
||||
if ( m_minDateTime.isValid() )
|
||||
{
|
||||
changeTime( COMPARE_MIN, MONTH );
|
||||
}
|
||||
else if ( m_maxDateTime.isValid() )
|
||||
{
|
||||
changeTime( COMPARE_MAX, MONTH );
|
||||
}
|
||||
|
||||
m_currentMonth = m_monthItem->value();
|
||||
|
||||
QDate date;
|
||||
date.setDate( m_currentYear, m_currentMonth, 1 );
|
||||
|
||||
m_dayItem->setValueRange( 1, date.daysInMonth() );
|
||||
}
|
||||
void Calendar::slot_dayChange( int value )
|
||||
{
|
||||
if ( m_minDateTime.isValid() )
|
||||
{
|
||||
changeTime( COMPARE_MIN, DAY );
|
||||
}
|
||||
else if ( m_maxDateTime.isValid() )
|
||||
{
|
||||
changeTime( COMPARE_MAX, DAY );
|
||||
}
|
||||
}
|
||||
|
||||
void Calendar::slot_hourChange( int value )
|
||||
{
|
||||
if ( m_minDateTime.isValid() )
|
||||
{
|
||||
changeTime( COMPARE_MIN, HOUR );
|
||||
}
|
||||
else if ( m_maxDateTime.isValid() )
|
||||
{
|
||||
changeTime( COMPARE_MAX, HOUR );
|
||||
}
|
||||
}
|
||||
|
||||
void Calendar::slot_minuteChange( int value )
|
||||
{
|
||||
if ( m_minDateTime.isValid() )
|
||||
{
|
||||
changeTime( COMPARE_MIN, MINUTE );
|
||||
}
|
||||
else if ( m_maxDateTime.isValid() )
|
||||
{
|
||||
changeTime( COMPARE_MAX, MINUTE );
|
||||
}
|
||||
}
|
||||
|
||||
void Calendar::slot_secondChange( int value )
|
||||
{
|
||||
if ( m_minDateTime.isValid() )
|
||||
{
|
||||
changeTime( COMPARE_MIN, SECOND );
|
||||
}
|
||||
else if ( m_maxDateTime.isValid() )
|
||||
{
|
||||
changeTime( COMPARE_MAX, SECOND );
|
||||
}
|
||||
}
|
||||
|
||||
void Calendar::changeTime( CompareType compare, TimeType time)
|
||||
{
|
||||
if ( COMPARE_MAX == compare )
|
||||
{
|
||||
/* switch没有break语句,因为年月日时分秒要依次比较 */
|
||||
switch( time )
|
||||
{
|
||||
case YEAR:
|
||||
{
|
||||
if ( m_maxDateTime < getDateTime() )
|
||||
{
|
||||
m_yearItem->setCurrentValue( m_maxDateTime.date().year(), true );
|
||||
}
|
||||
}
|
||||
case MONTH:
|
||||
{
|
||||
if ( m_maxDateTime < getDateTime() )
|
||||
{
|
||||
m_monthItem->setCurrentValue(m_maxDateTime.date().month(), true);
|
||||
}
|
||||
}
|
||||
case DAY:
|
||||
{
|
||||
if ( m_maxDateTime < getDateTime() )
|
||||
{
|
||||
m_dayItem->setCurrentValue( m_maxDateTime.date().day(), true );
|
||||
}
|
||||
}
|
||||
case HOUR:
|
||||
{
|
||||
if ( m_maxDateTime < getDateTime() )
|
||||
{
|
||||
m_hourItem->setCurrentValue( m_maxDateTime.time().hour(), true );
|
||||
}
|
||||
}
|
||||
case MINUTE:
|
||||
{
|
||||
if ( m_maxDateTime < getDateTime() )
|
||||
{
|
||||
m_minuteItem->setCurrentValue( m_maxDateTime.time().minute(), true );
|
||||
}
|
||||
}
|
||||
case SECOND:
|
||||
{
|
||||
if ( m_maxDateTime < getDateTime() )
|
||||
{
|
||||
m_secondItem->setCurrentValue( m_maxDateTime.time().second(), true );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ( COMPARE_MIN == compare )
|
||||
{
|
||||
switch( time )
|
||||
{
|
||||
case YEAR:
|
||||
{
|
||||
if ( m_minDateTime > getDateTime() )
|
||||
{
|
||||
m_yearItem->setCurrentValue( m_minDateTime.date().year(), true );
|
||||
}
|
||||
}
|
||||
case MONTH:
|
||||
{
|
||||
if ( m_minDateTime > getDateTime() )
|
||||
{
|
||||
m_monthItem->setCurrentValue(m_minDateTime.date().month(), true);
|
||||
}
|
||||
}
|
||||
case DAY:
|
||||
{
|
||||
if ( m_minDateTime > getDateTime() )
|
||||
{
|
||||
m_dayItem->setCurrentValue( m_minDateTime.date().day(), true );
|
||||
}
|
||||
}
|
||||
case HOUR:
|
||||
{
|
||||
if ( m_minDateTime > getDateTime() )
|
||||
{
|
||||
m_hourItem->setCurrentValue( m_minDateTime.time().hour(), true );
|
||||
}
|
||||
}
|
||||
case MINUTE:
|
||||
{
|
||||
if ( m_minDateTime > getDateTime() )
|
||||
{
|
||||
m_minuteItem->setCurrentValue( m_minDateTime.time().minute(), true );
|
||||
}
|
||||
}
|
||||
case SECOND:
|
||||
{
|
||||
if ( m_minDateTime > getDateTime() )
|
||||
{
|
||||
m_secondItem->setCurrentValue( m_minDateTime.time().second(), true );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Calendar::setDateTime( const QDateTime& dateTime)
|
||||
{
|
||||
m_yearItem->setCurrentValue( dateTime.date().year(), false );
|
||||
m_monthItem->setCurrentValue( dateTime.date().month(), false );
|
||||
m_dayItem->setCurrentValue( dateTime.date().day(), false );
|
||||
m_hourItem->setCurrentValue( dateTime.time().hour(), false );
|
||||
m_minuteItem->setCurrentValue( dateTime.time().minute(), false );
|
||||
m_secondItem->setCurrentValue( dateTime.time().second(), false );
|
||||
|
||||
m_currentYear = dateTime.date().year();
|
||||
m_currentMonth = dateTime.date().month();
|
||||
|
||||
QDate date;
|
||||
date.setDate( m_currentYear, m_currentMonth, 1 );
|
||||
|
||||
m_dayItem->setValueRange( 1, date.daysInMonth() );
|
||||
}
|
||||
|
||||
QDateTime Calendar::getDateTime( ) const
|
||||
{
|
||||
QDateTime tmp( QDate( m_yearItem->value(), m_monthItem->value(), m_dayItem->value() ),
|
||||
QTime( m_hourItem->value(), m_minuteItem->value(), m_secondItem->value() ) );
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void Calendar::resizeEvent( QResizeEvent *e )
|
||||
{
|
||||
QLabel::resizeEvent( e );
|
||||
const int h = e->size().height();
|
||||
|
||||
m_yearItem->setGeometry( 10, 0, 150, h );
|
||||
m_monthItem->setGeometry( 165, 0, 95, h );
|
||||
m_dayItem->setGeometry( 265, 0, 95, h );
|
||||
m_hourItem->setGeometry( 380, 0, 95, h );
|
||||
m_minuteItem->setGeometry( 480, 0, 95, h );
|
||||
m_secondItem->setGeometry( 580, 0, 95, h );
|
||||
}
|
||||
|
||||
void Calendar::setMinDateTime( const QDateTime & dateTime )
|
||||
{
|
||||
m_minDateTime = dateTime;
|
||||
if (m_minDateTime.isValid())
|
||||
{
|
||||
changeTime( COMPARE_MIN, YEAR);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Calendar::setMaxDateTime( const QDateTime & dateTime )
|
||||
{
|
||||
m_maxDateTime = dateTime;
|
||||
if ( m_maxDateTime.isValid() )
|
||||
{
|
||||
changeTime( COMPARE_MAX, YEAR);
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************************************/
|
||||
CalendarDialog::CalendarDialog( QWidget *parent )
|
||||
: TVTMenu( parent )
|
||||
{
|
||||
m_Calendar = new Calendar( this );
|
||||
m_Calendar->setDateTime( QDateTime::currentDateTime() );
|
||||
m_line = new QWidget( this );
|
||||
m_line->setStyleSheet( "QWidget {background: rgb(40,40,40);}" );
|
||||
m_btnEnter = new TVTPushButton( GET_TXT( "IDCS_OK" ), this );
|
||||
m_btnCancel = new TVTPushButton( GET_TXT( "IDCS_CANCEL" ), this );
|
||||
|
||||
//嵌入式linux下改成直角,圆角弹出时闪烁setAttribute( Qt::WA_TranslucentBackground );
|
||||
setStyleSheet( "CalendarDialog {border :1px solid rgb(149,149,149);background-color :rgb(16,17,20);margin:0px; }" );
|
||||
setFixedSize( 685, 350 );
|
||||
|
||||
connect( m_btnEnter, SIGNAL( clicked() ), this, SLOT( slot_enter() ) );
|
||||
connect( m_btnCancel, SIGNAL( clicked() ), this, SLOT( slot_cancel() ) );
|
||||
}
|
||||
|
||||
void CalendarDialog::setMinDateTime( const QDateTime & dateTime )
|
||||
{
|
||||
m_Calendar->setMinDateTime( dateTime );
|
||||
}
|
||||
|
||||
void CalendarDialog::setMaxDateTime( const QDateTime & dateTime )
|
||||
{
|
||||
m_Calendar->setMaxDateTime( dateTime );
|
||||
}
|
||||
|
||||
void CalendarDialog::setDateTime( const QDateTime & dateTime )
|
||||
{
|
||||
m_Calendar->setDateTime( dateTime );
|
||||
}
|
||||
|
||||
void CalendarDialog::slot_enter()
|
||||
{
|
||||
emit sig_sendDateTime( m_Calendar->getDateTime() );
|
||||
hide();
|
||||
}
|
||||
|
||||
void CalendarDialog::slot_cancel()
|
||||
{
|
||||
hide();
|
||||
}
|
||||
|
||||
void CalendarDialog::resizeEvent( QResizeEvent* e )
|
||||
{
|
||||
TVTMenu::resizeEvent( e );
|
||||
const int w = e->size().width();
|
||||
m_Calendar->setGeometry( 0, 0, 685, 280 );
|
||||
m_line->setGeometry( 1, 280, w - 2, 2 );
|
||||
|
||||
m_btnEnter->setGeometry( (w-240)/2, 295, 105, 40 );
|
||||
m_btnCancel->setGeometry( (w-240)/2 + 150, 295, 105, 40 );
|
||||
}
|
||||
|
||||
void CalendarDialog::mousePressEvent( QMouseEvent *ev )
|
||||
{
|
||||
QRect rect = this->rect();
|
||||
if( rect.contains( ev->pos() ) )
|
||||
{
|
||||
ev->accept();
|
||||
}
|
||||
else
|
||||
{
|
||||
TVTMenu::mousePressEvent( ev );
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************************************/
|
||||
DateDialog::DateDialog( QWidget *parent /* = 0 */ )
|
||||
: TVTMenu( parent )
|
||||
{
|
||||
m_yearItem = new CalendarItem( GET_TXT( "IDCS_YEAR" ), this );
|
||||
m_yearItem->setValueRange( 2010, 2037 );
|
||||
m_monthItem = new CalendarItem( GET_TXT( "IDCS_MONTH" ), this );
|
||||
m_monthItem->setValueRange( 1, 12 );
|
||||
m_dayItem = new CalendarItem( GET_TXT( "IDCS_DAY" ), this );
|
||||
m_dayItem->setValueRange( 1, 31 );
|
||||
|
||||
QDate date = QDate::currentDate();
|
||||
m_yearItem->setCurrentValue( date.year(), false );
|
||||
m_monthItem->setCurrentValue( date.month(), false );
|
||||
m_dayItem->setCurrentValue( date.day(), false );
|
||||
|
||||
m_bg = new QWidget( this );
|
||||
m_line = new QWidget( this );
|
||||
m_line->setStyleSheet( "QWidget {background: rgb(40,40,40);}" );
|
||||
m_btnEnter = new TVTPushButton( GET_TXT( "IDCS_OK" ), this );
|
||||
m_btnCancel = new TVTPushButton( GET_TXT( "IDCS_CANCEL" ), this );
|
||||
|
||||
m_bg->setStyleSheet( ".QWidget { border : 1px solid rgb(149,149,149); border-radius : 4px; background-color : rgb(16,17,20); }" );
|
||||
|
||||
setFixedSize( 460, 350 );
|
||||
setAttribute( Qt::WA_TranslucentBackground );
|
||||
|
||||
setStyleSheet( "DateDialog { border-radius : 4px; background : transparent; }" );
|
||||
|
||||
connect( m_yearItem, SIGNAL( sig_value( int ) ), this, SLOT( slot_yearChange( int ) ) );
|
||||
connect( m_monthItem, SIGNAL( sig_value( int ) ), this, SLOT( slot_monthChange( int ) ) );
|
||||
connect( m_btnEnter, SIGNAL( clicked() ), this, SLOT( slot_enter() ) );
|
||||
connect( m_btnCancel, SIGNAL( clicked() ), this, SLOT( slot_cancel() ) );
|
||||
}
|
||||
|
||||
void DateDialog::slot_enter()
|
||||
{
|
||||
hide();
|
||||
}
|
||||
|
||||
void DateDialog::slot_cancel()
|
||||
{
|
||||
hide();
|
||||
}
|
||||
|
||||
void DateDialog::slot_yearChange( int value )
|
||||
{
|
||||
m_currentYear = value;
|
||||
|
||||
QDate date;
|
||||
date.setDate( m_currentYear, m_currentMonth, 1 );
|
||||
|
||||
/* 根据年份和月份调整日期的最大最小值 */
|
||||
m_dayItem->setValueRange( 1, date.daysInMonth() );
|
||||
|
||||
}
|
||||
|
||||
void DateDialog::slot_monthChange( int value )
|
||||
{
|
||||
m_currentMonth = value;
|
||||
|
||||
QDate date;
|
||||
date.setDate( m_currentYear, m_currentMonth, 1 );
|
||||
|
||||
m_dayItem->setValueRange( 1, date.daysInMonth() );
|
||||
}
|
||||
|
||||
void DateDialog::resizeEvent( QResizeEvent* e )
|
||||
{
|
||||
TVTMenu::resizeEvent( e );
|
||||
const int w = e->size().width();
|
||||
m_bg->setGeometry( rect() );
|
||||
m_yearItem->setGeometry( 10, 0, 180, 280 );
|
||||
m_monthItem->setGeometry( 200, 0, 120, 280 );
|
||||
m_dayItem->setGeometry( 330, 0, 120, 280 );
|
||||
|
||||
m_line->setGeometry( 1, 280, w - 2, 2 );
|
||||
|
||||
m_btnEnter->setGeometry( (w-240)/2, 295, 105, 40 );
|
||||
m_btnCancel->setGeometry( (w-240)/2 + 150, 295, 105, 40 );
|
||||
}
|
||||
|
||||
/***************************************************************************************************/
|
||||
TimeDialog::TimeDialog( QWidget *parent /* = 0 */ )
|
||||
: TVTMenu( parent )
|
||||
{
|
||||
m_bg = new QWidget( this );
|
||||
|
||||
QTime time = QTime::currentTime();
|
||||
|
||||
m_hourItem = new CalendarItem( GET_TXT( "IDCS_HOUR" ), this );
|
||||
m_hourItem->setValueRange( 0, 23 );
|
||||
m_minuteItem = new CalendarItem( GET_TXT( "IDCS_MINUTE" ), this );
|
||||
m_minuteItem->setValueRange( 0, 59 );
|
||||
m_secondItem = new CalendarItem( GET_TXT( "IDCS_SECOND" ), this );
|
||||
m_secondItem->setValueRange( 0, 59 );
|
||||
|
||||
m_hourItem->setCurrentValue( time.hour(), false );
|
||||
m_minuteItem->setCurrentValue( time.minute(), false );
|
||||
m_secondItem->setCurrentValue( time.second(), false );
|
||||
|
||||
m_line = new QWidget( this );
|
||||
m_line->setStyleSheet( "QWidget {background: rgb(40,40,40);}" );
|
||||
m_btnEnter = new TVTPushButton( GET_TXT( "IDCS_OK" ), this );
|
||||
m_btnCancel = new TVTPushButton( GET_TXT( "IDCS_CANCEL" ), this );
|
||||
|
||||
m_bg->setStyleSheet( ".QWidget { border : 1px solid rgb(149,149,149); border-radius : 4px; background-color : rgb(16,17,20); }" );
|
||||
|
||||
setStyleSheet( "TimeDialog { border-radius : 4px; background : transparent; }" );
|
||||
|
||||
setFixedSize( 400, 350 );
|
||||
setAttribute( Qt::WA_TranslucentBackground );
|
||||
|
||||
connect( m_btnEnter, SIGNAL( clicked() ), this, SLOT( slot_enter() ) );
|
||||
connect( m_btnCancel, SIGNAL( clicked() ), this, SLOT( slot_cancel() ) );
|
||||
}
|
||||
|
||||
void TimeDialog::slot_enter()
|
||||
{
|
||||
QTime time = QTime( m_hourItem->value(), m_minuteItem->value(), m_secondItem->value() );
|
||||
emit sig_sendTime( time );
|
||||
hide();
|
||||
}
|
||||
|
||||
void TimeDialog::slot_cancel()
|
||||
{
|
||||
hide();
|
||||
}
|
||||
|
||||
void TimeDialog::resizeEvent( QResizeEvent* e )
|
||||
{
|
||||
TVTMenu::resizeEvent( e );
|
||||
const int w = e->size().width();
|
||||
m_bg->setGeometry( rect() );
|
||||
m_hourItem->setGeometry( 10, 0, 120, 280 );
|
||||
m_minuteItem->setGeometry( 140, 0, 120, 280 );
|
||||
m_secondItem->setGeometry( 270, 0, 120, 280 );
|
||||
|
||||
m_line->setGeometry( 1, 280, w - 2, 2 );
|
||||
|
||||
m_btnEnter->setGeometry( (w-240)/2, 295, 105, 40 );
|
||||
m_btnCancel->setGeometry( (w-240)/2 + 140, 295, 105, 40 );
|
||||
}
|
||||
222
platform/src/public/pub_widget/CustomDialog.cpp
Normal file
222
platform/src/public/pub_widget/CustomDialog.cpp
Normal file
@ -0,0 +1,222 @@
|
||||
#include "pub_widget/CustomDialog.h"
|
||||
#include <QLabel>
|
||||
#include <QGraphicsDropShadowEffect>
|
||||
#include <QVBoxLayout>
|
||||
#include <QPushButton>
|
||||
#include "pub_utility_api/FileStyle.h"
|
||||
|
||||
CustomDialog::CustomDialog(QWidget *parent,bool translucentBackground) : FramelessWindow<QDialog>(translucentBackground, parent), shadow_(nullptr)
|
||||
{
|
||||
setupUi();
|
||||
CustomDialog::setWindowTitle(QApplication::applicationName());
|
||||
|
||||
QVector<QWidget*> widgets = m_titleWidget->getAllWidgets();
|
||||
widgets.push_back(m_titleWidget);
|
||||
setTitlebar(widgets);
|
||||
|
||||
setShadowEnable(false);
|
||||
setResizeable(true);
|
||||
connect(m_titleWidget, SIGNAL(closeClicked()), this,SLOT(slot_close()));
|
||||
}
|
||||
|
||||
CustomDialog::~CustomDialog()
|
||||
{
|
||||
if(!shadow_)
|
||||
{
|
||||
delete shadow_;
|
||||
shadow_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void CustomDialog::addUserLayout(QLayout *layout,int spacing)
|
||||
{
|
||||
mainLayout_->addLayout(layout);
|
||||
mainLayout_->addSpacing(spacing);
|
||||
}
|
||||
|
||||
void CustomDialog::setLayout(QLayout *layout)
|
||||
{
|
||||
mainLayout_->addLayout(layout);
|
||||
}
|
||||
|
||||
void CustomDialog::setCloseBtnVisible(bool visible)
|
||||
{
|
||||
m_titleWidget->setCloseBtnVisible(visible);
|
||||
}
|
||||
|
||||
int CustomDialog::titleHeight()
|
||||
{
|
||||
return m_titleWidget->height();
|
||||
}
|
||||
|
||||
void CustomDialog::setupUi()
|
||||
{
|
||||
this->setObjectName("CustomDialog");
|
||||
|
||||
centralWidget_ = new QWidget();
|
||||
centralWidget_->setObjectName("CustomDialogCentralWidget");
|
||||
m_titleWidget = new CustomDialogTitle(this);
|
||||
|
||||
QHBoxLayout* hlTitle = new QHBoxLayout();
|
||||
hlTitle->setContentsMargins(0, 0, 0, 0);
|
||||
hlTitle->setSpacing(0);
|
||||
hlTitle->addWidget(m_titleWidget);
|
||||
// hlTitle->setSizeConstraint(QLayout::SetMinimumSize); //设定其为固定的大小
|
||||
|
||||
mainLayout_ = new QVBoxLayout();
|
||||
centralWidget_->setLayout(mainLayout_);
|
||||
|
||||
QVBoxLayout* hMain = new QVBoxLayout();
|
||||
hMain->setContentsMargins(0, 0, 0, 0);
|
||||
hMain->setSpacing(0);
|
||||
hMain->addLayout(hlTitle);
|
||||
hMain->addWidget(centralWidget_);
|
||||
|
||||
QDialog::setLayout(hMain);
|
||||
}
|
||||
|
||||
void CustomDialog::setShadowEnable(bool enable)
|
||||
{
|
||||
if (!shadow_) {
|
||||
shadow_ = new QGraphicsDropShadowEffect();
|
||||
shadow_->setColor(QColor(2, 122, 255, 255));
|
||||
shadow_->setBlurRadius(20);
|
||||
shadow_->setOffset(0.0);
|
||||
}
|
||||
|
||||
centralWidget_->setGraphicsEffect(enable ? shadow_ : nullptr);
|
||||
}
|
||||
|
||||
void CustomDialog::setWindowTitle(const QString &title)
|
||||
{
|
||||
QDialog::setWindowTitle(title);
|
||||
m_titleWidget->setTitle(title);
|
||||
}
|
||||
|
||||
void CustomDialog::slot_close()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
////用UI方式加载的用以下方法
|
||||
CustomUiDialog::CustomUiDialog(QWidget *parent,bool translucentBackground) : FramelessWindow<QDialog>(translucentBackground, parent)
|
||||
{
|
||||
m_mainLayout_ = NULL;
|
||||
m_centralWidget_ = NULL;
|
||||
m_bAutoLayout = false;
|
||||
this->setObjectName("CustomDialog");
|
||||
m_titleWidget = new CustomDialogTitle(this);
|
||||
|
||||
CustomUiDialog::setWindowTitle(QApplication::applicationName());
|
||||
|
||||
QVector<QWidget*> widgets = m_titleWidget->getAllWidgets();
|
||||
widgets.push_back(m_titleWidget);
|
||||
setTitlebar(widgets);
|
||||
|
||||
m_titleWidget->raise();
|
||||
|
||||
setResizeable(true);
|
||||
connect(m_titleWidget, SIGNAL(closeClicked()), this,SLOT(slot_close()));
|
||||
}
|
||||
|
||||
|
||||
CustomUiDialog::~CustomUiDialog()
|
||||
{
|
||||
}
|
||||
|
||||
void CustomUiDialog::resizeEvent(QResizeEvent *ev)
|
||||
{
|
||||
QDialog::resizeEvent( ev );
|
||||
|
||||
const int w = ev->size().width();
|
||||
const int t_h = m_titleWidget->height();
|
||||
|
||||
m_titleWidget->setGeometry(0,0, w,t_h);
|
||||
|
||||
if(m_bAutoLayout)
|
||||
{
|
||||
QMargins margins = this->contentsMargins();
|
||||
if(margins.top() != m_titleWidget->height())
|
||||
{
|
||||
margins.setTop(m_titleWidget->height());
|
||||
this->setContentsMargins(margins);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CustomUiDialog::keyPressEvent(QKeyEvent *ev)
|
||||
{
|
||||
if (!ev->modifiers() || (ev->modifiers() & Qt::KeypadModifier && ev->key() == Qt::Key_Enter))
|
||||
{
|
||||
if( ev->key() == Qt::Key_Enter || ev->key() == Qt::Key_Return )
|
||||
{
|
||||
ev->accept();
|
||||
return;
|
||||
}
|
||||
else if( ev->key() == Qt::Key_Escape )
|
||||
{
|
||||
ev->accept();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
QDialog::keyPressEvent( ev );
|
||||
}
|
||||
|
||||
|
||||
void CustomUiDialog::setCloseBtnVisible(bool visible)
|
||||
{
|
||||
m_titleWidget->setCloseBtnVisible(visible);
|
||||
}
|
||||
|
||||
void CustomUiDialog::addTitlebar(QWidget *w)
|
||||
{
|
||||
w->stackUnder(m_titleWidget);
|
||||
w->lower();
|
||||
m_titleWidget->raise();
|
||||
w->setMinimumHeight(m_titleWidget->height());
|
||||
FramelessWindow<QDialog>::addTitlebar(w);
|
||||
}
|
||||
|
||||
int CustomUiDialog::titleHeight()
|
||||
{
|
||||
return m_titleWidget->height();
|
||||
}
|
||||
|
||||
void CustomUiDialog::setAutoLayout(bool bEnable)
|
||||
{
|
||||
if(m_mainLayout_ == NULL)
|
||||
{
|
||||
m_mainLayout_ = new QVBoxLayout();
|
||||
m_mainLayout_->setSpacing(0);
|
||||
m_mainLayout_->setContentsMargins(0,0,0,0);
|
||||
}
|
||||
|
||||
if(m_centralWidget_ == NULL)
|
||||
{
|
||||
m_centralWidget_ = new QWidget();
|
||||
m_centralWidget_->setObjectName("CustomDialogCentralWidget");
|
||||
m_mainLayout_->addWidget(m_centralWidget_);
|
||||
|
||||
m_centralWidget_->setLayout(this->layout());
|
||||
this->setLayout(m_mainLayout_);
|
||||
}
|
||||
|
||||
m_bAutoLayout = bEnable;
|
||||
setCustomMainMargins(bEnable);
|
||||
}
|
||||
|
||||
|
||||
void CustomUiDialog::setWindowTitle(const QString &title)
|
||||
{
|
||||
QDialog::setWindowTitle(title);
|
||||
m_titleWidget->setTitle(title);
|
||||
}
|
||||
|
||||
|
||||
void CustomUiDialog::slot_close()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
92
platform/src/public/pub_widget/CustomDialog2.cpp
Normal file
92
platform/src/public/pub_widget/CustomDialog2.cpp
Normal file
@ -0,0 +1,92 @@
|
||||
#include "pub_widget/CustomDialog2.h"
|
||||
#include <QLabel>
|
||||
#include <QGraphicsDropShadowEffect>
|
||||
#include <QVBoxLayout>
|
||||
#include <QPushButton>
|
||||
#include "pub_utility_api/FileStyle.h"
|
||||
|
||||
CustomDialog2::CustomDialog2(QWidget *parent) : FramelessWindow<QDialog>(true, parent), shadow_(nullptr)
|
||||
{
|
||||
setupUi();
|
||||
CustomDialog2::setWindowTitle(QApplication::applicationName());
|
||||
|
||||
setTitlebar({centralWidget_, labelTitle_});
|
||||
|
||||
std::string strFullPath = iot_public::CFileStyle::getPathOfStyleFile("customDialog2.qss");
|
||||
loadStyleSheetFile(strFullPath.c_str(), this);
|
||||
|
||||
setShadowEnable(true);
|
||||
setResizeable(true);
|
||||
connect(pushButtonClose_, &QPushButton::clicked, [this]() { reject(); });
|
||||
}
|
||||
|
||||
CustomDialog2::~CustomDialog2()
|
||||
{
|
||||
if(!shadow_)
|
||||
{
|
||||
delete shadow_;
|
||||
shadow_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void CustomDialog2::addUserLayout(QLayout *layout,int spacing)
|
||||
{
|
||||
mainLayout_->addLayout(layout);
|
||||
mainLayout_->addSpacing(spacing);
|
||||
}
|
||||
|
||||
void CustomDialog2::setLayout(QLayout *layout)
|
||||
{
|
||||
addUserLayout(layout,0);
|
||||
}
|
||||
|
||||
void CustomDialog2::setupUi()
|
||||
{
|
||||
this->setObjectName("CustomDialog");
|
||||
|
||||
centralWidget_ = new QWidget();
|
||||
centralWidget_->setObjectName("CustomDialogCentralWidget");
|
||||
|
||||
pushButtonClose_ = new QPushButton();
|
||||
pushButtonClose_->setObjectName("CustomDialogButtonClose");
|
||||
pushButtonClose_->setCursor(QCursor(Qt::PointingHandCursor));
|
||||
|
||||
labelTitle_ = new QLabel();
|
||||
labelTitle_->setObjectName("CustomDialogTitle");
|
||||
|
||||
QHBoxLayout* hlTitle = new QHBoxLayout();
|
||||
hlTitle->setContentsMargins(0, 0, 0, 0);
|
||||
hlTitle->setSpacing(0);
|
||||
hlTitle->addWidget(labelTitle_);
|
||||
hlTitle->addStretch();
|
||||
hlTitle->addWidget(pushButtonClose_);
|
||||
// hlTitle->setSizeConstraint(QLayout::SetMinimumSize); //设定其为固定的大小
|
||||
|
||||
mainLayout_ = new QVBoxLayout();
|
||||
mainLayout_->addLayout(hlTitle);
|
||||
|
||||
centralWidget_->setLayout(mainLayout_);
|
||||
|
||||
QHBoxLayout* hMain = new QHBoxLayout();
|
||||
hMain->setContentsMargins(0, 0, 0, 0);
|
||||
hMain->addWidget(centralWidget_);
|
||||
QDialog::setLayout(hMain);
|
||||
}
|
||||
|
||||
void CustomDialog2::setShadowEnable(bool enable)
|
||||
{
|
||||
if (!shadow_) {
|
||||
shadow_ = new QGraphicsDropShadowEffect();
|
||||
shadow_->setColor(QColor(2, 122, 255, 255));
|
||||
shadow_->setBlurRadius(20);
|
||||
shadow_->setOffset(0.0);
|
||||
}
|
||||
|
||||
centralWidget_->setGraphicsEffect(enable ? shadow_ : nullptr);
|
||||
}
|
||||
|
||||
void CustomDialog2::setWindowTitle(const QString &title)
|
||||
{
|
||||
QDialog::setWindowTitle(title);
|
||||
labelTitle_->setText(title);
|
||||
}
|
||||
55
platform/src/public/pub_widget/CustomDialogTitle.cpp
Normal file
55
platform/src/public/pub_widget/CustomDialogTitle.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
#include "pub_widget/CustomDialogTitle.h"
|
||||
#include <QApplication>
|
||||
|
||||
CustomDialogTitle::CustomDialogTitle(QWidget *parent)
|
||||
: QLabel(parent)
|
||||
{
|
||||
m_btnClose = new QPushButton(this);
|
||||
m_icon = new AdaptImage(this);
|
||||
m_title = new CustomLabel(this);
|
||||
m_icon->setObjectName("icon");
|
||||
m_title->setObjectName("title");
|
||||
|
||||
// 最小化、最大化、关闭按钮
|
||||
m_btnClose->setToolTip(tr("关闭"));
|
||||
m_btnClose->setObjectName("close_btn");
|
||||
|
||||
//这个close 没有信号了
|
||||
connect(m_btnClose, SIGNAL(clicked()), this, SIGNAL(closeClicked()));
|
||||
}
|
||||
|
||||
CustomDialogTitle::~CustomDialogTitle()
|
||||
{
|
||||
}
|
||||
|
||||
void CustomDialogTitle::setTitle(const QString& title)
|
||||
{
|
||||
m_title->setText(title);
|
||||
}
|
||||
|
||||
void CustomDialogTitle::setCloseBtnVisible(bool visible)
|
||||
{
|
||||
m_btnClose->setVisible( visible );
|
||||
}
|
||||
|
||||
QVector<QWidget*> CustomDialogTitle::getAllWidgets()
|
||||
{
|
||||
return {m_icon,m_title};
|
||||
}
|
||||
|
||||
void CustomDialogTitle::resizeEvent(QResizeEvent *ev)
|
||||
{
|
||||
const int w = ev->size().width();
|
||||
const int h = ev->size().height();
|
||||
|
||||
int curX = 10;
|
||||
int curY = (h-32)/2;
|
||||
|
||||
m_icon->setGeometry( curX, curY, 32, 32 );
|
||||
curX += 32;
|
||||
m_title->setGeometry(curX,curY, w-(32+curX+10),32);
|
||||
|
||||
curX = w - 10;
|
||||
curX -= 32;
|
||||
m_btnClose->setGeometry( curX, curY, 32, 32 );
|
||||
}
|
||||
179
platform/src/public/pub_widget/CustomMainWindow.cpp
Normal file
179
platform/src/public/pub_widget/CustomMainWindow.cpp
Normal file
@ -0,0 +1,179 @@
|
||||
#include "pub_widget/CustomMainWindow.h"
|
||||
#include <QVBoxLayout>
|
||||
|
||||
CustomMainWindow::CustomMainWindow(QWidget *parent)
|
||||
: FramelessWindow<QMainWindow>(false,parent)
|
||||
{
|
||||
setupUi();
|
||||
CustomMainWindow::setWindowTitle(QApplication::applicationName());
|
||||
|
||||
QVector<QWidget*> widgets = m_titleWidget->getAllWidgets();
|
||||
widgets.push_back(m_titleWidget);
|
||||
setTitlebar(widgets);
|
||||
|
||||
setResizeable(true);
|
||||
|
||||
}
|
||||
|
||||
CustomMainWindow::~CustomMainWindow()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CustomMainWindow::setWindowTitle(const QString &title)
|
||||
{
|
||||
FramelessWindow<QMainWindow>::setWindowTitle(title);
|
||||
m_titleWidget->setTitle(title);
|
||||
}
|
||||
|
||||
void CustomMainWindow::setCentralWidget(QWidget *widget)
|
||||
{
|
||||
mainLayout_->addWidget(widget);
|
||||
}
|
||||
|
||||
void CustomMainWindow::setLayout(QLayout *layout)
|
||||
{
|
||||
mainLayout_->addLayout(layout);
|
||||
}
|
||||
|
||||
void CustomMainWindow::setSendCloseSignal(bool isSend)
|
||||
{
|
||||
m_titleWidget->setSendCloseSignal(isSend);
|
||||
}
|
||||
|
||||
void CustomMainWindow::setupUi()
|
||||
{
|
||||
this->setObjectName("CustomMainWindow");
|
||||
|
||||
QWidget* mainWidget = new QWidget();
|
||||
|
||||
centralWidget_ = new QWidget();
|
||||
centralWidget_->setObjectName("CustomDialogCentralWidget");
|
||||
|
||||
m_titleWidget = new MainTitle(this);
|
||||
|
||||
QHBoxLayout* hlTitle = new QHBoxLayout();
|
||||
hlTitle->setContentsMargins(0, 0, 0, 0);
|
||||
hlTitle->setSpacing(0);
|
||||
hlTitle->addWidget(m_titleWidget);
|
||||
// hlTitle->setSizeConstraint(QLayout::SetMinimumSize); //设定其为固定的大小
|
||||
|
||||
mainLayout_ = new QVBoxLayout();
|
||||
centralWidget_->setLayout(mainLayout_);
|
||||
|
||||
QVBoxLayout* hMain = new QVBoxLayout(mainWidget);
|
||||
hMain->setContentsMargins(0, 0, 0, 0);
|
||||
hMain->setSpacing(0);
|
||||
hMain->addLayout(hlTitle);
|
||||
hMain->addWidget(centralWidget_);
|
||||
|
||||
connect(m_titleWidget , &MainTitle::closeClicked , [=](){
|
||||
emit closeClicked();
|
||||
});
|
||||
|
||||
QMainWindow::setCentralWidget(mainWidget);
|
||||
}
|
||||
|
||||
|
||||
|
||||
////用UI方式加载的用以下方法
|
||||
CustomUiMainWindow::CustomUiMainWindow(QWidget *parent)
|
||||
: FramelessWindow<QMainWindow>(false, parent)
|
||||
{
|
||||
m_bAutoLayout = false;
|
||||
m_userTitleBar = nullptr;
|
||||
this->setObjectName("CustomUiMainWindow");
|
||||
m_titleWidget = new MainTitle(this);
|
||||
|
||||
CustomUiMainWindow::setWindowTitle(QApplication::applicationName());
|
||||
|
||||
QVector<QWidget*> widgets = m_titleWidget->getAllWidgets();
|
||||
widgets.push_back(m_titleWidget);
|
||||
setTitlebar(widgets);
|
||||
|
||||
m_titleWidget->raise();
|
||||
setResizeable(true);
|
||||
|
||||
connect(m_titleWidget, SIGNAL(sizeChanged()), this, SLOT(slot_titleSizeChanged()));
|
||||
connect(m_titleWidget , &MainTitle::closeClicked , [=](){
|
||||
emit closeClicked();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
CustomUiMainWindow::~CustomUiMainWindow()
|
||||
{
|
||||
}
|
||||
|
||||
void CustomUiMainWindow::resizeEvent(QResizeEvent *ev)
|
||||
{
|
||||
int w = this->width();
|
||||
// int h = this->height();
|
||||
|
||||
const int t_h = m_titleWidget->height();
|
||||
|
||||
m_titleWidget->setGeometry(0,0, w,t_h);
|
||||
|
||||
if(m_bAutoLayout)
|
||||
{
|
||||
QMargins margins = this->contentsMargins();
|
||||
if(margins.top() != m_titleWidget->height())
|
||||
{
|
||||
margins.setTop(m_titleWidget->height());
|
||||
this->setContentsMargins(margins);
|
||||
}
|
||||
}
|
||||
|
||||
QMainWindow::resizeEvent( ev );
|
||||
}
|
||||
|
||||
void CustomUiMainWindow::setTitleWidget(QWidget *w)
|
||||
{
|
||||
m_userTitleBar = w;
|
||||
w->stackUnder(m_titleWidget);
|
||||
w->lower();
|
||||
m_titleWidget->raise();
|
||||
int h = m_titleWidget->maximumHeight();
|
||||
w->setMinimumHeight(h);
|
||||
w->setMaximumHeight(h);
|
||||
FramelessWindow<QMainWindow>::addTitlebar(w);
|
||||
}
|
||||
|
||||
void CustomUiMainWindow::setAutoLayout(bool bEnable)
|
||||
{
|
||||
m_bAutoLayout = bEnable;
|
||||
setCustomMainMargins(bEnable);
|
||||
}
|
||||
|
||||
void CustomUiMainWindow::hideWindowTitle()
|
||||
{
|
||||
m_titleWidget->hide();
|
||||
}
|
||||
|
||||
int CustomUiMainWindow::titleHeight()
|
||||
{
|
||||
return m_titleWidget->height();
|
||||
}
|
||||
|
||||
void CustomUiMainWindow::setSendCloseSignal(bool isSend)
|
||||
{
|
||||
m_titleWidget->setSendCloseSignal(isSend);
|
||||
}
|
||||
|
||||
void CustomUiMainWindow::setWindowTitle(const QString &title)
|
||||
{
|
||||
m_titleWidget->show();
|
||||
QMainWindow::setWindowTitle(title);
|
||||
m_titleWidget->setTitle(title);
|
||||
}
|
||||
|
||||
void CustomUiMainWindow::slot_titleSizeChanged()
|
||||
{
|
||||
int h = m_titleWidget->maximumHeight();
|
||||
if(m_userTitleBar)
|
||||
{
|
||||
m_userTitleBar->setMinimumHeight(h);
|
||||
m_userTitleBar->setMaximumHeight(h);
|
||||
}
|
||||
}
|
||||
|
||||
150
platform/src/public/pub_widget/MainTitle.cpp
Normal file
150
platform/src/public/pub_widget/MainTitle.cpp
Normal file
@ -0,0 +1,150 @@
|
||||
#include "pub_widget/MainTitle.h"
|
||||
#include "pub_widget/Widgets.h"
|
||||
#include <QApplication>
|
||||
#include <QDesktopWidget>
|
||||
#include <QDesktopServices>
|
||||
#include <QUrl>
|
||||
#include <QMessageBox>
|
||||
#include "pub_widget/MessageBox.h"
|
||||
|
||||
MainTitle::MainTitle(QWidget *parent)
|
||||
: QLabel(parent), m_isMaximized(false),m_sendCloseSignal(false)
|
||||
{
|
||||
m_btnMax = new CustomButton(this);
|
||||
m_btnMin = new CustomButton(this);
|
||||
m_btnClose = new CustomButton(this);
|
||||
|
||||
m_icon = new QLabel(this);
|
||||
m_title = new CustomLabel(this);
|
||||
m_icon->setObjectName("icon");
|
||||
m_title->setObjectName("title");
|
||||
|
||||
// 最小化、最大化、关闭按钮
|
||||
m_btnMin->setToolTip(tr("最小化"));
|
||||
m_btnMax->setToolTip(tr("最大化"));
|
||||
m_btnClose->setToolTip(tr("关闭"));
|
||||
|
||||
m_btnMin->setObjectName("min_btn");
|
||||
m_btnMax->setObjectName("max_btn");
|
||||
m_btnClose->setObjectName("close_btn");
|
||||
|
||||
connect(m_btnMin, SIGNAL(clicked()), this, SLOT(slot_min()));
|
||||
connect(m_btnMax, SIGNAL(clicked()), this, SLOT(slot_max()));
|
||||
connect(m_btnClose, SIGNAL(clicked()), this, SLOT(slot_close()));
|
||||
|
||||
QWidget *win = this->window();
|
||||
Q_ASSERT( win != NULL );
|
||||
bool isMax = win->isMaximized();
|
||||
setBtnMaxSheet(isMax);
|
||||
}
|
||||
|
||||
void MainTitle::setBtnMaxSheet(bool isMax)
|
||||
{
|
||||
if(isMax)
|
||||
{
|
||||
m_btnMax->setProperty("buttonStatus", "max");
|
||||
m_btnMax->setToolTip(tr("最大化"));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_btnMax->setProperty("buttonStatus", "normal");
|
||||
m_btnMax->setToolTip(tr("正常"));
|
||||
}
|
||||
m_btnMax->style()->polish(m_btnMax);
|
||||
}
|
||||
|
||||
void MainTitle::setSendCloseSignal(bool isSend)
|
||||
{
|
||||
m_sendCloseSignal = isSend;
|
||||
}
|
||||
|
||||
QVector<QWidget *> MainTitle::getAllWidgets()
|
||||
{
|
||||
return {m_icon,m_title};
|
||||
}
|
||||
|
||||
void MainTitle::slot_min()
|
||||
{
|
||||
QWidget *win = this->window();
|
||||
Q_ASSERT( win != NULL );
|
||||
win->showMinimized();
|
||||
}
|
||||
|
||||
void MainTitle::slot_max()
|
||||
{
|
||||
QWidget *win = this->window();
|
||||
Q_ASSERT( win != NULL );
|
||||
if (win->isMaximized())
|
||||
{
|
||||
win->showNormal();
|
||||
}
|
||||
else
|
||||
{
|
||||
win->showMaximized();
|
||||
}
|
||||
|
||||
bool isMax = win->isMaximized();
|
||||
|
||||
setBtnMaxSheet(isMax);
|
||||
emit maximized(isMax);
|
||||
}
|
||||
|
||||
void MainTitle::slot_close()
|
||||
{
|
||||
if(!m_sendCloseSignal)
|
||||
{
|
||||
int button = N_MessageBox::question(this, tr("提示"),tr("是否退出?"));
|
||||
if (button == N_MessageBox::Ok) {
|
||||
QMetaObject::invokeMethod( qApp, "quit", Qt::QueuedConnection );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
emit closeClicked();
|
||||
}
|
||||
}
|
||||
|
||||
MainTitle::~MainTitle()
|
||||
{
|
||||
}
|
||||
|
||||
void MainTitle::setTitle(const QString& title)
|
||||
{
|
||||
m_title->setText(title);
|
||||
}
|
||||
|
||||
void MainTitle::resizeEvent(QResizeEvent *ev)
|
||||
{
|
||||
const int w = ev->size().width();
|
||||
const int h = ev->size().height();
|
||||
|
||||
int curX = 10;
|
||||
int curY = (h-32)/2;
|
||||
|
||||
m_icon->setGeometry( curX, curY, 32, 32 );
|
||||
curX += 32;
|
||||
m_title->setGeometry(curX,curY, w-(32*6),32);
|
||||
|
||||
curX = w - 10;
|
||||
curX -= 32;
|
||||
m_btnClose->setGeometry( curX, curY, 32, 32 );
|
||||
curX -= 32;
|
||||
m_btnMax->setGeometry( curX, curY, 32, 32 );
|
||||
curX -= 32;
|
||||
m_btnMin->setGeometry( curX, curY, 32, 32 );
|
||||
|
||||
QWidget *win = this->window();
|
||||
if(win)
|
||||
{
|
||||
bool isMax = win->isMaximized();
|
||||
setBtnMaxSheet(isMax);
|
||||
}
|
||||
|
||||
emit sizeChanged();
|
||||
}
|
||||
|
||||
void MainTitle::mouseDoubleClickEvent(QMouseEvent *ev)
|
||||
{
|
||||
slot_max();
|
||||
}
|
||||
|
||||
198
platform/src/public/pub_widget/MenuFrame.cpp
Normal file
198
platform/src/public/pub_widget/MenuFrame.cpp
Normal file
@ -0,0 +1,198 @@
|
||||
#include "pub_widget/MenuFrame.h"
|
||||
#include <QHBoxLayout>
|
||||
#include <QScrollArea>
|
||||
#include <QScrollBar>
|
||||
#include <QDebug>
|
||||
|
||||
MenuFrame::MenuFrame(QWidget *parent) : QFrame(parent)
|
||||
{
|
||||
this->setObjectName("MenuForm");
|
||||
m_btnGroup = new QButtonGroup;
|
||||
|
||||
// 创建滚动区域
|
||||
m_scrollArea = new QScrollArea(this);
|
||||
m_scrollArea->setWidgetResizable(true);
|
||||
m_scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
m_scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
|
||||
QWidget* scrollAreaWidget = new QWidget(m_scrollArea);
|
||||
scrollAreaWidget->setObjectName("scrollAreaWidget");
|
||||
|
||||
QVBoxLayout* scrollAreaWidgetVLayout = new QVBoxLayout(scrollAreaWidget);
|
||||
scrollAreaWidgetVLayout->setSpacing(0);
|
||||
scrollAreaWidgetVLayout->setContentsMargins(0,0,0,0);
|
||||
|
||||
m_centralWidget = new QWidget(scrollAreaWidget);
|
||||
scrollAreaWidget->setObjectName("centralWidget");
|
||||
|
||||
QSpacerItem* verticalSpacer = new QSpacerItem(5, 5, QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
|
||||
|
||||
scrollAreaWidgetVLayout->addWidget(m_centralWidget);
|
||||
scrollAreaWidgetVLayout->addItem(verticalSpacer);
|
||||
|
||||
QVBoxLayout* verticalLayout = new QVBoxLayout(m_centralWidget);
|
||||
verticalLayout->setSpacing(0);
|
||||
verticalLayout->setContentsMargins(0,0,0,0);
|
||||
|
||||
|
||||
QWidget* toolBtnWidget = new QWidget(m_scrollArea);
|
||||
scrollAreaWidget->setObjectName("toolBtnWidget");
|
||||
|
||||
QHBoxLayout* HLayout = new QHBoxLayout(toolBtnWidget);
|
||||
HLayout->setSpacing(0);
|
||||
HLayout->setContentsMargins(0,0,0,0);
|
||||
// 创建自定义滚动按钮
|
||||
m_upButton = new QPushButton("↑", toolBtnWidget);
|
||||
m_upButton->setObjectName("upButton");
|
||||
m_downButton = new QPushButton("↓", toolBtnWidget);
|
||||
m_downButton->setObjectName("downButton");
|
||||
|
||||
QSpacerItem* horizontalSpacer1 = new QSpacerItem(20, 5, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||
QSpacerItem* horizontalSpacer2 = new QSpacerItem(20, 5, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||
HLayout->addItem(horizontalSpacer1);
|
||||
HLayout->addWidget(m_upButton);
|
||||
HLayout->addWidget(m_downButton);
|
||||
HLayout->addItem(horizontalSpacer2);
|
||||
|
||||
QSizePolicy sizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
|
||||
sizePolicy.setHorizontalStretch(0);
|
||||
sizePolicy.setVerticalStretch(0);
|
||||
sizePolicy.setHeightForWidth(toolBtnWidget->sizePolicy().hasHeightForWidth());
|
||||
toolBtnWidget->setSizePolicy(sizePolicy);
|
||||
|
||||
|
||||
QHBoxLayout* scrollAreaHLayout = new QHBoxLayout(m_scrollArea);
|
||||
scrollAreaHLayout->setSpacing(0);
|
||||
scrollAreaHLayout->setContentsMargins(0,0,0,0);
|
||||
scrollAreaHLayout->addWidget(scrollAreaWidget);
|
||||
|
||||
m_scrollArea->setWidget(scrollAreaWidget);
|
||||
|
||||
// 设置布局
|
||||
QVBoxLayout* mainLayout = new QVBoxLayout(this);
|
||||
mainLayout->setSpacing(0);
|
||||
mainLayout->setContentsMargins(0,0,0,0);
|
||||
this->setLayout(mainLayout);
|
||||
mainLayout->addWidget(m_scrollArea);
|
||||
mainLayout->addWidget(toolBtnWidget);
|
||||
|
||||
connect( m_btnGroup, static_cast<void (QButtonGroup::*)(int)
|
||||
>(&QButtonGroup::buttonClicked),
|
||||
this, &MenuFrame::slotButtonEmit);
|
||||
|
||||
connect( m_upButton, SIGNAL(clicked()), this, SLOT(slotUpBtnClicked()) );
|
||||
connect( m_downButton, SIGNAL(clicked()), this, SLOT(slotDownBtnClicked()) );
|
||||
}
|
||||
|
||||
|
||||
MenuFrame::~MenuFrame()
|
||||
{
|
||||
}
|
||||
|
||||
void MenuFrame::addToolBtn(QPushButton *btn,int id)
|
||||
{
|
||||
btn->setCheckable(true);
|
||||
|
||||
int nBtnId = (id==-1) ? m_btnGroup->buttons().count() : id;
|
||||
m_btnGroup->addButton(btn,nBtnId);
|
||||
m_centralWidget->layout()->addWidget(btn);
|
||||
}
|
||||
|
||||
QPushButton *MenuFrame::addToolBtn(const QString &btnStr,int id)
|
||||
{
|
||||
QPushButton* btn = new QPushButton(m_centralWidget);
|
||||
btn->setCheckable(true);
|
||||
int nBtnId = (id==-1) ? m_btnGroup->buttons().count() : id;
|
||||
m_btnGroup->addButton(btn,nBtnId);
|
||||
btn->setText(btnStr);
|
||||
btn->setToolTip(btnStr);
|
||||
m_centralWidget->layout()->addWidget(btn);
|
||||
return btn;
|
||||
}
|
||||
|
||||
void MenuFrame::setButtonClicked(int id)
|
||||
{
|
||||
QAbstractButton *btn = m_btnGroup->button(id);
|
||||
if(btn != NULL)
|
||||
{
|
||||
slotButtonEmit(id);
|
||||
btn->setChecked(true);
|
||||
}
|
||||
}
|
||||
|
||||
int MenuFrame::checkedId()
|
||||
{
|
||||
return m_btnGroup->checkedId();
|
||||
}
|
||||
|
||||
void MenuFrame::resizeEvent(QResizeEvent *ev)
|
||||
{
|
||||
QFrame::resizeEvent(ev);
|
||||
|
||||
QList<QAbstractButton*> btns = m_btnGroup->buttons();
|
||||
int btnsHeight = 0;
|
||||
if(btns.count() != 0)
|
||||
{
|
||||
btnsHeight = btns.count()*btns.at(0)->height();
|
||||
}
|
||||
|
||||
int upBtnHeight = m_upButton->height();
|
||||
|
||||
if(btnsHeight + upBtnHeight > m_scrollArea->height())
|
||||
{
|
||||
m_upButton->setHidden(false);
|
||||
m_downButton->setHidden(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_upButton->setHidden(true);
|
||||
m_downButton->setHidden(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MenuFrame::slotButtonEmit(int index )
|
||||
{
|
||||
if( index >= 0)
|
||||
{
|
||||
emit buttonClicked(index);
|
||||
}
|
||||
}
|
||||
|
||||
void MenuFrame::slotUpBtnClicked()
|
||||
{
|
||||
QScrollBar * verticalScrollBar = m_scrollArea->verticalScrollBar();
|
||||
|
||||
QList<QAbstractButton*> btns = m_btnGroup->buttons();
|
||||
int btnsHeight = 0;
|
||||
if(btns.count() != 0)
|
||||
{
|
||||
btnsHeight = btns.at(0)->height();
|
||||
}
|
||||
|
||||
|
||||
int value = verticalScrollBar->value() - btnsHeight; // 向上滚动
|
||||
if (value < verticalScrollBar->minimum()) {
|
||||
value = verticalScrollBar->minimum();
|
||||
}
|
||||
verticalScrollBar->setValue(value);
|
||||
}
|
||||
|
||||
void MenuFrame::slotDownBtnClicked()
|
||||
{
|
||||
QScrollBar * verticalScrollBar = m_scrollArea->verticalScrollBar();
|
||||
|
||||
QList<QAbstractButton*> btns = m_btnGroup->buttons();
|
||||
int btnsHeight = 0;
|
||||
if(btns.count() != 0)
|
||||
{
|
||||
btnsHeight = btns.at(0)->height();
|
||||
}
|
||||
|
||||
int value = verticalScrollBar->value() + btnsHeight; // 向下滚动
|
||||
if (value > verticalScrollBar->maximum()) {
|
||||
value = verticalScrollBar->maximum();
|
||||
}
|
||||
verticalScrollBar->setValue(value);
|
||||
}
|
||||
|
||||
232
platform/src/public/pub_widget/MessageBox.cpp
Normal file
232
platform/src/public/pub_widget/MessageBox.cpp
Normal file
@ -0,0 +1,232 @@
|
||||
#include "pub_widget/MessageBox.h"
|
||||
#include <QtDebug>
|
||||
#include <QApplication>
|
||||
#include "pub_widget/Widgets.h"
|
||||
|
||||
N_MessageBox::N_MessageBox( const QString &text, int btnMode, N_MSG_BOX_ICON icon, QWidget* parent )
|
||||
: CustomDialog( parent ), m_curReturnValue( NoButton ), m_btnMode( btnMode )
|
||||
{
|
||||
switch ( icon )//初始化图标
|
||||
{
|
||||
case ICON_WARNING:
|
||||
{
|
||||
m_icon = new AdaptImage(this );
|
||||
m_icon->setProperty("MSG_TYPE","ICON_WARNING");
|
||||
setWindowTitle( tr( "警告" ) );
|
||||
}
|
||||
break;
|
||||
case ICON_ERROR:
|
||||
{
|
||||
m_icon = new AdaptImage(this );
|
||||
m_icon->setProperty("MSG_TYPE","ICON_ERROR");
|
||||
setWindowTitle( tr( "错误" ) );
|
||||
}
|
||||
break;
|
||||
case ICON_INFORMATION:
|
||||
{
|
||||
m_icon = new AdaptImage(this );
|
||||
m_icon->setProperty("MSG_TYPE","ICON_INFORMATION");
|
||||
setWindowTitle( tr( "提示" ) );
|
||||
}
|
||||
break;
|
||||
case ICON_QUESTION:
|
||||
{
|
||||
m_icon = new AdaptImage(this );
|
||||
m_icon->setProperty("MSG_TYPE","ICON_QUESTION");
|
||||
setWindowTitle( tr( "问题" ) );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
m_icon = new AdaptImage(this );
|
||||
m_icon->setProperty("MSG_TYPE","ICON_DEFAULT");
|
||||
break;
|
||||
}
|
||||
|
||||
//初始化文字及分割线
|
||||
m_text = new QLabel( text, this );
|
||||
m_text->setObjectName( "showText" );
|
||||
m_text->setAlignment( Qt::AlignCenter );
|
||||
m_text->setWordWrap( true );
|
||||
adjustTextToFixWidth( text );
|
||||
|
||||
setCloseBtnVisible( false );
|
||||
|
||||
m_btnGroup = new QButtonGroup( this );
|
||||
connect( m_btnGroup, SIGNAL( buttonClicked( int ) ), this, SLOT( slot_buttonClicked( int ) ) );
|
||||
|
||||
QPushButton *lastButton = NULL;
|
||||
if ( 0 != ( YesToAll & btnMode ) )
|
||||
lastButton = AddButton( YesToAll, tr( "全部是" ) );
|
||||
|
||||
if ( 0 != ( NoToAll & btnMode ) )
|
||||
lastButton = AddButton( NoToAll, tr( "全部否" ) );
|
||||
|
||||
if ( 0 != ( Ok & btnMode ) )
|
||||
lastButton = AddButton( Ok, tr( "确定" ) );
|
||||
|
||||
if ( 0 != ( Cancel & btnMode ) )
|
||||
lastButton = AddButton( Cancel, tr( "取消" ) );
|
||||
|
||||
if ( 0 != ( Yes & btnMode ) )
|
||||
lastButton = AddButton( Yes, tr( "是" ) );
|
||||
|
||||
if ( 0 != ( No & btnMode ) )
|
||||
lastButton = AddButton( No, tr( "否" ) );
|
||||
|
||||
//最右边的作为默认按钮
|
||||
if ( NULL != lastButton )
|
||||
{
|
||||
lastButton->setAutoDefault( true );
|
||||
lastButton->setFocus();
|
||||
m_curReturnValue = m_btnGroup->id( lastButton );
|
||||
}
|
||||
}
|
||||
|
||||
N_MessageBox::~N_MessageBox()
|
||||
{
|
||||
}
|
||||
|
||||
int N_MessageBox::message(const QString &title, const QString &text, int btnMode, N_MSG_BOX_ICON icon, QWidget *parent )
|
||||
{
|
||||
N_MessageBox box( text, btnMode, icon, parent );
|
||||
if(!title.isEmpty())
|
||||
{
|
||||
box.setWindowTitle(title);
|
||||
}
|
||||
box.exec();
|
||||
|
||||
return box.m_curReturnValue;
|
||||
}
|
||||
|
||||
int N_MessageBox::warning(QWidget *parent,const QString &title, const QString &text, int button0 , int button1 , int button2 )
|
||||
{
|
||||
return N_MessageBox::message(title, text, button0 | button1 | button2, ICON_WARNING, parent );
|
||||
}
|
||||
|
||||
|
||||
void N_MessageBox::error(QWidget *parent,const QString &title, const QString &text )
|
||||
{
|
||||
N_MessageBox::message(title, text, Ok, ICON_ERROR, parent );
|
||||
}
|
||||
|
||||
int N_MessageBox::information(QWidget *parent,const QString &title, const QString &text , int button0, int button1, int button2 )
|
||||
{
|
||||
return N_MessageBox::message(title, text, button0 | button1 | button2, ICON_INFORMATION, parent );
|
||||
}
|
||||
|
||||
|
||||
int N_MessageBox::question(QWidget *parent,const QString &title, const QString &text, int button0 , int button1 , int button2 )
|
||||
{
|
||||
return N_MessageBox::message(title, text, button0 | button1 | button2, ICON_QUESTION, parent );
|
||||
}
|
||||
|
||||
int N_MessageBox::choice(QWidget *parent,const QString &title, const QString &text )
|
||||
{
|
||||
return N_MessageBox::message(title, text, Yes | No, ICON_QUESTION, parent );
|
||||
}
|
||||
|
||||
int N_MessageBox::error_choice(QWidget *parent,const QString &title, const QString &text )
|
||||
{
|
||||
return N_MessageBox::message(title, text, Yes | No, ICON_ERROR, parent );
|
||||
}
|
||||
|
||||
int N_MessageBox::about(QWidget *parent, const QString &title, const QString &text)
|
||||
{
|
||||
return N_MessageBox::message(title, text, Yes, ICON_INFORMATION, parent );
|
||||
}
|
||||
|
||||
int N_MessageBox::critical(QWidget *parent, const QString &title, const QString &text)
|
||||
{
|
||||
return N_MessageBox::message(title, text, Yes, ICON_WARNING, parent );
|
||||
}
|
||||
|
||||
void N_MessageBox::slot_buttonClicked( int id )
|
||||
{
|
||||
m_curReturnValue = id;
|
||||
accept();
|
||||
}
|
||||
|
||||
void N_MessageBox::resizeEvent(QResizeEvent *ev)
|
||||
{
|
||||
CustomDialog::resizeEvent( ev );
|
||||
|
||||
const int title_h = this->titleHeight();
|
||||
int w = ev->size().width();
|
||||
int h = ev->size().height()-title_h;
|
||||
|
||||
const int x_begin = 0;
|
||||
const int y_begin = title_h;
|
||||
|
||||
if(h<=84)
|
||||
{
|
||||
h = 86;
|
||||
}
|
||||
|
||||
m_icon->setGeometry( x_begin+50,(h-42+y_begin)/2, 42, 42 );
|
||||
m_text->setGeometry( x_begin+50+42+10, (h-84+y_begin)/2, w - (x_begin+50+42+10+20), 84 );
|
||||
|
||||
QList<QAbstractButton*> listBtn = m_btnGroup->buttons();
|
||||
int curX = w - 10;
|
||||
int curY = title_h;
|
||||
bool bSpace = true;
|
||||
for ( int i = listBtn.size() - 1; i >= 0; i-- )
|
||||
{
|
||||
///如果是全否或者全是需要间隔大一点
|
||||
if ( bSpace && ( 0 != ( NoToAll & m_btnGroup->id( listBtn[i] ) ) || 0 != ( YesToAll == m_btnGroup->id( listBtn[i] ) ) ) )
|
||||
{
|
||||
curX -= 10;
|
||||
bSpace = false;
|
||||
}
|
||||
|
||||
curX -= 90;
|
||||
listBtn[i]->setGeometry( curX, ev->size().height() - 52, 80, 32 );
|
||||
}
|
||||
}
|
||||
|
||||
void N_MessageBox::keyPressEvent( QKeyEvent *ev )
|
||||
{
|
||||
bool ok = false;
|
||||
if ( !ev->modifiers() && ev->key() == Qt::Key_Escape )//不是单纯的esc键就退出
|
||||
{
|
||||
ok = true;
|
||||
}
|
||||
|
||||
if ( ok )
|
||||
{
|
||||
if ( 0 != ( NoToAll & m_btnMode ) )
|
||||
{
|
||||
m_curReturnValue = NoToAll;
|
||||
}
|
||||
if ( 0 != ( No & m_btnMode ) )
|
||||
{
|
||||
m_curReturnValue = No;
|
||||
}
|
||||
if ( 0 != ( Cancel & m_btnMode ) )
|
||||
{
|
||||
m_curReturnValue = Cancel;
|
||||
}
|
||||
}
|
||||
CustomDialog::keyPressEvent( ev );
|
||||
}
|
||||
|
||||
CustomPushButton *N_MessageBox::AddButton( N_MSG_BOX_RETURN retValue, const QString &text )
|
||||
{
|
||||
CustomPushButton *btn = new CustomPushButton( text, this );
|
||||
m_btnGroup->addButton( btn, retValue );
|
||||
return btn;
|
||||
}
|
||||
|
||||
void N_MessageBox::adjustTextToFixWidth( const QString & text )
|
||||
{
|
||||
QFontMetrics fm ( m_text->font() );
|
||||
int textWidth = fm.width( text );
|
||||
int nWidth = m_text->width();
|
||||
if ( nWidth < textWidth )
|
||||
{
|
||||
m_text->setAlignment( Qt::AlignVCenter| Qt::AlignLeft );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_text->setAlignment( Qt::AlignCenter );
|
||||
}
|
||||
}
|
||||
620
platform/src/public/pub_widget/NcFramelessHelper.cpp
Normal file
620
platform/src/public/pub_widget/NcFramelessHelper.cpp
Normal file
@ -0,0 +1,620 @@
|
||||
/*
|
||||
FramelessHelper, an easy way to support move/resize on
|
||||
frameless toplevel windows.
|
||||
Copyright (C) 2011 Nishant Parashar
|
||||
Email:- nishcode (at) gmail (dot) com
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <QRubberBand>
|
||||
#include <QMouseEvent>
|
||||
#include <QMutex>
|
||||
#include <QDebug>
|
||||
#include "pub_widget/NcFramelessHelper.h"
|
||||
|
||||
class NcCursorPosCalculator
|
||||
{
|
||||
|
||||
public:
|
||||
NcCursorPosCalculator();
|
||||
void reset();
|
||||
void recalculate( const QPoint& globalMousePos, const QRect& frameRect );
|
||||
|
||||
public:
|
||||
bool onEdges;
|
||||
bool onLeftEdge;
|
||||
bool onRightEdge;
|
||||
bool onTopEdge;
|
||||
bool onBottomEdge;
|
||||
bool onTopLeftEdge;
|
||||
bool onBottomLeftEdge;
|
||||
bool onTopRightEdge;
|
||||
bool onBottomRightEdge;
|
||||
|
||||
static int mBorderWidth;
|
||||
};
|
||||
//TODO: Should not be static.
|
||||
int NcCursorPosCalculator::mBorderWidth = 5;
|
||||
|
||||
class NcWidgetData
|
||||
{
|
||||
public:
|
||||
NcWidgetData( NcFramelessHelperImpl* _d, QWidget* topLevelWidget );
|
||||
~NcWidgetData();
|
||||
|
||||
//void setWidget( QWidget* topLevelWidget );
|
||||
QWidget* widget();
|
||||
void handleWidgetEvent( QEvent* event );
|
||||
void updateRubberBandStatus();
|
||||
|
||||
private:
|
||||
void updateCursorShape( const QPoint& globalMousePos );
|
||||
void resizeWidget( const QPoint& globalMousePos );
|
||||
void moveWidget( const QPoint& globalMousePos );
|
||||
|
||||
void handleMousePressEvent( QMouseEvent* event );
|
||||
void handleMouseReleaseEvent( QMouseEvent* event );
|
||||
void handleMouseMoveEvent( QMouseEvent* event );
|
||||
void handleLeaveEvent( QEvent* event );
|
||||
void handleHoverMoveEvent( QHoverEvent* event );
|
||||
|
||||
private:
|
||||
NcFramelessHelperImpl* d;
|
||||
QRubberBand* mRubberBand;
|
||||
bool mLeftButtonPressed;
|
||||
QWidget* mWidget;
|
||||
QPoint mDragPos;
|
||||
NcCursorPosCalculator mPressedMousePos;
|
||||
NcCursorPosCalculator mMoveMousePos;
|
||||
bool mCursorShapeChanged;
|
||||
Qt::WindowFlags mWindowFlags;
|
||||
|
||||
//鼠标是否在标题栏中点击
|
||||
bool mTitlePressed;
|
||||
};
|
||||
|
||||
|
||||
class NcFramelessHelperImpl
|
||||
{
|
||||
public:
|
||||
QHash< QWidget*, NcWidgetData* > mHashWidgetData;
|
||||
bool mWidgetMovable;
|
||||
bool mWidgetResizable;
|
||||
bool mUseRubberBandOnResize;
|
||||
bool mUseRubberBandOnMove;
|
||||
};
|
||||
|
||||
NcCursorPosCalculator::NcCursorPosCalculator()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void NcCursorPosCalculator::reset()
|
||||
{
|
||||
onEdges = false;
|
||||
onLeftEdge = false;
|
||||
onRightEdge = false;
|
||||
onTopEdge = false;
|
||||
onBottomEdge = false;
|
||||
onTopLeftEdge = false;
|
||||
onBottomLeftEdge = false;
|
||||
onTopRightEdge = false;
|
||||
onBottomRightEdge = false;
|
||||
}
|
||||
|
||||
void NcCursorPosCalculator::recalculate( const QPoint& globalMousePos, const QRect& frameRect )
|
||||
{
|
||||
int globalMouseX = globalMousePos.x();
|
||||
int globalMouseY = globalMousePos.y();
|
||||
|
||||
int frameX = frameRect.x();
|
||||
int frameY = frameRect.y();
|
||||
|
||||
int frameWidth = frameRect.width();
|
||||
int frameHeight = frameRect.height();
|
||||
|
||||
onLeftEdge = globalMouseX >= frameX &&
|
||||
globalMouseX <= frameX + mBorderWidth;
|
||||
|
||||
|
||||
onRightEdge = globalMouseX >= frameX + frameWidth - mBorderWidth &&
|
||||
globalMouseX <= frameX + frameWidth;
|
||||
|
||||
onTopEdge = globalMouseY >= frameY &&
|
||||
globalMouseY <= frameY + mBorderWidth;
|
||||
|
||||
|
||||
onBottomEdge = globalMouseY >= frameY + frameHeight - mBorderWidth &&
|
||||
globalMouseY <= frameY + frameHeight;
|
||||
|
||||
onTopLeftEdge = onTopEdge && onLeftEdge;
|
||||
onBottomLeftEdge = onBottomEdge && onLeftEdge;
|
||||
onTopRightEdge = onTopEdge && onRightEdge;
|
||||
onBottomRightEdge = onBottomEdge && onRightEdge;
|
||||
|
||||
//only these checks would be enough
|
||||
onEdges = onLeftEdge || onRightEdge ||
|
||||
onTopEdge || onBottomEdge;
|
||||
|
||||
}
|
||||
|
||||
|
||||
NcWidgetData::NcWidgetData( NcFramelessHelperImpl* _d, QWidget* topLevelWidget )
|
||||
{
|
||||
d = _d;
|
||||
mWidget = topLevelWidget;
|
||||
mLeftButtonPressed = false;
|
||||
mRubberBand = 0;
|
||||
mCursorShapeChanged = false;
|
||||
mTitlePressed = false;
|
||||
|
||||
mWindowFlags = mWidget->windowFlags();
|
||||
|
||||
//---from Qt docs of setWindowFlags()----
|
||||
//Note: This function calls setParent() when
|
||||
//changing the flags for a window, causing the
|
||||
//widget to be hidden. You must call show()
|
||||
//to make the widget visible again..
|
||||
|
||||
bool visible = mWidget->isVisible();
|
||||
|
||||
mWidget->setMouseTracking( true );
|
||||
//mWidget->setWindowFlags( Qt::CustomizeWindowHint|Qt::FramelessWindowHint );
|
||||
mWidget->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowMinimizeButtonHint );
|
||||
|
||||
//Bug fix, mouse move events does not propagate from child widgets.
|
||||
//so need the hover events.
|
||||
mWidget->setAttribute( Qt::WA_Hover );
|
||||
|
||||
updateRubberBandStatus();
|
||||
|
||||
mWidget->setVisible( visible );
|
||||
}
|
||||
|
||||
NcWidgetData::~NcWidgetData()
|
||||
{
|
||||
//---from Qt docs of setWindowFlags()----
|
||||
//Note: This function calls setParent() when
|
||||
//changing the flags for a window, causing the
|
||||
//widget to be hidden. You must call show()
|
||||
//to make the widget visible again..
|
||||
|
||||
bool visible = mWidget->isVisible();
|
||||
|
||||
mWidget->setMouseTracking( false );
|
||||
mWidget->setWindowFlags( mWindowFlags );//^ Qt::CustomizeWindowHint ^ Qt::FramelessWindowHint );
|
||||
mWidget->setAttribute( Qt::WA_Hover, false );
|
||||
|
||||
mWidget->setVisible( visible );
|
||||
|
||||
delete mRubberBand;
|
||||
}
|
||||
|
||||
void NcWidgetData::updateRubberBandStatus()
|
||||
{
|
||||
if ( d->mUseRubberBandOnMove || d->mUseRubberBandOnResize )
|
||||
{
|
||||
if ( !mRubberBand )
|
||||
mRubberBand = new QRubberBand( QRubberBand::Rectangle );
|
||||
}
|
||||
else
|
||||
{
|
||||
delete mRubberBand;
|
||||
mRubberBand = 0;
|
||||
}
|
||||
}
|
||||
|
||||
QWidget* NcWidgetData::widget()
|
||||
{
|
||||
return mWidget;
|
||||
}
|
||||
|
||||
void NcWidgetData::handleWidgetEvent( QEvent* event )
|
||||
{
|
||||
switch ( event->type() )
|
||||
{
|
||||
default: //qDebug() << "Event = " << event;
|
||||
break;
|
||||
case QEvent::MouseButtonPress:
|
||||
handleMousePressEvent( static_cast<QMouseEvent*>( event ) );
|
||||
break;
|
||||
|
||||
case QEvent::MouseButtonRelease:
|
||||
handleMouseReleaseEvent( static_cast<QMouseEvent*>( event ) );
|
||||
break;
|
||||
|
||||
case QEvent::MouseMove:
|
||||
handleMouseMoveEvent( static_cast<QMouseEvent*>( event ) );
|
||||
break;
|
||||
|
||||
case QEvent::Leave:
|
||||
handleLeaveEvent( event );
|
||||
break;
|
||||
|
||||
//Bug fix, hover event is necessary coz child widget does not
|
||||
//propagate mousemove events. so the cursor remains in edge shape
|
||||
//even in middle of widget.
|
||||
case QEvent::HoverMove:
|
||||
handleHoverMoveEvent( static_cast<QHoverEvent*>( event ) );
|
||||
break;
|
||||
//case QEvent::Enter:
|
||||
//qDebug() << "Enter event";//d->handleEnterEvent( event );
|
||||
//break;
|
||||
}
|
||||
}
|
||||
|
||||
void NcWidgetData::updateCursorShape( const QPoint& globalMousePos )
|
||||
{
|
||||
if ( mWidget->isFullScreen() || mWidget->isMaximized() )
|
||||
{
|
||||
if ( mCursorShapeChanged )
|
||||
mWidget->unsetCursor();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
mMoveMousePos.recalculate( globalMousePos, mWidget->frameGeometry() );
|
||||
|
||||
if( mMoveMousePos.onTopLeftEdge || mMoveMousePos.onBottomRightEdge )
|
||||
{
|
||||
mWidget->setCursor( Qt::SizeFDiagCursor );
|
||||
mCursorShapeChanged = true;
|
||||
}
|
||||
else if( mMoveMousePos.onTopRightEdge || mMoveMousePos.onBottomLeftEdge )
|
||||
{
|
||||
mWidget->setCursor( Qt::SizeBDiagCursor );
|
||||
mCursorShapeChanged = true;
|
||||
}
|
||||
else if( mMoveMousePos.onLeftEdge || mMoveMousePos.onRightEdge )
|
||||
{
|
||||
mWidget->setCursor( Qt::SizeHorCursor );
|
||||
mCursorShapeChanged = true;
|
||||
}
|
||||
else if( mMoveMousePos.onTopEdge || mMoveMousePos.onBottomEdge )
|
||||
{
|
||||
mWidget->setCursor( Qt::SizeVerCursor );
|
||||
mCursorShapeChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( mCursorShapeChanged )
|
||||
{
|
||||
mWidget->unsetCursor();
|
||||
mCursorShapeChanged = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NcWidgetData::resizeWidget( const QPoint& globalMousePos )
|
||||
{
|
||||
QRect origRect;
|
||||
|
||||
if ( d->mUseRubberBandOnResize )
|
||||
origRect = mRubberBand->frameGeometry();
|
||||
else
|
||||
origRect = mWidget->frameGeometry();
|
||||
|
||||
|
||||
int left = origRect.left();
|
||||
int top = origRect.top();
|
||||
int right = origRect.right();
|
||||
int bottom = origRect.bottom();
|
||||
origRect.getCoords( &left, &top, &right, &bottom );
|
||||
|
||||
int minWidth = mWidget->minimumWidth();
|
||||
int minHeight = mWidget->minimumHeight();
|
||||
|
||||
if ( mPressedMousePos.onTopLeftEdge )
|
||||
{
|
||||
left = globalMousePos.x();
|
||||
top = globalMousePos.y();
|
||||
}
|
||||
else if ( mPressedMousePos.onBottomLeftEdge )
|
||||
{
|
||||
left = globalMousePos.x();
|
||||
bottom = globalMousePos.y();
|
||||
}
|
||||
else if ( mPressedMousePos.onTopRightEdge )
|
||||
{
|
||||
right = globalMousePos.x();
|
||||
top = globalMousePos.y();
|
||||
}
|
||||
else if ( mPressedMousePos.onBottomRightEdge )
|
||||
{
|
||||
right = globalMousePos.x();
|
||||
bottom = globalMousePos.y();
|
||||
}
|
||||
else if ( mPressedMousePos.onLeftEdge )
|
||||
{
|
||||
left = globalMousePos.x();
|
||||
}
|
||||
else if ( mPressedMousePos.onRightEdge )
|
||||
{
|
||||
right = globalMousePos.x();
|
||||
}
|
||||
else if ( mPressedMousePos.onTopEdge )
|
||||
{
|
||||
top = globalMousePos.y();
|
||||
}
|
||||
else if ( mPressedMousePos.onBottomEdge )
|
||||
{
|
||||
bottom = globalMousePos.y();
|
||||
}
|
||||
|
||||
QRect newRect( QPoint(left, top), QPoint(right, bottom) );
|
||||
|
||||
if ( newRect.isValid() )
|
||||
{
|
||||
if ( minWidth > newRect.width() )
|
||||
{
|
||||
//determine what has caused the width change.
|
||||
if( left != origRect.left() )
|
||||
newRect.setLeft( origRect.left() );
|
||||
else
|
||||
newRect.setRight( origRect.right() );
|
||||
}
|
||||
if ( minHeight > newRect.height() )
|
||||
{
|
||||
//determine what has caused the height change.
|
||||
if ( top != origRect.top() )
|
||||
newRect.setTop( origRect.top() );
|
||||
else
|
||||
newRect.setBottom( origRect.bottom() );
|
||||
}
|
||||
|
||||
if ( d->mUseRubberBandOnResize )
|
||||
{
|
||||
mRubberBand->setGeometry( newRect );
|
||||
}
|
||||
else
|
||||
{
|
||||
mWidget->setGeometry( newRect );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//qDebug() << "Calculated Rect is not valid" << newRect;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void NcWidgetData::moveWidget( const QPoint &globalMousePos )
|
||||
{
|
||||
//鼠标点击在标题栏,按住不放快速拖动,窗口并没有随着鼠标拖动位置的变化而变化,原因是鼠标当前点的位置并没有落在标题栏中
|
||||
//在标题栏内点击才可以移动
|
||||
/*const int width = mWidget->width();
|
||||
QRect rect( 0, 0, width, 28 );
|
||||
QPoint pt = mWidget->mapFromGlobal( globalMousePos );
|
||||
if( !rect.contains( pt ) )
|
||||
return;*/
|
||||
if ( d->mUseRubberBandOnMove )
|
||||
{
|
||||
mRubberBand->move( globalMousePos - mDragPos );
|
||||
}
|
||||
else
|
||||
{
|
||||
mWidget->move( globalMousePos - mDragPos );
|
||||
}
|
||||
}
|
||||
|
||||
void NcWidgetData::handleMousePressEvent( QMouseEvent* event )
|
||||
{
|
||||
if ( event->button() == Qt::LeftButton )
|
||||
{
|
||||
mLeftButtonPressed = true;
|
||||
|
||||
QRect frameRect = mWidget->frameGeometry();
|
||||
mPressedMousePos.recalculate( event->globalPos(), frameRect );
|
||||
|
||||
mDragPos = event->globalPos() - frameRect.topLeft();
|
||||
|
||||
if ( mPressedMousePos.onEdges )
|
||||
{
|
||||
if ( d->mUseRubberBandOnResize && !mWidget->isFullScreen() )
|
||||
{
|
||||
mRubberBand->setGeometry( frameRect );
|
||||
mRubberBand->show();
|
||||
}
|
||||
}
|
||||
else if ( d->mUseRubberBandOnMove && !mWidget->isFullScreen() )
|
||||
{
|
||||
mRubberBand->setGeometry( frameRect );
|
||||
mRubberBand->show();
|
||||
}
|
||||
|
||||
const int width = mWidget->width();
|
||||
QRect rect( 5, 5, width-10, 50 );
|
||||
if ( rect.contains(event->pos()) )
|
||||
{
|
||||
mTitlePressed = true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void NcWidgetData::handleMouseReleaseEvent( QMouseEvent* event )
|
||||
{
|
||||
if ( event->button() == Qt::LeftButton )
|
||||
{
|
||||
mLeftButtonPressed = false;
|
||||
mTitlePressed = false;
|
||||
mPressedMousePos.reset();
|
||||
if ( mRubberBand && mRubberBand->isVisible() )
|
||||
{
|
||||
mRubberBand->hide();
|
||||
mWidget->setGeometry( mRubberBand->geometry() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NcWidgetData::handleMouseMoveEvent( QMouseEvent* event )
|
||||
{
|
||||
if ( mLeftButtonPressed )
|
||||
{
|
||||
if ( d->mWidgetResizable && mPressedMousePos.onEdges )
|
||||
{
|
||||
resizeWidget( event->globalPos() );
|
||||
}
|
||||
else if ( d->mWidgetMovable && mTitlePressed )
|
||||
{
|
||||
moveWidget( event->globalPos() );
|
||||
}
|
||||
}
|
||||
else if ( d->mWidgetResizable )
|
||||
{
|
||||
updateCursorShape( event->globalPos() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void NcWidgetData::handleLeaveEvent( QEvent* /*event*/ )
|
||||
{
|
||||
if ( !mLeftButtonPressed )
|
||||
mWidget->unsetCursor();
|
||||
}
|
||||
|
||||
void NcWidgetData::handleHoverMoveEvent( QHoverEvent* event )
|
||||
{
|
||||
if ( d->mWidgetResizable )
|
||||
updateCursorShape( mWidget->mapToGlobal( event->pos() ) );
|
||||
}
|
||||
|
||||
NcFramelessHelper::NcFramelessHelper( QObject* parent )
|
||||
: QObject( parent ),
|
||||
d( new NcFramelessHelperImpl )
|
||||
{
|
||||
d->mWidgetMovable = true;
|
||||
d->mWidgetResizable = true;
|
||||
d->mUseRubberBandOnResize = false;
|
||||
d->mUseRubberBandOnMove = false;
|
||||
}
|
||||
|
||||
NcFramelessHelper::~NcFramelessHelper()
|
||||
{
|
||||
QList<QWidget*> keys = d->mHashWidgetData.keys();
|
||||
int size = keys.size();
|
||||
for ( int i = 0; i < size; ++i )
|
||||
{
|
||||
delete d->mHashWidgetData.take( keys[i] );
|
||||
}
|
||||
|
||||
delete d;
|
||||
}
|
||||
|
||||
bool NcFramelessHelper::eventFilter( QObject *obj, QEvent *event )
|
||||
{
|
||||
QEvent::Type type = event->type();
|
||||
|
||||
if ( type == QEvent::MouseMove ||
|
||||
type == QEvent::HoverMove ||
|
||||
type == QEvent::MouseButtonPress ||
|
||||
type == QEvent::MouseButtonRelease ||
|
||||
type == QEvent::Leave
|
||||
)
|
||||
{
|
||||
NcWidgetData* data = d->mHashWidgetData.value( static_cast<QWidget*>(obj) );
|
||||
if ( data )
|
||||
{
|
||||
data->handleWidgetEvent( event );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void NcFramelessHelper::activateOn( QWidget* topLevelWidget )
|
||||
{
|
||||
if ( d->mHashWidgetData.contains( topLevelWidget ) )
|
||||
return;
|
||||
|
||||
NcWidgetData* data = new NcWidgetData( d, topLevelWidget );
|
||||
d->mHashWidgetData.insert( topLevelWidget, data );
|
||||
|
||||
topLevelWidget->installEventFilter( this );
|
||||
|
||||
}
|
||||
|
||||
void NcFramelessHelper::removeFrom( QWidget* topLevelWidget )
|
||||
{
|
||||
NcWidgetData* data = d->mHashWidgetData.take( topLevelWidget );
|
||||
if ( data )
|
||||
{
|
||||
topLevelWidget->removeEventFilter( this );
|
||||
delete data;
|
||||
}
|
||||
}
|
||||
|
||||
void NcFramelessHelper::setWidgetMovable( bool movable )
|
||||
{
|
||||
d->mWidgetMovable = movable;
|
||||
}
|
||||
|
||||
bool NcFramelessHelper::isWidgetMovable()
|
||||
{
|
||||
return d->mWidgetMovable;
|
||||
}
|
||||
|
||||
void NcFramelessHelper::setWidgetResizable( bool resizable )
|
||||
{
|
||||
d->mWidgetResizable = resizable;
|
||||
}
|
||||
|
||||
bool NcFramelessHelper::isWidgetResizable()
|
||||
{
|
||||
return d->mWidgetResizable;
|
||||
}
|
||||
|
||||
void NcFramelessHelper::useRubberBandOnMove( bool use )
|
||||
{
|
||||
d->mUseRubberBandOnMove = use;
|
||||
QList<NcWidgetData*> list = d->mHashWidgetData.values();
|
||||
int size = list.size();
|
||||
for ( int i = 0; i < size; ++i )
|
||||
list[i]->updateRubberBandStatus();
|
||||
}
|
||||
|
||||
bool NcFramelessHelper::isUsingRubberBandOnMove()
|
||||
{
|
||||
return d->mUseRubberBandOnMove;
|
||||
}
|
||||
|
||||
void NcFramelessHelper::useRubberBandOnResize( bool use )
|
||||
{
|
||||
d->mUseRubberBandOnResize = use;
|
||||
QList<NcWidgetData*> list = d->mHashWidgetData.values();
|
||||
int size = list.size();
|
||||
for ( int i = 0; i < size; ++i )
|
||||
list[i]->updateRubberBandStatus();
|
||||
}
|
||||
|
||||
bool NcFramelessHelper::isUsingRubberBandOnResisze()
|
||||
{
|
||||
return d->mUseRubberBandOnResize;
|
||||
}
|
||||
|
||||
void NcFramelessHelper::setBorderWidth( int newBorderWidth )
|
||||
{
|
||||
//TODO: Make it non-static.
|
||||
if ( newBorderWidth >= 0 )
|
||||
NcCursorPosCalculator::mBorderWidth = newBorderWidth;
|
||||
}
|
||||
|
||||
int NcFramelessHelper::borderWidth()
|
||||
{
|
||||
return NcCursorPosCalculator::mBorderWidth;
|
||||
}
|
||||
32
platform/src/public/pub_widget/PubWidgetInit.cpp
Normal file
32
platform/src/public/pub_widget/PubWidgetInit.cpp
Normal file
@ -0,0 +1,32 @@
|
||||
#include "pub_widget/PubWidgetInit.h"
|
||||
#include "pub_utility_api/I18N.h"
|
||||
#include "pub_utility_api/FileUtil.h"
|
||||
#include <QString>
|
||||
#include <QTranslator>
|
||||
#include <QApplication>
|
||||
|
||||
namespace iot_public
|
||||
{
|
||||
bool installTranslator(const std::string& pLanguage)
|
||||
{
|
||||
bool res = false;
|
||||
const std::string strLanguage = pLanguage;
|
||||
std::string strOmFile = iot_public::CFileUtil::getPathOfResFile( "pub_widget/translate/pub_widget_" + strLanguage + ".qm" );
|
||||
if( !strOmFile.empty() )
|
||||
{
|
||||
res = true;
|
||||
auto *pTrans = new QTranslator;
|
||||
res = pTrans->load( strOmFile.c_str());
|
||||
res = QApplication::installTranslator( pTrans );
|
||||
}
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool installTranslatorFromConfig()
|
||||
{
|
||||
const std::string strLanguage = std::move( iot_public::getCurLanguage());
|
||||
return installTranslator(strLanguage);
|
||||
}
|
||||
}
|
||||
1598
platform/src/public/pub_widget/Widgets.cpp
Normal file
1598
platform/src/public/pub_widget/Widgets.cpp
Normal file
File diff suppressed because it is too large
Load Diff
11
platform/src/public/pub_widget/WorkFrame.cpp
Normal file
11
platform/src/public/pub_widget/WorkFrame.cpp
Normal file
@ -0,0 +1,11 @@
|
||||
#include "pub_widget/WorkFrame.h"
|
||||
|
||||
WorkFrame::WorkFrame(QWidget *parent) : QFrame(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
WorkFrame::~WorkFrame()
|
||||
{
|
||||
|
||||
}
|
||||
53
platform/src/public/pub_widget/pub_widget.pro
Normal file
53
platform/src/public/pub_widget/pub_widget.pro
Normal file
@ -0,0 +1,53 @@
|
||||
QT += core gui
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
TEMPLATE = lib
|
||||
TARGET = pub_widget
|
||||
|
||||
DEFINES += PUB_WIDGET_LIBRARY
|
||||
|
||||
win32{
|
||||
QMAKE_CXXFLAGS -= -Zc:strictStrings
|
||||
}
|
||||
|
||||
# Input
|
||||
HEADERS += \
|
||||
../../include/public/pub_widget/widget_global.h \
|
||||
../../include/public/pub_widget/Widgets.h \
|
||||
../../include/public/pub_widget/NcFramelessHelper.h \
|
||||
../../include/public/pub_widget/MainTitle.h \
|
||||
../../include/public/pub_widget/WorkFrame.h \
|
||||
../../include/public/pub_widget/MenuFrame.h \
|
||||
../../include/public/pub_widget/MessageBox.h \
|
||||
../../include/public/pub_widget/AlertMessageBox.h \
|
||||
../../include/public/pub_widget/FramelessWindow.hpp \
|
||||
../../include/public/pub_widget/CustomDialogTitle.h \
|
||||
../../include/public/pub_widget/CustomDialog.h \
|
||||
../../include/public/pub_widget/CustomMainWindow.h \
|
||||
../../include/public/pub_widget/PubWidgetInit.h
|
||||
|
||||
SOURCES += \
|
||||
../../public/pub_widget/MainTitle.cpp \
|
||||
../../public/pub_widget/Widgets.cpp \
|
||||
../../public/pub_widget/NcFramelessHelper.cpp \
|
||||
../../public/pub_widget/MenuFrame.cpp \
|
||||
../../public/pub_widget/WorkFrame.cpp \
|
||||
../../public/pub_widget/MessageBox.cpp \
|
||||
../../public/pub_widget/AlertMessageBox.cpp \
|
||||
../../public/pub_widget/CustomDialog.cpp \
|
||||
../../public/pub_widget/CustomDialogTitle.cpp \
|
||||
../../public/pub_widget/CustomMainWindow.cpp \
|
||||
../../public/pub_widget/PubWidgetInit.cpp
|
||||
|
||||
LIBS += -lpub_utility_api
|
||||
|
||||
TRANSLATIONS += pub_widget_en.ts \
|
||||
pub_widget_fr.ts
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
COMMON_PRI=$$PWD/../../common.pri
|
||||
exists($$COMMON_PRI) {
|
||||
include($$COMMON_PRI)
|
||||
}else {
|
||||
error("FATAL error: can not find common.pri")
|
||||
}
|
||||
@ -7,3 +7,6 @@ CONFIG += ordered
|
||||
SUBDIRS += pub_logger_api \
|
||||
pub_utility_api \
|
||||
pub_sysinfo_api \
|
||||
pub_excel \
|
||||
pub_widget \
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user