Merge with dev

This commit is contained in:
2012-06-10 18:05:47 +02:00
426 changed files with 54971 additions and 8451 deletions

View File

@@ -1,4 +1,33 @@
v0.2 (24/07/2011)
v0.3 (31/05/2012)
** User **
New interface in Qt4
Use BDD file from .local/share/kisscount
Use libkchart for graphics
Use oxygen icons
New account attribute : hidden
Description is now auto-completed
Snapshot feature
Display date in locale format
Better auto completion for transfert operation (not two times the same operation completed)
Add Win32 support (OFX import disabled)
** Dev **
Version 3 of database : account hidden item added, some id deleted, on delete constraints added
This version is not compatible with previous ones
Values are in fix point (no double anymore)
** Bugs **
Fix a bug in language settings
Virtual transferts must not be considered as a debit
Last account/category wasn't taken in account during search
New users have system language set instead of English
Account/Category modification are immediatly reported in other panels
Accounts and categories where badly mapped during import
Fix cost not taken in account during import
v0.2 (04/07/2011)
Remove dependancies of libsqlite and libxml
User throws exception if account/category not found
** User **
Better use of sizers (so better interface!)

25
INSTALL
View File

@@ -1,30 +1,21 @@
** Dependencies for compilation (on Debian) **
libsqlite3-dev
libwxgtk2.8-dev
libqt4-dev (>= 4.7)
libqt4-sql-sqlite (>= 4.7)
libofx4
g++
make
gettext
Optionnal :
Optional :
git
poeditor
xgettext
qt4-dev-tools
debhelper, devscripts, dh-make, fakeroot
php5
** Compilation of extra libraries **
lib is not included by default and must be downloaded http://indefero.soutade.fr/p/kisscount/downloads/
It must be decompressed beside "src" directory.
cd lib/wxsqlite3-1.9.9
./configure
make
cd -
cd lib/freechart
make # wxFreechart is already configured
cd -
** Compilation of KissCount **
make clean
make

View File

@@ -1,51 +1,84 @@
ROOT_DIR="/usr/local"
ROOT_DIR="/usr"
LIB_DIR=$(DESTDIR)$(ROOT_DIR)"/lib/kisscount/"
SHARE_DIR=$(DESTDIR)$(ROOT_DIR)"/share/kisscount/"
DOC_DIR=$(DESTDIR)$(ROOT_DIR)"/share/doc/kisscount/"
BIN_DIR=$(DESTDIR)$(ROOT_DIR)"/bin/"
CXXFLAGS+=`wx-config --cxxflags` -Wall -Isrc -ggdb
CXXFLAGS+=-I./lib/wxsqlite3-1.9.9/include
CXXFLAGS+=-I./lib/freechart/include
CXXFLAGS+=-I/usr/include/libxml2
CXXFLAGS+=-Wl,--rpath,"$(LIB_DIR)"
QT_PACKAGES="QtCore QtGui QtSql QtXml"
CXXFLAGS+=`pkg-config --cflags $(QT_PACKAGES)`
CXXFLAGS+=-Wall -Isrc -Isrc/win32 -ggdb -fPIC
ifdef WIN32
CXXFLAGS+=-DRESSOURCES_ROOT="\"./ressources/\""
else
CXXFLAGS+=-DRESSOURCES_ROOT="\"$(SHARE_DIR)\""
# For developpers
#CXXFLAGS+=-DRESSOURCES_ROOT="\"./ressources/\""
endif
LDFLAGS+=`wx-config --libs`
LDFLAGS+=`pkg-config --libs $(QT_PACKAGES)`
ifndef WIN32
LDFLAGS+=-lofx
LDFLAGS+=-lxml2
ifdef WIN32
LDFLAGS+=-L./lib/wxsqlite3-1.9.9/lib/ -lwxcode_msw_wxsqlite3-2.8
LDFLAGS+=-L./lib/freechart/lib -lwxcode_msw_freechart-2.8
else
LDFLAGS+=-L./lib/wxsqlite3-1.9.9/lib/ -lwxcode_gtk2u_wxsqlite3-2.8
LDFLAGS+=-L./lib/freechart/lib -lwxcode_gtk2u_freechart-2.8
endif
CXX=$(HOST)g++
SOURCES=$(shell find src -name '*.cpp' -type f | tr '\n' ' ')
HEADERS=$(shell find src -name '*.h' -type f)
OBJS=$(SOURCES:.cpp=.o)
MOC_HEADERS=$(shell find src/view -name '*.hpp' -type f | tr '\n' ' ')
MOCS=$(MOC_HEADERS:.hpp=.objs)
MOCS_OBJS=$(MOC_HEADERS:.hpp=.moc)
all: check kc
CXXFLAGS+=-Ilib/libkdchart/include -Ilib/libkdchart/src -Ilib/libkdchart/kdablibfakes/include
CXXFLAGS+=-DKDCHART_BUILD_KDCHART_LIB
KDCHART_SOURCES=$(shell find lib/libkdchart/src -name '*.cpp' -type f | tr '\n' ' ')
KDCHART_OBJS=$(KDCHART_SOURCES:.cpp=.o)
UI_CHARTSELECTOR=lib/libkdchart/src/ui_KDChartDatasetSelector.h
KDCHART_MOC_HEADERS=$(shell find lib/libkdchart/src -name '*.h' -type f | tr '\n' ' ')
KDCHART_MOCS=$(KDCHART_MOC_HEADERS:.h=.objs)
KDCHART_MOCS_OBJS=$(KDCHART_MOC_HEADERS:.h=.moc)
LDFLAGS+=lib/libkdchart.a
clean:
find src -type f -name '*.[o~]' -exec rm -f \{\} \;
all: mojito lib/libkdchart.a kc
clean_all: clean clean_libkdchart
clean:
find src -type f -name '*.o' -delete
find src -type f -name '*~' -delete
find src -type f -name '*.moc' -delete
find src -type f -name '*.objs' -delete
rm -f kc
%.o : src/model/%.cpp src/model/import/%.cpp src/model/export/%.cpp src/view/%.cpp src/view/grid/%.cpp src/controller/%.cpp src/%.cpp
$(CXX) $(CXXFLAGS) -c $<
%.o : %.cpp
$(CXX) $(CXXFLAGS) -c $< -o $@
check:
if ! test -d lib ; then echo lib directory not found, please see INSTALL ; return 1 ; fi
%.objs : %.moc
$(CXX) $(CXXFLAGS) -x c++ $< -c -o $@
kc: $(OBJS)
%.moc : %.hpp
moc -nw $< -o $@
%.moc : %.h
moc -nw $< -o $@
mojito : $(MOCS_OBJS) $(KDCHART_MOCS_OBJS)
kc: $(MOCS) $(OBJS)
$(CXX) $(CXXFLAGS) $^ -o $@ $(LDFLAGS)
$(UI_CHARTSELECTOR): lib/libkdchart/src/KDChartDatasetSelector.ui
uic $< > $(UI_CHARTSELECTOR)
sed s/KDCHARTDATASETSELECTOR_H/UI_KDCHARTDATASETSELECTOR_H/g -i $(UI_CHARTSELECTOR)
lib/libkdchart.a: $(UI_CHARTSELECTOR) $(KDCHART_MOCS) $(KDCHART_OBJS)
$(HOST)ar rcu lib/libkdchart.a $(KDCHART_MOCS) $(KDCHART_OBJS)
clean_libkdchart:
rm -rf lib/libkdchart.a
find lib/libkdchart -name '*.o' -delete
find lib/libkdchart -type f -name '*.moc' -delete
find lib/libkdchart -type f -name '*.objs' -delete
generate_locales:
./tools/generate_locales.sh
@@ -58,11 +91,14 @@ package:
endif
install:
mkdir -p $(LIB_DIR) $(BIN_DIR) $(SHARE_DIR) $(DOC_DIR)
mkdir -p $(BIN_DIR) $(SHARE_DIR) $(DOC_DIR)
cp kc $(BIN_DIR)
find lib -name '*.so*' -exec cp -rf \{\} $(LIB_DIR) \;
cp -rf ressources/* $(SHARE_DIR)
cp -rf README* ChangeLog CONTRIBUTORS COPYING TODO $(DOC_DIR)
rm -rf $(SHARE_DIR)/ressources/po/*
cp -rf ressources/po/*.qm $(SHARE_DIR)/ressources/po/
cp -rf README* ChangeLog AUTHORS COPYING TODO $(DOC_DIR)
remove:
rm -rf $(LIB_DIR) $(SHARE_DIR) $(DOC_DIR) $(BIN_DIR)/kc
uninstall: remove

6
README
View File

@@ -1,10 +1,8 @@
KissCount is personnal account software delivered under GPL v3 licence terms.
Current version is 0.2
Current version is 0.3
wxWidgets 2.8, sqlite3, libofx and libxml2 are needed
A modified version of wxFreeChart is used : warning during recompilation, don't overwrite autotools files with ./configure
Qt4 (>= 4.7), libqt4-sql-sqlite and libofx (Linux only) are needed
If you use web view, edit database.php and set $BDD_FILE, it's higly recommanded to use an SSL certificate.

View File

@@ -1,10 +1,8 @@
KissCount est un logiciel de gestion de comptes personnels délivré sous licence GPL v3
La version actuelle est 0.2
La version actuelle est 0.3
wxWidgets 2.8, sqlite3, libofx et libxml2 sont nécessaires
Une version modifiée de wxFreeChart est utilisée : attention à lors de la recompilation à ne pas écraser les fichiers des autotools (pas de ./configure)
Qt4 (>= 4.7), libqt4-sql-sqlite et libofx (Uniquement pour Linux) sont nécessaires
Si vous utilisez la version web pour visualiser vos comptes, éditez d'abord le fichier database.php en positionnant correctement la variable $BDD_FILE, il est fortement recommandé d'utiliser un certificat SSL.

15
TODO
View File

@@ -1,18 +1,15 @@
Version 0.3
Version 0.4
Statistics (need to add months/years label on graph)
Auto completion (already up into wxwidgets 2.9)
Using tabulation to navigate throw interface (Search Panel)
Can type a letter with a comboboxes
Windows version
Choosing accounts & categories position
Cool for 0.3:
Cool for 0.5:
Database auto saving at startup
Use caches for created panels (avoid destroying/creating panels for nothing)
Add search function to web view
Need optimizations by caching operations and categories (using hastables)
Packaging for more distributions
Optimizations in GridAccount (Add/Delete operation / multiple operations)
===============================================================
Next version
@@ -20,7 +17,6 @@ Next version
More translations
Printing (maybe in xml/html)
Plugins ?
WxWidgets 2.9
===============================================================
Will not be implemented
@@ -38,4 +34,7 @@ it's not taken in account by UpdateStats
* If a sub operation is found using SearchPanel but not its parent
it will not be displayed. In this case we must load whole meta.
This bug can't be resolved without use of hashtable because of
complexity in searching this issue.
complexity in searching this issue.
* When changing date in a sub operation (set date > main date),
meta amount is set to 0

72
debian/Makefile vendored
View File

@@ -1,72 +0,0 @@
LIB_DIR=$(DESTDIR)"/usr/lib/kisscount/"
SHARE_DIR=$(DESTDIR)"/usr/share/kisscount/"
DOC_DIR=$(DESTDIR)"/usr/share/doc/kisscount/"
BIN_DIR=$(DESTDIR)"/usr/bin/"
CXXFLAGS+=`wx-config --cxxflags` -Wall -Isrc -ggdb
CXXFLAGS+=-I./lib/wxsqlite3-1.9.9/include
CXXFLAGS+=-I./lib/freechart/include
CXXFLAGS+=-Wl,--rpath,"$(LIB_DIR)"
CXXFLAGS+=-DRESSOURCES_ROOT="\"$(SHARE_DIR)\""
#CXXFLAGS+=-DRESSOURCES_ROOT="\"./ressources/\""
LDFLAGS+=`wx-config --libs`
ifdef WIN32
LDFLAGS+=-L./lib/wxsqlite3-1.9.9/lib/ -lwxcode_msw_wxsqlite3-2.8
LDFLAGS+=-L./lib/freechart/lib -lwxcode_msw_freechart-2.8
else
LDFLAGS+=-L./lib/wxsqlite3-1.9.9/lib/ -lwxcode_gtk2u_wxsqlite3-2.8
LDFLAGS+=-L./lib/freechart/lib -lwxcode_gtk2u_freechart-2.8
endif
CXX=$(PREFIX)g++
SOURCES=$(wildcard src/model/*.cpp)
SOURCES+=$(wildcard src/view/*.cpp)
SOURCES+=$(wildcard src/view/grid/*.cpp)
SOURCES+=$(wildcard src/controller/*.cpp)
SOURCES+=src/main.cpp src/sha1.cpp src/ParseExp.cpp
HEADERS=$(wildcard src/model/*.h)
HEADERS+=$(wildcard src/view/*.h)
HEADERS+=$(wildcard src/view/grid/*.h)
HEADERS+=$(wildcard src/controller/*.h)
HEADERS+=src/main.h src/sha1.h
OBJS=$(SOURCES:.cpp=.o)
all: check kc
clean:
rm -f *~ src/*~ src/*.o src/model/*.o src/model/*~ src/view/*.o src/view/grid/*.o src/view/grid/*~ src/view/*~ src/controller/*.o src/controller/*~ kc
# %.o : src/model/%.cpp src/view/%.cpp src/view/grid/%.cpp src/controller/%.cpp src/%.cpp
# $(CXX) $(CXXFLAGS) $< -c
check:
# if ! test -d lib ; then echo lib directory not found, please see INSTALL ; return 1 ; fi
#kc: $(OBJS)
# $(CXX) $(CXXFLAGS) $^ -o $@ $(LDFLAGS)
kc:
cp ../kc .
generate_locales:
./tools/generate_locales.sh
ifdef WIN32
package:
./tools/package_win32.sh
else
package:
./tools/package.sh
endif
install:
mkdir -p $(LIB_DIR) $(BIN_DIR) $(SHARE_DIR) $(DOC_DIR)
cp kc $(BIN_DIR)
cp -rf lib/*.so* $(LIB_DIR)
cp -rf ressources/* $(SHARE_DIR)
cp -rf README* ChangeLog CONTRIBUTORS TODO $(DOC_DIR)
remove:
rm -rf $(LIB_DIR) $(SHARE_DIR) $(DOC_DIR) $(BIN_DIR)/kc

1
debian/Makefile vendored Symbolic link
View File

@@ -0,0 +1 @@
../Makefile

4
debian/changelog vendored
View File

@@ -1,5 +1,5 @@
kisscount (0.2-1) unstable; urgency=low
kisscount (0.3-1) unstable; urgency=low
* Initial release
-- Grégory Soutadé <soutade@gmail.com> Sat, 26 Feb 2011 13:13:52 +0100
-- Grégory Soutadé <soutade@gmail.com> Sun, 24 Aug 2011 13:13:52 +0100

2
debian/control vendored
View File

@@ -2,7 +2,7 @@ Source: kisscount
Section: misc
Priority: extra
Maintainer: Grégory Soutadé <soutade@gmail.com>
Build-Depends: debhelper (>= 7.0.50~), libsqlite3-dev, libwxgtk2.8-dev (>= 2.8.10), libofx-dev, libxml2-dev
Build-Depends: debhelper (>= 7.0.50~), libofx-dev, libqt4-dev (>= 4.7), libqt4-sql-sqlite
Standards-Version: 3.9.1
Homepage: http://indefero.soutade.fr/p/kisscount/
Vcs-Git: git://soutade.fr/kisscount.git

4
debian/copyright vendored
View File

@@ -3,12 +3,12 @@ Upstream-Name: kisscount
Source: http://indefero.soutade.fr/p/kisscount/
Files: *
Copyright: 2010-2011 Grégory Soutadé
Copyright: 2010-2012 Grégory Soutadé
License: GPL-3.0+
Files: debian/*
Copyright: 2011 Grégory Soutadé <soutade@gmail.com>
Copyright: 2012 Grégory Soutadé <soutade@gmail.com>
License: GPL-3.0+
License: GPL-3.0+

2
debian/docs vendored
View File

@@ -2,4 +2,4 @@ README
README.fr
ChangeLog
TODO
CONTRIBUTORS
AUTHORS

3
debian/rules vendored
View File

@@ -28,3 +28,6 @@ export DH_VERBOSE=1
override_dh_strip:
# Full compilation has already been done
override_dh_auto_clean:

View File

@@ -2,7 +2,7 @@
# KissCount installation script for .tar.bz2 package
# Copyright 2010-2011 Grégory Soutadé
# Copyright 2010-2012 Grégory Soutadé
# This file is part of KissCount.
@@ -19,10 +19,11 @@
# You should have received a copy of the GNU General Public License
# along with KissCount. If not, see <http://www.gnu.org/licenses/>.
ROOT_DIR=/usr/local
SHARE_DIR=$ROOT_DIR/share/kisscount
LIB_DIR=$ROOT_DIR/lib/kisscount
BIN_DIR=$ROOT_DIR/bin
DEST_DIR=""
ROOT_DIR=$DEST_DIR/usr
SHARE_DIR=$DEST_DIR$ROOT_DIR/share/kisscount
LIB_DIR=$DEST_DIR$ROOT_DIR/lib/kisscount
BIN_DIR=$DEST_DIR$ROOT_DIR/bin
case "$1" in
--install|-i)
@@ -34,6 +35,7 @@ case "$1" in
sudo mkdir -p $SHARE_DIR
sudo mkdir -p $LIB_DIR
sudo mkdir -p ~/.local/share/kisscount
sudo cp -r ressources/* $SHARE_DIR
sudo cp kc $BIN_DIR
sudo cp -r lib/* $LIB_DIR
@@ -47,6 +49,8 @@ case "$1" in
sudo rm -rf $LIB_DIR
sudo rm -f $BIN_DIR/kc
echo "Private database (~/.local/share/kisscount) not deleted"
echo
echo "KissCount successfully uninstalled !"
;;

6
kc.1
View File

@@ -2,7 +2,7 @@
.\" First parameter, NAME, should be all caps
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
.\" other parameters are allowed: see man(7), man(1)
.TH KC 1 "February 26, 2011"
.TH KC 1 "February 27, 2012"
.\" Please adjust this date whenever revising the manpage.
.\"
.\" Some roff macros, for reference:
@@ -26,9 +26,9 @@ KissCount is a personal accounting software. Its goal is to be as simple as poss
It focuses on PERSONAL accounting (not companies/associations). You only have to enter operations and see what you have (or not).
.TP
.B bdd_file
Choose another database file than ~/.kisscount/kc.bdd
Choose another database file than ~/.local/share/kisscount/kc.bdd
.SH FILES
Default database is ~/.kisscount/kc.bdd
Default database is ~/.local/share/kisscount/kc.bdd
.SH AUTHOR
KissCount was written by <Grégory Soutadé>.
.PP

1241
lib/libkdchart/Doxyfile Normal file

File diff suppressed because it is too large Load Diff

1027
lib/libkdchart/LICENSE.GPL Normal file

File diff suppressed because it is too large Load Diff

24
lib/libkdchart/README.txt Normal file
View File

@@ -0,0 +1,24 @@
Welcome to KD Chart 2, Klaralvdalens Datakonsult's charting engine for Qt!
Please refer to the license file for conditions of use.
After reading the introductory overview files in doc/
you will find more information at three places:
detailed browsable API reference: doc/refman/index.html
or: http://docs.kdab.com/kdchart/2.4/
programmers manual with examples: doc/manual/kdchart.pdf
our sorted example programs: examples/
In case of additional questions during evaluation or use of
KD Chart please contact our technical support by mail:
kdchart-support@kdab.com
We thank you for your interest in KD Chart and we are here
to assist you if the documentation leaves open questions or
if you just need some help with finding the best way in which
to realize your charting ideas.
The KDAB KD Chart Support Team.

View File

@@ -0,0 +1 @@
#include "../src/KDChartAbstractAxis.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartAbstractCartesianDiagram.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartAbstractCoordinatePlane.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartAbstractDiagram.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartAbstractPieDiagram.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartAbstractPolarDiagram.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartAbstractProxyModel.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartAbstractTernaryDiagram.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartAbstractThreeDAttributes.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartAttributesModel.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartBackgroundAttributes.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartBarAttributes.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartBarDiagram.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartCartesianAxis.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartCartesianCoordinatePlane.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartChart.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartDataValueAttributes.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartDatasetProxyModel.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartDatasetSelector.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartDiagramObserver.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartEnums.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartFrameAttributes.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartGlobal.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartGridAttributes.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartHeaderFooter.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartLegend.h"

View File

@@ -0,0 +1 @@
#include "../src/LeveyJennings/KDChartLeveyJenningsAxis.h"

View File

@@ -0,0 +1 @@
#include "../src/LeveyJennings/KDChartLeveyJenningsCoordinatePlane.h"

View File

@@ -0,0 +1 @@
#include "../src/LeveyJennings/KDChartLeveyJenningsDiagram.h"

View File

@@ -0,0 +1 @@
#include "../src/LeveyJennings/KDChartLeveyJenningsGrid.h"

View File

@@ -0,0 +1 @@
#include "../src/LeveyJennings/KDChartLeveyJenningsGridAttributes.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartLineAttributes.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartLineDiagram.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartMarkerAttributes.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartMeasure.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartPaintContext.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartPalette.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartPieAttributes.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartPieDiagram.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartPlotter.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartPolarCoordinatePlane.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartPolarDiagram.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartPosition.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartRelativePosition.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartRingDiagram.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartRulerAttributes.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartStockBarAttributes.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartStockDiagram.h"

View File

@@ -0,0 +1 @@
#include "../src/Ternary/KDChartTernaryAxis.h"

View File

@@ -0,0 +1 @@
#include "../src/Ternary/KDChartTernaryCoordinatePlane.h"

View File

@@ -0,0 +1 @@
#include "../src/Ternary/KDChartTernaryLineDiagram.h"

View File

@@ -0,0 +1 @@
#include "../src/Ternary/KDChartTernaryPointDiagram.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartTextAttributes.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartThreeDBarAttributes.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartThreeDLineAttributes.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartThreeDPieAttributes.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartValueTrackerAttributes.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartWidget.h"

View File

@@ -0,0 +1 @@
#include "../src/KDChartZoomParameters.h"

View File

@@ -0,0 +1 @@
#include "../src/KDTextDocument.h"

View File

@@ -0,0 +1,181 @@
/********************************************************************************
** Form generated from reading UI file 'KDChartDatasetSelector.ui'
**
** Created: Sat Jan 7 12:36:09 2012
** by: Qt User Interface Compiler version 4.7.3
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/
#ifndef KDCHARTDATASETSELECTOR_H
#define KDCHARTDATASETSELECTOR_H
#include <QtCore/QVariant>
#include <QtGui/QAction>
#include <QtGui/QApplication>
#include <QtGui/QButtonGroup>
#include <QtGui/QCheckBox>
#include <QtGui/QGridLayout>
#include <QtGui/QGroupBox>
#include <QtGui/QHBoxLayout>
#include <QtGui/QHeaderView>
#include <QtGui/QLabel>
#include <QtGui/QSpacerItem>
#include <QtGui/QSpinBox>
#include <QtGui/QWidget>
QT_BEGIN_NAMESPACE
class Ui_DatasetSelector
{
public:
QHBoxLayout *hboxLayout;
QGroupBox *groupBox;
QGridLayout *gridLayout;
QCheckBox *cbReverseColumns;
QLabel *label_5;
QSpinBox *sbStartColumn;
QLabel *label_2;
QSpinBox *sbColumnCount;
QLabel *label;
QLabel *label_6;
QSpinBox *sbStartRow;
QLabel *label_4;
QCheckBox *cbReverseRows;
QLabel *label_3;
QSpinBox *sbRowCount;
QSpacerItem *spacerItem;
void setupUi(QWidget *DatasetSelector)
{
if (DatasetSelector->objectName().isEmpty())
DatasetSelector->setObjectName(QString::fromUtf8("DatasetSelector"));
DatasetSelector->resize(728, 344);
QSizePolicy sizePolicy(static_cast<QSizePolicy::Policy>(3), static_cast<QSizePolicy::Policy>(3));
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
sizePolicy.setHeightForWidth(DatasetSelector->sizePolicy().hasHeightForWidth());
DatasetSelector->setSizePolicy(sizePolicy);
DatasetSelector->setMinimumSize(QSize(0, 0));
hboxLayout = new QHBoxLayout(DatasetSelector);
#ifndef Q_OS_MAC
hboxLayout->setSpacing(6);
#endif
#ifndef Q_OS_MAC
hboxLayout->setContentsMargins(9, 9, 9, 9);
#endif
hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
groupBox = new QGroupBox(DatasetSelector);
groupBox->setObjectName(QString::fromUtf8("groupBox"));
groupBox->setCheckable(true);
groupBox->setChecked(false);
gridLayout = new QGridLayout(groupBox);
#ifndef Q_OS_MAC
gridLayout->setSpacing(6);
#endif
#ifndef Q_OS_MAC
gridLayout->setContentsMargins(9, 9, 9, 9);
#endif
gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
cbReverseColumns = new QCheckBox(groupBox);
cbReverseColumns->setObjectName(QString::fromUtf8("cbReverseColumns"));
gridLayout->addWidget(cbReverseColumns, 3, 1, 1, 3);
label_5 = new QLabel(groupBox);
label_5->setObjectName(QString::fromUtf8("label_5"));
label_5->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
gridLayout->addWidget(label_5, 3, 0, 1, 1);
sbStartColumn = new QSpinBox(groupBox);
sbStartColumn->setObjectName(QString::fromUtf8("sbStartColumn"));
gridLayout->addWidget(sbStartColumn, 2, 3, 1, 1);
label_2 = new QLabel(groupBox);
label_2->setObjectName(QString::fromUtf8("label_2"));
label_2->setAlignment(Qt::AlignCenter);
gridLayout->addWidget(label_2, 2, 2, 1, 1);
sbColumnCount = new QSpinBox(groupBox);
sbColumnCount->setObjectName(QString::fromUtf8("sbColumnCount"));
gridLayout->addWidget(sbColumnCount, 2, 1, 1, 1);
label = new QLabel(groupBox);
label->setObjectName(QString::fromUtf8("label"));
label->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
gridLayout->addWidget(label, 2, 0, 1, 1);
label_6 = new QLabel(groupBox);
label_6->setObjectName(QString::fromUtf8("label_6"));
label_6->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
gridLayout->addWidget(label_6, 1, 0, 1, 1);
sbStartRow = new QSpinBox(groupBox);
sbStartRow->setObjectName(QString::fromUtf8("sbStartRow"));
gridLayout->addWidget(sbStartRow, 0, 3, 1, 1);
label_4 = new QLabel(groupBox);
label_4->setObjectName(QString::fromUtf8("label_4"));
label_4->setAlignment(Qt::AlignCenter);
gridLayout->addWidget(label_4, 0, 2, 1, 1);
cbReverseRows = new QCheckBox(groupBox);
cbReverseRows->setObjectName(QString::fromUtf8("cbReverseRows"));
gridLayout->addWidget(cbReverseRows, 1, 1, 1, 3);
label_3 = new QLabel(groupBox);
label_3->setObjectName(QString::fromUtf8("label_3"));
label_3->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
gridLayout->addWidget(label_3, 0, 0, 1, 1);
sbRowCount = new QSpinBox(groupBox);
sbRowCount->setObjectName(QString::fromUtf8("sbRowCount"));
gridLayout->addWidget(sbRowCount, 0, 1, 1, 1);
spacerItem = new QSpacerItem(169, 31, QSizePolicy::Minimum, QSizePolicy::Expanding);
gridLayout->addItem(spacerItem, 4, 2, 1, 1);
hboxLayout->addWidget(groupBox);
retranslateUi(DatasetSelector);
QMetaObject::connectSlotsByName(DatasetSelector);
} // setupUi
void retranslateUi(QWidget *DatasetSelector)
{
DatasetSelector->setWindowTitle(QApplication::translate("DatasetSelector", "Data Selector", 0, QApplication::UnicodeUTF8));
groupBox->setTitle(QApplication::translate("DatasetSelector", "Only display a subset of the model in the chart:", 0, QApplication::UnicodeUTF8));
cbReverseColumns->setText(QApplication::translate("DatasetSelector", "in reverse order.", 0, QApplication::UnicodeUTF8));
label_5->setText(QApplication::translate("DatasetSelector", "...", 0, QApplication::UnicodeUTF8));
label_2->setText(QApplication::translate("DatasetSelector", "columns starting at column", 0, QApplication::UnicodeUTF8));
label->setText(QApplication::translate("DatasetSelector", "Display", 0, QApplication::UnicodeUTF8));
label_6->setText(QApplication::translate("DatasetSelector", "...", 0, QApplication::UnicodeUTF8));
label_4->setText(QApplication::translate("DatasetSelector", "rows starting at row", 0, QApplication::UnicodeUTF8));
cbReverseRows->setText(QApplication::translate("DatasetSelector", "in reverse order.", 0, QApplication::UnicodeUTF8));
label_3->setText(QApplication::translate("DatasetSelector", "Display", 0, QApplication::UnicodeUTF8));
} // retranslateUi
};
namespace Ui {
class DatasetSelector: public Ui_DatasetSelector {};
} // namespace Ui
QT_END_NAMESPACE
#endif // KDCHARTDATASETSELECTOR_H

View File

@@ -0,0 +1 @@
#include "../src/KDABLibFakes.h"

View File

@@ -0,0 +1,80 @@
/****************************************************************************
** Copyright (C) 2001-2011 Klaralvdalens Datakonsult AB. All rights reserved.
**
** This file is part of the KD Chart library.
**
** Licensees holding valid commercial KD Chart licenses may use this file in
** accordance with the KD Chart Commercial License Agreement provided with
** the Software.
**
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 and version 3 as published by the
** Free Software Foundation and appearing in the file LICENSE.GPL.txt included.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** Contact info@kdab.com if any conditions of this licensing are not
** clear to you.
**
**********************************************************************/
#ifndef KDAB_LIB_FAKES_H
#define KDAB_LIB_FAKES_H
#if defined Q_OS_DARWIN
/* On Mac OS X, ensure that <cmath> will define std::isnan */
#define _GLIBCPP_USE_C99 1
#endif
#include <cmath>
#ifdef Q_OS_SOLARIS
#include <sunmath.h>
#include <math.h>
#endif
#include <qglobal.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#define DEGTORAD(d) (d)*M_PI/180
// Smybian's math.h doesn't define a trunc function
#if defined(Q_OS_SYMBIAN) || defined(QT_SIMULATOR)
#define trunc(x) (double) ((int) (x + (x >= 0.0 ? -0.5 : 0.5)))
#endif
// We use our own ISNAN / ISINF in the code to detect
// that we defined them.
// reason: Windows / MacOS do not have isnan() / isinf()
#if defined (Q_OS_WIN) && defined(_MSC_VER)
#include <float.h>
#define ISNAN(x ) _isnan(x )
#define ISINF(x ) (!(_finite(x ) + _isnan(x ) ) )
#elif defined (Q_OS_DARWIN) || defined (Q_OS_CYGWIN)
#define ISNAN(x) std::isnan(x)
#define ISINF(x) std::isinf(x)
#else
#define ISNAN(x) isnan(x)
#define ISINF(x) isinf(x)
#endif
// We wrap every for() by extra { } to work around
// the scope bug for loop counters in MS Visual C++ v6
#if defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET)
/* This is done in Qt41 qglobal.h but not Qt42*/
#if QT_VERSION < 0x040200
#define for if (0) {} else for
#endif
#define KDAB_FOREACH( v, c ) if (0) {} else Q_FOREACH( v, c )
#else
#define KDAB_FOREACH( v, c ) Q_FOREACH( v, c )
#endif
#endif

View File

@@ -0,0 +1,182 @@
/****************************************************************************
** Copyright (C) 2001-2011 Klaralvdalens Datakonsult AB. All rights reserved.
**
** This file is part of the KD Chart library.
**
** Licensees holding valid commercial KD Chart licenses may use this file in
** accordance with the KD Chart Commercial License Agreement provided with
** the Software.
**
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 and version 3 as published by the
** Free Software Foundation and appearing in the file LICENSE.GPL.txt included.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** Contact info@kdab.com if any conditions of this licensing are not
** clear to you.
**
**********************************************************************/
#ifndef CARTESIANCOORDINATETRANSFORMATION_H
#define CARTESIANCOORDINATETRANSFORMATION_H
#include <QList>
#include <QRectF>
#include <QPointF>
#include "KDChartZoomParameters.h"
#include <cmath>
#include <limits>
namespace KDChart {
// FIXME: if this struct is used more often, we need to make it a class
// with proper accessor methods:
/**
* \internal
*/
struct CoordinateTransformation {
QRectF diagramRect;
// represents the distance of the diagram coordinate origin to the
// origin of the coordinate plane space:
QPointF originTranslation;
// make a vector base for R2:
double unitVectorX;
double unitVectorY;
// implement isometric scaling:
double isoScaleX;
double isoScaleY;
CartesianCoordinatePlane::AxesCalcMode axesCalcModeY;
CartesianCoordinatePlane::AxesCalcMode axesCalcModeX;
ZoomParameters zoom;
typedef QPair< qreal, qreal > qrealPair;
inline qreal makeLogarithmic( qrealPair reference, qreal value ) const
{
qreal result = value;
qreal relation;
if( reference.second == -1.0 )
relation = 1.0;
else if( reference.second == 1.0 )
relation = 1.0;
else if( reference.second > 0.0 )
relation = reference.second / log10( reference.second );
else if( result < 0.0 )
relation = reference.second / log10( -reference.second );
else
relation = 10.0;
if( value == 0.0 )
result = 0.0;//std::numeric_limits< qreal >::quiet_NaN();
else if( value > 0.0 )
result = log10( result ) * relation;
else if( value < 0.0 )
result = -log10( -result ) * relation;
if( value == 0.0 )
return result;
result -= log10( qAbs( reference.first ) ) * relation;
result *= ( reference.second - reference.first ) / relation / (log10(qAbs(reference.second))-log10(qAbs(reference.first)));
result += reference.first;
if( reference.first < 0.0 )
{
result += reference.first;
result -= reference.second;
result = reference.first - result + reference.second;
}
return result;
}
inline QPointF translate( const QPointF& diagramPoint ) const
{
// ### de-inline me
QPointF result = originTranslation;
QPointF tempPoint = diagramPoint;
const QRectF& diagRect = diagramRect;
if( axesCalcModeY == CartesianCoordinatePlane::Logarithmic )
{
tempPoint.setY( makeLogarithmic( qrealPair( diagRect.bottom(), diagRect.y() ), tempPoint.y() ) );
}
if( axesCalcModeX == CartesianCoordinatePlane::Logarithmic )
{
tempPoint.setX( makeLogarithmic( qrealPair( diagRect.x(), diagRect.right() ), tempPoint.x() ) );
}
tempPoint.rx() += diagRect.width() / (2.0 * zoom.xFactor);
tempPoint.ry() += diagRect.height() / (2.0 * zoom.yFactor);
tempPoint.rx() -= diagRect.width() * zoom.xCenter;
tempPoint.ry() -= diagRect.height() * zoom.yCenter;
// translate: xNew = (xOld - diaX) * zoomX + diaX
tempPoint.setX( ( tempPoint.x() - diagRect.x() ) * zoom.xFactor + diagRect.x() );
tempPoint.setY( ( tempPoint.y() - diagRect.y() ) * zoom.yFactor + diagRect.y() );
result.rx() += isoScaleX * unitVectorX * tempPoint.x();
result.ry() += isoScaleY * unitVectorY * tempPoint.y();
return result;
}
// convert screen points to value space points
inline const QPointF translateBack( const QPointF& screenPoint ) const
{
qreal x, y;
x = screenPoint.x() - originTranslation.x();
y = screenPoint.y() - originTranslation.y();
x /= isoScaleX * unitVectorX;
y /= isoScaleY * unitVectorY;
// translate back: xOld = DiaX + (xNew - DiaX) / zoomX
x = diagramRect.x() + (x - diagramRect.x()) / zoom.xFactor;
y = diagramRect.y() + (y - diagramRect.y()) / zoom.yFactor;
x += diagramRect.width() * zoom.xCenter;
y += diagramRect.height() * zoom.yCenter;
x -= diagramRect.width() / (2.0 * zoom.xFactor);
y -= diagramRect.height() / (2.0 * zoom.yFactor);
/*
if ( axesCalcModeY == CartesianCoordinatePlane::Logarithmic ){
tempPoint.setY( makeLogarithmic( diagramRect.y(), tempPoint.y() ) );
//qDebug() << "Y: " << tempPoint.y();
}
if ( axesCalcModeX == CartesianCoordinatePlane::Logarithmic ){
//qDebug() << "X diagramRect.x(): " << diagramRect.x();
//qDebug() << "X tempPoint old: " << tempPoint;
tempPoint.setX( makeLogarithmic( diagramRect.width(), tempPoint.x() ) );
//qDebug() << "X tempPoint new: " << tempPoint;
}
// qDebug() << "CoordinateTransformation::translate() using diagramRect: "
// << diagramRect.x() << diagramRect.y() << diagramRect.width() << diagramRect.height();
*/
return QPointF(x, y);
}
};
typedef QList<CoordinateTransformation> CoordinateTransformationList;
}
#endif

View File

@@ -0,0 +1,156 @@
/****************************************************************************
** Copyright (C) 2001-2011 Klaralvdalens Datakonsult AB. All rights reserved.
**
** This file is part of the KD Chart library.
**
** Licensees holding valid commercial KD Chart licenses may use this file in
** accordance with the KD Chart Commercial License Agreement provided with
** the Software.
**
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 and version 3 as published by the
** Free Software Foundation and appearing in the file LICENSE.GPL.txt included.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** Contact info@kdab.com if any conditions of this licensing are not
** clear to you.
**
**********************************************************************/
#include "KDChartAbstractArea.h"
#include "KDChartAbstractArea_p.h"
#include <qglobal.h>
#include <QPainter>
#include <QRect>
#include <KDABLibFakes>
using namespace KDChart;
#define d (d_func())
AbstractArea::Private::Private() :
AbstractAreaBase::Private()
{
// this bloc left empty intentionally
}
AbstractArea::Private::~Private()
{
// this bloc left empty intentionally
}
AbstractArea::AbstractArea()
: QObject()
, KDChart::AbstractAreaBase()
, KDChart::AbstractLayoutItem()
{
init();
}
AbstractArea::~AbstractArea()
{
// this bloc left empty intentionally
}
void AbstractArea::init()
{
d->amountOfLeftOverlap = 0;
d->amountOfRightOverlap = 0;
d->amountOfTopOverlap = 0;
d->amountOfBottomOverlap = 0;
}
int AbstractArea::leftOverlap( bool doNotRecalculate ) const
{
// Re-calculate the sizes,
// so we also get the amountOf..Overlap members set newly:
if( ! doNotRecalculate )
sizeHint();
return d->amountOfLeftOverlap;
}
int AbstractArea::rightOverlap( bool doNotRecalculate ) const
{
// Re-calculate the sizes,
// so we also get the amountOf..Overlap members set newly:
if( ! doNotRecalculate )
sizeHint();
return d->amountOfRightOverlap;
}
int AbstractArea::topOverlap( bool doNotRecalculate ) const
{
// Re-calculate the sizes,
// so we also get the amountOf..Overlap members set newly:
if( ! doNotRecalculate )
sizeHint();
return d->amountOfTopOverlap;
}
int AbstractArea::bottomOverlap( bool doNotRecalculate ) const
{
// Re-calculate the sizes,
// so we also get the amountOf..Overlap members set newly:
if( ! doNotRecalculate )
sizeHint();
return d->amountOfBottomOverlap;
}
void AbstractArea::paintIntoRect( QPainter& painter, const QRect& rect )
{
const QRect oldGeometry( geometry() );
if( oldGeometry != rect )
setGeometry( rect );
painter.translate( rect.left(), rect.top() );
paintAll( painter );
painter.translate( -rect.left(), -rect.top() );
if( oldGeometry != rect )
setGeometry( oldGeometry );
}
void AbstractArea::paintAll( QPainter& painter )
{
// Paint the background and frame
const QRect overlappingArea( geometry().adjusted(
-d->amountOfLeftOverlap,
-d->amountOfTopOverlap,
d->amountOfRightOverlap,
d->amountOfBottomOverlap ) );
paintBackground( painter, overlappingArea );
paintFrame( painter, overlappingArea );
// temporarily adjust the widget size, to be sure all content gets calculated
// to fit into the inner rectangle
const QRect oldGeometry( areaGeometry() );
QRect inner( innerRect() );
inner.moveTo(
oldGeometry.left() + inner.left(),
oldGeometry.top() + inner.top() );
const bool needAdjustGeometry = oldGeometry != inner;
if( needAdjustGeometry )
setGeometry( inner );
paint( &painter );
if( needAdjustGeometry )
setGeometry( oldGeometry );
//qDebug() << "AbstractAreaWidget::paintAll() done.";
}
QRect AbstractArea::areaGeometry() const
{
return geometry();
}
void AbstractArea::positionHasChanged()
{
emit positionChanged( this );
}

View File

@@ -0,0 +1,140 @@
/****************************************************************************
** Copyright (C) 2001-2011 Klaralvdalens Datakonsult AB. All rights reserved.
**
** This file is part of the KD Chart library.
**
** Licensees holding valid commercial KD Chart licenses may use this file in
** accordance with the KD Chart Commercial License Agreement provided with
** the Software.
**
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 and version 3 as published by the
** Free Software Foundation and appearing in the file LICENSE.GPL.txt included.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** Contact info@kdab.com if any conditions of this licensing are not
** clear to you.
**
**********************************************************************/
#ifndef KDCHARTABSTRACTAREA_H
#define KDCHARTABSTRACTAREA_H
#include <QObject>
#include "KDChartGlobal.h"
#include "KDChartAbstractAreaBase.h"
#include "KDChartLayoutItems.h"
namespace KDChart {
/**
* @class AbstractArea KDChartAbstractArea.h
* @brief An area in the chart with a background, a frame, etc.
*
* AbstractArea is the base class for all non-widget chart elements that have
* a set of background attributes and frame attributes, such as
* coordinate planes or axes.
*
* @note This class inherits from AbstractAreaBase, AbstractLayoutItem, QObject.
* The reason for this tripple inheritance is that neither AbstractAreaBase nor
* AbstractLayoutItem are QObject.
*/
class KDCHART_EXPORT AbstractArea : public QObject,
public AbstractAreaBase,
public AbstractLayoutItem
{
Q_OBJECT
Q_DISABLE_COPY( AbstractArea )
KDCHART_DECLARE_PRIVATE_DERIVED( AbstractArea )
public:
virtual ~AbstractArea() ;
// virtual AbstractArea * clone() const = 0;
/**
* @brief Draws the background and frame, then calls paint().
*
* In most cases there is no need to overwrite this method in a derived
* class, but you would overwrite AbstractLayoutItem::paint() instead.
*/
virtual void paintIntoRect( QPainter& painter, const QRect& rect );
/**
* Call paintAll, if you want the background and the frame to be drawn
* before the normal paint() is invoked automatically.
*/
virtual void paintAll( QPainter& painter );
/**
* This is called at layout time by KDChart::AutoSpacerLayoutItem::sizeHint().
*
* The method triggers AbstractArea::sizeHint() to find out the
* amount of overlap at the left edge of the area.
*
* \note The default implementation is not using any caching,
* it might make sense to implement a more sophisticated solution
* for derived classes that have complex work to do in sizeHint().
* All we have here is a primitive flag to be set by the caller
* if it is sure that no sizeHint() needs to be called.
*/
virtual int leftOverlap( bool doNotRecalculate=false ) const;
/**
* This is called at layout time by KDChart::AutoSpacerLayoutItem::sizeHint().
*
* The method triggers AbstractArea::sizeHint() to find out the
* amount of overlap at the right edge of the area.
*
* \note The default implementation is not using any caching,
* it might make sense to implement a more sophisticated solution
* for derived classes that have complex work to do in sizeHint().
* All we have here is a primitive flag to be set by the caller
* if it is sure that no sizeHint() needs to be called.
*/
virtual int rightOverlap( bool doNotRecalculate=false ) const;
/**
* This is called at layout time by KDChart::AutoSpacerLayoutItem::sizeHint().
*
* The method triggers AbstractArea::sizeHint() to find out the
* amount of overlap at the top edge of the area.
*
* \note The default implementation is not using any caching,
* it might make sense to implement a more sophisticated solution
* for derived classes that have complex work to do in sizeHint().
* All we have here is a primitive flag to be set by the caller
* if it is sure that no sizeHint() needs to be called.
*/
virtual int topOverlap( bool doNotRecalculate=false ) const;
/**
* This is called at layout time by KDChart:AutoSpacerLayoutItem::sizeHint().
*
* The method triggers AbstractArea::sizeHint() to find out the
* amount of overlap at the bottom edge of the area.
*
* \note The default implementation is not using any caching,
* it might make sense to implement a more sophisticated solution
* for derived classes that have complex work to do in sizeHint().
* All we have here is a primitive flag to be set by the caller
* if it is sure that no sizeHint() needs to be called.
*/
virtual int bottomOverlap( bool doNotRecalculate=false ) const;
protected:
AbstractArea();
virtual QRect areaGeometry() const;
virtual void positionHasChanged();
Q_SIGNALS:
void positionChanged( AbstractArea * );
//KDCHART_DECLARE_PRIVATE_DERIVED(AbstractArea)
}; // End of class AbstractArea
}
#endif // KDCHARTABSTRACTAREA_H

View File

@@ -0,0 +1,242 @@
/****************************************************************************
** Copyright (C) 2001-2011 Klaralvdalens Datakonsult AB. All rights reserved.
**
** This file is part of the KD Chart library.
**
** Licensees holding valid commercial KD Chart licenses may use this file in
** accordance with the KD Chart Commercial License Agreement provided with
** the Software.
**
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 and version 3 as published by the
** Free Software Foundation and appearing in the file LICENSE.GPL.txt included.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** Contact info@kdab.com if any conditions of this licensing are not
** clear to you.
**
**********************************************************************/
#include "KDChartAbstractAreaBase.h"
#include "KDChartAbstractAreaBase_p.h"
#include <KDChartBackgroundAttributes.h>
#include <KDChartFrameAttributes.h>
#include <KDChartTextAttributes.h>
#include "KDChartPainterSaver_p.h"
#include "KDChartPrintingParameters.h"
#include <QPainter>
#include <KDABLibFakes>
using namespace KDChart;
AbstractAreaBase::Private::Private() :
visible( true )
// PENDING(khz) dockingPointToPadding?, alignToDockingPoint?
{
init();
}
AbstractAreaBase::Private::~Private() {}
void AbstractAreaBase::Private::init()
{
}
AbstractAreaBase::AbstractAreaBase() :
_d( new Private() )
{
}
AbstractAreaBase::~AbstractAreaBase()
{
delete _d; _d = 0;
}
void AbstractAreaBase::init()
{
}
#define d d_func()
bool AbstractAreaBase::compare( const AbstractAreaBase* other )const
{
if( other == this ) return true;
if( ! other ){
//qDebug() << "CartesianAxis::compare() cannot compare to Null pointer";
return false;
}
/*
qDebug() << "AbstractAreaBase:" << (frameAttributes() == other->frameAttributes())
<< (backgroundAttributes() == other->backgroundAttributes()) << "\n";
*/
return (frameAttributes() == other->frameAttributes()) &&
(backgroundAttributes() == other->backgroundAttributes());
}
void AbstractAreaBase::alignToReferencePoint( const RelativePosition& position )
{
Q_UNUSED( position );
// PENDING(kalle) FIXME
qWarning( "Sorry, not implemented: void AbstractAreaBase::alignToReferencePoint( const RelativePosition& position )" );
}
void AbstractAreaBase::setFrameAttributes( const FrameAttributes &a )
{
if( d->frameAttributes == a )
return;
d->frameAttributes = a;
positionHasChanged();
}
FrameAttributes AbstractAreaBase::frameAttributes() const
{
return d->frameAttributes;
}
void AbstractAreaBase::setBackgroundAttributes( const BackgroundAttributes &a )
{
if( d->backgroundAttributes == a )
return;
d->backgroundAttributes = a;
positionHasChanged();
}
BackgroundAttributes AbstractAreaBase::backgroundAttributes() const
{
return d->backgroundAttributes;
}
/* static */
void AbstractAreaBase::paintBackgroundAttributes( QPainter& painter, const QRect& rect,
const KDChart::BackgroundAttributes& attributes )
{
if( !attributes.isVisible() ) return;
/* first draw the brush (may contain a pixmap)*/
if( Qt::NoBrush != attributes.brush().style() ) {
KDChart::PainterSaver painterSaver( &painter );
painter.setPen( Qt::NoPen );
const QPointF newTopLeft( painter.deviceMatrix().map( rect.topLeft() ) );
painter.setBrushOrigin( newTopLeft );
painter.setBrush( attributes.brush() );
painter.drawRect( rect.adjusted( 0, 0, -1, -1 ) );
}
/* next draw the backPixmap over the brush */
if( !attributes.pixmap().isNull() &&
attributes.pixmapMode() != BackgroundAttributes::BackgroundPixmapModeNone ) {
QPointF ol = rect.topLeft();
if( BackgroundAttributes::BackgroundPixmapModeCentered == attributes.pixmapMode() )
{
ol.setX( rect.center().x() - attributes.pixmap().width() / 2 );
ol.setY( rect.center().y() - attributes.pixmap().height()/ 2 );
painter.drawPixmap( ol, attributes.pixmap() );
} else {
QMatrix m;
double zW = (double)rect.width() / (double)attributes.pixmap().width();
double zH = (double)rect.height() / (double)attributes.pixmap().height();
switch( attributes.pixmapMode() ) {
case BackgroundAttributes::BackgroundPixmapModeScaled:
{
double z;
z = qMin( zW, zH );
m.scale( z, z );
}
break;
case BackgroundAttributes::BackgroundPixmapModeStretched:
m.scale( zW, zH );
break;
default:
; // Cannot happen, previously checked
}
QPixmap pm = attributes.pixmap().transformed( m );
ol.setX( rect.center().x() - pm.width() / 2 );
ol.setY( rect.center().y() - pm.height()/ 2 );
painter.drawPixmap( ol, pm );
}
}
}
/* static */
void AbstractAreaBase::paintFrameAttributes( QPainter& painter, const QRect& rect,
const KDChart::FrameAttributes& attributes )
{
if( !attributes.isVisible() ) return;
// Note: We set the brush to NoBrush explicitly here.
// Otherwise we might get a filled rectangle, so any
// previously drawn background would be overwritten by that area.
const QPen oldPen( painter.pen() );
const QBrush oldBrush( painter.brush() );
painter.setPen( PrintingParameters::scalePen( attributes.pen() ) );
painter.setBrush( Qt::NoBrush );
painter.drawRect( rect.adjusted( 0, 0, -1, -1 ) );
painter.setBrush( oldBrush );
painter.setPen( oldPen );
}
void AbstractAreaBase::paintBackground( QPainter& painter, const QRect& rect )
{
Q_ASSERT_X ( d != 0, "AbstractAreaBase::paintBackground()",
"Private class was not initialized!" );
paintBackgroundAttributes( painter, rect, d->backgroundAttributes );
}
void AbstractAreaBase::paintFrame( QPainter& painter, const QRect& rect )
{
Q_ASSERT_X ( d != 0, "AbstractAreaBase::paintFrame()",
"Private class was not initialized!" );
paintFrameAttributes( painter, rect, d->frameAttributes );
}
void AbstractAreaBase::getFrameLeadings(int& left, int& top, int& right, int& bottom ) const
{
if( d && d->frameAttributes.isVisible() ){
const int padding = qMax( d->frameAttributes.padding(), 0 );
left = padding;
top = padding;
right = padding;
bottom = padding;
}else{
left = 0;
top = 0;
right = 0;
bottom = 0;
}
}
QRect AbstractAreaBase::innerRect() const
{
int left;
int top;
int right;
int bottom;
getFrameLeadings( left, top, right, bottom );
return
QRect( QPoint(0,0), areaGeometry().size() )
.adjusted( left, top, -right, -bottom );
}
void AbstractAreaBase::positionHasChanged()
{
// this bloc left empty intentionally
}

View File

@@ -0,0 +1,129 @@
/****************************************************************************
** Copyright (C) 2001-2011 Klaralvdalens Datakonsult AB. All rights reserved.
**
** This file is part of the KD Chart library.
**
** Licensees holding valid commercial KD Chart licenses may use this file in
** accordance with the KD Chart Commercial License Agreement provided with
** the Software.
**
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 and version 3 as published by the
** Free Software Foundation and appearing in the file LICENSE.GPL.txt included.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** Contact info@kdab.com if any conditions of this licensing are not
** clear to you.
**
**********************************************************************/
#ifndef KDCHARTABSTRACTAREABASE_H
#define KDCHARTABSTRACTAREABASE_H
#include <QPointF>
#include <QSizeF>
#include <QRectF>
#include "KDChartGlobal.h"
#include "KDChartLayoutItems.h"
#include "KDChartRelativePosition.h"
#include "KDChartAbstractAreaBase.h"
class QPainter;
class QString;
namespace KDChart {
class TextAttributes;
class BackgroundAttributes;
class FrameAttributes;
class PaintContext;
/**
* @class AbstractAreaBase KDChartAbstractAreaBase.h
* @brief Base class for AbstractArea and AbstractAreaWidget: An area
* in the chart with a background, a frame, etc.
*
* AbstractAreaBase is the base class for all chart elements that have
* a set of background attributes and frame attributes, such as
* legends or axes.
*
* @note Normally you should not use AbstractAreaBase directly, but
* derive your classes from AbstractArea or AbstractAreaWidget.
*
* @note This classis not a QObject, so it is easier to inherit from
* it, if your are inheriting from a QObject too like AbstractAreaWidget does it.
*
* @sa AbstractArea, AbstractAreaWidget
*/
class KDCHART_EXPORT AbstractAreaBase
{
Q_DISABLE_COPY( AbstractAreaBase )
KDCHART_DECLARE_PRIVATE_BASE_POLYMORPHIC( AbstractAreaBase )
protected:
AbstractAreaBase();
virtual ~AbstractAreaBase() ;
public:
// virtual AbstractAreaBase * clone() const = 0;
/**
* Returns true if both areas have the same settings.
*/
bool compare( const AbstractAreaBase* other )const;
void alignToReferencePoint( const RelativePosition& position );
void setFrameAttributes( const FrameAttributes &a );
FrameAttributes frameAttributes() const;
void setBackgroundAttributes( const BackgroundAttributes &a );
BackgroundAttributes backgroundAttributes() const;
virtual void paintBackground( QPainter& painter, const QRect& rectangle );
virtual void paintFrame( QPainter& painter, const QRect& rectangle );
static void paintBackgroundAttributes( QPainter& painter, const QRect& rectangle,
const KDChart::BackgroundAttributes& attributes );
static void paintFrameAttributes( QPainter& painter, const QRect& rectangle,
const KDChart::FrameAttributes& attributes );
/** \internal
* \note Normally you should not call this method, but derive your classes
* from AbstractArea or AbstractAreaWidget.
* \sa AbstractArea, AbstractAreaWidget
*/
void getFrameLeadings(int& left, int& top, int& right, int& bottom ) const;
protected:
/** \internal
* \note Normally you should not call this method, but derive your classes
* from AbstractArea or AbstractAreaWidget.
* \sa AbstractArea, AbstractAreaWidget
*/
QRect innerRect() const;
/** \internal
* This internal method is used by AbstractArea and AbstractAreaWidget
* to find out the real widget size.
* \sa AbstractArea, AbstractAreaWidget
*/
virtual QRect areaGeometry() const = 0;
/** \internal
* This internal method can be overwritten by derived classes,
* if they want to emit a signal (or perform other actions, resp.)
* when the Position of the area has been changed.
* The default implementation does nothing.
*/
virtual void positionHasChanged();
}; // End of class AbstractAreaBase
}
#endif // KDCHARTABSTRACTAREABASE_H

View File

@@ -0,0 +1,94 @@
/****************************************************************************
** Copyright (C) 2001-2011 Klaralvdalens Datakonsult AB. All rights reserved.
**
** This file is part of the KD Chart library.
**
** Licensees holding valid commercial KD Chart licenses may use this file in
** accordance with the KD Chart Commercial License Agreement provided with
** the Software.
**
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 and version 3 as published by the
** Free Software Foundation and appearing in the file LICENSE.GPL.txt included.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** Contact info@kdab.com if any conditions of this licensing are not
** clear to you.
**
**********************************************************************/
#ifndef KDCHARTABSTRACTAREABASE_P_H
#define KDCHARTABSTRACTAREABASE_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the KD Chart API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
/** \file KDChartAbstractAreaBase_p.h
* \internal
*/
#include "KDChartAbstractAreaBase.h"
#include "KDChartTextAttributes.h"
#include "KDChartFrameAttributes.h"
#include "KDChartBackgroundAttributes.h"
#include <KDABLibFakes>
namespace KDChart {
/**
* \internal
*/
class AbstractAreaBase::Private
{
friend class AbstractAreaBase;
public:
explicit Private();
virtual ~Private();
Private( const Private& rhs ) :
visible( rhs.visible ),
frameAttributes( rhs.frameAttributes ),
backgroundAttributes( rhs.backgroundAttributes )
{
}
protected:
void init();
// These are set each time the area's sizeHint()
// (or the maximumSize(), resp.) is calculated:
// They store additional layout-information about
// space needed around the area.
// Other classes (e.g. KDChart::AutoSpacer) can use
// these data to determine how much space has to
// be added additionally ...
mutable int amountOfLeftOverlap;
mutable int amountOfRightOverlap;
mutable int amountOfTopOverlap;
mutable int amountOfBottomOverlap;
private:
bool visible;
KDChart::FrameAttributes frameAttributes;
KDChart::BackgroundAttributes backgroundAttributes;
};
inline AbstractAreaBase::AbstractAreaBase( AbstractAreaBase::Private * p ) :
_d( p ) { init(); }
}
#endif /* KDCHARTABSTRACTAREABASE_P_H */

View File

@@ -0,0 +1,201 @@
/****************************************************************************
** Copyright (C) 2001-2011 Klaralvdalens Datakonsult AB. All rights reserved.
**
** This file is part of the KD Chart library.
**
** Licensees holding valid commercial KD Chart licenses may use this file in
** accordance with the KD Chart Commercial License Agreement provided with
** the Software.
**
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 and version 3 as published by the
** Free Software Foundation and appearing in the file LICENSE.GPL.txt included.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** Contact info@kdab.com if any conditions of this licensing are not
** clear to you.
**
**********************************************************************/
#include "KDChartAbstractAreaWidget.h"
#include "KDChartAbstractAreaWidget_p.h"
#include <KDABLibFakes>
using namespace KDChart;
AbstractAreaWidget::Private::Private()
{
// this block left empty intentionally
}
AbstractAreaWidget::Private::~Private()
{
// this block left empty intentionally
}
void AbstractAreaWidget::Private::resizeLayout(
AbstractAreaWidget* widget, const QSize& size )
{
if( size == currentLayoutSize ) return;
currentLayoutSize = size;
// Now we call adjust the size, for the inner parts of the widget.
int left;
int top;
int right;
int bottom;
widget->getFrameLeadings( left, top, right, bottom );
const QSize innerSize( size.width() - left - right,
size.height() - top - bottom );
// With this adjusted size we call the real resizeLayout method,
// which normally will call resizeLayout( size ) in the derived class
// - which in turn is the place to resize the layout member variable
// of that class.
widget->resizeLayout( innerSize );
}
AbstractAreaWidget::AbstractAreaWidget( QWidget* parent )
: QWidget( parent )
, AbstractAreaBase( new Private() )
{
init();
}
AbstractAreaWidget::~AbstractAreaWidget()
{
// this block left empty intentionally
}
void AbstractAreaWidget::init()
{
// this block left empty intentionally
}
void AbstractAreaWidget::needSizeHint()
{
// this block left empty intentionally
}
#define d d_func()
void AbstractAreaWidget::resizeLayout( const QSize& size )
{
Q_UNUSED( size );
// this block left empty intentionally
}
void AbstractAreaWidget::paintEvent( QPaintEvent* event )
{
Q_UNUSED( event );
QPainter painter( this );
if( size() != d->currentLayoutSize ){
d->resizeLayout( this, size() );
}
paintAll( painter );
}
void AbstractAreaWidget::paintIntoRect( QPainter& painter, const QRect& rect )
{
//qDebug() << "AbstractAreaWidget::paintIntoRect() called rect=" << rect;
if( rect.isEmpty() ) return;
d->resizeLayout( this, rect.size() );
const QPoint translation( rect.topLeft() );
painter.translate( translation );
paintAll( painter );
painter.translate( -translation.x(), -translation.y() );
/*
// make sure, the contents of the widget have been set up,
// so we get a useful geometry:
needSizeHint();
const QRect oldGeometry( layout()->geometry() );
const QRect newGeo( QPoint(0,0), rect.size() );
const bool mustChangeGeo = layout() && oldGeometry != newGeo;
if( mustChangeGeo )
layout()->setGeometry( newGeo );
painter.translate( rect.left(), rect.top() );
paintAll( painter );
painter.translate( -rect.left(), -rect.top() );
if( mustChangeGeo )
layout()->setGeometry( oldGeometry );
*/
}
void AbstractAreaWidget::forceRebuild()
{
//bloc left empty intentionally
}
void AbstractAreaWidget::paintAll( QPainter& painter )
{
//qDebug() << "AbstractAreaWidget::paintAll() called";
// Paint the background and frame
paintBackground( painter, QRect(QPoint(0, 0), size() ) );
paintFrame( painter, QRect(QPoint(0, 0), size() ) );
/*
we do not call setContentsMargins() now,
but we call resizeLayout() whenever the size or the frame has changed
// adjust the widget's content margins,
// to be sure all content gets calculated
// to fit into the inner rectangle
const QRect oldGeometry( areaGeometry() );
const QRect inner( innerRect() );
//qDebug() << "areaGeometry():" << oldGeometry
// << " contentsRect():" << contentsRect() << " inner:" << inner;
if( contentsRect() != inner ){
//qDebug() << "old contentsRect():" << contentsRect() << " new innerRect:" << inner;
setContentsMargins(
inner.left(),
inner.top(),
oldGeometry.width() -inner.width()-1,
oldGeometry.height()-inner.height()-1 );
//forceRebuild();
}
*/
int left;
int top;
int right;
int bottom;
getFrameLeadings( left, top, right, bottom );
const QPoint translation( left, top );
painter.translate( translation );
paint( &painter );
painter.translate( -translation.x(), -translation.y() );
//qDebug() << "AbstractAreaWidget::paintAll() done.";
}
QRect AbstractAreaWidget::areaGeometry() const
{
return geometry();
}
void AbstractAreaWidget::positionHasChanged()
{
emit positionChanged( this );
}
/*
void AbstractAreaWidget::setGeometry( const QRect & rect )
{
qDebug() << "AbstractAreaWidget::setGeometry("<< rect << ") called";
const bool bChanged = rect != geometry();
QWidget::setGeometry( rect );
if( bChanged )
forceRebuild();
}
*/

View File

@@ -0,0 +1,119 @@
/****************************************************************************
** Copyright (C) 2001-2011 Klaralvdalens Datakonsult AB. All rights reserved.
**
** This file is part of the KD Chart library.
**
** Licensees holding valid commercial KD Chart licenses may use this file in
** accordance with the KD Chart Commercial License Agreement provided with
** the Software.
**
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 and version 3 as published by the
** Free Software Foundation and appearing in the file LICENSE.GPL.txt included.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** Contact info@kdab.com if any conditions of this licensing are not
** clear to you.
**
**********************************************************************/
#ifndef KDCHARTABSTRACTAREAWIDGET_H
#define KDCHARTABSTRACTAREAWIDGET_H
#include <QWidget>
#include <QPaintEvent>
#include <QPainter>
#include <QRect>
#include "KDChartAbstractAreaBase.h"
namespace KDChart {
/**
* @class AbstractAreaWidget KDChartAbstractArea.h
* @brief An area in the chart with a background, a frame, etc.
*
* AbstractAreaWidget is the base for all widget classes that have
* a set of background attributes and frame attributes, such as
* KDChart::Chart and KDChart::Legend.
*/
class KDCHART_EXPORT AbstractAreaWidget : public QWidget, public AbstractAreaBase
{
Q_OBJECT
Q_DISABLE_COPY( AbstractAreaWidget )
KDCHART_DECLARE_PRIVATE_DERIVED_QWIDGET( AbstractAreaWidget )
public:
explicit AbstractAreaWidget( QWidget* parent = 0 );
/**
* @brief Draws the background and frame, then calls paint().
*
* In most cases there is no need to overwrite this method in a derived
* class, but you would overwrite paint() instead.
* @sa paint
*/
virtual void paintEvent( QPaintEvent* event );
/**
* @brief Draws the background and frame, then calls paint().
*
* In most cases there is no need to overwrite this method in a derived
* class, but you would overwrite paint() instead.
*/
virtual void paintIntoRect( QPainter& painter, const QRect& rect );
/**
* Overwrite this to paint the inner contents of your widget.
*
* @note When overriding this method, please let your widget draw
* itself at the top/left corner of the painter. You should call rect()
* (or width(), height(), resp.) to find the drawable area's size:
* While the paint() method is being executed the frame of the widget
* is outside of its rect(), so you can use all of rect() for
* your custom drawing!
* @sa paint, paintIntoRect
*/
virtual void paint( QPainter* painter ) = 0;
/**
* Call paintAll, if you want the background and the frame to be drawn
* before the normal paint() is invoked automatically.
*/
void paintAll( QPainter& painter );
/**
* Call this to trigger an unconditional re-building of the widget's internals.
*/
virtual void forceRebuild();
/**
* Call this to trigger an conditional re-building of the widget's internals.
*
* e.g. AbstractAreaWidget call this, before calling layout()->setGeometry()
*/
virtual void needSizeHint();
//virtual void setGeometry( const QRect & rect );
virtual void resizeLayout( const QSize& );
protected:
virtual ~AbstractAreaWidget() ;
virtual QRect areaGeometry() const;
virtual void positionHasChanged();
public:
// virtual AbstractAreaWidget * clone() const = 0;
Q_SIGNALS:
void positionChanged( AbstractAreaWidget * );
}; // End of class AbstractAreaWidget
}
#endif // KDCHARTABSTRACTAREAWIDGET_H

View File

@@ -0,0 +1,90 @@
/****************************************************************************
** Copyright (C) 2001-2011 Klaralvdalens Datakonsult AB. All rights reserved.
**
** This file is part of the KD Chart library.
**
** Licensees holding valid commercial KD Chart licenses may use this file in
** accordance with the KD Chart Commercial License Agreement provided with
** the Software.
**
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 and version 3 as published by the
** Free Software Foundation and appearing in the file LICENSE.GPL.txt included.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** Contact info@kdab.com if any conditions of this licensing are not
** clear to you.
**
**********************************************************************/
#ifndef KDCHARTABSTRACTAREAWIDGET_P_H
#define KDCHARTABSTRACTAREAWIDGET_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the KD Chart API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
/** \file KDChartAbstractAreaWidget_p.h
* \internal
*/
#include "KDChartAbstractAreaWidget.h"
#include "KDChartAbstractAreaBase_p.h"
#include <KDABLibFakes>
namespace KDChart {
/**
* \internal
*/
class AbstractAreaWidget::Private : public AbstractAreaBase::Private
{
friend class AbstractAreaWidget;
public:
explicit Private();
virtual ~Private();
Private( const Private& rhs ) :
AbstractAreaBase::Private( rhs )
{
// Just for consistency
}
QSize currentLayoutSize;
// non-virtual method, calling widget->resizeLayout( size )
void resizeLayout( AbstractAreaWidget* widget, const QSize& sz );
};
inline AbstractAreaWidget::AbstractAreaWidget( AbstractAreaWidget::Private * p, QWidget* parent )
: QWidget( parent ), AbstractAreaBase( p )
{
init();
}
inline AbstractAreaWidget::Private * AbstractAreaWidget::d_func()
{
return static_cast<Private*>( AbstractAreaBase::d_func() );
}
inline const AbstractAreaWidget::Private * AbstractAreaWidget::d_func() const
{
return static_cast<const Private*>( AbstractAreaBase::d_func() );
}
}
#endif /* KDCHARTABSTRACTAREAWIDGET_P_H */

View File

@@ -0,0 +1,78 @@
/****************************************************************************
** Copyright (C) 2001-2011 Klaralvdalens Datakonsult AB. All rights reserved.
**
** This file is part of the KD Chart library.
**
** Licensees holding valid commercial KD Chart licenses may use this file in
** accordance with the KD Chart Commercial License Agreement provided with
** the Software.
**
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 and version 3 as published by the
** Free Software Foundation and appearing in the file LICENSE.GPL.txt included.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** Contact info@kdab.com if any conditions of this licensing are not
** clear to you.
**
**********************************************************************/
#ifndef KDCHARTABSTRACTAREA_P_H
#define KDCHARTABSTRACTAREA_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the KD Chart API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
/** \file KDChartAbstractArea_p.h
* \internal
*/
#include "KDChartAbstractArea.h"
#include "KDChartAbstractAreaBase_p.h"
#include <KDABLibFakes>
namespace KDChart {
/**
* \internal
*/
class AbstractArea::Private : public AbstractAreaBase::Private
{
friend class AbstractArea;
public:
explicit Private();
virtual ~Private();
};
inline AbstractArea::AbstractArea( Private * p )
: QObject(), AbstractAreaBase( p ), AbstractLayoutItem()
{
init();
}
inline AbstractArea::Private * AbstractArea::d_func()
{
return static_cast<Private*>( AbstractAreaBase::d_func() );
}
inline const AbstractArea::Private * AbstractArea::d_func() const
{
return static_cast<const Private*>( AbstractAreaBase::d_func() );
}
}
#endif /* KDCHARTABSTRACTAREA_P_H */

View File

@@ -0,0 +1,259 @@
/****************************************************************************
** Copyright (C) 2001-2011 Klaralvdalens Datakonsult AB. All rights reserved.
**
** This file is part of the KD Chart library.
**
** Licensees holding valid commercial KD Chart licenses may use this file in
** accordance with the KD Chart Commercial License Agreement provided with
** the Software.
**
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 and version 3 as published by the
** Free Software Foundation and appearing in the file LICENSE.GPL.txt included.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** Contact info@kdab.com if any conditions of this licensing are not
** clear to you.
**
**********************************************************************/
#include "KDChartAbstractAxis.h"
#include "KDChartAbstractAxis_p.h"
#include "KDChartAbstractDiagram.h"
#include "KDChartAbstractCartesianDiagram.h"
#include "KDChartEnums.h"
#include "KDChartMeasure.h"
#include <QDebug>
#include <KDABLibFakes>
using namespace KDChart;
#define d d_func()
AbstractAxis::Private::Private( AbstractDiagram* diagram, AbstractAxis* axis )
: observer( 0 )
, mDiagram( diagram )
, mAxis( axis )
{
// Note: We do NOT call setDiagram( diagram, axis );
// but it is called in AbstractAxis::delayedInit() instead!
}
AbstractAxis::Private::~Private()
{
delete observer;
observer = 0;
}
bool AbstractAxis::Private::setDiagram(
AbstractDiagram* diagram_,
bool delayedInit )
{
AbstractDiagram* diagram = delayedInit ? mDiagram : diagram_;
if( delayedInit ){
mDiagram = 0;
}
// do not set a diagram again that was already set
if ( diagram &&
((diagram == mDiagram) || secondaryDiagrams.contains( diagram )) )
return false;
bool bNewDiagramStored = false;
if ( ! mDiagram ) {
mDiagram = diagram;
delete observer;
if ( mDiagram ) {
//qDebug() << "axis" << (axis != 0);
observer = new DiagramObserver( mDiagram, mAxis );
bNewDiagramStored = true;
}else{
observer = 0;
}
} else {
if ( diagram )
secondaryDiagrams.enqueue( diagram );
}
return bNewDiagramStored;
}
void AbstractAxis::Private::unsetDiagram( AbstractDiagram* diagram )
{
if ( diagram == mDiagram ) {
mDiagram = 0;
delete observer;
observer = 0;
} else {
secondaryDiagrams.removeAll( diagram );
}
if( !secondaryDiagrams.isEmpty() ) {
AbstractDiagram *nextDiagram = secondaryDiagrams.dequeue();
setDiagram( nextDiagram );
}
}
bool AbstractAxis::Private::hasDiagram( AbstractDiagram* diagram ) const
{
return diagram == mDiagram || secondaryDiagrams.contains( diagram );
}
AbstractAxis::AbstractAxis ( AbstractDiagram* diagram )
: AbstractArea( new Private( diagram, this ) )
{
init();
QTimer::singleShot(0, this, SLOT(delayedInit()));
}
AbstractAxis::~AbstractAxis()
{
d->mDiagram = 0;
d->secondaryDiagrams.clear();
}
void AbstractAxis::init()
{
Measure m(
12.5,
KDChartEnums::MeasureCalculationModeAuto,
KDChartEnums::MeasureOrientationAuto );
d->textAttributes.setFontSize( m );
m.setValue( 5 );
m.setCalculationMode( KDChartEnums::MeasureCalculationModeAbsolute );
d->textAttributes.setMinimalFontSize( m );
}
void AbstractAxis::delayedInit()
{
// We call setDiagram() here, because the c'tor of Private
// only has stored the pointers, but it did not call setDiagram().
if( d )
d->setDiagram( 0, true /* delayedInit */ );
}
bool AbstractAxis::compare( const AbstractAxis* other )const
{
if( other == this ) return true;
if( ! other ){
//qDebug() << "CartesianAxis::compare() cannot compare to Null pointer";
return false;
}
/*
qDebug() << (textAttributes() == other->textAttributes());
qDebug() << (labels() == other->labels());
qDebug() << (shortLabels() == other->shortLabels());
*/
return ( static_cast<const AbstractAreaBase*>(this)->compare( other ) ) &&
(textAttributes() == other->textAttributes()) &&
(labels() == other->labels()) &&
(shortLabels() == other->shortLabels());
}
const QString AbstractAxis::customizedLabel( const QString& label )const
{
return label;
}
void AbstractAxis::createObserver( AbstractDiagram* diagram )
{
if( d->setDiagram( diagram ) )
connectSignals();
}
void AbstractAxis::deleteObserver( AbstractDiagram* diagram )
{
d->unsetDiagram( diagram );
}
void AbstractAxis::connectSignals()
{
if( d->observer ){
connect( d->observer, SIGNAL( diagramDataChanged( AbstractDiagram *) ),
this, SLOT( update() ) );
}
}
void AbstractAxis::setTextAttributes( const TextAttributes &a )
{
if( d->textAttributes == a )
return;
d->textAttributes = a;
update();
}
TextAttributes AbstractAxis::textAttributes() const
{
return d->textAttributes;
}
void AbstractAxis::setRulerAttributes( const RulerAttributes &a )
{
d->rulerAttributes = a;
update();
}
RulerAttributes AbstractAxis::rulerAttributes() const
{
return d->rulerAttributes;
}
void AbstractAxis::setLabels( const QStringList& list )
{
if( d->hardLabels == list )
return;
d->hardLabels = list;
update();
}
QStringList AbstractAxis::labels() const
{
return d->hardLabels;
}
void AbstractAxis::setShortLabels( const QStringList& list )
{
if( d->hardShortLabels == list )
return;
d->hardShortLabels = list;
update();
}
QStringList AbstractAxis::shortLabels() const
{
return d->hardShortLabels;
}
const AbstractCoordinatePlane* AbstractAxis::coordinatePlane() const
{
if( d->diagram() )
return d->diagram()->coordinatePlane();
return 0;
}
const AbstractDiagram * KDChart::AbstractAxis::diagram() const
{
return d->diagram();
}
bool KDChart::AbstractAxis::observedBy( AbstractDiagram * diagram ) const
{
return d->hasDiagram( diagram );
}
void KDChart::AbstractAxis::update()
{
if( d->diagram() )
d->diagram()->update();
}

View File

@@ -0,0 +1,245 @@
/****************************************************************************
** Copyright (C) 2001-2011 Klaralvdalens Datakonsult AB. All rights reserved.
**
** This file is part of the KD Chart library.
**
** Licensees holding valid commercial KD Chart licenses may use this file in
** accordance with the KD Chart Commercial License Agreement provided with
** the Software.
**
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 and version 3 as published by the
** Free Software Foundation and appearing in the file LICENSE.GPL.txt included.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** Contact info@kdab.com if any conditions of this licensing are not
** clear to you.
**
**********************************************************************/
#ifndef KDCHARTABSTRACTAXIS_H
#define KDCHARTABSTRACTAXIS_H
// #include <QObject>
// #include <QRectF>
// #include <QWidget>
#include "kdchart_export.h"
#include "KDChartGlobal.h"
#include "KDChartAbstractArea.h"
#include "KDChartTextAttributes.h"
#include "KDChartRulerAttributes.h"
class QPainter;
class QSizeF;
// class QRectF;
namespace KDChart {
class Area;
class AbstractCoordinatePlane;
class PaintContext;
class AbstractDiagram;
/**
* The base class for axes.
*
* For being useful, axes need to be assigned to a diagram, see
* AbstractCartesianDiagram::addAxis and AbstractCartesianDiagram::takeAxis.
*
* \sa PolarAxis, AbstractCartesianDiagram
*/
class KDCHART_EXPORT AbstractAxis : public AbstractArea
{
Q_OBJECT
Q_DISABLE_COPY( AbstractAxis )
KDCHART_DECLARE_PRIVATE_DERIVED_PARENT( AbstractAxis, AbstractDiagram* )
public:
explicit AbstractAxis( AbstractDiagram* diagram = 0 );
virtual ~AbstractAxis();
// FIXME implement when code os ready for it:
// virtual Area* clone() const = 0;
// FIXME (Mirko) readd when needed
// void copyRelevantDetailsFrom( const KDChartAxis* axis );
/* virtual void paint( PaintContext* ) const = 0;
virtual QSize sizeHint() const = 0;*/
//virtual void paintEvent( QPaintEvent* event) = 0;
/**
* \brief Implement this method if you want to adjust axis labels
* before they are printed.
*
* KD Chart is calling this method immediately before drawing the
* text, this means: What you return here will be drawn without
* further modifications.
*
* \param label The text of the label as KD Chart has calculated it
* automatically (or as it was taken from a QStringList provided
* by you, resp.)
*
* \return The text to be drawn. By default this is the same as \c label.
*/
virtual const QString customizedLabel( const QString& label )const;
/**
* Returns true if both axes have the same settings.
*/
bool compare( const AbstractAxis* other )const;
/**
* \internal
*
* Method invoked by AbstractCartesianDiagram::addAxis().
*
* You should not call this function, unless you know exactly,
* what you are doing.
*
* \sa connectSignals(), AbstractCartesianDiagram::addAxis()
*/
void createObserver( AbstractDiagram* diagram );
/**
* \internal
*
* Method invoked by AbstractCartesianDiagram::takeAxis().
*
* You should not call this function, unless you know exactly,
* what you are doing.
*
* \sa AbstractCartesianDiagram::takeAxis()
*/
void deleteObserver( AbstractDiagram* diagram );
const AbstractDiagram* diagram() const;
bool observedBy( AbstractDiagram* diagram ) const;
/**
* Wireing the signal/slot connections.
*
* This method gets called automatically, each time, when you assign
* the axis to a diagram, either by passing a diagram* to the c'tor,
* or by calling the diagram's setAxis method, resp.
*
* If overwriting this method in derived classes, make sure to call
* this base method AbstractAxis::connectSignals(), so your axis
* gets connected to the diagram's built-in signals.
*
* \sa AbstractCartesianDiagram::addAxis()
*/
virtual void connectSignals();
/**
\brief Use this to specify the text attributes to be used for axis labels.
By default, the reference area will be set at painting time.
It will be the then-valid coordinate plane's parent widget,
so normally, it will be the KDChart::Chart.
Thus the labels of all of your axes in all of your diagrams
within that Chart will be drawn in same font size, by default.
\sa textAttributes, setLabels
*/
void setTextAttributes( const TextAttributes &a );
/**
\brief Returns the text attributes to be used for axis labels.
\sa setTextAttributes
*/
TextAttributes textAttributes() const;
/**
\brief Use this to specify the attributes used to paint the axis ruler
Every axis has a default set of ruler attributes that is exactly the
same among them. Use this method to specify your own attributes.
\sa rulerAttributes
*/
void setRulerAttributes( const RulerAttributes &a );
/**
\brief Returns the attributes to be used for painting the rulers
\sa setRulerAttributes
*/
RulerAttributes rulerAttributes() const;
/**
\brief Use this to specify your own set of strings, to be used as axis labels.
Labels specified via setLabels take precedence:
If a non-empty list is passed, KD Chart will use these strings as axis labels,
instead of calculating them.
If you a smaller number of strings than the number of labels drawn at this
axis, KD Chart will iterate over the list, repeating the strings, until all
labels are drawn.
As an example you could specify the seven days of the week as abscissa labels,
which would be repeatedly used then.
By passing an empty QStringList you can reset the default behaviour.
\sa labels, setShortLabels
*/
void setLabels( const QStringList& list );
/**
Returns a list of strings, that are used as axis labels, as set via setLabels.
\sa setLabels
*/
QStringList labels() const;
/**
\brief Use this to specify your own set of strings, to be used as axis labels,
in case the normal labels are too long.
\note Setting done via setShortLabels will be ignored, if you did not pass
a non-empty string list via setLabels too!
By passing an empty QStringList you can reset the default behaviour.
\sa shortLabels, setLabels
*/
void setShortLabels( const QStringList& list );
/**
Returns a list of strings, that are used as axis labels, as set via setShortLabels.
\note Setting done via setShortLabels will be ignored, if you did not pass
a non-empty string list via setLabels too!
\sa setShortLabels
*/
QStringList shortLabels() const;
virtual void setGeometry( const QRect& rect ) = 0;
virtual QRect geometry() const = 0;
/**
\brief Convenience function, returns the coordinate plane, in which this axis is used.
If the axis is not used in a coordinate plane, the return value is Zero.
*/
const AbstractCoordinatePlane* coordinatePlane() const;
protected Q_SLOTS:
/** called for initializing after the c'tor has completed */
virtual void delayedInit();
public Q_SLOTS:
void update();
};
}
#endif // KDCHARTABSTRACTAXIS_H

View File

@@ -0,0 +1,99 @@
/****************************************************************************
** Copyright (C) 2001-2011 Klaralvdalens Datakonsult AB. All rights reserved.
**
** This file is part of the KD Chart library.
**
** Licensees holding valid commercial KD Chart licenses may use this file in
** accordance with the KD Chart Commercial License Agreement provided with
** the Software.
**
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 and version 3 as published by the
** Free Software Foundation and appearing in the file LICENSE.GPL.txt included.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** Contact info@kdab.com if any conditions of this licensing are not
** clear to you.
**
**********************************************************************/
#ifndef KDCHARTAXIS_P_H
#define KDCHARTAXIS_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the KD Chart API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <QQueue>
#include <QTimer>
#include "KDChartAbstractArea_p.h"
#include "KDChartAbstractDiagram.h"
#include <KDChartTextAttributes.h>
#include <KDChartRulerAttributes.h>
#include <KDChartDiagramObserver.h>
#include <KDABLibFakes>
namespace KDChart {
/**
* \internal
*/
class AbstractAxis::Private : public AbstractArea::Private
{
friend class AbstractAxis;
public:
Private( AbstractDiagram* diagram, AbstractAxis* axis );
~Private();
bool setDiagram( AbstractDiagram* diagram, bool delayedInit = false );
void unsetDiagram( AbstractDiagram* diagram );
const AbstractDiagram* diagram() const
{
return mDiagram;
}
bool hasDiagram( AbstractDiagram* diagram ) const;
DiagramObserver* observer;
TextAttributes textAttributes;
RulerAttributes rulerAttributes;
QStringList hardLabels;
QStringList hardShortLabels;
QQueue<AbstractDiagram*> secondaryDiagrams;
protected:
AbstractDiagram* mDiagram;
AbstractAxis* mAxis;
};
inline AbstractAxis::AbstractAxis( Private * p, AbstractDiagram* diagram )
: AbstractArea( p )
{
Q_UNUSED( diagram );
init();
QTimer::singleShot(0, this, SLOT(delayedInit()));
}
inline AbstractAxis::Private * AbstractAxis::d_func()
{ return static_cast<Private*>( AbstractArea::d_func() ); }
inline const AbstractAxis::Private * AbstractAxis::d_func() const
{ return static_cast<const Private*>( AbstractArea::d_func() ); }
}
#endif /* KDCHARTAREA_P_H */

View File

@@ -0,0 +1,193 @@
/****************************************************************************
** Copyright (C) 2001-2011 Klaralvdalens Datakonsult AB. All rights reserved.
**
** This file is part of the KD Chart library.
**
** Licensees holding valid commercial KD Chart licenses may use this file in
** accordance with the KD Chart Commercial License Agreement provided with
** the Software.
**
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 and version 3 as published by the
** Free Software Foundation and appearing in the file LICENSE.GPL.txt included.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** Contact info@kdab.com if any conditions of this licensing are not
** clear to you.
**
**********************************************************************/
#include "KDChartAbstractCartesianDiagram.h"
#include "KDChartAbstractCartesianDiagram_p.h"
#include "KDChartPaintContext.h"
#include <QDebug>
#include <QPainter>
#include <KDABLibFakes>
using namespace KDChart;
AbstractCartesianDiagram::Private::Private()
: referenceDiagram( 0 )
{
qRegisterMetaType< QModelIndex >( "QModelIndex" );
}
AbstractCartesianDiagram::Private::~Private()
{
}
bool AbstractCartesianDiagram::compare( const AbstractCartesianDiagram* other )const
{
if( other == this ) return true;
if( ! other ){
//qDebug() << "AbstractCartesianDiagram::compare() cannot compare to Null pointer";
return false;
}
/*
qDebug() << "\n AbstractCartesianDiagram::compare():";
// compare own properties
qDebug() <<
((referenceDiagram() == other->referenceDiagram()) &&
((! referenceDiagram()) || (referenceDiagramOffset() == other->referenceDiagramOffset())));
*/
return // compare the base class
( static_cast<const AbstractDiagram*>(this)->compare( other ) ) &&
// compare own properties
(referenceDiagram() == other->referenceDiagram()) &&
((! referenceDiagram()) || (referenceDiagramOffset() == other->referenceDiagramOffset()));
}
#define d d_func()
AbstractCartesianDiagram::AbstractCartesianDiagram ( QWidget* parent, CartesianCoordinatePlane* plane )
: AbstractDiagram ( new Private(), parent, plane )
{
init();
}
KDChart::AbstractCartesianDiagram::~AbstractCartesianDiagram()
{
Q_FOREACH( CartesianAxis* axis, d->axesList ) {
axis->deleteObserver( this );
}
d->axesList.clear();
}
void AbstractCartesianDiagram::init()
{
d->compressor.setModel( attributesModel() );
connect( this, SIGNAL( layoutChanged( AbstractDiagram* ) ),
&( d->compressor ), SLOT( slotDiagramLayoutChanged( AbstractDiagram* ) ) );
}
void AbstractCartesianDiagram::addAxis( CartesianAxis *axis )
{
if ( !d->axesList.contains( axis ) ) {
d->axesList.append( axis );
axis->createObserver( this );
layoutPlanes();
}
}
void AbstractCartesianDiagram::takeAxis( CartesianAxis *axis )
{
const int idx = d->axesList.indexOf( axis );
if( idx != -1 )
d->axesList.takeAt( idx );
axis->deleteObserver( this );
axis->setParentWidget( 0 );
layoutPlanes();
}
KDChart::CartesianAxisList AbstractCartesianDiagram::axes( ) const
{
return d->axesList;
}
void KDChart::AbstractCartesianDiagram::layoutPlanes()
{
//qDebug() << "KDChart::AbstractCartesianDiagram::layoutPlanes()";
AbstractCoordinatePlane* plane = coordinatePlane();
if( plane ){
plane->layoutPlanes();
//qDebug() << "KDChart::AbstractCartesianDiagram::layoutPlanes() OK";
}
}
void KDChart::AbstractCartesianDiagram::setCoordinatePlane( AbstractCoordinatePlane* plane )
{
if( coordinatePlane() ) {
disconnect( attributesModel(), SIGNAL( rowsRemoved( const QModelIndex&, int, int ) ),
coordinatePlane(), SLOT( relayout() ) );
disconnect( attributesModel(), SIGNAL( rowsInserted( const QModelIndex&, int, int ) ),
coordinatePlane(), SLOT( relayout() ) );
disconnect( attributesModel(), SIGNAL( columnsRemoved( const QModelIndex&, int, int ) ),
coordinatePlane(), SLOT( relayout() ) );
disconnect( attributesModel(), SIGNAL( columnsInserted( const QModelIndex&, int, int ) ),
coordinatePlane(), SLOT( relayout() ) );
disconnect( coordinatePlane() );
}
AbstractDiagram::setCoordinatePlane(plane);
if ( plane ) {
// Readjust the layout when the dataset count changes
connect( attributesModel(), SIGNAL( rowsRemoved( const QModelIndex&, int, int ) ),
plane, SLOT( relayout() ), Qt::QueuedConnection );
connect( attributesModel(), SIGNAL( rowsInserted( const QModelIndex&, int, int ) ),
plane, SLOT( relayout() ), Qt::QueuedConnection );
connect( attributesModel(), SIGNAL( columnsRemoved( const QModelIndex&, int, int ) ),
plane, SLOT( relayout() ), Qt::QueuedConnection );
connect( attributesModel(), SIGNAL( columnsInserted( const QModelIndex&, int, int ) ),
plane, SLOT( relayout() ), Qt::QueuedConnection );
}
// show the axes, after all have been layoutPlanes
// (because they might depend on each other)
/*
if( plane )
Q_FOREACH( CartesianAxis* axis, d->axesList )
axis->show();
else
Q_FOREACH( CartesianAxis* axis, d->axesList )
axis->hide();
*/
}
void AbstractCartesianDiagram::setReferenceDiagram( AbstractCartesianDiagram* diagram, const QPointF& offset )
{
d->referenceDiagram = diagram;
d->referenceDiagramOffset = offset;
}
AbstractCartesianDiagram* AbstractCartesianDiagram::referenceDiagram() const
{
return d->referenceDiagram;
}
QPointF AbstractCartesianDiagram::referenceDiagramOffset() const
{
return d->referenceDiagramOffset;
}
void AbstractCartesianDiagram::setRootIndex( const QModelIndex& index )
{
AbstractDiagram::setRootIndex( index );
d->compressor.setRootIndex( attributesModel()->mapFromSource( index ) );
}
void AbstractCartesianDiagram::setModel( QAbstractItemModel* model )
{
AbstractDiagram::setModel( model );
d->compressor.setModel( attributesModel() );
}
void AbstractCartesianDiagram::setAttributesModel( AttributesModel* model )
{
AbstractDiagram::setAttributesModel( model );
d->compressor.setModel( attributesModel() );
}

View File

@@ -0,0 +1,132 @@
/****************************************************************************
** Copyright (C) 2001-2011 Klaralvdalens Datakonsult AB. All rights reserved.
**
** This file is part of the KD Chart library.
**
** Licensees holding valid commercial KD Chart licenses may use this file in
** accordance with the KD Chart Commercial License Agreement provided with
** the Software.
**
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 and version 3 as published by the
** Free Software Foundation and appearing in the file LICENSE.GPL.txt included.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** Contact info@kdab.com if any conditions of this licensing are not
** clear to you.
**
**********************************************************************/
#ifndef KDCHARTABSTRACTCARTESIANDIAGRAM_H
#define KDCHARTABSTRACTCARTESIANDIAGRAM_H
#include "KDChartCartesianCoordinatePlane.h"
#include "KDChartAbstractDiagram.h"
#include "KDChartCartesianAxis.h"
namespace KDChart {
class GridAttributes;
// class PaintContext;
/**
* @brief Base class for diagrams based on a cartesian coordianate system.
*
* The AbstractCartesianDiagram interface adds those elements that are
* specific to diagrams based on a cartesian coordinate system to the
* basic AbstractDiagram interface.
*/
class KDCHART_EXPORT AbstractCartesianDiagram : public AbstractDiagram
{
Q_OBJECT
Q_DISABLE_COPY( AbstractCartesianDiagram )
// KDCHART_DECLARE_PRIVATE_DERIVED( AbstractCartesianDiagram )
KDCHART_DECLARE_DERIVED_DIAGRAM( AbstractCartesianDiagram, CartesianCoordinatePlane )
public:
explicit AbstractCartesianDiagram ( QWidget* parent = 0, CartesianCoordinatePlane* plane = 0 );
virtual ~AbstractCartesianDiagram();
/**
* Returns true if both diagrams have the same settings.
*/
bool compare( const AbstractCartesianDiagram* other )const;
#if QT_VERSION < 0x040400 || defined(Q_COMPILER_MANGLES_RETURN_TYPE)
virtual const int numberOfAbscissaSegments () const = 0;
virtual const int numberOfOrdinateSegments () const = 0;
#else
virtual int numberOfAbscissaSegments () const = 0;
virtual int numberOfOrdinateSegments () const = 0;
#endif
/**
* Add the axis to the diagram. The diagram takes ownership of the axis
* and will delete it.
*
* To gain back ownership (e.g. for assigning the axis to another diagram)
* use the takeAxis method, before calling addAxis on the other diagram.
*
* \sa takeAxis
*/
virtual void addAxis( CartesianAxis * axis );
/**
* Removes the axis from the diagram, without deleting it.
*
* The diagram no longer owns the axis, so it is
* the caller's responsibility to delete the axis.
*
* \sa addAxis
*/
virtual void takeAxis( CartesianAxis * axis );
/**
* @return a list of all axes added to the diagram
*/
virtual KDChart::CartesianAxisList axes () const;
/**
* Triggers layouting of all coordinate planes on the current chart.
* Normally you don't need to call this method. It's handled automatically for you.
*/
virtual void layoutPlanes();
/** \reimpl */
virtual void setCoordinatePlane( AbstractCoordinatePlane* plane );
/**
* Makes this diagram use another diagram \a diagram as reference diagram with relative offset
* \a offset.
* To share cartesian axes between different diagrams there might be cases when you need that.
* Normally you don't.
* \sa examples/SharedAbscissa
*/
virtual void setReferenceDiagram( AbstractCartesianDiagram* diagram, const QPointF& offset = QPointF() );
/**
* @return this diagram's reference diagram
* \sa setReferenceDiagram
*/
virtual AbstractCartesianDiagram* referenceDiagram() const;
/**
* @return the relative offset of this diagram's reference diagram
* \sa setReferenceDiagram
*/
virtual QPointF referenceDiagramOffset() const;
/* reimpl */
void setModel( QAbstractItemModel* model );
/* reimpl */
void setRootIndex( const QModelIndex& index );
/* reimpl */
void setAttributesModel( AttributesModel* model );
protected:
/** @return the 3D item depth of the model index \a index */
virtual double threeDItemDepth( const QModelIndex& index ) const = 0;
/** @return the 3D item depth of the data set \a column */
virtual double threeDItemDepth( int column ) const = 0;
};
}
#endif

View File

@@ -0,0 +1,105 @@
/****************************************************************************
** Copyright (C) 2001-2011 Klaralvdalens Datakonsult AB. All rights reserved.
**
** This file is part of the KD Chart library.
**
** Licensees holding valid commercial KD Chart licenses may use this file in
** accordance with the KD Chart Commercial License Agreement provided with
** the Software.
**
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 and version 3 as published by the
** Free Software Foundation and appearing in the file LICENSE.GPL.txt included.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** Contact info@kdab.com if any conditions of this licensing are not
** clear to you.
**
**********************************************************************/
#ifndef KDCHARTABSTRACTCARTESIANDIAGRAM_P_H
#define KDCHARTABSTRACTCARTESIANDIAGRAM_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the KD Chart API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include "KDChartAbstractCartesianDiagram.h"
#include <KDChartAbstractDiagram_p.h>
#include <KDChartAbstractThreeDAttributes.h>
#include <KDChartGridAttributes.h>
#include <KDABLibFakes>
namespace KDChart {
class CartesianCoordinatePlane;
class AbstractCartesianDiagram;
/**
* \internal
*/
class AbstractCartesianDiagram::Private : public AbstractDiagram::Private
{
friend class AbstractCartesianDiagram;
public:
Private();
virtual ~Private();
Private( const Private& rhs ) :
AbstractDiagram::Private( rhs ),
// Do not copy axes and reference diagrams.
axesList(),
referenceDiagram( 0 )
{
}
/** \reimpl */
virtual CartesianDiagramDataCompressor::DataValueAttributesList aggregatedAttrs(
AbstractDiagram * diagram,
const QModelIndex & index,
const CartesianDiagramDataCompressor::CachePosition * position ) const
{
if( position )
return compressor.aggregatedAttrs( diagram, index, *position );
CartesianDiagramDataCompressor::DataValueAttributesList allAttrs;
allAttrs[index] = diagram->dataValueAttributes( index );
return allAttrs;
}
CartesianAxisList axesList;
AbstractCartesianDiagram* referenceDiagram;
QPointF referenceDiagramOffset;
mutable CartesianDiagramDataCompressor compressor;
};
KDCHART_IMPL_DERIVED_DIAGRAM( AbstractCartesianDiagram, AbstractDiagram, CartesianCoordinatePlane )
/*
inline AbstractCartesianDiagram::AbstractCartesianDiagram( Private * p )
: AbstractDiagram( p ) { init(); }
inline AbstractCartesianDiagram::AbstractCartesianDiagram(
Private * p, QWidget* parent, CartesianCoordinatePlane* plane )
: AbstractDiagram( p, parent, plane ) { init(); }
inline AbstractCartesianDiagram::Private * AbstractCartesianDiagram::d_func()
{ return static_cast<Private*>( AbstractDiagram::d_func() ); }
inline const AbstractCartesianDiagram::Private * AbstractCartesianDiagram::d_func() const
{ return static_cast<const Private*>( AbstractDiagram::d_func() ); }
*/
}
#endif /* KDCHARTABSTRACTCARTESIANDIAGRAM_P_H */

View File

@@ -0,0 +1,453 @@
/****************************************************************************
** Copyright (C) 2001-2011 Klaralvdalens Datakonsult AB. All rights reserved.
**
** This file is part of the KD Chart library.
**
** Licensees holding valid commercial KD Chart licenses may use this file in
** accordance with the KD Chart Commercial License Agreement provided with
** the Software.
**
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 and version 3 as published by the
** Free Software Foundation and appearing in the file LICENSE.GPL.txt included.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** Contact info@kdab.com if any conditions of this licensing are not
** clear to you.
**
**********************************************************************/
#include "KDChartAbstractCoordinatePlane.h"
#include "KDChartAbstractCoordinatePlane_p.h"
#include <QGridLayout>
#include <QRubberBand>
#include <QMouseEvent>
#include "KDChartChart.h"
#include "KDChartGridAttributes.h"
#include <KDABLibFakes>
using namespace KDChart;
#define d d_func()
AbstractCoordinatePlane::Private::Private()
: AbstractArea::Private()
, parent( 0 )
, grid( 0 )
, referenceCoordinatePlane( 0 )
, enableRubberBandZooming( false )
, rubberBand( 0 )
{
// this bloc left empty intentionally
}
AbstractCoordinatePlane::AbstractCoordinatePlane ( KDChart::Chart* parent )
: AbstractArea ( new Private() )
{
d->parent = parent;
d->init();
}
AbstractCoordinatePlane::~AbstractCoordinatePlane()
{
emit destroyedCoordinatePlane( this );
}
void AbstractCoordinatePlane::init()
{
d->initialize(); // virtual method to init the correct grid: cartesian, polar, ...
connect( this, SIGNAL(internal_geometryChanged( QRect, QRect )),
this, SIGNAL(geometryChanged( QRect, QRect )),
Qt::QueuedConnection );
}
void AbstractCoordinatePlane::addDiagram ( AbstractDiagram* diagram )
{
// diagrams are invisible and paint through their paint() method
diagram->hide();
d->diagrams.append( diagram );
diagram->setParent( d->parent );
diagram->setCoordinatePlane( this );
layoutDiagrams();
layoutPlanes(); // there might be new axes, etc
connect( diagram, SIGNAL( modelsChanged() ), this, SLOT( layoutPlanes() ) );
connect( diagram, SIGNAL( modelDataChanged() ), this, SLOT( update()) );
connect( diagram, SIGNAL( modelDataChanged() ), this, SLOT( relayout()) );
update();
}
/*virtual*/
void AbstractCoordinatePlane::replaceDiagram ( AbstractDiagram* diagram, AbstractDiagram* oldDiagram_ )
{
if( diagram && oldDiagram_ != diagram ){
AbstractDiagram* oldDiagram = oldDiagram_;
if( d->diagrams.count() ){
if( ! oldDiagram ){
oldDiagram = d->diagrams.first();
if( oldDiagram == diagram )
return;
}
takeDiagram( oldDiagram );
}
delete oldDiagram;
addDiagram( diagram );
layoutDiagrams();
layoutPlanes(); // there might be new axes, etc
update();
}
}
/*virtual*/
void AbstractCoordinatePlane::takeDiagram ( AbstractDiagram* diagram )
{
const int idx = d->diagrams.indexOf( diagram );
if( idx != -1 ){
d->diagrams.removeAt( idx );
diagram->setParent( 0 );
diagram->setCoordinatePlane( 0 );
disconnect( diagram, SIGNAL( modelsChanged() ), this, SLOT( layoutPlanes() ) );
disconnect( diagram, SIGNAL( modelDataChanged() ), this, SLOT( update()) );
disconnect( diagram, SIGNAL( modelDataChanged() ), this, SLOT( relayout()) );
layoutDiagrams();
update();
}
}
AbstractDiagram* AbstractCoordinatePlane::diagram()
{
if ( d->diagrams.isEmpty() )
{
return 0;
} else {
return d->diagrams.first();
}
}
AbstractDiagramList AbstractCoordinatePlane::diagrams()
{
return d->diagrams;
}
ConstAbstractDiagramList AbstractCoordinatePlane::diagrams() const
{
ConstAbstractDiagramList list;
#ifndef QT_NO_STL
qCopy( d->diagrams.begin(), d->diagrams.end(), std::back_inserter( list ) );
#else
Q_FOREACH( AbstractDiagram * a, d->diagrams )
list.push_back( a );
#endif
return list;
}
QSize KDChart::AbstractCoordinatePlane::minimumSizeHint() const
{
return QSize( 200, 200 );
}
QSizePolicy KDChart::AbstractCoordinatePlane::sizePolicy() const
{
return QSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding );
}
void KDChart::AbstractCoordinatePlane::setGlobalGridAttributes( const GridAttributes& a )
{
d->gridAttributes = a;
update();
}
GridAttributes KDChart::AbstractCoordinatePlane::globalGridAttributes() const
{
return d->gridAttributes;
}
KDChart::DataDimensionsList KDChart::AbstractCoordinatePlane::gridDimensionsList()
{
//KDChart::DataDimensionsList l( d->grid->updateData( this ) );
//qDebug() << "AbstractCoordinatePlane::gridDimensionsList() Y-range:" << l.last().end - l.last().start << " step width:" << l.last().stepWidth;
//qDebug() << "AbstractCoordinatePlane::gridDimensionsList() X-range:" << l.first().end - l.first().start << " step width:" << l.first().stepWidth;
return d->grid->updateData( this );
}
void KDChart::AbstractCoordinatePlane::setGridNeedsRecalculate()
{
d->grid->setNeedRecalculate();
}
void KDChart::AbstractCoordinatePlane::setReferenceCoordinatePlane( AbstractCoordinatePlane * plane )
{
d->referenceCoordinatePlane = plane;
}
AbstractCoordinatePlane * KDChart::AbstractCoordinatePlane::referenceCoordinatePlane( ) const
{
return d->referenceCoordinatePlane;
}
void KDChart::AbstractCoordinatePlane::setParent( KDChart::Chart* parent )
{
d->parent = parent;
}
const KDChart::Chart* KDChart::AbstractCoordinatePlane::parent() const
{
return d->parent;
}
KDChart::Chart* KDChart::AbstractCoordinatePlane::parent()
{
return d->parent;
}
/* pure virtual in QLayoutItem */
bool KDChart::AbstractCoordinatePlane::isEmpty() const
{
return false; // never empty!
// coordinate planes with no associated diagrams
// are showing a default grid of ()1..10, 1..10) stepWidth 1
}
/* pure virtual in QLayoutItem */
Qt::Orientations KDChart::AbstractCoordinatePlane::expandingDirections() const
{
return Qt::Vertical | Qt::Horizontal;
}
/* pure virtual in QLayoutItem */
QSize KDChart::AbstractCoordinatePlane::maximumSize() const
{
// No maximum size set. Especially not parent()->size(), we are not layouting
// to the parent widget's size when using Chart::paint()!
return QSize(QLAYOUTSIZE_MAX, QLAYOUTSIZE_MAX);
}
/* pure virtual in QLayoutItem */
QSize KDChart::AbstractCoordinatePlane::minimumSize() const
{
return QSize(60, 60); // this default can be overwritten by derived classes
}
/* pure virtual in QLayoutItem */
QSize KDChart::AbstractCoordinatePlane::sizeHint() const
{
// we return our maxiumu (which is the full size of the Chart)
// even if we know the plane will be smaller
return maximumSize();
}
/* pure virtual in QLayoutItem */
void KDChart::AbstractCoordinatePlane::setGeometry( const QRect& r )
{
// qDebug() << "KDChart::AbstractCoordinatePlane::setGeometry(" << r << ") called";
if( d->geometry != r ){
//qDebug() << "entering KDChart::AbstractCoordinatePlane::setGeometry(" << r << ")";
// inform the outside word by Signal geometryChanged()
// via a queued connection to internal_geometryChanged()
emit internal_geometryChanged( d->geometry, r );
d->geometry = r;
// Note: We do *not* call update() here
// because it would invoke KDChart::update() recursively.
//qDebug() << "leaving KDChart::AbstractCoordinatePlane::setGeometry(" << r << ")";
}
}
/* pure virtual in QLayoutItem */
QRect KDChart::AbstractCoordinatePlane::geometry() const
{
return d->geometry;
}
void KDChart::AbstractCoordinatePlane::update()
{
//qDebug("KDChart::AbstractCoordinatePlane::update() called");
emit needUpdate();
}
void KDChart::AbstractCoordinatePlane::relayout()
{
//qDebug("KDChart::AbstractCoordinatePlane::relayout() called");
emit needRelayout();
}
void KDChart::AbstractCoordinatePlane::layoutPlanes()
{
//qDebug("KDChart::AbstractCoordinatePlane::relayout() called");
emit needLayoutPlanes();
}
void KDChart::AbstractCoordinatePlane::setRubberBandZoomingEnabled( bool enable )
{
d->enableRubberBandZooming = enable;
if( !enable && d->rubberBand != 0 )
{
delete d->rubberBand;
d->rubberBand = 0;
}
}
bool KDChart::AbstractCoordinatePlane::isRubberBandZoomingEnabled() const
{
return d->enableRubberBandZooming;
}
void KDChart::AbstractCoordinatePlane::mousePressEvent( QMouseEvent* event )
{
if( event->button() == Qt::LeftButton )
{
if( d->enableRubberBandZooming && d->rubberBand == 0 )
d->rubberBand = new QRubberBand( QRubberBand::Rectangle, qobject_cast< QWidget* >( parent() ) );
if( d->rubberBand != 0 )
{
d->rubberBandOrigin = event->pos();
d->rubberBand->setGeometry( QRect( event->pos(), QSize() ) );
d->rubberBand->show();
event->accept();
}
}
else if( event->button() == Qt::RightButton )
{
if( d->enableRubberBandZooming && !d->rubberBandZoomConfigHistory.isEmpty() )
{
// restore the last config from the stack
ZoomParameters config = d->rubberBandZoomConfigHistory.pop();
setZoomFactorX( config.xFactor );
setZoomFactorY( config.yFactor );
setZoomCenter( config.center() );
QWidget* const p = qobject_cast< QWidget* >( parent() );
if( p != 0 )
p->update();
event->accept();
}
}
KDAB_FOREACH( AbstractDiagram * a, d->diagrams )
{
a->mousePressEvent( event );
}
}
void KDChart::AbstractCoordinatePlane::mouseDoubleClickEvent( QMouseEvent* event )
{
if( event->button() == Qt::RightButton )
{
// othewise the second click gets lost
// which is pretty annoying when zooming out fast
mousePressEvent( event );
}
KDAB_FOREACH( AbstractDiagram * a, d->diagrams )
{
a->mouseDoubleClickEvent( event );
}
}
void KDChart::AbstractCoordinatePlane::mouseReleaseEvent( QMouseEvent* event )
{
if( d->rubberBand != 0 )
{
// save the old config on the stack
d->rubberBandZoomConfigHistory.push( ZoomParameters( zoomFactorX(), zoomFactorY(), zoomCenter() ) );
// this is the height/width of the rubber band in pixel space
const double rubberWidth = static_cast< double >( d->rubberBand->width() );
const double rubberHeight = static_cast< double >( d->rubberBand->height() );
if( rubberWidth > 0.0 && rubberHeight > 0.0 )
{
// this is the center of the rubber band in pixel space
const double rubberCenterX = static_cast< double >( d->rubberBand->geometry().center().x() - geometry().x() );
const double rubberCenterY = static_cast< double >( d->rubberBand->geometry().center().y() - geometry().y() );
// this is the height/width of the plane in pixel space
const double myWidth = static_cast< double >( geometry().width() );
const double myHeight = static_cast< double >( geometry().height() );
// this describes the new center of zooming, relative to the plane pixel space
const double newCenterX = rubberCenterX / myWidth / zoomFactorX() + zoomCenter().x() - 0.5 / zoomFactorX();
const double newCenterY = rubberCenterY / myHeight / zoomFactorY() + zoomCenter().y() - 0.5 / zoomFactorY();
// this will be the new zoom factor
const double newZoomFactorX = zoomFactorX() * myWidth / rubberWidth;
const double newZoomFactorY = zoomFactorY() * myHeight / rubberHeight;
// and this the new center
const QPointF newZoomCenter( newCenterX, newCenterY );
setZoomFactorX( newZoomFactorX );
setZoomFactorY( newZoomFactorY );
setZoomCenter( newZoomCenter );
}
d->rubberBand->parentWidget()->update();
delete d->rubberBand;
d->rubberBand = 0;
event->accept();
}
KDAB_FOREACH( AbstractDiagram * a, d->diagrams )
{
a->mouseReleaseEvent( event );
}
}
void KDChart::AbstractCoordinatePlane::mouseMoveEvent( QMouseEvent* event )
{
if( d->rubberBand != 0 )
{
const QRect normalized = QRect( d->rubberBandOrigin, event->pos() ).normalized();
d->rubberBand->setGeometry( normalized & geometry() );
event->accept();
}
KDAB_FOREACH( AbstractDiagram * a, d->diagrams )
{
a->mouseMoveEvent( event );
}
}
#if QT_VERSION < 0x040400 || defined(Q_COMPILER_MANGLES_RETURN_TYPE)
const
#endif
bool KDChart::AbstractCoordinatePlane::isVisiblePoint( const QPointF& point ) const
{
return d->isVisiblePoint( this, point );
}
AbstractCoordinatePlane* KDChart::AbstractCoordinatePlane::sharedAxisMasterPlane( QPainter* p )
{
Q_UNUSED( p );
return this;
}
#if !defined(QT_NO_DEBUG_STREAM)
#include "KDChartEnums.h"
QDebug KDChart::operator<<( QDebug stream, const DataDimension& r )
{
stream << "DataDimension("
<< " start=" << r.start
<< " end=" << r.end
<< " sequence=" << KDChartEnums::granularitySequenceToString( r.sequence )
<< " isCalculated=" << r.isCalculated
<< " calcMode=" << ( r.calcMode == AbstractCoordinatePlane::Logarithmic ? "Logarithmic" : "Linear" )
<< " stepWidth=" << r.stepWidth
<< " subStepWidth=" << r.subStepWidth
<< " )";
return stream;
}
#endif
#undef d

View File

@@ -0,0 +1,437 @@
/****************************************************************************
** Copyright (C) 2001-2011 Klaralvdalens Datakonsult AB. All rights reserved.
**
** This file is part of the KD Chart library.
**
** Licensees holding valid commercial KD Chart licenses may use this file in
** accordance with the KD Chart Commercial License Agreement provided with
** the Software.
**
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 and version 3 as published by the
** Free Software Foundation and appearing in the file LICENSE.GPL.txt included.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** Contact info@kdab.com if any conditions of this licensing are not
** clear to you.
**
**********************************************************************/
#ifndef KDCHARTABSTRACTCOORDINATEPLANE_H
#define KDCHARTABSTRACTCOORDINATEPLANE_H
#include <QObject>
#include <QList>
#include "KDChartAbstractArea.h"
#include "KDChartAbstractDiagram.h"
#include "KDChartEnums.h"
namespace KDChart {
class Chart;
class GridAttributes;
class DataDimension;
typedef QList<DataDimension> DataDimensionsList;
/**
* @brief Base class common for all coordinate planes, CartesianCoordinatePlane, PolarCoordinatePlane, TernaryCoordinatePlane
*/
class KDCHART_EXPORT AbstractCoordinatePlane : public AbstractArea
{
Q_OBJECT
Q_DISABLE_COPY( AbstractCoordinatePlane )
KDCHART_DECLARE_PRIVATE_DERIVED_PARENT( AbstractCoordinatePlane, Chart* )
friend class AbstractGrid;
public:
enum AxesCalcMode { Linear, Logarithmic };
protected:
explicit AbstractCoordinatePlane ( Chart* parent = 0 );
public:
virtual ~AbstractCoordinatePlane();
/**
* Adds a diagram to this coordinate plane.
* @param diagram The diagram to add.
*
* \sa replaceDiagram, takeDiagram
*/
virtual void addDiagram ( AbstractDiagram* diagram );
/**
* Replaces the old diagram, or appends the
* diagram, it there is none yet.
*
* @param diagram The diagram to be used instead of the old diagram.
* This parameter must not be zero, or the method will do nothing.
*
* @param oldDiagram The diagram to be removed by the new diagram. This
* diagram will be deleted automatically. If the parameter is omitted,
* the very first diagram will be replaced. In case, there was no
* diagram yet, the new diagram will just be added.
*
* \note If you want to re-use the old diagram, call takeDiagram and
* addDiagram, instead of using replaceDiagram.
*
* \sa addDiagram, takeDiagram
*/
virtual void replaceDiagram ( AbstractDiagram* diagram, AbstractDiagram* oldDiagram = 0 );
/**
* Removes the diagram from the plane, without deleting it.
*
* The plane no longer owns the diagram, so it is
* the caller's responsibility to delete the diagram.
*
* \sa addDiagram, replaceDiagram
*/
virtual void takeDiagram( AbstractDiagram* diagram );
/**
* @return The first diagram associated with this coordinate plane.
*/
AbstractDiagram* diagram();
/**
* @return The list of diagrams associated with this coordinate plane.
*/
AbstractDiagramList diagrams();
/**
* @return The list of diagrams associated with this coordinate plane.
*/
ConstAbstractDiagramList diagrams() const;
/**
* Distribute the available space among the diagrams and axes.
*/
virtual void layoutDiagrams() = 0;
/**
* Translate the given point in value space coordinates to a position
* in pixel space.
* @param diagramPoint The point in value coordinates.
* @returns The translated point.
*/
virtual const QPointF translate ( const QPointF& diagramPoint ) const = 0;
/** \reimpl */
virtual QSize minimumSizeHint() const;
/** \reimpl */
virtual QSizePolicy sizePolicy() const;
/**
* @return Whether zooming with a rubber band using the mouse is enabled.
*/
bool isRubberBandZoomingEnabled() const;
/**
* Enables or disables zooming with a rubber band using the mouse.
*/
void setRubberBandZoomingEnabled( bool enable );
/**
* @return The zoom factor in horizontal direction, that is applied
* to all coordinate transformations.
*/
virtual double zoomFactorX() const { return 1.0; }
/**
* @return The zoom factor in vertical direction, that is applied
* to all coordinate transformations.
*/
virtual double zoomFactorY() const { return 1.0; }
/**
* Sets both zoom factors in one go.
* \sa setZoomFactorX,setZoomFactorY
*/
virtual void setZoomFactors( double factorX, double factorY ) { Q_UNUSED( factorX ); Q_UNUSED( factorY ); }
/**
* Sets the zoom factor in horizontal direction, that is applied
* to all coordinate transformations.
* @param factor The new zoom factor
*/
virtual void setZoomFactorX( double factor ) { Q_UNUSED( factor ); }
/**
* Sets the zoom factor in vertical direction, that is applied
* to all coordinate transformations.
* @param factor The new zoom factor
*/
virtual void setZoomFactorY( double factor ) { Q_UNUSED( factor ); }
/**
* @return The center point (in value coordinates) of the
* coordinate plane, that is used for zoom operations.
*/
virtual QPointF zoomCenter() const { return QPointF(0.0, 0.0); }
/**
* Set the point (in value coordinates) to be used as the
* center point in zoom operations.
* @param center The point to use.
*/
virtual void setZoomCenter( const QPointF& center ) { Q_UNUSED( center ); }
/**
* Set the grid attributes to be used by this coordinate plane.
* To disable grid painting, for example, your code should like this:
* \code
* GridAttributes ga = plane->globalGridAttributes();
* ga.setGlobalGridVisible( false );
* plane->setGlobalGridAttributes( ga );
* \endcode
* \sa globalGridAttributes
* \sa CartesianCoordinatePlane::setGridAttributes
*/
void setGlobalGridAttributes( const GridAttributes & );
/**
* @return The grid attributes used by this coordinate plane.
* \sa setGlobalGridAttributes
* \sa CartesianCoordinatePlane::gridAttributes
*/
GridAttributes globalGridAttributes() const;
/**
* Returns the dimensions used for drawing the grid lines.
*
* Returned data is the result of (cached) grid calculations,
* so - if you need that information for your own tasks - make sure to
* call again this function after every data modification that has changed
* the data range, since grid calculation is based upon the data range,
* thus the grid start/end might have changed if the data was changed.
*
* @note Returned list will contain different numbers of DataDimension,
* depending on the kind of coordinate plane used.
* For CartesianCoordinatePlane two DataDimension are returned: the first
* representing grid lines in X direction (matching the Abscissa axes)
* and the second indicating vertical grid lines (or Ordinate axes, resp.).
*
* @return The dimensions used for drawing the grid lines.
* @sa DataDimension
*/
DataDimensionsList gridDimensionsList();
/**
* Set another coordinate plane to be used as the reference plane
* for this one.
* @param plane The coordinate plane to be used the reference plane
* for this one.
* @see referenceCoordinatePlane
*/
void setReferenceCoordinatePlane( AbstractCoordinatePlane * plane );
/**
* There are two ways, in which planes can be caused to interact, in
* where they are put layouting wise: The first is the reference plane. If
* such a reference plane is set, on a plane, it will use the same cell in the
* layout as that one. In addition to this, planes can share an axis. In that case
* they will be laid out in relation to each other as suggested by the position
* of the axis. If, for example Plane1 and Plane2 share an axis at position Left,
* that will result in the layout: Axis Plane1 Plane 2, vertically. If Plane1
* also happens to be Plane2's reference plane, both planes are drawn over each
* other. The reference plane concept allows two planes to share the same space
* even if neither has any axis, and in case there are shared axis, it is used
* to decided, whether the planes should be painted on top of each other or
* laid out vertically or horizontally next to each other.
* @return The reference coordinate plane associated with this one.
*/
AbstractCoordinatePlane * referenceCoordinatePlane() const;
virtual AbstractCoordinatePlane* sharedAxisMasterPlane( QPainter* p = 0 );
/** pure virtual in QLayoutItem */
virtual bool isEmpty() const;
/** pure virtual in QLayoutItem */
virtual Qt::Orientations expandingDirections() const;
/** pure virtual in QLayoutItem */
virtual QSize maximumSize() const;
/** pure virtual in QLayoutItem */
virtual QSize minimumSize() const;
/** pure virtual in QLayoutItem */
virtual QSize sizeHint() const;
/** pure virtual in QLayoutItem
*
* \note Do not call this function directly, unless you know
* exactly what you are doing. Geometry management is done
* by KD Chart's internal layouting measures.
*/
virtual void setGeometry( const QRect& r );
/** pure virtual in QLayoutItem */
virtual QRect geometry() const;
virtual void mousePressEvent( QMouseEvent* event );
virtual void mouseDoubleClickEvent( QMouseEvent* event );
virtual void mouseMoveEvent( QMouseEvent* event );
virtual void mouseReleaseEvent( QMouseEvent* event );
/**
* Called internally by KDChart::Chart
*/
void setParent( Chart* parent );
Chart* parent();
const Chart* parent() const;
/**
* Tests, if a point is visible on the coordinate plane.
*
* \note Before calling this function the point must have been translated into coordinate plane space.
*/
#if QT_VERSION < 0x040400 || defined(Q_COMPILER_MANGLES_RETURN_TYPE)
const bool isVisiblePoint( const QPointF& point ) const;
#else
bool isVisiblePoint( const QPointF& point ) const;
#endif
public Q_SLOTS:
/**
* Calling update() on the plane triggers the global KDChart::Chart::update()
*/
void update();
/**
* Calling relayout() on the plane triggers the global KDChart::Chart::slotRelayout()
*/
void relayout();
/**
* Calling layoutPlanes() on the plane triggers the global KDChart::Chart::slotLayoutPlanes()
*/
void layoutPlanes();
/**
* Used by the chart to clear the cached grid data.
*/
void setGridNeedsRecalculate();
Q_SIGNALS:
/** Emitted when this coordinate plane is destroyed. */
void destroyedCoordinatePlane( AbstractCoordinatePlane* );
/** Emitted when plane needs to update its drawings. */
void needUpdate();
/** Emitted when plane needs to trigger the Chart's layouting. */
void needRelayout();
/** Emitted when plane needs to trigger the Chart's layouting of the coord. planes. */
void needLayoutPlanes();
/** Emitted upon change of a property of the Coordinate Plane or any of its components. */
void propertiesChanged();
/** Emitted after the geometry of the Coordinate Plane has been changed.
* and control has returned to the event loop.
*
* Parameters are the the old geometry, the new geometry.
*/
void geometryChanged( QRect, QRect );
private:
Q_SIGNALS:
// Emitted from inside the setGeometry()
// This is connected via QueuedConnection to the geometryChanged() Signal
// that users can connect to safely then.
void internal_geometryChanged( QRect, QRect );
protected:
virtual DataDimensionsList getDataDimensionsList() const = 0;
//KDCHART_DECLARE_PRIVATE_DERIVED( AbstractCoordinatePlane )
};
/**
* \brief Helper class for one dimension of data, e.g. for the rows in a data model,
* or for the labels of an axis, or for the vertical lines in a grid.
*
* isCalculated specifies whether this dimension's values are calculated or counted.
* (counted == "Item 1", "Item 2", "Item 3" ...)
*
* sequence is the GranularitySequence, as specified at for the respective
* coordinate plane.
*
* Step width is an optional parameter, to be omitted (or set to Zero, resp.)
* if the step width is unknown.
*
* The default c'tor just gets you counted values from 1..10, using step width 1,
* used by the CartesianGrid, when showing an empty plane without any diagrams.
*/
class DataDimension{
public:
DataDimension()
: start( 1.0 )
, end( 10.0 )
, isCalculated( false )
, calcMode( AbstractCoordinatePlane::Linear )
, sequence( KDChartEnums::GranularitySequence_10_20 )
, stepWidth( 1.0 )
, subStepWidth( 0.0 )
{}
DataDimension( qreal start_,
qreal end_,
bool isCalculated_,
AbstractCoordinatePlane::AxesCalcMode calcMode_,
KDChartEnums::GranularitySequence sequence_,
qreal stepWidth_=0.0,
qreal subStepWidth_=0.0 )
: start( start_ )
, end( end_ )
, isCalculated( isCalculated_ )
, calcMode( calcMode_ )
, sequence( sequence_ )
, stepWidth( stepWidth_ )
, subStepWidth( subStepWidth_ )
{}
/**
* Returns the size of the distance,
* equivalent to the width() (or height(), resp.) of a QRectF.
*
* Note that this value can be negative, e.g. indicating axis labels
* going in reversed direction.
*/
qreal distance() const
{
return end-start;
}
bool operator==( const DataDimension& r ) const
{
return
(start == r.start) &&
(end == r.end) &&
(sequence == r.sequence) &&
(isCalculated == r.isCalculated) &&
(calcMode == r.calcMode) &&
(stepWidth == r.stepWidth) &&
(subStepWidth == r.subStepWidth);
}
bool operator!=( const DataDimension& other ) const
{ return !operator==( other ); }
qreal start;
qreal end;
bool isCalculated;
AbstractCoordinatePlane::AxesCalcMode calcMode;
KDChartEnums::GranularitySequence sequence;
qreal stepWidth;
qreal subStepWidth;
};
#if !defined(QT_NO_DEBUG_STREAM)
QDebug operator<<( QDebug stream, const DataDimension& r );
#endif
}
#endif

Some files were not shown because too many files have changed in this diff Show More