add massif-visualizer

This commit is contained in:
Ivailo Monev 2015-09-30 16:47:20 +03:00
parent b7327cfea8
commit d6419d5b2a
514 changed files with 123370 additions and 0 deletions

View file

@ -0,0 +1,4 @@
kate: space-indent on; indent-width 4; replace-tabs on; auto-insert-doxygen on;
kate: eol unix; replace-trailing-space-save on; show-tabs on; tab-indents on;
kate: tab-width 4;

View file

@ -0,0 +1,6 @@
Main author:
Milian Wolff <mail@milianw.de>
Contributions by:
Andrei Nistor <coder.tux@ceata.org>
Arnold Dumas <contact@arnolddumas.fr>

View file

@ -0,0 +1,38 @@
cmake_minimum_required(VERSION 2.8.9)
PROJECT(massif-visualizer)
enable_testing()
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/ ${CMAKE_MODULE_PATH})
set(KDE_MIN_VERSION "4.7.0")
find_package(KDE4 4.7.0 REQUIRED)
include (KDE4Defaults)
include (MacroLibrary)
macro_optional_find_package(KGraphViewer 2.1)
macro_log_feature(KGRAPHVIEWER_FOUND "KGraphViewer" "KPart to view callgraph dot files."
"http://extragear.kde.org/apps/kgraphviewer/" FALSE ""
"Required for detailed snapshot analysis. From KDE SDK Extragear package, KGraphViewer 2.1 or higher is required.")
macro_display_feature_log()
include_directories(
${KDE4_INCLUDES}
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/kdchart/include/KDChart
)
add_definitions(-Wall)
add_subdirectory(kdchart)
add_subdirectory(massifdata)
add_subdirectory(visualizer)
add_subdirectory(app)
add_subdirectory(pics)
if(ENABLE_TESTING)
add_subdirectory(test)
endif()

340
massif-visualizer/COPYING Normal file
View file

@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

15
massif-visualizer/INSTALL Normal file
View file

@ -0,0 +1,15 @@
Build requirements:
- kdelibs headers from KDE4
- optional: kgraphviewer 2.1: http://kde-apps.org/content/show.php/KGraphViewer+and+KGraphEditor?content=23999
When you got all this, you simply do the usual CMake run:
cd massif-visualizer
mkdir build
cd build
cmake ..
make
sudo make install
That should be it.

16
massif-visualizer/Messages.sh Executable file
View file

@ -0,0 +1,16 @@
#! /usr/bin/env bash
subdirs="app kdchart massifdata visualizer"
rcfiles="`find $subdirs -name \*.rc`"
uifiles="`find $subdirs -name \*.ui`"
kcfgfiles="`find $subdirs -name \*.kcfg`"
if [[ "$rcfiles" != "" ]] ; then
$EXTRACTRC $rcfiles >> rc.cpp || exit 11
fi
if [[ "$uifiles" != "" ]] ; then
$EXTRACTRC $uifiles >> rc.cpp || exit 12
fi
if [[ "$kcfgfiles" != "" ]] ; then
$EXTRACTRC $kcfgfiles >> rc.cpp || exit 13
fi
$XGETTEXT `find $subdirs -name \*.cc -o -name \*.cpp -o -name \*.h` rc.cpp -o $podir/massif-visualizer.pot
rm -f rc.cpp

93
massif-visualizer/README Normal file
View file

@ -0,0 +1,93 @@
=================
massif-visualizer
=================
---------------------------------------------------------
visualizer for Valgrind Massif memory-usage tracking tool
---------------------------------------------------------
:Author: Milian Wolff <mail@milianw.de>
:Date: 2011-11-21
:Manual section: 1
SYNOPSIS
========
**massif-visualizer [massif-data-file]**
DESCRIPTION
===========
Massif Visualizer is a tool that visualizes massif data. You run your
application in Valgrind with ``--tool=massif`` and then open the generated
``massif.out.%pid`` in the visualizer. Gzip or Bzip2 compressed massif files can
also be opened transparently.
The application consists of three parts:
**The Overview Chart**
The first thing you'll notice is a nice chart that displays the same as e.g.
``ms_print`` does in Ascii-Art: total memory consumption over time.
Massif-Visualizer goes beyond that by additionally showing the top most
cost-intensive locations in your code as a stacked graph below the total cost.
The graph also reacts on user-interaction.
This view you can use for:
- checking whether your application has memory leaks
- finding expensive peaks
- finding locations that significantly contribute to the overall memory
consumption of your application
**The Snapshot Data Tree**
Directly next to the above chart, you'll see a tree with all of the massif
data. The tree items are colored depending on their cost, with red opaque being
the most interesting (peak) elements. Green/transparent items are negligible
and don't add significant cost to your application.
You can also search the tree and when you select something in it, the snapshot
gets highlighted in the overview chart and the call graph gets updated.
**The Call Graph for Detailed Snapshots**
Massif generates a few detailed snapshots that essentially make up the tree. If
you want to get an overview in a more comfortable way than the simple tree
view, switch over to the detailed snapshot tab and see the tree visualized as a
call graph. Zoom in, zoom out, use the birds eye view and see what contributes
to a given snapshot. Note that function calls with the same memory cost are
grouped to easily find the interesting parts.
OPTIONS
=======
--help Show help about options
--help-all Show all options
--author Show author information
-v, --version Show version information
--license Show license information
AUTHOR
======
Written by Milian Wolff.
REPORTING BUGS
==============
Please report bugs on https://bugs.kde.org under the massif-visualizer product.
COPYRIGHT
=========
Copyright © 2011 Milian Wolff.
License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
SEE ALSO
========
**valgrind(1)**, **ms_print(1)**

View file

@ -0,0 +1,55 @@
include_directories(
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
)
set(massif-visualizer_SRCS
main.cpp
mainwindow.cpp
configdialog.cpp
documentwidget.cpp
documenttabinterface.cpp
charttab.cpp
allocatorstab.cpp
)
if(KGRAPHVIEWER_FOUND)
include_directories(
${KGRAPHVIEWER_INCLUDE_DIRECTORIES}
)
add_definitions(-DHAVE_KGRAPHVIEWER)
list(APPEND massif-visualizer_SRCS callgraphtab.cpp)
endif(KGRAPHVIEWER_FOUND)
kde4_add_kcfg_files(massif-visualizer_SRCS massif-visualizer-settings.kcfgc)
add_executable(massif-visualizer ${massif-visualizer_SRCS})
target_link_libraries(massif-visualizer LINK_PRIVATE
${KDE4_KDEUI_LIBS}
${KDE4_KIO_LIBS}
${KDE4_KPARTS_LIBS}
mv-kdchart
mv-massifdata
mv-visualizer
)
install( TARGETS massif-visualizer ${INSTALL_TARGETS_DEFAULT_ARGS} )
install(
FILES massif-visualizerui.rc documentwidgetui.rc charttabui.rc callgraphtabui.rc
DESTINATION ${DATA_INSTALL_DIR}/massif-visualizer
)
install(FILES massif-visualizer-settings.kcfg DESTINATION ${KCFG_INSTALL_DIR})
install(PROGRAMS massif-visualizer.desktop DESTINATION ${XDG_APPS_INSTALL_DIR})
# XML mime type
set( SHARED_MIME_INFO_MINIMUM_VERSION "0.30" )
set( XDG_MIME_INSTALL_DIR "share/mime/packages" )
find_package( SharedMimeInfo )
if( SHARED_MIME_INFO_FOUND )
install( FILES massif.xml DESTINATION ${XDG_MIME_INSTALL_DIR} )
update_xdg_mimetypes( ${XDG_MIME_INSTALL_DIR} )
endif( SHARED_MIME_INFO_FOUND )

View file

@ -0,0 +1,103 @@
/*
This file is part of Massif Visualizer
Copyright 2014 Milian Wolff <mail@milianw.de>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License or (at your option) version 3 or any later version
accepted by the membership of KDE e.V. (or its successor approved
by the membership of KDE e.V.), which shall act as a proxy
defined in Section 14 of version 3 of the license.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "allocatorstab.h"
#include "visualizer/allocatorsmodel.h"
#include <QVBoxLayout>
#include <QTreeView>
#include <QSortFilterProxyModel>
#include <QMenu>
using namespace Massif;
AllocatorsTab::AllocatorsTab(const FileData* data,
KXMLGUIClient* guiParent, QWidget* parent)
: DocumentTabInterface(data, guiParent, parent)
, m_model(new AllocatorsModel(data, this))
, m_proxy(new QSortFilterProxyModel(this))
, m_view(new QTreeView(this))
{
m_proxy->setSourceModel(m_model);
m_proxy->setSortRole(AllocatorsModel::SortRole);
m_view->setRootIsDecorated(false);
m_view->setModel(m_proxy);
m_view->setSortingEnabled(true);
m_view->sortByColumn(AllocatorsModel::Peak);
m_view->resizeColumnToContents(AllocatorsModel::Function);
m_view->resizeColumnToContents(AllocatorsModel::Peak);
m_view->setContextMenuPolicy(Qt::CustomContextMenu);
connect(m_view->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
this, SLOT(selectionChanged(QModelIndex,QModelIndex)));
connect(m_view, SIGNAL(customContextMenuRequested(QPoint)),
this, SLOT(customContextMenuRequested(QPoint)));
setLayout(new QVBoxLayout(this));
layout()->addWidget(m_view);
}
AllocatorsTab::~AllocatorsTab()
{
}
void AllocatorsTab::selectModelItem(const ModelItem& item)
{
const QModelIndex idx = m_model->indexForItem(item);
if (!idx.isValid()) {
return;
}
m_view->selectionModel()->clearSelection();
m_view->selectionModel()->setCurrentIndex(m_proxy->mapFromSource(idx),
QItemSelectionModel::Select | QItemSelectionModel::Rows);
m_view->scrollTo(m_view->selectionModel()->currentIndex());
}
void AllocatorsTab::settingsChanged()
{
m_model->settingsChanged();
}
void AllocatorsTab::selectionChanged(const QModelIndex& current, const QModelIndex& /*previous*/)
{
const ModelItem item = current.data(AllocatorsModel::ItemRole).value<ModelItem>();
if (item.first) {
emit modelItemSelected(item);
}
}
void AllocatorsTab::customContextMenuRequested(const QPoint& pos)
{
const QModelIndex idx = m_view->indexAt(pos);
const ModelItem item = idx.data(AllocatorsModel::ItemRole).value<ModelItem>();
QMenu menu;
emit contextMenuRequested(item, &menu);
if (!menu.actions().isEmpty()) {
menu.exec(m_view->mapToGlobal(pos));
}
}
#include "allocatorstab.moc"

View file

@ -0,0 +1,57 @@
/*
This file is part of Massif Visualizer
Copyright 2014 Milian Wolff <mail@milianw.de>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License or (at your option) version 3 or any later version
accepted by the membership of KDE e.V. (or its successor approved
by the membership of KDE e.V.), which shall act as a proxy
defined in Section 14 of version 3 of the license.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ALLOCATORSTAB_H
#define ALLOCATORSTAB_H
#include "documenttabinterface.h"
class QTreeView;
class QSortFilterProxyModel;
class QModelIndex;
namespace Massif {
class AllocatorsModel;
}
class AllocatorsTab : public DocumentTabInterface
{
Q_OBJECT
public:
explicit AllocatorsTab(const Massif::FileData* data, KXMLGUIClient* guiParent, QWidget* parent = 0);
virtual ~AllocatorsTab();
virtual void selectModelItem(const Massif::ModelItem& item);
virtual void settingsChanged();
private slots:
void selectionChanged(const QModelIndex& current, const QModelIndex& previous);
void customContextMenuRequested(const QPoint& pos);
private:
Massif::AllocatorsModel* m_model;
QSortFilterProxyModel* m_proxy;
QTreeView* m_view;
};
#endif // ALLOCATORSTAB_H

View file

@ -0,0 +1,194 @@
/*
This file is part of Massif Visualizer
Copyright 2014 Milian Wolff <mail@milianw.de>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License or (at your option) version 3 or any later version
accepted by the membership of KDE e.V. (or its successor approved
by the membership of KDE e.V.), which shall act as a proxy
defined in Section 14 of version 3 of the license.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "callgraphtab.h"
#include "visualizer/dotgraphgenerator.h"
#include "massifdata/filedata.h"
#include <QVBoxLayout>
#include <KDebug>
#include <KParts/Part>
#include <KStandardAction>
#include <KActionCollection>
#include <KAction>
#include <KLocalizedString>
#include <kgraphviewer_interface.h>
using namespace Massif;
CallGraphTab::CallGraphTab(const FileData* data, KParts::ReadOnlyPart* graphViewerPart,
KXMLGUIClient* guiParent, QWidget* parent)
: DocumentTabInterface(data, guiParent, parent)
, m_graphViewerPart(graphViewerPart)
, m_graphViewer(qobject_cast<KGraphViewer::KGraphViewerInterface*>(m_graphViewerPart))
, m_dotGenerator(0)
, m_zoomIn(0)
, m_zoomOut(0)
, m_focusExpensive(0)
{
setXMLFile("callgraphtabui.rc", true);
setupActions();
Q_ASSERT(m_graphViewer);
setLayout(new QVBoxLayout);
layout()->addWidget(m_graphViewerPart->widget());
connect(m_graphViewerPart, SIGNAL(graphLoaded()),
this, SLOT(slotGraphLoaded()));
showDotGraph(ModelItem(0, data->peak()));
}
CallGraphTab::~CallGraphTab()
{
if (m_dotGenerator) {
if (m_dotGenerator->isRunning()) {
disconnect(m_dotGenerator.data(), 0, this, 0);
connect(m_dotGenerator.data(), SIGNAL(finished()),
m_dotGenerator.data(), SLOT(deleteLater()));
m_dotGenerator->cancel();
m_dotGenerator.take();
}
m_dotGenerator.reset();
}
if (m_graphViewer) {
m_graphViewerPart->closeUrl();
}
m_lastDotItem.first = 0;
m_lastDotItem.second = 0;
}
void CallGraphTab::setupActions()
{
m_zoomIn = KStandardAction::zoomIn(this, SLOT(zoomIn()), actionCollection());
actionCollection()->addAction("zoomIn", m_zoomIn);
m_zoomOut = KStandardAction::zoomOut(this, SLOT(zoomOut()), actionCollection());
actionCollection()->addAction("zoomOut", m_zoomOut);
m_focusExpensive = new KAction(KIcon("flag-red"), i18n("Focus most expensive node"), actionCollection());
connect(m_focusExpensive, SIGNAL(triggered()), this, SLOT(focusExpensiveGraphNode()));
actionCollection()->addAction("focusExpensive", m_focusExpensive);
}
void CallGraphTab::settingsChanged()
{
}
void CallGraphTab::focusExpensiveGraphNode()
{
Q_ASSERT(m_graphViewer);
Q_ASSERT(m_dotGenerator);
m_graphViewer->centerOnNode(m_dotGenerator->mostCostIntensiveGraphvizId());
}
void CallGraphTab::showDotGraph(const ModelItem& item)
{
m_nextDotItem = item;
if (item == m_lastDotItem && m_graphViewerPart->url().isValid()) {
return;
}
if (!isVisible()) {
return;
}
m_lastDotItem = item;
Q_ASSERT(m_graphViewer);
kDebug() << "new dot graph requested" << item;
if (m_dotGenerator) {
kDebug() << "existing generator is running:" << m_dotGenerator->isRunning();
if (m_dotGenerator->isRunning()) {
disconnect(m_dotGenerator.data(), 0, this, 0);
connect(m_dotGenerator.data(), SIGNAL(finished()),
m_dotGenerator.data(), SLOT(deleteLater()));
m_dotGenerator->cancel();
m_dotGenerator.take();
}
m_dotGenerator.reset();
}
if (!item.first && !item.second) {
return;
}
if (item.second) {
m_dotGenerator.reset(new DotGraphGenerator(item.second, m_data->timeUnit(), this));
} else {
m_dotGenerator.reset(new DotGraphGenerator(item.first, m_data->timeUnit(), this));
}
m_dotGenerator->start();
connect(m_dotGenerator.data(), SIGNAL(finished()), this, SLOT(showDotGraph()));
}
void CallGraphTab::setVisible(bool visible)
{
QWidget::setVisible(visible);
if (visible) {
showDotGraph(m_nextDotItem);
}
}
void CallGraphTab::showDotGraph()
{
if (!m_dotGenerator || !m_graphViewerPart || !isVisible()) {
return;
}
kDebug() << "show dot graph in output file" << m_dotGenerator->outputFile();
if (!m_dotGenerator->outputFile().isEmpty() && m_graphViewerPart->url() != KUrl(m_dotGenerator->outputFile())) {
m_graphViewerPart->openUrl(KUrl(m_dotGenerator->outputFile()));
}
}
void CallGraphTab::slotGraphLoaded()
{
Q_ASSERT(m_graphViewer);
if (!m_dotGenerator) {
return;
}
m_graphViewer->setZoomFactor(0.75);
m_graphViewer->setPannerPosition(KGraphViewer::KGraphViewerInterface::BottomRight);
m_graphViewer->setPannerEnabled(true);
m_graphViewer->centerOnNode(m_dotGenerator->mostCostIntensiveGraphvizId());
}
void CallGraphTab::zoomIn()
{
m_graphViewer->zoomIn();
}
void CallGraphTab::zoomOut()
{
m_graphViewer->zoomOut();
}
void CallGraphTab::selectModelItem(const ModelItem& item)
{
showDotGraph(item);
}
#include "callgraphtab.moc"

View file

@ -0,0 +1,84 @@
/*
This file is part of Massif Visualizer
Copyright 2014 Milian Wolff <mail@milianw.de>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License or (at your option) version 3 or any later version
accepted by the membership of KDE e.V. (or its successor approved
by the membership of KDE e.V.), which shall act as a proxy
defined in Section 14 of version 3 of the license.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CALLGRAPHTAB_H
#define CALLGRAPHTAB_H
#include "documenttabinterface.h"
#include <visualizer/modelitem.h>
class KAction;
namespace KGraphViewer {
class KGraphViewerInterface;
}
namespace Massif {
class DotGraphGenerator;
}
namespace KParts {
class ReadOnlyPart;
}
class CallGraphTab : public DocumentTabInterface
{
Q_OBJECT
public:
CallGraphTab(const Massif::FileData* data, KParts::ReadOnlyPart* graphViewerPart,
KXMLGUIClient* guiParent, QWidget* parent = 0);
~CallGraphTab();
void showDotGraph(const Massif::ModelItem& item);
virtual void settingsChanged();
virtual void selectModelItem(const Massif::ModelItem& item);
virtual void setVisible(bool visible);
public slots:
void showDotGraph();
private slots:
void slotGraphLoaded();
void zoomIn();
void zoomOut();
void focusExpensiveGraphNode();
private:
void setupActions();
private:
KParts::ReadOnlyPart* m_graphViewerPart;
KGraphViewer::KGraphViewerInterface* m_graphViewer;
QScopedPointer<Massif::DotGraphGenerator> m_dotGenerator;
Massif::ModelItem m_lastDotItem;
Massif::ModelItem m_nextDotItem;
KAction* m_zoomIn;
KAction* m_zoomOut;
KAction* m_focusExpensive;
};
#endif // CALLGRAPHTAB_H

View file

@ -0,0 +1,19 @@
<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
<kpartgui name="callgraphtab" version="1">
<MenuBar>
<Menu name="view">
<Action name="zoomIn"/>
<Action name="zoomOut"/>
<Action name="focusExpensive"/>
</Menu>
</MenuBar>
<ToolBar name="callgraphToolBar">
<text>CallGraph Toolbar</text>
<Action name="zoomIn"/>
<Action name="zoomOut"/>
<Action name="focusExpensive"/>
</ToolBar>
</kpartgui>

View file

@ -0,0 +1,620 @@
/*
This file is part of Massif Visualizer
Copyright 2014 Milian Wolff <mail@milianw.de>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License or (at your option) version 3 or any later version
accepted by the membership of KDE e.V. (or its successor approved
by the membership of KDE e.V.), which shall act as a proxy
defined in Section 14 of version 3 of the license.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "charttab.h"
#include "KDChartChart"
#include "KDChartGridAttributes"
#include "KDChartHeaderFooter"
#include "KDChartCartesianCoordinatePlane"
#include "KDChartPlotter"
#include "KDChartLegend"
#include "KDChartDataValueAttributes"
#include "KDChartBackgroundAttributes"
#include <KDChartFrameAttributes.h>
#include "visualizer/totalcostmodel.h"
#include "visualizer/detailedcostmodel.h"
#include "visualizer/datatreemodel.h"
#include "visualizer/filtereddatatreemodel.h"
#include "massifdata/util.h"
#include "massifdata/snapshotitem.h"
#include "massifdata/treeleafitem.h"
#include "massifdata/filedata.h"
#include "massif-visualizer-settings.h"
#include <QVBoxLayout>
#include <QPrinter>
#include <QPrintPreviewDialog>
#include <QLabel>
#include <QMenu>
#include <QApplication>
#include <QDesktopWidget>
#include <QSvgGenerator>
#include <KColorScheme>
#include <KLocalizedString>
#include <KStandardAction>
#include <KActionCollection>
#include <KAction>
#include <KFileDialog>
#include <KMessageBox>
#include <KLocale>
using namespace KDChart;
using namespace Massif;
namespace {
class TimeAxis : public CartesianAxis
{
Q_OBJECT
public:
explicit TimeAxis(AbstractCartesianDiagram* diagram = 0)
: CartesianAxis(diagram)
{}
virtual const QString customizedLabel(const QString& label) const
{
// squeeze large numbers here
// TODO: when the unit is 'b' also use prettyCost() here
return QString::number(label.toDouble());
}
};
class SizeAxis : public CartesianAxis
{
Q_OBJECT
public:
explicit SizeAxis(AbstractCartesianDiagram* diagram = 0)
: CartesianAxis(diagram)
{}
virtual const QString customizedLabel(const QString& label) const
{
// TODO: change distance between labels to 1024 and simply use prettyCost() here
return KGlobal::locale()->formatByteSize(label.toDouble(), 1, KLocale::MetricBinaryDialect);
}
};
void markPeak(Plotter* p, const QModelIndex& peak, quint64 cost, const KColorScheme& scheme)
{
QBrush brush = p->model()->data(peak, DatasetBrushRole).value<QBrush>();
QColor outline = brush.color();
QColor foreground = scheme.foreground().color();
QBrush background = scheme.background();
DataValueAttributes dataAttributes = p->dataValueAttributes(peak);
dataAttributes.setDataLabel(prettyCost(cost));
dataAttributes.setVisible(true);
dataAttributes.setShowRepetitiveDataLabels(true);
dataAttributes.setShowOverlappingDataLabels(false);
FrameAttributes frameAttrs = dataAttributes.frameAttributes();
QPen framePen(outline);
framePen.setWidth(2);
frameAttrs.setPen(framePen);
frameAttrs.setVisible(true);
dataAttributes.setFrameAttributes(frameAttrs);
MarkerAttributes a = dataAttributes.markerAttributes();
a.setMarkerSize(QSizeF(7, 7));
a.setPen(outline);
a.setMarkerStyle(KDChart::MarkerAttributes::MarkerDiamond);
a.setVisible(true);
dataAttributes.setMarkerAttributes(a);
TextAttributes txtAttrs = dataAttributes.textAttributes();
txtAttrs.setPen(foreground);
txtAttrs.setFontSize(Measure(12));
dataAttributes.setTextAttributes(txtAttrs);
BackgroundAttributes bkgAtt = dataAttributes.backgroundAttributes();
bkgAtt.setBrush(background);
bkgAtt.setVisible(true);
dataAttributes.setBackgroundAttributes(bkgAtt);
p->setDataValueAttributes(peak, dataAttributes);
}
}
ChartTab::ChartTab(const FileData* data,
KXMLGUIClient* guiParent, QWidget* parent)
: DocumentTabInterface(data, guiParent, parent)
, m_chart(new Chart(this))
, m_header(new QLabel(this))
, m_totalDiagram(0)
, m_totalCostModel(new TotalCostModel(m_chart))
, m_detailedDiagram(0)
, m_detailedCostModel(new DetailedCostModel(m_chart))
, m_legend(new Legend(m_chart))
, m_print(0)
, m_saveAs(0)
, m_toggleTotal(0)
, m_toggleDetailed(0)
, m_hideFunction(0)
, m_hideOtherFunctions(0)
, m_box(new QSpinBox(this))
, m_settingSelection(false)
{
setXMLFile("charttabui.rc", true);
setupActions();
setLayout(new QVBoxLayout(this));
setupGui();
}
ChartTab::~ChartTab()
{
}
void ChartTab::setupActions()
{
m_print = KStandardAction::print(this, SLOT(showPrintPreviewDialog()), actionCollection());
actionCollection()->addAction("file_print", m_print);
m_saveAs = KStandardAction::saveAs(this, SLOT(saveCurrentDocument()), actionCollection());
actionCollection()->addAction("file_save_as", m_saveAs);
m_toggleTotal = new KAction(KIcon("office-chart-area"), i18n("Toggle total cost graph"), actionCollection());
m_toggleTotal->setCheckable(true);
m_toggleTotal->setChecked(true);
connect(m_toggleTotal, SIGNAL(toggled(bool)), SLOT(showTotalGraph(bool)));
actionCollection()->addAction("toggle_total", m_toggleTotal);
m_toggleDetailed = new KAction(KIcon("office-chart-area-stacked"), i18n("Toggle detailed cost graph"), actionCollection());
m_toggleDetailed->setCheckable(true);
m_toggleDetailed->setChecked(true);
connect(m_toggleDetailed, SIGNAL(toggled(bool)), SLOT(showDetailedGraph(bool)));
actionCollection()->addAction("toggle_detailed", m_toggleDetailed);
KAction* stackNumAction = actionCollection()->addAction("stackNum");
stackNumAction->setText(i18n("Stacked diagrams"));
QWidget *stackNumWidget = new QWidget;
QHBoxLayout* stackNumLayout = new QHBoxLayout;
stackNumLayout->addWidget(new QLabel(i18n("Stacked diagrams:")));
m_box->setMinimum(0);
m_box->setMaximum(50);
m_box->setValue(10);
connect(m_box, SIGNAL(valueChanged(int)), this, SLOT(setStackNum(int)));
stackNumLayout->addWidget(m_box);
stackNumWidget->setLayout(stackNumLayout);
stackNumAction->setDefaultWidget(stackNumWidget);
m_hideFunction = new KAction(i18n("hide function"), this);
connect(m_hideFunction, SIGNAL(triggered()),
this, SLOT(slotHideFunction()));
m_hideOtherFunctions = new KAction(i18n("hide other functions"), this);
connect(m_hideOtherFunctions, SIGNAL(triggered()),
this, SLOT(slotHideOtherFunctions()));
}
void ChartTab::setupGui()
{
layout()->addWidget(m_header);
layout()->addWidget(m_chart);
// HACK: otherwise the legend becomes _really_ large and might even crash X...
// to visualize the issue, try: m_chart->setMaximumSize(QSize(10000, 10000));
m_chart->setMaximumSize(qApp->desktop()->size());
// for axis labels to fit
m_chart->setGlobalLeadingRight(10);
m_chart->setGlobalLeadingLeft(10);
m_chart->setGlobalLeadingTop(20);
m_chart->setContextMenuPolicy(Qt::CustomContextMenu);
updateLegendPosition();
m_legend->setTitleText(QString());
m_legend->setSortOrder(Qt::DescendingOrder);
m_chart->addLegend(m_legend);
//NOTE: this has to be set _after_ the legend was added to the chart...
updateLegendFont();
m_legend->setTextAlignment(Qt::AlignLeft);
m_legend->hide();
connect(m_chart, SIGNAL(customContextMenuRequested(QPoint)),
this, SLOT(chartContextMenuRequested(QPoint)));
//BEGIN KDChart
KColorScheme scheme(QPalette::Active, KColorScheme::Window);
QPen foreground(scheme.foreground().color());
//Begin Legend
BackgroundAttributes bkgAtt = m_legend->backgroundAttributes();
QColor background = scheme.background(KColorScheme::AlternateBackground).color();
background.setAlpha(200);
bkgAtt.setBrush(QBrush(background));
bkgAtt.setVisible(true);
m_legend->setBackgroundAttributes(bkgAtt);
TextAttributes txtAttrs = m_legend->textAttributes();
txtAttrs.setPen(foreground);
m_legend->setTextAttributes(txtAttrs);
m_header->setAlignment(Qt::AlignCenter);
updateHeader();
//BEGIN TotalDiagram
m_totalDiagram = new Plotter(this);
m_totalDiagram->setAntiAliasing(true);
CartesianAxis* bottomAxis = new TimeAxis(m_totalDiagram);
TextAttributes axisTextAttributes = bottomAxis->textAttributes();
axisTextAttributes.setPen(foreground);
axisTextAttributes.setFontSize(Measure(10));
bottomAxis->setTextAttributes(axisTextAttributes);
TextAttributes axisTitleTextAttributes = bottomAxis->titleTextAttributes();
axisTitleTextAttributes.setPen(foreground);
axisTitleTextAttributes.setFontSize(Measure(12));
bottomAxis->setTitleTextAttributes(axisTitleTextAttributes);
bottomAxis->setTitleText(i18n("time in %1", m_data->timeUnit()));
bottomAxis->setPosition ( CartesianAxis::Bottom );
m_totalDiagram->addAxis(bottomAxis);
CartesianAxis* rightAxis = new SizeAxis(m_totalDiagram);
rightAxis->setTextAttributes(axisTextAttributes);
rightAxis->setTitleTextAttributes(axisTitleTextAttributes);
rightAxis->setTitleText(i18n("memory heap size"));
rightAxis->setPosition ( CartesianAxis::Right );
m_totalDiagram->addAxis(rightAxis);
m_totalCostModel->setSource(m_data);
m_totalDiagram->setModel(m_totalCostModel);
CartesianCoordinatePlane* coordinatePlane = dynamic_cast<CartesianCoordinatePlane*>(m_chart->coordinatePlane());
Q_ASSERT(coordinatePlane);
coordinatePlane->addDiagram(m_totalDiagram);
GridAttributes gridAttributes = coordinatePlane->gridAttributes(Qt::Horizontal);
gridAttributes.setAdjustBoundsToGrid(false, false);
coordinatePlane->setGridAttributes(Qt::Horizontal, gridAttributes);
m_legend->addDiagram(m_totalDiagram);
m_detailedDiagram = new Plotter;
m_detailedDiagram->setAntiAliasing(true);
m_detailedDiagram->setType(KDChart::Plotter::Stacked);
m_detailedCostModel->setSource(m_data);
m_detailedDiagram->setModel(m_detailedCostModel);
updatePeaks();
m_chart->coordinatePlane()->addDiagram(m_detailedDiagram);
m_legend->addDiagram(m_detailedDiagram);
m_legend->show();
m_box->setValue(m_detailedCostModel->maximumDatasetCount());
connect(m_totalDiagram, SIGNAL(clicked(QModelIndex)),
this, SLOT(totalItemClicked(QModelIndex)));
connect(m_detailedDiagram, SIGNAL(clicked(QModelIndex)),
this, SLOT(detailedItemClicked(QModelIndex)));
}
void ChartTab::settingsChanged()
{
updateHeader();
updatePeaks();
updateLegendPosition();
updateLegendFont();
}
void ChartTab::setDetailedDiagramHidden(bool hidden)
{
m_detailedDiagram->setHidden(hidden);
}
void ChartTab::setDetailedDiagramVisible(bool visible)
{
m_detailedDiagram->setVisible(visible);
}
void ChartTab::setTotalDiagramHidden(bool hidden)
{
m_totalDiagram->setHidden(hidden);
}
void ChartTab::setTotalDiagramVisible(bool visible)
{
m_totalDiagram->setVisible(visible);
}
void ChartTab::updatePeaks()
{
KColorScheme scheme(QPalette::Active, KColorScheme::Window);
if (m_data->peak()) {
const QModelIndex peak = m_totalCostModel->peak();
Q_ASSERT(peak.isValid());
markPeak(m_totalDiagram, peak, m_data->peak()->cost(), scheme);
}
updateDetailedPeaks();
}
void ChartTab::updateLegendPosition()
{
KDChartEnums::PositionValue pos;
switch (Settings::self()->legendPosition()) {
case Settings::EnumLegendPosition::North:
pos = KDChartEnums::PositionNorth;
break;
case Settings::EnumLegendPosition::South:
pos = KDChartEnums::PositionSouth;
break;
case Settings::EnumLegendPosition::East:
pos = KDChartEnums::PositionEast;
break;
case Settings::EnumLegendPosition::West:
pos = KDChartEnums::PositionWest;
break;
case Settings::EnumLegendPosition::Floating:
pos = KDChartEnums::PositionFloating;
break;
default:
pos = KDChartEnums::PositionFloating;
kDebug() << "invalid legend position";
}
m_legend->setPosition(Position(pos));
Qt::Alignment align;
switch (Settings::self()->legendAlignment()) {
case Settings::EnumLegendAlignment::Left:
align = Qt::AlignLeft;
break;
case Settings::EnumLegendAlignment::Center:
align = Qt::AlignHCenter | Qt::AlignVCenter;
break;
case Settings::EnumLegendAlignment::Right:
align = Qt::AlignRight;
break;
case Settings::EnumLegendAlignment::Top:
align = Qt::AlignTop;
break;
case Settings::EnumLegendAlignment::Bottom:
align = Qt::AlignBottom;
break;
default:
align = Qt::AlignHCenter | Qt::AlignVCenter;
kDebug() << "invalid legend alignmemnt";
}
// do something reasonable since top,bottom have no effect
// when used with north,south, same for left,right used with
// east,west
if ((((pos == KDChartEnums::PositionNorth) || (pos == KDChartEnums::PositionSouth))
&& ((align == Qt::AlignTop) || (align == Qt::AlignBottom)))
|| (((pos == KDChartEnums::PositionEast) || (pos == KDChartEnums::PositionWest))
&& ((align == Qt::AlignLeft) || (align == Qt::AlignRight)))) {
align = Qt::AlignHCenter | Qt::AlignVCenter;
}
m_legend->setAlignment(align);
}
void ChartTab::updateLegendFont()
{
TextAttributes att = m_legend->textAttributes();
att.setAutoShrink(true);
att.setFontSize(Measure(Settings::self()->legendFontSize()));
QFont font("monospace");
font.setStyleHint(QFont::TypeWriter);
att.setFont(font);
m_legend->setTextAttributes(att);
}
void ChartTab::updateDetailedPeaks()
{
KColorScheme scheme(QPalette::Active, KColorScheme::Window);
const DetailedCostModel::Peaks& peaks = m_detailedCostModel->peaks();
DetailedCostModel::Peaks::const_iterator it = peaks.constBegin();
while (it != peaks.constEnd()) {
const QModelIndex peak = it.key();
Q_ASSERT(peak.isValid());
markPeak(m_detailedDiagram, peak, it.value()->cost(), scheme);
++it;
}
}
void ChartTab::updateHeader()
{
const QString app = m_data->cmd().split(' ', QString::SkipEmptyParts).first();
m_header->setText(QString("<b>%1</b><br /><i>%2</i>")
.arg(i18n("Memory consumption of %1", app))
.arg(i18n("Peak of %1 at snapshot #%2", prettyCost(m_data->peak()->cost()), m_data->peak()->number()))
);
m_header->setToolTip(i18n("Command: %1\nValgrind Options: %2", m_data->cmd(), m_data->description()));
}
void ChartTab::saveCurrentDocument()
{
QString saveFilename = KFileDialog::getSaveFileName(KUrl("kfiledialog:///massif-visualizer"),
QString("image/png image/jpeg image/tiff image/svg+xml"),
this, i18n("Save Current Visualization"), KFileDialog::ConfirmOverwrite);
if (!saveFilename.isEmpty()) {
// TODO: implement a dialog to expose more options to the user.
// for example we could expose dpi, size, and various format
// dependent options such as compressions settings.
// Vector graphic format
if (QFileInfo(saveFilename).suffix().compare(QLatin1String("svg")) == 0) {
QSvgGenerator generator;
generator.setFileName(saveFilename);
generator.setSize(m_chart->size());
generator.setViewBox(m_chart->rect());
QPainter painter;
painter.begin(&generator);
m_chart->paint(&painter, m_chart->rect());
painter.end();
}
// Other format
else if (!QPixmap::grabWidget(m_chart).save(saveFilename)) {
KMessageBox::sorry(this, QString(
i18n("Error, failed to save the image to %1.")
).arg(saveFilename));
}
}
}
void ChartTab::showPrintPreviewDialog()
{
QPrinter printer;
QPrintPreviewDialog *ppd = new QPrintPreviewDialog(&printer, this);
ppd->setAttribute(Qt::WA_DeleteOnClose);
connect(ppd, SIGNAL(paintRequested(QPrinter*)), SLOT(printFile(QPrinter*)));
ppd->setWindowTitle(i18n("Massif Chart Print Preview"));
ppd->resize(800, 600);
ppd->exec();
}
void ChartTab::printFile(QPrinter *printer)
{
QPainter painter;
painter.begin(printer);
m_chart->paint(&painter, printer->pageRect());
painter.end();
}
void ChartTab::showDetailedGraph(bool show)
{
m_detailedDiagram->setHidden(!show);
m_toggleDetailed->setChecked(show);
m_chart->update();
}
void ChartTab::showTotalGraph(bool show)
{
m_totalDiagram->setHidden(!show);
m_toggleTotal->setChecked(show);
m_chart->update();
}
void ChartTab::slotHideFunction()
{
m_detailedCostModel->hideFunction(m_hideFunction->data().value<const TreeLeafItem*>());
}
void ChartTab::slotHideOtherFunctions()
{
m_detailedCostModel->hideOtherFunctions(m_hideOtherFunctions->data().value<const TreeLeafItem*>());
}
void ChartTab::chartContextMenuRequested(const QPoint& pos)
{
const QPoint dPos = m_detailedDiagram->mapFromGlobal(m_chart->mapToGlobal(pos));
const QModelIndex idx = m_detailedDiagram->indexAt(dPos);
if (!idx.isValid()) {
return;
}
// hack: the ToolTip will only be queried by KDChart and that one uses the
// left index, but we want it to query the right one
const QModelIndex _idx = m_detailedCostModel->index(idx.row() + 1, idx.column(), idx.parent());
ModelItem item = m_detailedCostModel->itemForIndex(_idx);
if (!item.first) {
return;
}
QMenu menu;
m_hideFunction->setData(QVariant::fromValue(item.first));
menu.addAction(m_hideFunction);
m_hideOtherFunctions->setData(QVariant::fromValue(item.first));
menu.addAction(m_hideOtherFunctions);
menu.addSeparator();
emit contextMenuRequested(item, &menu);
menu.exec(m_detailedDiagram->mapToGlobal(dPos));
}
void ChartTab::setStackNum(int num)
{
m_detailedCostModel->setMaximumDatasetCount(num);
updatePeaks();
}
void ChartTab::detailedItemClicked(const QModelIndex& idx)
{
m_detailedCostModel->setSelection(idx);
m_totalCostModel->setSelection(QModelIndex());
m_chart->update();
// hack: the ToolTip will only be queried by KDChart and that one uses the
// left index, but we want it to query the right one
m_settingSelection = true;
const QModelIndex _idx = m_detailedCostModel->index(idx.row() + 1, idx.column(), idx.parent());
emit modelItemSelected(m_detailedCostModel->itemForIndex(_idx));
m_settingSelection = false;
}
void ChartTab::totalItemClicked(const QModelIndex& idx)
{
const QModelIndex _idx = m_totalCostModel->index(idx.row() + 1, idx.column(), idx.parent());
m_totalCostModel->setSelection(_idx);
m_detailedCostModel->setSelection(QModelIndex());
m_chart->update();
m_settingSelection = true;
emit modelItemSelected(m_totalCostModel->itemForIndex(_idx));
m_settingSelection = false;
}
void ChartTab::selectModelItem(const ModelItem& item)
{
if (m_settingSelection) {
return;
}
if (item.first) {
m_detailedCostModel->setSelection(m_detailedCostModel->indexForItem(item));
m_totalCostModel->setSelection(QModelIndex());
} else {
m_totalCostModel->setSelection(m_totalCostModel->indexForItem(item));
m_detailedCostModel->setSelection(QModelIndex());
}
m_chart->update();
}
#include "charttab.moc"
#include "moc_charttab.cpp"

View file

@ -0,0 +1,123 @@
/*
This file is part of Massif Visualizer
Copyright 2014 Milian Wolff <mail@milianw.de>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License or (at your option) version 3 or any later version
accepted by the membership of KDE e.V. (or its successor approved
by the membership of KDE e.V.), which shall act as a proxy
defined in Section 14 of version 3 of the license.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CHARTTAB_H
#define CHARTTAB_H
#include "documenttabinterface.h"
#include <QSpinBox>
class QLabel;
class QModelIndex;
class KAction;
namespace KDChart {
class Chart;
class HeaderFooter;
class Plotter;
class CartesianAxis;
class Legend;
class BarDiagram;
}
namespace Massif {
class FileData;
class TotalCostModel;
class DetailedCostModel;
class DataTreeModel;
class FilteredDataTreeModel;
}
class ChartTab : public DocumentTabInterface
{
Q_OBJECT
public:
ChartTab(const Massif::FileData* data,
KXMLGUIClient* guiParent, QWidget* parent = 0);
~ChartTab();
virtual void settingsChanged();
virtual void selectModelItem(const Massif::ModelItem& item);
private:
void setupGui();
void setupActions();
void updateHeader();
void updatePeaks();
void updateLegendPosition();
void updateLegendFont();
void updateDetailedPeaks();
private slots:
void setDetailedDiagramHidden(bool hidden);
void setDetailedDiagramVisible(bool visible);
void setTotalDiagramHidden(bool hidden);
void setTotalDiagramVisible(bool visible);
void saveCurrentDocument();
void showPrintPreviewDialog();
void showDetailedGraph(bool show);
void showTotalGraph(bool show);
void setStackNum(int num);
void chartContextMenuRequested(const QPoint &pos);
void slotHideFunction();
void slotHideOtherFunctions();
void detailedItemClicked(const QModelIndex& item);
void totalItemClicked(const QModelIndex& item);
void printFile(QPrinter *printer);
private:
KDChart::Chart* m_chart;
QLabel* m_header;
KDChart::Plotter* m_totalDiagram;
Massif::TotalCostModel* m_totalCostModel;
KDChart::Plotter* m_detailedDiagram;
Massif::DetailedCostModel* m_detailedCostModel;
KDChart::Legend* m_legend;
KAction* m_print;
KAction* m_saveAs;
KAction* m_toggleTotal;
KAction* m_toggleDetailed;
KAction* m_hideFunction;
KAction* m_hideOtherFunctions;
QSpinBox* m_box;
bool m_settingSelection;
};
#endif // CHARTTAB_H

View file

@ -0,0 +1,23 @@
<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
<kpartgui name="charttab" version="1">
<MenuBar>
<Menu name="file">
<Action name="file_save_as" group="file_saveas_merge"/>
<Action name="file_print" group="file_saveas_merge"/>
</Menu>
<Menu name="view">
<Action name="toggle_total"/>
<Action name="toggle_detailed"/>
</Menu>
</MenuBar>
<ToolBar name="chartToolBar">
<text>Chart Toolbar</text>
<Action name="toggle_total"/>
<Action name="toggle_detailed"/>
<Action name="stackNum"/>
</ToolBar>
</kpartgui>

View file

@ -0,0 +1,129 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Config</class>
<widget class="QWidget" name="Config">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>283</width>
<height>216</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="costLabel">
<property name="text">
<string>Cost Precision:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="kcfg_PrettyCostPrecision"/>
</item>
<item row="2" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Legend</string>
</property>
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="0" column="0">
<widget class="QLabel" name="legendPositionLabel">
<property name="text">
<string>Position:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="kcfg_LegendPosition">
<item>
<property name="text">
<string>North</string>
</property>
</item>
<item>
<property name="text">
<string>East</string>
</property>
</item>
<item>
<property name="text">
<string>South</string>
</property>
</item>
<item>
<property name="text">
<string>West</string>
</property>
</item>
<item>
<property name="text">
<string>Floating</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="legendAlignmentLabel">
<property name="text">
<string>Alignment:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="kcfg_LegendAlignment">
<item>
<property name="text">
<string>Left</string>
</property>
</item>
<item>
<property name="text">
<string>Center</string>
</property>
</item>
<item>
<property name="text">
<string>Right</string>
</property>
</item>
<item>
<property name="text">
<string>Top</string>
</property>
</item>
<item>
<property name="text">
<string>Bottom</string>
</property>
</item>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="legendFontSizeLabel">
<property name="text">
<string>Font Size:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="kcfg_LegendFontSize"/>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="kcfg_ShortenTemplates">
<property name="text">
<string>Shorten Templates</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View file

@ -0,0 +1,54 @@
/*
This file is part of Massif Visualizer
Copyright 2010 Milian Wolff <mail@milianw.de>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License or (at your option) version 3 or any later version
accepted by the membership of KDE e.V. (or its successor approved
by the membership of KDE e.V.), which shall act as a proxy
defined in Section 14 of version 3 of the license.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "configdialog.h"
#include "massif-visualizer-settings.h"
#include "ui_config.h"
#include <KLocale>
using namespace Massif;
ConfigDialog::ConfigDialog(QWidget* parent)
: KConfigDialog(parent, "settings", Settings::self())
, m_ui(new Ui::Config)
{
setAttribute(Qt::WA_DeleteOnClose, true);
QWidget* settingsPage = new QWidget(this);
m_ui->setupUi(settingsPage);
addPage(settingsPage, Settings::self(), i18n("Settings"));
setFaceType(KPageDialog::Plain);
}
ConfigDialog::~ConfigDialog()
{
}
bool ConfigDialog::isShown()
{
return KConfigDialog::showDialog("settings");
}
#include "configdialog.moc"

View file

@ -0,0 +1,53 @@
/*
This file is part of Massif Visualizer
Copyright 2010 Milian Wolff <mail@milianw.de>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License or (at your option) version 3 or any later version
accepted by the membership of KDE e.V. (or its successor approved
by the membership of KDE e.V.), which shall act as a proxy
defined in Section 14 of version 3 of the license.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CONFIGDIALOG_H
#define CONFIGDIALOG_H
#include <KConfigDialog>
namespace Ui {
class Config;
}
namespace Massif {
/**
* Config dialog, gets deleted when closed.
*/
class ConfigDialog : public KConfigDialog
{
Q_OBJECT
public:
ConfigDialog(QWidget* parent);
virtual ~ConfigDialog();
static bool isShown();
private:
QScopedPointer<Ui::Config> m_ui;
};
}
#endif // CONFIGDIALOG_H

View file

@ -0,0 +1,41 @@
/*
This file is part of Massif Visualizer
Copyright 2014 Milian Wolff <mail@milianw.de>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License or (at your option) version 3 or any later version
accepted by the membership of KDE e.V. (or its successor approved
by the membership of KDE e.V.), which shall act as a proxy
defined in Section 14 of version 3 of the license.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "documenttabinterface.h"
using namespace Massif;
DocumentTabInterface::DocumentTabInterface(const FileData* data,
KXMLGUIClient* guiParent, QWidget* parent)
: QWidget(parent)
, KXMLGUIClient(guiParent)
, m_data(data)
{
}
DocumentTabInterface::~DocumentTabInterface()
{
}
#include "documenttabinterface.moc"

View file

@ -0,0 +1,59 @@
/*
This file is part of Massif Visualizer
Copyright 2014 Milian Wolff <mail@milianw.de>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License or (at your option) version 3 or any later version
accepted by the membership of KDE e.V. (or its successor approved
by the membership of KDE e.V.), which shall act as a proxy
defined in Section 14 of version 3 of the license.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef DOCUMENTTABINTERFACE_H
#define DOCUMENTTABINTERFACE_H
#include <QWidget>
#include <KXMLGUIClient>
#include "visualizer/modelitem.h"
class QMenu;
namespace Massif {
class FileData;
}
class DocumentTabInterface : public QWidget, public KXMLGUIClient
{
Q_OBJECT
public:
explicit DocumentTabInterface(const Massif::FileData* data,
KXMLGUIClient* guiParent, QWidget* parent = 0);
virtual ~DocumentTabInterface();
virtual void settingsChanged() = 0;
public slots:
virtual void selectModelItem(const Massif::ModelItem& item) = 0;
signals:
void modelItemSelected(const Massif::ModelItem& item);
void contextMenuRequested(const Massif::ModelItem& item, QMenu* menu);
protected:
const Massif::FileData* const m_data;
};
#endif // DOCUMENTTABINTERFACE_H

View file

@ -0,0 +1,306 @@
/*
This file is part of Massif Visualizer
Copyright 2010 Milian Wolff <mail@milianw.de>
Copyright 2013 Arnold Dumas <contact@arnolddumas.fr>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License or (at your option) version 3 or any later version
accepted by the membership of KDE e.V. (or its successor approved
by the membership of KDE e.V.), which shall act as a proxy
defined in Section 14 of version 3 of the license.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "documentwidget.h"
#include <QApplication>
#include "massifdata/filedata.h"
#include "massifdata/parser.h"
#include "massifdata/parseworker.h"
#include "massifdata/snapshotitem.h"
#include "massifdata/treeleafitem.h"
#include "massifdata/util.h"
#include <KStandardAction>
#include <KColorScheme>
#include <KLocalizedString>
// forward include not available until later KDE versions...
#include <kmessagewidget.h>
#include <KIcon>
#include <KDebug>
#include <KXMLGUIFactory>
#include <QLabel>
#include <QProgressBar>
#include <QStackedWidget>
#include <QTabWidget>
#include <QToolButton>
#include <QVBoxLayout>
#include "charttab.h"
#include "allocatorstab.h"
#ifdef HAVE_KGRAPHVIEWER
#include "callgraphtab.h"
#include <KPluginLoader>
#include <KPluginFactory>
#include <KParts/ReadOnlyPart>
#endif
using namespace Massif;
DocumentWidget::DocumentWidget(const KUrl& file, const QStringList& customAllocators,
KXMLGUIClient* guiParent, QWidget* parent)
: QWidget(parent)
, KXMLGUIClient(guiParent)
, m_data(0)
, m_parseWorker(new ParseWorker)
, m_file(file)
, m_currentTab(0)
, m_stackedWidget(new QStackedWidget(this))
, m_tabs(new QTabWidget(m_stackedWidget))
, m_errorMessage(0)
, m_loadingMessage(0)
, m_loadingProgressBar(0)
, m_stopParserButton(0)
, m_isLoaded(false)
{
connect(m_parseWorker, SIGNAL(finished(KUrl, Massif::FileData*)),
this, SLOT(parserFinished(KUrl, Massif::FileData*)));
connect(m_parseWorker, SIGNAL(error(QString, QString)),
this, SLOT(showError(QString, QString)));
connect(m_parseWorker, SIGNAL(progressRange(int, int)),
this, SLOT(setRange(int,int)));
connect(m_parseWorker, SIGNAL(progress(int)),
this, SLOT(setProgress(int)));
// Create dedicated thread for this document.
// TODO: use ThreadWeaver
QThread* thread = new QThread(this);
thread->start();
m_parseWorker->moveToThread(thread);
m_parseWorker->parse(file, customAllocators);
setXMLFile("documentwidgetui.rc", true);
// Set m_stackedWidget as the main widget.
setLayout(new QVBoxLayout(this));
layout()->addWidget(m_stackedWidget);
m_tabs->setTabPosition(QTabWidget::South);
m_stackedWidget->addWidget(m_tabs);
// Second widget : loadingPage
QWidget* loadingPage = new QWidget(m_stackedWidget);
QVBoxLayout* verticalLayout = new QVBoxLayout(loadingPage);
QSpacerItem* upperSpacerItem = new QSpacerItem(20, 247, QSizePolicy::Minimum, QSizePolicy::Expanding);
verticalLayout->addItem(upperSpacerItem);
m_loadingMessage = new QLabel(loadingPage);
m_loadingMessage->setText(i18n("loading file <i>%1</i>...", file.pathOrUrl()));
m_loadingMessage->setAlignment(Qt::AlignCenter);
verticalLayout->addWidget(m_loadingMessage);
m_loadingProgressBar = new QProgressBar(loadingPage);
m_loadingProgressBar->setValue(24);
m_loadingProgressBar->setRange(0, 0);
verticalLayout->addWidget(m_loadingProgressBar);
QWidget* stopParserWidget = new QWidget(loadingPage);
stopParserWidget->setLayoutDirection(Qt::LeftToRight);
QHBoxLayout* stopParserWidgetLayout = new QHBoxLayout(stopParserWidget);
m_stopParserButton = new QToolButton(stopParserWidget);
m_stopParserButton->setObjectName(QString::fromUtf8("stopParsing"));
m_stopParserButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
m_stopParserButton->setIcon(KIcon("process-stop"));
m_stopParserButton->setIconSize(QSize(48, 48));
connect(m_stopParserButton, SIGNAL(clicked()),
this, SIGNAL(requestClose()));
stopParserWidgetLayout->addWidget(m_stopParserButton);
verticalLayout->addWidget(stopParserWidget);
QSpacerItem* bottomSpacerItem = new QSpacerItem(20, 230, QSizePolicy::Minimum, QSizePolicy::Expanding);
verticalLayout->addItem(bottomSpacerItem);
m_stackedWidget->addWidget(loadingPage);
// By default we show the loadingPage.
m_stackedWidget->setCurrentIndex(1);
}
DocumentWidget::~DocumentWidget()
{
stopParser();
if (m_data) {
delete m_data;
m_data = 0;
m_file.clear();
}
}
FileData* DocumentWidget::data() const
{
return m_data;
}
KUrl DocumentWidget::file() const
{
return m_file;
}
bool DocumentWidget::isLoaded() const
{
return m_isLoaded;
}
void DocumentWidget::settingsChanged()
{
for (int i = 0; i < m_tabs->count(); ++i) {
static_cast<DocumentTabInterface*>(m_tabs->widget(i))->settingsChanged();
}
}
void DocumentWidget::parserFinished(const KUrl& file, FileData* data)
{
Q_ASSERT(data->peak());
kDebug() << "loaded massif file:" << file;
qDebug() << "description:" << data->description();
qDebug() << "command:" << data->cmd();
qDebug() << "time unit:" << data->timeUnit();
qDebug() << "snapshots:" << data->snapshots().size();
qDebug() << "peak: snapshot #" << data->peak()->number() << "after" << QString("%1%2").arg(data->peak()->time()).arg(data->timeUnit());
qDebug() << "peak cost:" << prettyCost(data->peak()->memHeap()) << " heap"
<< prettyCost(data->peak()->memHeapExtra()) << " heap extra"
<< prettyCost(data->peak()->memStacks()) << " stacks";
m_data = data;
m_file = file;
m_tabs->addTab(new ChartTab(m_data, this, this), KIcon("office-chart-area-stacked"),
i18n("Memory Chart"));
#ifdef HAVE_KGRAPHVIEWER
static KPluginFactory *factory = KPluginLoader("kgraphviewerpart").factory();
if (factory) {
KParts::ReadOnlyPart* part = factory->create<KParts::ReadOnlyPart>("kgraphviewerpart", this);
if (part) {
m_tabs->addTab(new CallGraphTab(m_data, part, this, this), KIcon("kgraphviewer"),
i18n("Callgraph"));
}
}
#endif
m_tabs->addTab(new AllocatorsTab(m_data, this, this), KIcon("view-list-text"),
i18n("Allocators"));
for (int i = 0; i < m_tabs->count(); ++i) {
DocumentTabInterface* tab = static_cast<DocumentTabInterface*>(m_tabs->widget(i));
connect(tab, SIGNAL(modelItemSelected(Massif::ModelItem)),
this, SIGNAL(modelItemSelected(Massif::ModelItem)));
connect(tab, SIGNAL(contextMenuRequested(Massif::ModelItem,QMenu*)),
this, SIGNAL(contextMenuRequested(Massif::ModelItem,QMenu*)));
}
m_tabs->setCurrentIndex(0);
connect(m_tabs, SIGNAL(currentChanged(int)),
this, SLOT(slotTabChanged(int)));
slotTabChanged(0);
m_isLoaded = true;
// Switch to the display page and notify that everything is setup.
m_stackedWidget->setCurrentIndex(0);
emit loadingFinished();
}
void DocumentWidget::addGuiActions(KXMLGUIFactory* factory)
{
factory->addClient(this);
// ensure only the current tab's client is in the factory
// otherwise the actions from the other tabs are visible
const int current = m_tabs->currentIndex();
for (int i = 0; i < m_tabs->count(); ++i) {
if (i != current) {
factory->removeClient(static_cast<DocumentTabInterface*>(m_tabs->widget(i)));
}
}
}
void DocumentWidget::clearGuiActions(KXMLGUIFactory* factory)
{
factory->removeClient(this);
}
void DocumentWidget::slotTabChanged(int tab)
{
if (!factory()) {
return;
}
if (m_currentTab) {
factory()->removeClient(m_currentTab);
}
if (tab >= 0 && tab < m_tabs->count()) {
m_currentTab = static_cast<DocumentTabInterface*>(m_tabs->widget(tab));
factory()->addClient(m_currentTab);
}
}
void DocumentWidget::selectModelItem(const ModelItem& item)
{
for (int i = 0; i < m_tabs->count(); ++i) {
static_cast<DocumentTabInterface*>(m_tabs->widget(i))->selectModelItem(item);
}
}
void DocumentWidget::setProgress(int value)
{
m_loadingProgressBar->setValue(value);
}
void DocumentWidget::setRange(int minimum, int maximum)
{
m_loadingProgressBar->setRange(minimum, maximum);
}
void DocumentWidget::showError(const QString& title, const QString& error)
{
if (!m_errorMessage) {
m_errorMessage = new KMessageWidget(m_stackedWidget);
m_stackedWidget->addWidget(m_errorMessage);
m_errorMessage->setWordWrap(true);
m_errorMessage->setMessageType(KMessageWidget::Error);
m_errorMessage->setCloseButtonVisible(false);
}
m_errorMessage->setText(QString("<b>%1</b><p style=\"text-align:left\">%2</p>").arg(title).arg(error));
m_stackedWidget->setCurrentWidget(m_errorMessage);
}
void DocumentWidget::stopParser()
{
if (!m_parseWorker) {
return;
}
QThread* thread = m_parseWorker->thread();
m_parseWorker->stop();
m_parseWorker->deleteLater();
m_parseWorker = 0;
thread->quit();
thread->wait();
}

View file

@ -0,0 +1,104 @@
/*
This file is part of Massif Visualizer
Copyright 2010 Milian Wolff <mail@milianw.de>
Copyright 2013 Arnold Dumas <contact@arnolddumas.fr>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License or (at your option) version 3 or any later version
accepted by the membership of KDE e.V. (or its successor approved
by the membership of KDE e.V.), which shall act as a proxy
defined in Section 14 of version 3 of the license.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef DOCUMENTWIDGET_H
#define DOCUMENTWIDGET_H
#include <QWidget>
#include <KUrl>
#include <KXMLGUIClient>
#include "visualizer/modelitem.h"
class DocumentTabInterface;
class QMenu;
class QLabel;
class QProgressBar;
class QToolButton;
class QStackedWidget;
class QTabWidget;
class KMessageWidget;
namespace Massif {
class FileData;
class ParseWorker;
}
class DocumentWidget : public QWidget, public KXMLGUIClient
{
Q_OBJECT
public:
explicit DocumentWidget(const KUrl& file, const QStringList& customAllocators,
KXMLGUIClient* guiParent, QWidget* parent = 0);
~DocumentWidget();
Massif::FileData* data() const;
KUrl file() const;
bool isLoaded() const;
void settingsChanged();
void addGuiActions(KXMLGUIFactory* factory);
void clearGuiActions(KXMLGUIFactory* factory);
void selectModelItem(const Massif::ModelItem& item);
signals:
void loadingFinished();
void modelItemSelected(const Massif::ModelItem& item);
void contextMenuRequested(const Massif::ModelItem& item, QMenu* menu);
void requestClose();
private slots:
void stopParser();
void parserFinished(const KUrl& file, Massif::FileData* data);
void setProgress(int value);
void setRange(int minimum, int maximum);
void showError(const QString& title, const QString& error);
void slotTabChanged(int tab);
private:
Massif::FileData* m_data;
Massif::ParseWorker* m_parseWorker;
KUrl m_file;
DocumentTabInterface* m_currentTab;
QStackedWidget* m_stackedWidget;
QTabWidget* m_tabs;
KMessageWidget* m_errorMessage;
QLabel* m_loadingMessage;
QProgressBar* m_loadingProgressBar;
QToolButton* m_stopParserButton;
bool m_isLoaded;
};
#endif // DOCUMENTWIDGET_H

View file

@ -0,0 +1,4 @@
<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
<kpartgui name="documentwidget" version="1">
</kpartgui>

View file

@ -0,0 +1,65 @@
/*
This file is part of Massif Visualizer
Copyright 2010 Milian Wolff <mail@milianw.de>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License or (at your option) version 3 or any later version
accepted by the membership of KDE e.V. (or its successor approved
by the membership of KDE e.V.), which shall act as a proxy
defined in Section 14 of version 3 of the license.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <KLocalizedString>
#include <KAboutData>
#include <KApplication>
#include <KCmdLineArgs>
#include <KCmdLineOptions>
#include <KUrl>
#include <QtCore/QDebug>
#include "mainwindow.h"
int main( int argc, char *argv[] )
{
KAboutData aboutData( "massif-visualizer", 0, ki18n( "Massif Visualizer" ),
"0.5", ki18n("A visualizer for output generated by Valgrind's massif tool."), KAboutData::License_LGPL,
ki18n( "Copyright 2010-2014, Milian Wolff <mail@milianw.de>" ),
KLocalizedString(), QByteArray(), "massif-visualizer@kde.org" );
aboutData.addAuthor(ki18n("Milian Wolff"), ki18n("Original author, maintainer"),
"mail@milianw.de", "http://milianw.de");
aboutData.addAuthor(ki18n("Arnold Dumas"), ki18n("Multiple document interface, bug fixes"),
"contact@arnolddumas.fr", "http://arnolddumas.fr");
aboutData.setProgramIconName("office-chart-area");
KCmdLineArgs::init( argc, argv, &aboutData, KCmdLineArgs::CmdLineArgNone );
KCmdLineOptions options;
options.add("+file(s)", ki18n("Opens given output file(s) and visualize it."));
KCmdLineArgs::addCmdLineOptions( options );
KCmdLineArgs* args = KCmdLineArgs::parsedArgs();
KApplication app;
Massif::MainWindow* window = new Massif::MainWindow;
for (int i = 0; i < args->count(); ++i) {
window->openFile(args->url(i));
}
window->show();
return app.exec();
}

View file

@ -0,0 +1,528 @@
/*
This file is part of Massif Visualizer
Copyright 2010 Milian Wolff <mail@milianw.de>
Copyright 2013 Arnold Dumas <contact@arnolddumas.fr>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License or (at your option) version 3 or any later version
accepted by the membership of KDE e.V. (or its successor approved
by the membership of KDE e.V.), which shall act as a proxy
defined in Section 14 of version 3 of the license.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "mainwindow.h"
#include "massifdata/filedata.h"
#include "massifdata/snapshotitem.h"
#include "massifdata/treeleafitem.h"
#include "massifdata/util.h"
#include "visualizer/totalcostmodel.h"
#include "visualizer/detailedcostmodel.h"
#include "visualizer/datatreemodel.h"
#include "visualizer/filtereddatatreemodel.h"
#include "visualizer/dotgraphgenerator.h"
#include "massif-visualizer-settings.h"
#include "configdialog.h"
#include <KStandardAction>
#include <KActionCollection>
#include <KFileDialog>
#include <KRecentFilesAction>
#include <KColorScheme>
#include <KStatusBar>
#include <KToolBar>
#include <KParts/Part>
#include <KPluginFactory>
#include <KPluginLoader>
#include <KXMLGUIFactory>
#include <KLocale>
#include <QSortFilterProxyModel>
#include <QStringListModel>
#include <QLabel>
#include <QSpinBox>
#include <QInputDialog>
#include <KMessageBox>
#ifdef HAVE_KGRAPHVIEWER
#include <kgraphviewer_interface.h>
#endif
using namespace Massif;
// Helper function
static KConfigGroup allocatorConfig()
{
return KGlobal::config()->group("Allocators");
}
MainWindow::MainWindow(QWidget* parent, Qt::WindowFlags f)
: KParts::MainWindow(parent, f)
, m_recentFiles(0)
, m_close(0)
, m_allocatorModel(new QStringListModel(this))
, m_newAllocator(0)
, m_removeAllocator(0)
, m_shortenTemplates(0)
, m_selectPeak(0)
, m_currentDocument(0)
, m_dataTreeModel(new DataTreeModel(this))
, m_dataTreeFilterModel(new FilteredDataTreeModel(m_dataTreeModel))
, m_settingSelection(false)
{
ui.setupUi(this);
setWindowTitle(i18n("Massif Visualizer"));
//BEGIN KGraphViewer
bool haveGraphViewer = false;
// NOTE: just check if kgraphviewer is available at runtime.
// The former logic has been moved to DocumentWidget constructor.
#ifdef HAVE_KGRAPHVIEWER
KPluginFactory *factory = KPluginLoader("kgraphviewerpart").factory();
if (factory) {
KParts::ReadOnlyPart* readOnlyPart = factory->create<KParts::ReadOnlyPart>("kgraphviewerpart", this);
if (readOnlyPart) {
readOnlyPart->widget()->hide();
haveGraphViewer = true;
}
}
#endif
if (!haveGraphViewer) {
// cleanup UI when we installed with kgraphviewer but it's not available at runtime
KToolBar* callgraphToolbar = toolBar("callgraphToolBar");
removeToolBar(callgraphToolbar);
delete callgraphToolbar;
}
//END KGraphViewer
ui.documents->setMovable(true);
ui.documents->setTabsClosable(true);
connect(ui.documents, SIGNAL(currentChanged(int)),
this, SLOT(documentChanged()));
connect(ui.documents, SIGNAL(tabCloseRequested(int)),
this, SLOT(closeFileTab(int)));
//BEGIN custom allocators
tabifyDockWidget(ui.allocatorDock, ui.dataTreeDock);
ui.allocatorView->setModel(m_allocatorModel);
int iconSize = style()->pixelMetric(QStyle::PM_SmallIconSize);
ui.dockMenuBar->setIconSize(QSize(iconSize, iconSize));
ui.dockMenuBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
ui.dockMenuBar->setFloatable(false);
ui.dockMenuBar->setMovable(false);
KConfigGroup cfg = allocatorConfig();
m_allocatorModel->setStringList(cfg.entryMap().values());
connect(m_allocatorModel, SIGNAL(modelReset()),
this, SLOT(allocatorsChanged()));
connect(m_allocatorModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
this, SLOT(allocatorsChanged()));
connect(ui.dataTreeView, SIGNAL(customContextMenuRequested(QPoint)),
this, SLOT(dataTreeContextMenuRequested(QPoint)));
ui.dataTreeView->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui.allocatorView, SIGNAL(customContextMenuRequested(QPoint)),
this, SLOT(allocatorViewContextMenuRequested(QPoint)));
ui.allocatorView->setContextMenuPolicy(Qt::CustomContextMenu);
//END custom allocators
setupActions();
setupGUI(StandardWindowOptions(Default ^ StatusBar));
statusBar()->hide();
ui.dataTreeView->setModel(m_dataTreeFilterModel);
connect(ui.filterDataTree, SIGNAL(textChanged(QString)),
m_dataTreeFilterModel, SLOT(setFilter(QString)));
connect(ui.dataTreeView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
this, SLOT(treeSelectionChanged(QModelIndex,QModelIndex)));
// open page
ui.stackedWidget->setCurrentWidget(ui.openPage);
}
MainWindow::~MainWindow()
{
while (ui.documents->count()) {
closeCurrentFile();
}
m_recentFiles->saveEntries(KGlobal::config()->group( QString() ));
}
void MainWindow::setupActions()
{
KAction* openFile = KStandardAction::open(this, SLOT(openFile()), actionCollection());
m_recentFiles = KStandardAction::openRecent(this, SLOT(openFile(KUrl)), actionCollection());
m_recentFiles->loadEntries(KGlobal::config()->group( QString() ));
KAction* reload = KStandardAction::redisplay(this, SLOT(reloadCurrentFile()), actionCollection());
actionCollection()->addAction("file_reload", reload);
reload->setEnabled(false);
m_close = KStandardAction::close(this, SLOT(closeCurrentFile()), actionCollection());
m_close->setEnabled(false);
KStandardAction::quit(qApp, SLOT(closeAllWindows()), actionCollection());
KStandardAction::preferences(this, SLOT(preferences()), actionCollection());
m_shortenTemplates = new KAction(KIcon("shortentemplates"), i18n("Shorten Templates"), actionCollection());
m_shortenTemplates->setCheckable(true);
m_shortenTemplates->setChecked(Settings::shortenTemplates());
connect(m_shortenTemplates, SIGNAL(toggled(bool)), SLOT(slotShortenTemplates(bool)));
actionCollection()->addAction("shorten_templates", m_shortenTemplates);
m_selectPeak = new KAction(KIcon("flag-red"), i18n("Select peak snapshot"), actionCollection());
connect(m_selectPeak, SIGNAL(triggered()), this, SLOT(selectPeakSnapshot()));
actionCollection()->addAction("selectPeak", m_selectPeak);
m_selectPeak->setEnabled(false);
//BEGIN custom allocators
m_newAllocator = new KAction(KIcon("list-add"), i18n("add"), ui.allocatorDock);
m_newAllocator->setToolTip(i18n("add custom allocator"));
connect(m_newAllocator, SIGNAL(triggered()), this, SLOT(slotNewAllocator()));
ui.dockMenuBar->addAction(m_newAllocator);
m_removeAllocator = new KAction(KIcon("list-remove"), i18n("remove"),
ui.allocatorDock);
m_newAllocator->setToolTip(i18n("remove selected allocator"));
connect(m_removeAllocator, SIGNAL(triggered()), this, SLOT(slotRemoveAllocator()));
connect(ui.allocatorView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
this, SLOT(allocatorSelectionChanged()));
m_removeAllocator->setEnabled(false);
ui.dockMenuBar->addAction(m_removeAllocator);
m_markCustomAllocator = new KAction(i18n("mark as custom allocator"), ui.allocatorDock);
connect(m_markCustomAllocator, SIGNAL(triggered()),
this, SLOT(slotMarkCustomAllocator()), Qt::QueuedConnection);
//END custom allocators
//dock actions
actionCollection()->addAction("toggleDataTree", ui.dataTreeDock->toggleViewAction());
actionCollection()->addAction("toggleAllocators", ui.allocatorDock->toggleViewAction());
//open page actions
ui.openFile->setDefaultAction(openFile);
ui.openFile->setText(i18n("Open Massif Data File"));
ui.openFile->setIconSize(QSize(48, 48));
}
void MainWindow::preferences()
{
if (ConfigDialog::isShown()) {
return;
}
ConfigDialog* dlg = new ConfigDialog(this);
connect(dlg, SIGNAL(settingsChanged(QString)),
this, SLOT(settingsChanged()));
dlg->show();
}
void MainWindow::settingsChanged()
{
if (Settings::self()->shortenTemplates() != m_shortenTemplates->isChecked()) {
m_shortenTemplates->setChecked(Settings::self()->shortenTemplates());
}
Settings::self()->writeConfig();
if (m_currentDocument) {
m_currentDocument->settingsChanged();
}
ui.dataTreeView->viewport()->update();
}
void MainWindow::openFile()
{
const KUrl::List files = KFileDialog::getOpenUrls(KUrl("kfiledialog:///massif-visualizer"),
QString("application/x-valgrind-massif"),
this, i18n("Open Massif Output File"));
foreach (const KUrl& file, files) {
openFile(file);
}
}
void MainWindow::reloadCurrentFile()
{
if (m_currentDocument->file().isValid()) {
openFile(KUrl(m_currentDocument->file()));
}
}
void MainWindow::openFile(const KUrl& file)
{
Q_ASSERT(file.isValid());
// Is file already opened ?
int indexToInsert = -1;
for (int i = 0; i < ui.documents->count(); ++i) {
if (qobject_cast<DocumentWidget*>(ui.documents->widget(i))->file() == file) {
indexToInsert = i;
break;
}
}
DocumentWidget* documentWidget = new DocumentWidget(file.pathOrUrl(), m_allocatorModel->stringList(),
this, this);
if (indexToInsert != -1) {
// Remove existing instance of the file.
ui.documents->setCurrentIndex(indexToInsert);
closeCurrentFile();
// Insert the new tab at the correct position.
ui.documents->insertTab(indexToInsert, documentWidget, file.fileName());
ui.documents->setCurrentIndex(indexToInsert);
} else {
const int idx = ui.documents->addTab(documentWidget, file.fileName());
ui.documents->setCurrentIndex(idx);
}
connect(documentWidget, SIGNAL(loadingFinished()),
this, SLOT(documentChanged()));
connect(documentWidget, SIGNAL(requestClose()),
this, SLOT(closeRequested()));
m_recentFiles->addUrl(file);
ui.stackedWidget->setCurrentWidget(ui.displayPage);
}
void MainWindow::treeSelectionChanged(const QModelIndex& now, const QModelIndex& before)
{
if (!m_currentDocument || m_settingSelection || now == before) {
return;
}
m_settingSelection = true;
const ModelItem& item = now.data(DataTreeModel::ModelItemRole).value<ModelItem>();
m_currentDocument->selectModelItem(item);
m_settingSelection = false;
}
void MainWindow::modelItemSelected(const ModelItem& item)
{
if (!m_currentDocument || m_settingSelection) {
return;
}
m_settingSelection = true;
const QModelIndex& newIndex = m_dataTreeFilterModel->mapFromSource(
m_dataTreeModel->indexForItem(item)
);
ui.dataTreeView->selectionModel()->clearSelection();
ui.dataTreeView->selectionModel()->setCurrentIndex(newIndex, QItemSelectionModel::Select | QItemSelectionModel::Rows);
ui.dataTreeView->scrollTo(ui.dataTreeView->selectionModel()->currentIndex());
m_currentDocument->selectModelItem(item);
m_settingSelection = false;
}
void MainWindow::selectPeakSnapshot()
{
ui.dataTreeView->selectionModel()->clearSelection();
ui.dataTreeView->selectionModel()->setCurrentIndex(
m_dataTreeFilterModel->mapFromSource(
m_dataTreeModel->indexForSnapshot(m_currentDocument->data()->peak())),
QItemSelectionModel::Select | QItemSelectionModel::Rows
);
}
void MainWindow::closeCurrentFile()
{
closeFileTab(ui.documents->currentIndex());
}
void MainWindow::closeRequested()
{
DocumentWidget* widget = qobject_cast<DocumentWidget*>(sender());
Q_ASSERT(widget);
closeFileTab(ui.documents->indexOf(widget));
}
void MainWindow::closeFileTab(int idx)
{
Q_ASSERT(idx != -1);
ui.documents->widget(idx)->deleteLater();
ui.documents->removeTab(idx);
}
void MainWindow::allocatorsChanged()
{
KConfigGroup cfg = allocatorConfig();
cfg.deleteGroup();
int i = 0;
foreach(const QString& allocator, m_allocatorModel->stringList()) {
if (allocator.isEmpty()) {
m_allocatorModel->removeRow(i);
continue;
}
cfg.writeEntry(QString::number(i++), allocator);
}
cfg.sync();
if (m_currentDocument) {
reloadCurrentFile();
}
}
void MainWindow::allocatorSelectionChanged()
{
m_removeAllocator->setEnabled(ui.allocatorView->selectionModel()->hasSelection());
}
void MainWindow::slotNewAllocator()
{
QString allocator = QInputDialog::getText(this, i18n("Add Custom Allocator"), i18n("allocator:"));
if (allocator.isEmpty()) {
return;
}
if (!m_allocatorModel->stringList().contains(allocator)) {
m_allocatorModel->setStringList(m_allocatorModel->stringList() << allocator);
}
}
void MainWindow::slotRemoveAllocator()
{
Q_ASSERT(ui.allocatorView->selectionModel()->hasSelection());
foreach(const QModelIndex& idx, ui.allocatorView->selectionModel()->selectedRows()) {
m_allocatorModel->removeRow(idx.row(), idx.parent());
}
allocatorsChanged();
}
void MainWindow::slotMarkCustomAllocator()
{
const QString allocator = m_markCustomAllocator->data().toString();
Q_ASSERT(!allocator.isEmpty());
if (!m_allocatorModel->stringList().contains(allocator)) {
m_allocatorModel->setStringList(m_allocatorModel->stringList() << allocator);
}
}
void MainWindow::allocatorViewContextMenuRequested(const QPoint& pos)
{
const QModelIndex idx = ui.allocatorView->indexAt(pos);
QMenu menu;
menu.addAction(m_newAllocator);
if (idx.isValid()) {
menu.addAction(m_removeAllocator);
}
menu.exec(ui.allocatorView->mapToGlobal(pos));
}
void MainWindow::dataTreeContextMenuRequested(const QPoint& pos)
{
const QModelIndex idx = ui.dataTreeView->indexAt(pos);
const TreeLeafItem* item = idx.data(DataTreeModel::TreeItemRole).value<const TreeLeafItem*>();
if (!item) {
return;
}
QMenu menu;
contextMenuRequested(ModelItem(item, 0), &menu);
menu.exec(ui.dataTreeView->mapToGlobal(pos));
}
void MainWindow::contextMenuRequested(const ModelItem& item, QMenu* menu)
{
if (!item.first) {
// only handle context menu on tree-leaf items for now
return;
}
QString func = functionInLabel(item.first->label());
if (func.length() > 40) {
func.resize(40);
func.append("...");
}
menu->setTitle(func);
m_markCustomAllocator->setData(item.first->label());
menu->addAction(m_markCustomAllocator);
}
void MainWindow::slotShortenTemplates(bool shorten)
{
if (shorten == Settings::self()->shortenTemplates()) {
return;
}
Settings::self()->setShortenTemplates(shorten);
settingsChanged();
}
void MainWindow::updateWindowTitle()
{
if (m_currentDocument && m_currentDocument->isLoaded()) {
setWindowTitle(i18n("Massif Visualizer - evaluation of %1 (%2)", m_currentDocument->data()->cmd(), m_currentDocument->file().fileName()));
} else {
setWindowTitle(i18n("Massif Visualizer"));
}
}
void MainWindow::documentChanged()
{
// required to prevent GUI flickering when changing documents
// the changing actions in the toolbar are really flickering bad otherwise
setUpdatesEnabled(false);
if (m_currentDocument) {
m_dataTreeModel->setSource(0);
m_dataTreeFilterModel->setFilter(QString());
m_currentDocument->clearGuiActions(guiFactory());
disconnect(m_currentDocument, SIGNAL(modelItemSelected(Massif::ModelItem)),
this, SLOT(modelItemSelected(Massif::ModelItem)));
disconnect(m_currentDocument, SIGNAL(contextMenuRequested(Massif::ModelItem,QMenu*)),
this, SLOT(contextMenuRequested(Massif::ModelItem,QMenu*)));
}
m_currentDocument = qobject_cast<DocumentWidget*>(ui.documents->currentWidget());
updateWindowTitle();
actionCollection()->action("file_reload")->setEnabled(m_currentDocument && m_currentDocument->isLoaded());
m_close->setEnabled(m_currentDocument);
m_selectPeak->setEnabled(m_currentDocument && m_currentDocument->isLoaded());
if (!m_currentDocument) {
ui.stackedWidget->setCurrentWidget(ui.openPage);
setUpdatesEnabled(true);
return;
} else {
m_dataTreeModel->setSource(m_currentDocument->data());
m_currentDocument->addGuiActions(guiFactory());
connect(m_currentDocument, SIGNAL(modelItemSelected(Massif::ModelItem)),
this, SLOT(modelItemSelected(Massif::ModelItem)));
connect(m_currentDocument, SIGNAL(contextMenuRequested(Massif::ModelItem,QMenu*)),
this, SLOT(contextMenuRequested(Massif::ModelItem,QMenu*)));
}
setUpdatesEnabled(true);
}
#include "mainwindow.moc"

View file

@ -0,0 +1,145 @@
/*
This file is part of Massif Visualizer
Copyright 2010 Milian Wolff <mail@milianw.de>
Copyright 2013 Arnold Dumas <contact@arnolddumas.fr>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License or (at your option) version 3 or any later version
accepted by the membership of KDE e.V. (or its successor approved
by the membership of KDE e.V.), which shall act as a proxy
defined in Section 14 of version 3 of the license.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef MASSIF_MAINWINDOW_H
#define MASSIF_MAINWINDOW_H
#include <KParts/MainWindow>
#include <QPrintPreviewDialog>
#include "ui_mainwindow.h"
#include "documentwidget.h"
class QSpinBox;
class QStringListModel;
namespace KDChart {
class Chart;
class HeaderFooter;
class Plotter;
class CartesianAxis;
class Legend;
class BarDiagram;
}
class KAction;
class KRecentFilesAction;
#ifdef HAVE_KGRAPHVIEWER
namespace KGraphViewer {
class KGraphViewerInterface;
}
#endif
namespace Massif {
class FilteredDataTreeModel;
class DataTreeModel;
class SnapshotItem;
class TreeLeafItem;
class MainWindow : public KParts::MainWindow
{
Q_OBJECT
public:
MainWindow(QWidget* parent = 0, Qt::WindowFlags f = 0);
virtual ~MainWindow();
void setupActions();
public slots:
/**
* Open a dialog to pick a massif output file(s) to display.
*/
void openFile();
/**
* Opens @p file as massif output file and visualize it.
*/
void openFile(const KUrl& file);
/**
* reload currently opened file
*/
void reloadCurrentFile();
/**
* Close currently opened file.
*/
void closeCurrentFile();
private slots:
void closeRequested();
void closeFileTab(int idx);
void preferences();
void settingsChanged();
void treeSelectionChanged(const QModelIndex& now, const QModelIndex& before);
void selectPeakSnapshot();
void modelItemSelected(const Massif::ModelItem& item);
void contextMenuRequested(const Massif::ModelItem& item, QMenu* menu);
void documentChanged();
void allocatorsChanged();
void allocatorSelectionChanged();
void dataTreeContextMenuRequested(const QPoint &pos);
void slotNewAllocator();
void slotRemoveAllocator();
/// operates on data of @c m_markCustomAllocator
void slotMarkCustomAllocator();
void allocatorViewContextMenuRequested(const QPoint &pos);
void slotShortenTemplates(bool);
private:
void updateWindowTitle();
// Helper
Ui::MainWindow ui;
KRecentFilesAction* m_recentFiles;
KAction* m_close;
QStringListModel* m_allocatorModel;
KAction* m_newAllocator;
KAction* m_removeAllocator;
KAction* m_markCustomAllocator;
KAction* m_shortenTemplates;
KAction* m_selectPeak;
DocumentWidget* m_currentDocument;
Massif::DataTreeModel* m_dataTreeModel;
Massif::FilteredDataTreeModel* m_dataTreeFilterModel;
bool m_settingSelection;
};
}
#endif // MASSIF_MAINWINDOW_H

View file

@ -0,0 +1,169 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout_4">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QStackedWidget" name="stackedWidget">
<property name="currentIndex">
<number>1</number>
</property>
<widget class="QWidget" name="displayPage">
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QTabWidget" name="documents">
<property name="currentIndex">
<number>-1</number>
</property>
<property name="documentMode">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="openPage">
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>252</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QToolButton" name="openFile">
<property name="text">
<string>...</string>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextUnderIcon</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>19</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<widget class="QDockWidget" name="dataTreeDock">
<property name="windowTitle">
<string>Massif Data</string>
</property>
<attribute name="dockWidgetArea">
<number>2</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="KLineEdit" name="filterDataTree">
<property name="urlDropsEnabled" stdset="0">
<bool>false</bool>
</property>
<property name="clickMessage" stdset="0">
<string>filter</string>
</property>
<property name="showClearButton" stdset="0">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QTreeView" name="dataTreeView"/>
</item>
</layout>
</widget>
</widget>
<widget class="QDockWidget" name="allocatorDock">
<property name="windowTitle">
<string>Custom Allocators</string>
</property>
<attribute name="dockWidgetArea">
<number>2</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_2">
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="KToolBar" name="dockMenuBar" native="true"/>
</item>
<item>
<widget class="QListView" name="allocatorView"/>
</item>
</layout>
</widget>
</widget>
</widget>
<customwidgets>
<customwidget>
<class>KLineEdit</class>
<extends>QLineEdit</extends>
<header>klineedit.h</header>
</customwidget>
<customwidget>
<class>KToolBar</class>
<extends>QWidget</extends>
<header location="global">ktoolbar.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View file

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
http://www.kde.org/standards/kcfg/1.0/kcfg.xsd">
<group name="Settings">
<entry name="PrettyCostPrecision" key="prettyCostPrecision" type="int">
<default>1</default>
<label>Cost Precision</label>
<tooltip>Defines the number of places after the comma for memory costs shown in the application.</tooltip>
</entry>
<entry name="ShortenTemplates" key="shortenTemplates" type="bool">
<default>0</default>
<label>Shorten Templates</label>
<tooltip>Defines whether identifiers of C++ template instantiations should be shortened by removing their template arguments.</tooltip>
</entry>
<entry name="LegendPosition" key="legendPosition" type="Enum">
<default>EnumLegendPosition::Floating</default>
<label>Legend Position</label>
<tooltip>Defines the position of the legend relative to the plot.</tooltip>
<choices label="PositionValue">
<choice name="North"/>
<choice name="East"/>
<choice name="South"/>
<choice name="West"/>
<choice name="Floating"/>
</choices>
</entry>
<entry name="LegendAlignment" key="legendAlignment" type="Enum">
<default>EnumLegendAlignment::Center</default>
<label>Legend Alignment</label>
<tooltip>Defines the alignment of the legend.</tooltip>
<choices label="AlignmentValue">
<choice name="Left"/>
<choice name="Center"/>
<choice name="Right"/>
<choice name="Top"/>
<choice name="Bottom"/>
</choices>
</entry>
<entry name="LegendFontSize" key="legendFontSize" type="int">
<default>12</default>
<min>6</min>
<max>14</max>
<label>Legend Font Size</label>
<tooltip>Defines the font size used in the legend.</tooltip>
</entry>
</group>
</kcfg>

View file

@ -0,0 +1,8 @@
File=massif-visualizer-settings.kcfg
ClassName=Settings
NameSpace=Massif
Singleton=true
UseEnumTypes=true
SetUserTexts=true
ItemAccessors=true
Mutators=true

View file

@ -0,0 +1,172 @@
<?xml version="1.0" encoding="utf-8"?>
<component type="desktop">
<id>massif-visualizer.desktop</id>
<metadata_license>CC0-1.0</metadata_license>
<project_license>GPL-2.0+</project_license>
<name>Massif-Visualizer</name>
<name xml:lang="ca">Massif-Visualizer</name>
<name xml:lang="cs">Massif-Visualizer</name>
<name xml:lang="de">Massif-Visualizer</name>
<name xml:lang="en-GB">Massif-Visualizer</name>
<name xml:lang="es">Massif-Visualizer</name>
<name xml:lang="gl">Visualizador de Massif</name>
<name xml:lang="ko">Massif 시각화 도구</name>
<name xml:lang="nl">Massif-Visualizer</name>
<name xml:lang="pl">Wizualizacja-Massif</name>
<name xml:lang="pt">Visualizador do Massif</name>
<name xml:lang="pt-BR">Visualizador de Massif</name>
<name xml:lang="sk">Massif-Visualizer</name>
<name xml:lang="sv">Massif visualisering</name>
<name xml:lang="uk">Візуалізатор Massif</name>
<name xml:lang="x-test">xxMassif-Visualizerxx</name>
<summary>A visualizer for Valgrind Massif data files.</summary>
<summary xml:lang="ca">Un visualitzador pels fitxers de dades Massif del Valgrind.</summary>
<summary xml:lang="de">Ein Programm zum Visualisieren von Massif-Datendateien.</summary>
<summary xml:lang="en-GB">A visualiser for Valgrind Massif data files.</summary>
<summary xml:lang="es">Un visualizador para archivos de datos Massif de Valgrind.</summary>
<summary xml:lang="gl">Un visualizador para ficheiros de datos Massif de Valgrind.</summary>
<summary xml:lang="ko">Valgrind의 massif 도구의 출력을 시각화합니다.</summary>
<summary xml:lang="nl">Een programma voor het zichtbaar maken van gegevensbestanden van Valgrind Massif.</summary>
<summary xml:lang="pl">Wizualizacja dla plików Valgrind Massif.</summary>
<summary xml:lang="pt">Um visualizador dos ficheiros dos dados do Massif para o Valgrind.</summary>
<summary xml:lang="pt-BR">Um visualizador para arquivos de dados Massif do Valgrind.</summary>
<summary xml:lang="sv">Ett visualiseringsverktyg för utdata skapad av Valgrinds verktyg Massif</summary>
<summary xml:lang="uk">Засіб візуалізації файлів даних Massif Valgrind.</summary>
<summary xml:lang="x-test">xxA visualizer for Valgrind Massif data files.xx</summary>
<description>
<p>
Massif Visualizer is a tool that - who'd guess that - visualizes massif data.
You run your application in Valgrind with --tool=massif and then open the generated
massif.out.%pid in the visualizer. Gzip or Bzip2 compressed massif files can also be
opened transparently.
</p>
<p xml:lang="ca">Massif Visualizer és una eina que -com imagineu- visualitza les dades massif. Executeu l'aplicació en Valgrind amb --tool=massif i després obriu el massif.out.%pid generat en el visualitzador. Els fitxers massif comprimits amb gzip o bzip2 també es poden obrir de forma transparent.</p>
<p xml:lang="en-GB">Massif Visualizer is a tool that - who'd guess that - visualises massif data. You run your application in Valgrind with --tool=massif and then open the generated massif.out.%pid in the visualiser. Gzip or Bzip2 compressed massif files can also be opened transparently.</p>
<p xml:lang="es">Massif Visualizer es una herramienta que sirve para visualizar datos de Massif. Puede ejecutar una aplicación en Valgrind con «--tool=massif» y abrir a continuación en el visualizador el archivo «massif.out.%pid» generado. También se pueden abrir de forma transparente los archivos de Massif comprimidos con Gzip o Bzip2.</p>
<p xml:lang="gl">Visualizador de Massif é unha ferramenta que, como o nome indica, permite visualizar datos Massif. Execute o seu programa en Valgrind usando a opción «--tool=massif» e a continuación abra o ficheiro «massif.out.%pid» xerado no visualizador. Tamén pode abrir ficheiros Massif comprimidos con Gzip ou Bzip2 de maneira transparente.</p>
<p xml:lang="ko">Massif 시각화 도구는 massif 데이터를 표시합니다. Valgrind에서 프로그램을 실행시킬 때 --tool=massif 인자로 실행시키고, 생성된 massif.out.%pid 파일을 시각화 도구로 엽니다. Gzip/Bzip2 압축된 파일도 별도의 과정 없이 열 수 있습니다.</p>
<p xml:lang="nl">Massif Visualizer is een hulpmiddel dat - u raad het - massif-gegevens visualiseert. U kunt uw toepassing in Valgrind uitvoeren met --tool=massif en dan de gegenereerde massif.out.%pid openen in het visualisatieprogramma. Gzip of Bzip2 gecomprimeerde massif-bestanden kunnen ook transparent geopend worden.</p>
<p xml:lang="pl">Program do wizualizacji Massif jest narzędziem, które wizualizuje dane massif. Uruchamiasz swoją aplikację w Valgrind przy użyciu --tool=massif a następnie otwierasz utworzony massif.out.%pid w programie do wizualizacji. Można otwierać pliki massif skompresowane przy użyciu Gzip lub Bzip2.</p>
<p xml:lang="pt">O Visualizador do Massif é uma ferramenta que, como é óbvio, apresenta dados do Massif. Você poderá executar a sua aplicação no Valgrind com a opção --tool=massif e depois abrir o ficheiro massif.out.%pid gerado no visualizador. Poderá abrir de forma transparente os ficheiros do Massif comprimidos com Gzip ou Bzip2.</p>
<p xml:lang="pt-BR">O Visualizador de Massif é uma ferramenta que, como o nome sugere, visualiza dados Massif. Você pode executar seu aplicativo no Valgrind com a opção --tool=massif e depois abrir o arquivo massif.out.%pid gerado no visualizador. Os arquivos Massif compactados com Gzip ou Bzip2 podem ser abertos de forma transparente.</p>
<p xml:lang="sv">Massif visualisering är ett verktyg som åskådliggöra data från Massif, som inte är svårt att gissa. Man kör sitt program i Valgrind med --tool=massif och öppnar den skapade massif.out.%pid i verktyget. Massif-filer komprimerade med gzip eller bzip2 kan också öppnas direkt.</p>
<p xml:lang="uk">Візуалізатор Massif, яким би дивним це не здавалося, — засіб для візуалізації даних massif. Ви запускаєте вашу програму у Valgrind із параметром --tool=massif, а потім відкриваєте створений файл massif.out.%pid у засобі візуалізації. Передбачено прозоре відкриття файлів massif, запакованих за допомогою Gzip або Bzip2.</p>
<p xml:lang="x-test">xxMassif Visualizer is a tool that - who'd guess that - visualizes massif data. You run your application in Valgrind with --tool=massif and then open the generated massif.out.%pid in the visualizer. Gzip or Bzip2 compressed massif files can also be opened transparently.xx</p>
<p>Features:</p>
<p xml:lang="ca">Característiques:</p>
<p xml:lang="cs">Vlastnosti:</p>
<p xml:lang="de">Funktionen:</p>
<p xml:lang="en-GB">Features:</p>
<p xml:lang="es">Funciones:</p>
<p xml:lang="gl">Funcionalidades:</p>
<p xml:lang="ko">기능:</p>
<p xml:lang="nl">Kenmerken:</p>
<p xml:lang="pl">Możliwości:</p>
<p xml:lang="pt">Funcionalidades:</p>
<p xml:lang="pt-BR">Funcionalidades:</p>
<p xml:lang="sk">Funkcie:</p>
<p xml:lang="sv">Funktioner:</p>
<p xml:lang="uk">Можливості:</p>
<p xml:lang="x-test">xxFeatures:xx</p>
<ul>
<li>Interactive chart of memory consumption over time.</li>
<li xml:lang="ca">Gràfic interactiu del consum de memòria al llarg del temps.</li>
<li xml:lang="de">Interaktive Diagramme des Speicherverbrauch über Zeiträume.</li>
<li xml:lang="en-GB">Interactive chart of memory consumption over time.</li>
<li xml:lang="es">Mapa interactivo del consumo de memoria a lo largo del tiempo.</li>
<li xml:lang="gl">Gráfica interactiva de consumo de memoria no tempo.</li>
<li xml:lang="ko">시간별 메모리 사용량 차트 표시.</li>
<li xml:lang="nl">Interactieve grafiek van geheugengebruik in de tijd.</li>
<li xml:lang="pl">Interaktywny wykres wykorzystania pamięci w czasie.</li>
<li xml:lang="pt">Gráfico interactivo do consumo de memória ao longo do tempo.</li>
<li xml:lang="pt-BR">Gráfico interativo do consumo de memória usada pelo aplicativo.</li>
<li xml:lang="sv">Interaktivt diagram av minnesanvändning över tid.</li>
<li xml:lang="uk">Інтерактивна діаграма споживання пам’яті.</li>
<li xml:lang="x-test">xxInteractive chart of memory consumption over time.xx</li>
<li>Detailed snapshot analysis with callgraph visualization (requires KGraphViewer).</li>
<li xml:lang="ca">Anàlisi detallat de les captures amb visualització de «callgraph» (requereix el KGraphViewer).</li>
<li xml:lang="en-GB">Detailed snapshot analysis with callgraph visualisation (requires KGraphViewer).</li>
<li xml:lang="es">Análisis detallado de instantáneas con visualización de «callgraph» (necesita KGraphViewer).</li>
<li xml:lang="gl">Análise detallada de capturas con visualización da gráfica de chamadas (require KGraphViewer).</li>
<li xml:lang="ko">호출 그래프 시각화 및 자세한 스냅샷 분석(KGraphViewer 필요).</li>
<li xml:lang="nl">Gedetailleerde analyses van momentopnamen met callgraph-visualisatie (vereist KGraphViewer).</li>
<li xml:lang="pl">Szczegółowe analizy zrzutów z wizualizacją wykresu wywołań (wymaga KGraphViewer).</li>
<li xml:lang="pt">Análise detalhada das capturas com a visualização do grafo de chamadas (precisa do KGraphViewer).</li>
<li xml:lang="pt-BR">Análise detalhada das capturas com a visualização do grafo de chamadas (é necessário o KGraphViewer).</li>
<li xml:lang="sv">Detaljerad ögonblicksanalys med visualisering av anropsgraf (kräver Kgraphviewer).</li>
<li xml:lang="uk">Докладний аналіз знімків із візуалізацією графу викликів (потребує KGraphViewer).</li>
<li xml:lang="x-test">xxDetailed snapshot analysis with callgraph visualization (requires KGraphViewer).xx</li>
<li>Summary of peak memory consumption of all allocating functions.</li>
<li xml:lang="ca">Resum dels pics de consum de memòria de totes les funcions d'assignació.</li>
<li xml:lang="en-GB">Summary of peak memory consumption of all allocating functions.</li>
<li xml:lang="es">Sumario de picos de consumo de memoria de todas las funciones de asignación.</li>
<li xml:lang="gl">Resumo dos picos de consumo de memoria de todas as funcións de reserva de memoria.</li>
<li xml:lang="ko">모든 할당된 함수의 메모리 소모 요약.</li>
<li xml:lang="nl">Overzicht van pieken in geheugengebruik van alle functies voor toekennen.</li>
<li xml:lang="pl">Podsumowanie szczytowego wykorzystania pamięci wszystkich przydzielonych funkcji.</li>
<li xml:lang="pt">Resumo do consumo de pico da memória de todas as funções de alocação.</li>
<li xml:lang="pt-BR">Resumo do consumo de pico da memória de todas as funções de alocação.</li>
<li xml:lang="sv">Sammanfattning av största minnesanvändning för alla allokerande funktioner.</li>
<li xml:lang="uk">Резюме щодо пікового споживання пам’яті для всіх функцій отримання об’ємів пам’яті.</li>
<li xml:lang="x-test">xxSummary of peak memory consumption of all allocating functions.xx</li>
</ul>
</description>
<url type="homepage">projects.kde.org/massif-visualizer</url>
<url type="bugtracker">https://bugs.kde.org/enter_bug.cgi?format=guided&amp;product=massif-visualizer</url>
<url type="help">https://mail.kde.org/mailman/listinfo/massif-visualizer</url>
<screenshots>
<screenshot type="default">
<image>http://milianw.de/files/massif-visualizer/memory-chart.png</image>
<caption>Interactive chart of memory consumption over time.</caption>
<caption xml:lang="ca">Gràfic interactiu del consum de memòria al llarg del temps.</caption>
<caption xml:lang="de">Interaktive Diagramme des Speicherverbrauch über Zeiträume.</caption>
<caption xml:lang="en-GB">Interactive chart of memory consumption over time.</caption>
<caption xml:lang="es">Mapa interactivo del consumo de memoria a lo largo del tiempo.</caption>
<caption xml:lang="gl">Gráfica interactiva de consumo de memoria no tempo.</caption>
<caption xml:lang="ko">시간별 메모리 사용량 차트 표시.</caption>
<caption xml:lang="nl">Interactieve grafiek van geheugengebruik in de tijd.</caption>
<caption xml:lang="pl">Interaktywny wykres wykorzystania pamięci w czasie.</caption>
<caption xml:lang="pt">Gráfico interactivo do consumo de memória ao longo do tempo.</caption>
<caption xml:lang="pt-BR">Gráfico interativo do consumo de memória usada pelo aplicativo.</caption>
<caption xml:lang="sv">Interaktivt diagram av minnesanvändning över tid.</caption>
<caption xml:lang="uk">Інтерактивна діаграма споживання пам’яті.</caption>
<caption xml:lang="x-test">xxInteractive chart of memory consumption over time.xx</caption>
</screenshot>
<screenshot>
<image>http://milianw.de/files/massif-visualizer/callgraph.png</image>
<caption>Detailed snapshot analysis with callgraph visualization (requires KGraphViewer).</caption>
<caption xml:lang="ca">Anàlisi detallat de les captures amb visualització de «callgraph» (requereix el KGraphViewer).</caption>
<caption xml:lang="en-GB">Detailed snapshot analysis with callgraph visualisation (requires KGraphViewer).</caption>
<caption xml:lang="es">Análisis detallado de instantáneas con visualización de «callgraph» (necesita KGraphViewer).</caption>
<caption xml:lang="gl">Análise detallada de capturas con visualización da gráfica de chamadas (require KGraphViewer).</caption>
<caption xml:lang="ko">호출 그래프 시각화 및 자세한 스냅샷 분석(KGraphViewer 필요).</caption>
<caption xml:lang="nl">Gedetailleerde analyses van momentopnamen met callgraph-visualisatie (vereist KGraphViewer).</caption>
<caption xml:lang="pl">Szczegółowe analizy zrzutów z wizualizacją wykresu wywołań (wymaga KGraphViewer).</caption>
<caption xml:lang="pt">Análise detalhada das capturas com a visualização do grafo de chamadas (precisa do KGraphViewer).</caption>
<caption xml:lang="pt-BR">Análise detalhada das capturas com a visualização do grafo de chamadas (é necessário o KGraphViewer).</caption>
<caption xml:lang="sv">Detaljerad ögonblicksanalys med visualisering av anropsgraf (kräver Kgraphviewer).</caption>
<caption xml:lang="uk">Докладний аналіз знімків із візуалізацією графу викликів (потребує KGraphViewer).</caption>
<caption xml:lang="x-test">xxDetailed snapshot analysis with callgraph visualization (requires KGraphViewer).xx</caption>
</screenshot>
<screenshot>
<image>http://milianw.de/files/massif-visualizer/allocators.png</image>
<caption>Summary of peak memory consumption of all allocating functions.</caption>
<caption xml:lang="ca">Resum dels pics de consum de memòria de totes les funcions d'assignació.</caption>
<caption xml:lang="en-GB">Summary of peak memory consumption of all allocating functions.</caption>
<caption xml:lang="es">Sumario de picos de consumo de memoria de todas las funciones de asignación.</caption>
<caption xml:lang="gl">Resumo dos picos de consumo de memoria de todas as funcións de reserva de memoria.</caption>
<caption xml:lang="ko">모든 할당된 함수의 메모리 소모 요약.</caption>
<caption xml:lang="nl">Overzicht van pieken in geheugengebruik van alle functies voor toekennen.</caption>
<caption xml:lang="pl">Podsumowanie szczytowego wykorzystania pamięci wszystkich przydzielonych funkcji.</caption>
<caption xml:lang="pt">Resumo do consumo de pico da memória de todas as funções de alocação.</caption>
<caption xml:lang="pt-BR">Resumo do consumo de pico da memória de todas as funções de alocação.</caption>
<caption xml:lang="sv">Sammanfattning av största minnesanvändning för alla allokerande funktioner.</caption>
<caption xml:lang="uk">Резюме щодо пікового споживання пам’яті для всіх функцій отримання об’ємів пам’яті.</caption>
<caption xml:lang="x-test">xxSummary of peak memory consumption of all allocating functions.xx</caption>
</screenshot>
</screenshots>
<project_group>KDE</project_group>
<provides>
<binary>massif-visualizer</binary>
</provides>
</component>

View file

@ -0,0 +1,112 @@
# KDE Config File
[Desktop Entry]
Type=Application
Exec=massif-visualizer %u
MimeType=application/x-valgrind-massif;
# FIXME: get an icon!
Icon=office-chart-area
# FIXME: write docs!
# X-DocPath=kcachegrind/index.html
Terminal=false
Name=Massif-Visualizer
Name[ast]=Massif-Visualizer
Name[bs]=Massif-Visualizer
Name[ca]=Massif-Visualizer
Name[ca@valencia]=Massif-Visualizer
Name[da]=Massif-Visualizer
Name[de]=Massif-Visualizer
Name[el]=Massif-Visualizer
Name[en_GB]=Massif-Visualizer
Name[es]=Visualizador Massif
Name[et]=Massif-Visualizer
Name[fi]=Massif-visualisointi
Name[fr]=Massif-Visualizer
Name[ga]=Amharcléiritheoir Massif
Name[gl]=Visualizador Massif
Name[hu]=Massif-megjelenítő
Name[it]=Visualizzatore Massif
Name[kk]=Massif визуализаторы
Name[ko]=Massif
Name[mr]=-ि
Name[nb]=Massif visualisering
Name[nds]=Massif-Visualiserer
Name[nl]=Massif - programma voor visualiseren
Name[pl]=Wizualizacja-Massif
Name[pt]=Visualizador Massif
Name[pt_BR]=Massif-Visualizer
Name[ru]=Визуализатор Massif
Name[sk]=Massif-Visualizer
Name[sv]=Massif visualisering
Name[tr]=Massif-Görselleyici
Name[ug]=Massif-Visualizer
Name[uk]=Візуалізатор Massif
Name[x-test]=xxMassif-Visualizerxx
Name[zh_TW]=Massif-Visualizer
GenericName=Profiler Frontend
GenericName[bs]=Profajlerski program
GenericName[ca]=Frontal de l'analitzador del rendiment
GenericName[ca@valencia]=Frontal del Profiler
GenericName[cs]=Rozhraní pro profilaci
GenericName[da]=Grænseflade til profilering
GenericName[de]=Profiler-Oberfläche
GenericName[el]=Σύστημα περιβάλλοντος προφίλ
GenericName[en_GB]=Profiler Frontend
GenericName[es]=Interfaz del analizador
GenericName[et]=Profileerimisrakendus
GenericName[fi]=Profiloijan käyttöliittymä
GenericName[fr]=Interface de profilage
GenericName[ga]=Comhéadan ar Phróifíleoir
GenericName[gl]=Interface do analizador
GenericName[hu]=Ábrázoló előtétprogram
GenericName[it]=Frontend dell'analizzatore di prestazioni
GenericName[kk]=Profiler-дың интерфейсі
GenericName[ko]=
GenericName[mr]=
GenericName[nb]=Grensesnitt for profilvisning
GenericName[nds]=Profiler-Böversiet
GenericName[nl]=Profiler-hulpprogramma
GenericName[pl]=Nakładka programu profilującego
GenericName[pt]=Interface de Análise de Performance
GenericName[pt_BR]=Frontend do Profiler (Analisador)
GenericName[ru]=Представитель данных профилировщика
GenericName[sk]=Rozhranie pre profiláciu
GenericName[sv]=Profileringsgränssnitt
GenericName[tr]=Profil Önyüzü
GenericName[uk]=Інтерфейс до Profiler
GenericName[x-test]=xxProfiler Frontendxx
GenericName[zh_TW]=
Comment=Visualization of Memory Profiling Data
Comment[bs]=Vizualizacija memorijsko profilizirajućih podatka
Comment[ca]=Visualització de les dades de l'anàlisi del rendiment de la memòria
Comment[ca@valencia]=Visualització de dades de perfilat de la memòria
Comment[cs]=Vizualizace dat profilování paměti
Comment[da]=Visualisering af data for hukommelsesprofilering
Comment[de]=Visualisierung von Daten des Speicherverhaltens eines Programms
Comment[el]=Οπτικοποίηση δεδομένων προφίλ μνήμης
Comment[en_GB]=Visualization of Memory Profiling Data
Comment[es]=Visualización de datos de análisis de memoria
Comment[et]=Mälu profileerimise andmete visualiseerimise vahend
Comment[fi]=Visualisointi muistiprofiloinnin tiedoista
Comment[fr]=Visualisation des données de profilage de la mémoire
Comment[ga]=Amharcléiriú ar Shonraí Próifílithe Chuimhne
Comment[gl]=Visualización dos datos da análise de rendemento
Comment[hu]=Memória adatábrázolás megjelenítése
Comment[it]=Visualizzazione dei dati di profiling della memoria
Comment[kk]=Жадын профильдеу деректерінің визуализаторы
Comment[ko]=
Comment[mr]= ि ि
Comment[nb]=Visualisering av minneprofileringsdata
Comment[nds]=Spiekerleisten-Looptietdaten sichtbor maken
Comment[nl]=Visualisatie van geheugenprofileringsgegevens
Comment[pl]=Wizualizacja danych profilowania pamięci
Comment[pt]=Visualização dos Dados de Performance da Memória
Comment[pt_BR]=Visualização de Dados de Análise da Memória
Comment[ru]=Визуализация данных потребления памяти
Comment[sk]=Vizualizácia dát profilovania pamäte
Comment[sv]=Visualisering av profileringsdata för minne
Comment[tr]=Bellek Profilleme Verisinin Görselleştirilmesi
Comment[ug]=ئىچكى ساقلغۇچتىكى سانلىق-مەلۇماتلارنىڭ سەپلىنىشىنى سۈرۈتلەشتۈرۈش
Comment[uk]=Візуалізація даних профілювання памяті
Comment[x-test]=xxVisualization of Memory Profiling Dataxx
Comment[zh_TW]=
Categories=Qt;KDE;Development;

View file

@ -0,0 +1,55 @@
<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
<kpartgui name="massif-visualizer" version="10">
<MenuBar>
<Menu name="file"><text>&amp;File</text>
<Action name="file_open"/>
<Action name="file_open_recent"/>
<Action name="file_reload"/>
<Separator/>
<DefineGroup name="file_saveas_merge" append="file_saveas_merge"/>
<Separator/>
<Action name="file_close"/>
<Separator/>
<Action name="file_quit"/>
<DefineGroup name="close_merge" append="close_merge"/>
</Menu>
<Menu name="view">
<text>&amp;View</text>
<Action name="selectPeak"/>
</Menu>
<Menu name="settings"><text>&amp;Settings</text>
<Merge name="StandardToolBarMenuHandler" />
<Menu name="dockWidgets"><text>&amp;Dock Widgets</text>
<Action name="toggleDataTree" />
<Action name="toggleAllocators" />
</Menu>
<DefineGroup name="show_toolbar_merge" />
<Action name="set_configure_toolbars" />
<Action name="settings_configure" />
</Menu>
<Menu name="help"><text>&amp;Help</text>
<Action name="help_whats_this"/>
<Separator/>
<Action name="help_report_bug"/>
<Separator/>
<Action name="help_about_app"/>
<Action name="help_about_editor"/>
<Action name="help_about_kde"/>
</Menu>
</MenuBar>
<ToolBar name="mainToolBar"><text>Main Toolbar</text>
<Action name="file_open" />
<Action name="file_close" />
<Separator />
<Action name="shorten_templates" />
<Separator />
<Action name="selectPeak"/>
<Separator />
</ToolBar>
</kpartgui>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
<mime-type type="application/x-valgrind-massif">
<sub-class-of type="text/plain"/>
<comment>Valgrind Massif data file</comment>
<magic priority="50">
<match value="desc: " type="string" offset="0"/>
</magic>
<glob pattern="massif.out.*"/>
</mime-type>
</mime-info>

View file

@ -0,0 +1,41 @@
#
# Find the KGraphViewer library and sets various variables accordingly
#
# Example usage of this module:
# find_package(KGraphViewer 2.1 REQUIRED)
#
# The version number and REQUIRED flag are optional. You can set CMAKE_PREFIX_PATH
# variable to help it find the required files and directories
#
# this will set the following variables:
# KGRAPHVIEWER_LIBRARIES - KGraphViewer library
# KGRAPHVIEWER_FOUND - Whether KGraphViewer was found
# KGRAPHVIEWER_INCLUDE_DIRECTORIES - Include directories for the KGraphViewer library
#
# Copyright 2010 Milian Wolff <mail@milianw.de>
# Redistribution and use is allowed according to the terms of the BSD license.
find_path( KGRAPHVIEWER_INCLUDE_DIRECTORIES
NAMES kgraphviewer_interface.h
HINTS
${KGRAPHVIEWER_INCLUDE_DIRS}
/usr/local/include
/usr/include
PATH_SUFFIXES kgraphviewer
)
find_library( KGRAPHVIEWER_LIBRARIES
NAMES kgraphviewer
HINTS
${KGRAPHVIEWER_LIBRARY_DIRS}
/usr/local/lib64
/usr/lib64
/usr/local/lib
/usr/lib
)
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set KGRAPHVIEWER_FOUND to TRUE if
# all listed variables are TRUE
find_package_handle_standard_args(KGRAPHVIEWER DEFAULT_MSG KGRAPHVIEWER_LIBRARIES KGRAPHVIEWER_INCLUDE_DIRECTORIES)

View file

@ -0,0 +1,3 @@
add_subdirectory(src)

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,148 @@
KD Chart COMMERCIAL LICENSE AGREEMENT
FOR COMMERCIAL VERSIONS
March 27, 2002
IMPORTANT-READ CAREFULLY: This Klaralvdalens Datakonsult AB End-User
License Agreement ("EULA") is a legal agreement between you (either an
individual or a legal entity) and Klaralvdalens Datakonsult AB
("KDAB") for the Klaralvdalens Datakonsult AB software product(s)
accompanying this EULA, which include(s) computer software and may
include "online" or electronic documentation, associated media, and
printed materials ("Licensed Product").
The Licensed Product is protected by copyright laws and international
copyright treaties, as well as other intellectual property laws and
treaties. The Licensed Product is licensed, not sold.
By installing, copying, or otherwise using the Licensed Product, you
agree to be bound by the terms of this EULA. If you do not agree to
the terms of this EULA, do not install, copy, or otherwise use the
Licensed Product; you may, however, return it to your place of
purchase for a full refund. In addition, by installing, copying, or
otherwise using any updates or other components of the Licensed
Product that you receive separately as part of the Licensed Product
("Updates"), you agree to be bound by any additional license terms
that accompany such Updates. If you do not agree to the additional
license terms that accompany such Updates, you may not install, copy,
or otherwise use such Updates.
Upon your acceptance of the terms and conditions of this EULA, KDAB
grants you the right to use the Licensed Product in the manner
provided below.
KDAB grants to you as an individual a personal, nonexclusive,
nontransferable license to make and use copies of the Licensed Product
for the sole purposes of designing, developing, and testing your
software product(s) ("Applications"). You may install copies of the
Licensed Product on an unlimited number of computers provided that you
are the only individual using the Licensed Product. If you are an
entity, KDAB grants you the right to designate one, and only one,
individual within your organization who shall have the sole right to
use the Licensed Product in the manner provided above. You may at any
time, but not more frequently that once every six (6) months,
designate another individual to replace the current designated user by
notifying KDAB, so long as there is no more than one designated user
at any given time.
GENERAL TERMS THAT APPLY TO APPLICATIONS AND REDISTRIBUTABLES
KDAB grants you a nonexclusive, royalty-free right to reproduce and
distribute the object code form of any portion of the Licensed Product
("Redistributables") for execution on any operating system of a type
listed in the License Certificate ("Platforms"). Copies of
Redistributables may only be distributed with and for the sole purpose
of executing Applications permitted under this License Agreement that
you have created using the Licensed Product. Under no circumstances
may any copies of Redistributables be distributed separately.
The license granted in this EULA for you to create your own
Applications and distribute them and the Redistributables (if any) to
your customers is subject to all of the following conditions: (i) all
copies of the Applications you create must bear a valid copyright
notice, either your own or the copyright notice that appears on the
Licensed Product; (ii) you may not remove or alter any copyright,
trademark or other proprietary rights notice contained in any portion
of the Licensed Product; (iii) Redistributables, if any, shall be
licensed to your customer "as is" (KDAB MAKES NO WARRANTIES OR
REPRESENTATIONS VIS-A-VIS YOUR CUSTOMER WITH RESPECT TO
REDISTRIBUTABLES, AND KDAB EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES
VIS-A-VIS YOUR CUSTOMER, WHETHER EXPRESS OR IMPLIED, ORAL OR WRITTEN,
INCLUDING, BUT NOT LIMITED TO ANY IMPLIED WARRANTY OF MERCHANTABILITY
OR FITNESS FOR ANY PARTICULAR PURPOSE, WHETHER OR NOT KDAB KNOWS, HAS
REASON TO KNOW, HAS BEEN ADVISED OR IS OTHERWISE AWARE OF SUCH
PURPOSE); (iv) you will indemnify and hold KDAB, its related companies
and its suppliers, harmless from and against any claims or liabilities
arising out of the use, reproduction or distribution of your
Applications; (v) your Applications must be written using a licensed,
registered copy of the Licensed Product; (vi) your Applications must
add primary and substantial functionality to the Licensed Product;
(vii) your Applications may not pass on functionality which in any way
makes it possible for others to create Applications with the Software;
(viii) your Applications may not compete with the Licensed Product;
(ix)) you may not use KDAB's or any of its suppliers' names, logos, or
trademarks to market your programs, except to state that your program
was written using the Licensed Product.
LICENSEE'S BREACH OF CONTRACT
In addition to penalties, other sanctions and the like as stated in
the Swedish Copyright Act (1960:729), or successive legislation as it
may appear, the Licensee agrees to pay a Contractual Fine in case of
his/her/their breach of any of the above mentioned obligations,
including but not limited to, the Licensee's obligation to let only
one person per license use the Software as stated under above. The
Contractual Fine is EUR 5000 and is payable by the Licensee to the
Licenser immediately upon the Licenser having reasonably demonstrated
that the Licensee is in breach of his obligations in this Agreement.
WARRANTY DISCLAIMER
THE LICENSED PRODUCT IS LICENSED TO YOU "AS IS". TO THE MAXIMUM
EXTENT PERMITTED BY APPLICABLE LAW, KDAB ON BEHALF OF ITSELF AND ITS
SUPPLIERS, DISCLAIMS ALL WARRANTIES AND CONDITIONS, EITHER EXPRESS OR
IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
NON-INFRINGEMENT WITH REGARD TO THE LICENSED PRODUCT. THIS WARRANTY
DISCLAIMER NOTWITHSTANDING, YOU MAY HAVE SPECIFIC LEGAL RIGHTS WHICH
MAY VARY FROM STATE/JURISDICTION TO STATE/JURISDICTION.
LIMITATION OF LIABILITY
IF, KDAB'S WARRANTY DISCLAIMER NOTWITHSTANDING, KDAB IS HELD LIABLE TO
YOU, WHETHER IN CONTRACT, TORT OR ANY OTHER LEGAL THEORY, BASED ON THE
LICENSED PRODUCT, KDAB'S ENTIRE LIABILITY TO YOU AND YOUR EXCLUSIVE
REMEDY SHALL BE, AT KDAB'S OPTION, EITHER (A) RETURN OF THE PRICE YOU
PAID FOR THE LICENSED PRODUCT, OR (B) REPAIR OR REPLACEMENT OF THE
LICENSED PRODUCT, PROVIDED YOU RETURN TO KDAB ALL COPIES OF THE
LICENSED PRODUCT AS ORIGINALLY DELIVERED TO YOU. KDAB SHALL NOT UNDER
ANY CIRCUMSTANCES BE LIABLE TO YOU BASED ON FAILURE OF THE LICENSED
PRODUCT IF THE FAILURE RESULTED FROM ACCIDENT, ABUSE OR
MISAPPLICATION, NOR SHALL KDAB UNDER ANY CIRCUMSTANCES BE LIABLE FOR
SPECIAL DAMAGES, PUNITIVE OR EXEMPLARY DAMAGES, DAMAGES FOR LOSS OF
PROFITS OR INTERRUPTION OF BUSINESS OR FOR LOSS OR CORRUPTION OF DATA.
ANY AWARD OF DAMAGES FROM KDAB TO YOU SHALL NOT EXCEED THE TOTAL AMOUNT
YOU HAVE PAID TO KDAB IN CONNECTION WITH THIS EULA.
SUPPORT AND UPDATES
You will receive email based, software developer support and access to
Updates to the Licensed Product for one year from the date of initial
delivery, in accordance with KDAB support policies and procedures.
Such policies and procedures may be changed from time to time.
GENERAL PROVISIONS
This EULA may only be modified in writing signed by you and an
authorized officer of KDAB. All terms of any purchase order or other
ordering document shall be superseded by this EULA. If any provision
of the EULA is found void or unenforceable, the remainder will remain
valid and enforceable according to its terms. If any remedy provided
is determined to have failed for its essential purpose, all
limitations of liability and exclusions of damages set forth in this
EULA shall remain in effect.
This EULA shall be construed, interpreted and governed by the laws of
Sweden, the venue to be Sunne Tingsratt. The EULA gives you specific
legal rights; you may have others, which vary from state to state and
from country to country. KDAB reserves all rights not specifically
granted in this EULA.

View file

@ -0,0 +1,104 @@
KD Chart COMMERCIAL LICENSE AGREEMENT
FOR COMMERCIAL VERSIONS
Version 1.0
Copyright of this license text (C) 2001 Trolltech AS and (C) 2002-2011
Klaralvdalens Datakonsult AB. All rights reserved. License text used
with kind permission of Trolltech AS. The software and accompanying
material is Copyright (C) 2002-2011 Klaralvdalens Datakonsult AB.
This non-exclusive non-transferable License Agreement ("Agreement") is
between you ("Licensee") and Klaralvdalens Datakonsult AB (KDAB), and
pertains to the Klaralvdalens Datakonsult AB software product(s)
accompanying this Agreement, which include(s) computer software and
may include "online" or electronic documentation, associated media,
and printed materials, including the source code, example programs and
the documentation ("Software").
COPYRIGHT AND RESTRICTIONS
1. All intellectual property rights in the Software are owned by KDAB
and are protected by Swedish copyright laws, other applicable
copyright laws, and international treaty provisions. KDAB retains all
rights not expressly granted. No title, property rights or copyright
in the Software or in any modifications to the Software shall pass to
the Licensee under any circumstances. The Software is licensed, not
sold.
2. By installing, copying, or otherwise using the Software, you agree
to be bound by the terms of this agreement. If you do not agree to the
terms of this Agreement, do not install, copy, or otherwise use the
Software.
3. Upon your acceptance of the terms and conditions of this Agreement,
KDAB grants you the right to use the Software in the manner provided
below.
4. KDAB grants to you as an individual a personal, nonexclusive,
non-transferable license to make and use copies of the Software for
the sole purposes of designing, developing, testing and distributing
your software product(s) ("Applications"). You may install copies of
the Software on an unlimited number of computers provided that you are
the only individual using the Software. If you are an entity, KDAB
grants you the right to designate one, and only one, individual within
your organization who shall have the sole right to use the Software in
the manner provided above.
5. The license granted in this Agreement for you to create and
distribute your own Applications is subject to all of the following
conditions: (i) all copies of the Applications you create must bear a
valid copyright notice, either your own or the copyright notice that
appears on the Software; (ii) you may not remove or alter any
copyright, trademark or other proprietary rights notice contained in
any portion of the Software; (iii) you will indemnify and hold KDAB, its
related companies and its suppliers, harmless from and against any
claims or liabilities arising out of the use and/or reproduction of
your Applications; (iv) your Applications must be written using a
licensed, registered copy of the Software; (v) your Applications must
add primary and substantial functionality to the Software; (vi) your
Applications may not pass on functionality which in any way makes it
possible for others to create Applications with the Software; (vii)
your Applications may not compete with the Software; (viii) you may
not use KDAB's or any of its suppliers' names, logos, or trademarks to
market your programs, except to state that your program was written
using the Software.
6. LICENSEE'S BREACH OF CONTRACT
In addition to penalties, other sanctions and the like as stated in
the Swedish Copyright Act (1960:729), or successive legislation as it
may appear, the Licensee agrees to pay a Contractual Fine in case of
his/her/their breach of any of the above mentioned obligations,
including but not limited to, the Licensee's obligation to let only
one person per license use the Software as stated under above. The
Contractual Fine is EUR 5000 and is payable by the Licensee to the
Licenser immediately upon the Licenser having reasonably demonstrated
that the Licensee is in breach of his obligations in this Agreement.
7. WARRANTY DISCLAIMER
THE SOFTWARE IS LICENSED TO YOU "AS IS". TO THE MAXIMUM EXTENT
PERMITTED BY APPLICABLE LAW, KDAB ON BEHALF OF ITSELF AND ITS SUPPLIERS,
DISCLAIMS ALL WARRANTIES AND CONDITIONS, EITHER EXPRESS OR IMPLIED,
INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT WITH
REGARD TO THE SOFTWARE.
8. LIMITATION OF LIABILITY
IF, KDAB'S WARRANTY DISCLAIMER NOTWITHSTANDING, KDAB IS HELD LIABLE TO
YOU BASED ON THE SOFTWARE, KDAB'S ENTIRE LIABILITY TO YOU AND YOUR
EXCLUSIVE REMEDY SHALL BE, AT REPAIR OR REPLACEMENT OF THE SOFTWARE,
PROVIDED YOU RETURN TO KDAB ALL COPIES OF THE SOFTWARE AS ORIGINALLY
DELIVERED TO YOU. KDAB SHALL NOT UNDER ANY CIRCUMSTANCES BE LIABLE TO
YOU BASED ON FAILURE OF THE SOFTWARE IF THE FAILURE RESULTED FROM
ACCIDENT, ABUSE OR MISAPPLICATION, NOR SHALL KDAB UNDER ANY
CIRCUMSTANCES BE LIABLE FOR SPECIAL DAMAGES, PUNITIVE OR EXEMPLARY
DAMAGES, DAMAGES FOR LOSS OF PROFITS OR INTERRUPTION OF BUSINESS OR
FOR LOSS OR CORRUPTION OF DATA.
9. This Agreement may only be modified in writing signed by you and an
authorized officer of KDAB. All terms of any purchase order or other
ordering document shall be superseded by this Agreement.
10. This Agreement shall be construed, interpreted and governed by the
laws of Sweden, the venue to be Sunne Tingsratt.

View file

@ -0,0 +1 @@
#include "CartesianCoordinateTransformation.h"

View file

@ -0,0 +1,147 @@
/****************************************************************************
** Copyright (C) 2001-2013 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 {
CoordinateTransformation()
: axesCalcModeY( CartesianCoordinatePlane::Linear ),
axesCalcModeX( CartesianCoordinatePlane::Linear ),
isPositiveX( true ),
isPositiveY( true )
{}
CartesianCoordinatePlane::AxesCalcMode axesCalcModeY;
CartesianCoordinatePlane::AxesCalcMode axesCalcModeX;
ZoomParameters zoom;
QTransform transform;
QTransform backTransform;
// a logarithmic scale cannot cross zero, so we have to know which side we are on.
bool isPositiveX;
bool isPositiveY;
qreal logTransform( qreal value, bool isPositiveRange ) const
{
if ( isPositiveRange ) {
return log10( value );
} else {
return -log10( -value );
}
}
qreal logTransformBack( qreal value, bool wasPositive ) const
{
if ( wasPositive ) {
return pow( 10.0, value );
} else {
return -pow( 10.0, -value );
}
}
void updateTransform( const QRectF& constDataRect, const QRectF& screenRect )
{
QRectF dataRect = constDataRect;
if ( axesCalcModeX == CartesianCoordinatePlane::Logarithmic ) {
// the data will be scaled by logTransform() later, so scale its bounds as well
isPositiveX = dataRect.left() >= 0.0;
dataRect.setLeft( logTransform( dataRect.left(), isPositiveX ) );
dataRect.setRight( logTransform( dataRect.right(), isPositiveX ) );
}
if ( axesCalcModeY == CartesianCoordinatePlane::Logarithmic ) {
isPositiveY = dataRect.top() >= 0.0;
dataRect.setTop( logTransform( dataRect.top(), isPositiveY ) );
dataRect.setBottom( logTransform( dataRect.bottom(), isPositiveY ) );
}
transform.reset();
// read the following transformation sequence from bottom to top(!)
transform.translate( screenRect.left(), screenRect.bottom() );
transform.scale( screenRect.width(), screenRect.height() );
// TODO: mirror in case of "reverse" axes?
// transform into screen space
transform.translate( 0.5, -0.5 );
transform.scale( zoom.xFactor, zoom.yFactor );
transform.translate( -zoom.xCenter, 1.0 - zoom.yCenter );
// zoom
transform.scale( 1.0 / dataRect.width(), 1.0 / dataRect.height() );
transform.translate( -dataRect.left(), -dataRect.bottom() );
// transform into the unit square
backTransform = transform.inverted();
}
// convert data space point to screen point
inline QPointF translate( const QPointF& dataPoint ) const
{
QPointF data = dataPoint;
if ( axesCalcModeX == CartesianCoordinatePlane::Logarithmic ) {
data.setX( logTransform( data.x(), isPositiveX ) );
}
if ( axesCalcModeY == CartesianCoordinatePlane::Logarithmic ) {
data.setY( logTransform( data.y(), isPositiveY ) );
}
return transform.map( data );
}
// convert screen point to data space point
inline const QPointF translateBack( const QPointF& screenPoint ) const
{
QPointF ret = backTransform.map( screenPoint );
if ( axesCalcModeX == CartesianCoordinatePlane::Logarithmic ) {
ret.setX( logTransformBack( ret.x(), isPositiveX ) );
}
if ( axesCalcModeY == CartesianCoordinatePlane::Logarithmic ) {
ret.setY( logTransformBack( ret.y(), isPositiveY ) );
}
return ret;
}
};
typedef QList<CoordinateTransformation> CoordinateTransformationList;
}
#endif

View file

@ -0,0 +1 @@
#include "ChartGraphicsItem.h"

View file

@ -0,0 +1,54 @@
/****************************************************************************
** Copyright (C) 2001-2013 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 CHARTGRAPHICSITEM_H
#define CHARTGRAPHICSITEM_H
#include <QGraphicsPolygonItem>
namespace KDChart {
/**
* @brief Graphics item used inside of the ReverseMapper
* \internal
*/
class ChartGraphicsItem : public QGraphicsPolygonItem
{
public:
enum { Type = UserType + 1 };
ChartGraphicsItem();
ChartGraphicsItem( int row, int column );
int row() const { return m_row; }
int column() const { return m_column; }
int type() const { return Type; }
private:
int m_row;
int m_column;
};
}
#endif

View file

@ -0,0 +1,45 @@
#include "KDChartDatasetProxyModel.h"
#include "KDChartNullPaintDevice.h"
#include "KDChartChart.h"
#include "KDChartHeaderFooter.h"
#include "KDChartGlobal.h"
#include "KDChartDataValueAttributes.h"
#include "KDChartPalette.h"
#include "KDChartSignalCompressor.h"
#include "KDChartDiagramObserver.h"
#include "KDTextDocument.h"
#include "KDChartMeasure.h"
#include "KDChartGridAttributes.h"
#include "KDChartPrintingParameters.h"
#include "KDChartLineAttributes.h"
#include "KDChartValueTrackerAttributes.h"
#include "ReverseMapper.h"
#include "KDChartAbstractGrid.h"
#include "KDChartRulerAttributes.h"
#include "KDChartTextArea.h"
#include "KDChartAttributesModel.h"
#include "KDChartEnums.h"
#include "kdchart_export.h"
#include "KDChartAbstractCoordinatePlane.h"
#include "KDChartLegend.h"
#include "KDChartRelativePosition.h"
#include "KDChartAbstractDiagram.h"
#include "KDChartMarkerAttributes.h"
#include "KDChartAbstractAxis.h"
#include "KDChartTextAttributes.h"
#include "KDChartFrameAttributes.h"
#include "KDChartAbstractThreeDAttributes.h"
#include "KDChartTextLabelCache.h"
#include "KDChartBackgroundAttributes.h"
#include "KDChartAbstractAreaWidget.h"
#include "KDChartThreeDLineAttributes.h"
#include "KDChartPosition.h"
#include "KDChartZoomParameters.h"
#include "ChartGraphicsItem.h"
#include "KDChartAbstractAreaBase.h"
#include "KDChartPaintContext.h"
#include "KDChartAbstractProxyModel.h"
#include "KDChartDatasetSelector.h"
#include "KDChartLayoutItems.h"
#include "KDChartAbstractArea.h"
#include "KDChartWidget.h"

View file

@ -0,0 +1 @@
#include "KDChartAbstractArea.h"

View file

@ -0,0 +1,136 @@
/****************************************************************************
** Copyright (C) 2001-2013 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 triple 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() ;
/**
* @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 * );
}; // End of class AbstractArea
}
#endif // KDCHARTABSTRACTAREA_H

View file

@ -0,0 +1 @@
#include "KDChartAbstractAreaBase.h"

View file

@ -0,0 +1,132 @@
/****************************************************************************
** Copyright (C) 2001-2013 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"
QT_BEGIN_NAMESPACE
class QPainter;
class QString;
QT_END_NAMESPACE
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 @@
#include "KDChartAbstractAreaWidget.h"

View file

@ -0,0 +1,119 @@
/****************************************************************************
** Copyright (C) 2001-2013 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 @@
#include "KDChartAbstractAxis.h"

View file

@ -0,0 +1,247 @@
/****************************************************************************
** Copyright (C) 2001-2013 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"
QT_BEGIN_NAMESPACE
class QPainter;
class QSizeF;
QT_END_NAMESPACE
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 pass a smaller number of strings than the number of labels drawn at this
axis, KD Chart will repeat 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();
Q_SIGNALS:
void coordinateSystemChanged();
};
}
#endif // KDCHARTABSTRACTAXIS_H

View file

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

View file

@ -0,0 +1,132 @@
/****************************************************************************
** Copyright (C) 2001-2013 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;
/**
* @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_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 Q_SLOTS:
void connectAttributesModel( AttributesModel* );
protected:
/** @return the 3D item depth of the model index \a index */
virtual qreal threeDItemDepth( const QModelIndex& index ) const = 0;
/** @return the 3D item depth of the data set \a column */
virtual qreal threeDItemDepth( int column ) const = 0;
};
}
#endif

View file

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

View file

@ -0,0 +1,446 @@
/****************************************************************************
** Copyright (C) 2001-2013 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
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;
/**
* @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 qreal zoomFactorX() const { return 1.0; }
/**
* @return The zoom factor in vertical direction, that is applied
* to all coordinate transformations.
*/
virtual qreal zoomFactorY() const { return 1.0; }
/**
* Sets both zoom factors in one go.
* \sa setZoomFactorX,setZoomFactorY
*/
virtual void setZoomFactors( qreal factorX, qreal 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( qreal 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( qreal 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;
/**
* @return Whether this plane should have spacers in the corners
* formed by the presence of axes.
*/
bool isCornerSpacersEnabled() const;
/**
* Enables or disables the use of spacers in the plane corners.
*/
void setCornerSpacersEnabled( bool enable );
virtual AbstractCoordinatePlane* sharedAxisMasterPlane( QPainter* p = 0 ); // KDChart 3: const method?
/** 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();
void boundariesChanged();
/** 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 );
/** Emitted upon change of the view coordinate system */
void viewportCoordinateSystemChanged();
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

View file

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

View file

@ -0,0 +1,742 @@
/****************************************************************************
** Copyright (C) 2001-2013 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 KDCHARTABSTRACTDIAGRAM_H
#define KDCHARTABSTRACTDIAGRAM_H
#include <QList>
#include <QRectF>
#include <QAbstractItemView>
#include "KDChartGlobal.h"
#include "KDChartMarkerAttributes.h"
#include "KDChartAttributesModel.h"
namespace KDChart {
class AbstractCoordinatePlane;
class AttributesModel;
class DataValueAttributes;
class PaintContext;
/**
* @brief AbstractDiagram defines the interface for diagram classes
*
* AbstractDiagram is the base class for diagram classes ("chart types").
*
* It defines the interface, that needs to be implemented for the diagram,
* to function within the KDChart framework. It extends Interview's
* QAbstractItemView.
*/
class KDCHART_EXPORT AbstractDiagram : public QAbstractItemView
{
Q_OBJECT
Q_DISABLE_COPY( AbstractDiagram )
KDCHART_DECLARE_PRIVATE_BASE_POLYMORPHIC( AbstractDiagram )
friend class AbstractCoordinatePlane;
friend class CartesianCoordinatePlane;
friend class PolarCoordinatePlane;
protected:
explicit inline AbstractDiagram(
Private *p, QWidget* parent, AbstractCoordinatePlane* plane );
explicit AbstractDiagram (
QWidget* parent = 0, AbstractCoordinatePlane* plane = 0 );
public:
virtual ~AbstractDiagram();
/**
* Returns true if both diagrams have the same settings.
*/
bool compare( const AbstractDiagram* other ) const;
/**
* @brief Return the bottom left and top right data point, that the
* diagram will display (unless the grid adjusts these values).
*
* This method returns a cached result of calculations done by
* calculateDataBoundaries.
* Classes derived from AbstractDiagram must implement the
* calculateDataBoundaries function, to specify their own
* way of calculating the data boundaries.
* If derived classes want to force recalculation of the
* data boundaries, they can call setDataBoundariesDirty()
*
* Returned value is in diagram coordinates.
*/
const QPair<QPointF, QPointF> dataBoundaries() const;
// protected: // FIXME: why should that be private? (Mirko)
/**
* Draw the diagram contents to the rectangle and painter, that are
* passed in as part of the paint context.
*
* @param paintContext All information needed for painting.
*/
virtual void paint ( PaintContext* paintContext ) = 0;
/**
* Called by the widget's sizeEvent. Adjust all internal structures,
* that are calculated, dependending on the size of the widget.
*
* @param area
*/
virtual void resize ( const QSizeF& area ) = 0;
/** Associate a model with the diagram. */
virtual void setModel ( QAbstractItemModel * model );
/** Associate a seleection model with the diagrom. */
virtual void setSelectionModel( QItemSelectionModel* selectionModel );
/**
* Associate an AttributesModel with this diagram. Note that
* the diagram does _not_ take ownership of the AttributesModel.
* This should thus only be used with AttributesModels that
* have been explicitly created by the user, and are owned
* by her. Setting an AttributesModel that is internal to
* another diagram is an error.
*
* Correct:
*
* \code
* AttributesModel *am = new AttributesModel( model, 0 );
* diagram1->setAttributesModel( am );
* diagram2->setAttributesModel( am );
*
* \endcode
*
* Wrong:
*
* \code
*
* diagram1->setAttributesModel( diagram2->attributesModel() );
*
* \endcode
*
* @param model The AttributesModel to use for this diagram.
* @see AttributesModel, usesExternalAttributesModel
*/
virtual void setAttributesModel( AttributesModel* model );
/**
* Returns whether the diagram is using its own built-in attributes model
* or an attributes model that was set via setAttributesModel.
*
* @see setAttributesModel
*/
virtual bool usesExternalAttributesModel() const;
/**
* Returns the AttributesModel, that is used by this diagram.
* By default each diagram owns its own AttributesModel, which
* should never be deleted. Only if a user-supplied AttributesModel
* has been set does the pointer returned here not belong to the
* diagram.
*
* @return The AttributesModel associated with the diagram.
* @see setAttributesModel
*/
virtual AttributesModel* attributesModel() const;
/** Set the root index in the model, where the diagram starts
* referencing data for display. */
virtual void setRootIndex ( const QModelIndex& idx );
/** \reimpl */
virtual QRect visualRect(const QModelIndex &index) const;
/** \reimpl */
virtual void scrollTo(const QModelIndex &index, ScrollHint hint = EnsureVisible);
/** \reimpl */
virtual QModelIndex indexAt(const QPoint &point) const;
/** \reimpl */
virtual QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers);
/** \reimpl */
virtual int horizontalOffset() const;
/** \reimpl */
virtual int verticalOffset() const;
/** \reimpl */
virtual bool isIndexHidden(const QModelIndex &index) const;
/** \reimpl */
virtual void setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command);
/** \reimpl */
virtual QRegion visualRegionForSelection(const QItemSelection &selection) const;
virtual QRegion visualRegion(const QModelIndex &index) const;
/** \reimpl */
#if QT_VERSION < 0x050000
virtual void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
#else
virtual void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles = QVector<int>());
#endif
/** \reimpl */
virtual void doItemsLayout();
/**
* The coordinate plane associated with the diagram. This determines
* how coordinates in value space are mapped into pixel space. By default
* this is a CartesianCoordinatePlane.
* @return The coordinate plane associated with the diagram.
*/
AbstractCoordinatePlane* coordinatePlane() const;
/**
* Set the coordinate plane associated with the diagram. This determines
* how coordinates in value space are mapped into pixel space. The chart
* takes ownership.
* @return The coordinate plane associated with the diagram.
*/
virtual void setCoordinatePlane( AbstractCoordinatePlane* plane );
/**
* Hide (or unhide, resp.) a data cell.
*
* \note Hidden data are still taken into account by the coordinate plane,
* so neither the grid nor your axes' ranges will change, when you hide data.
* For totally removing data from KD Chart's view you can use another approach:
* e.g. you could define a proxy model on top of your data model, and register
* the proxy model calling setModel() instead of registering your real data model.
*
* @param index The datapoint to set the hidden status for. With a dataset dimension
* of two, this is the index of the key of each key/value pair.
* @param hidden The hidden status to set.
*/
void setHidden( const QModelIndex & index, bool hidden );
/**
* Hide (or unhide, resp.) a dataset.
*
* \note Hidden data are still taken into account by the coordinate plane,
* so neither the grid nor your axes' ranges will change, when you hide data.
* For totally removing data from KD Chart's view you can use another approach:
* e.g. you could define a proxy model on top of your data model, and register
* the proxy model calling setModel() instead of registering your real data model.
*
* @param dataset The dataset to set the hidden status for.
* @param hidden The hidden status to set.
*/
void setHidden( int dataset, bool hidden );
/**
* Hide (or unhide, resp.) all datapoints in the model.
*
* \note Hidden data are still taken into account by the coordinate plane,
* so neither the grid nor your axes' ranges will change, when you hide data.
* For totally removing data from KD Chart's view you can use another approach:
* e.g. you could define a proxy model on top of your data model, and register
* the proxy model calling setModel() instead of registering your real data model.
*
* @param hidden The hidden status to set.
*/
void setHidden( bool hidden );
/**
* Retrieve the hidden status specified globally. This will fall
* back automatically to the default settings ( = not hidden), if there
* are no specific settings.
* @return The global hidden status.
*/
bool isHidden() const;
/**
* Retrieve the hidden status for the given dataset. This will fall
* back automatically to what was set at diagram level, if there
* are no dataset specific settings.
* @param dataset The dataset to retrieve the hidden status for.
* @return The hidden status for the given dataset.
*/
bool isHidden( int dataset ) const;
/**
* Retrieve the hidden status for the given index. This will fall
* back automatically to what was set at dataset or diagram level, if there
* are no datapoint specific settings.
* @param index The datapoint to retrieve the hidden status for.
* @return The hidden status for the given index.
*/
bool isHidden( const QModelIndex & index ) const;
/**
* Set the DataValueAttributes for the given index.
* @param index The datapoint to set the attributes for. With a dataset dimension
* of two, this is the index of the key of each key/value pair.
* @param a The attributes to set.
*/
void setDataValueAttributes( const QModelIndex & index,
const DataValueAttributes & a );
/**
* Set the DataValueAttributes for the given dataset.
* @param dataset The dataset to set the attributes for.
* @param a The attributes to set.
*/
void setDataValueAttributes( int dataset, const DataValueAttributes & a );
/**
* Set the DataValueAttributes for all datapoints in the model.
* @param a The attributes to set.
*/
void setDataValueAttributes( const DataValueAttributes & a );
/**
* Retrieve the DataValueAttributes specified globally. This will fall
* back automatically to the default settings, if there
* are no specific settings.
* @return The global DataValueAttributes.
*/
DataValueAttributes dataValueAttributes() const;
/**
* Retrieve the DataValueAttributes for the given dataset. This will fall
* back automatically to what was set at model level, if there
* are no dataset specific settings.
* @param dataset The dataset to retrieve the attributes for.
* @return The DataValueAttributes for the given dataset.
*/
DataValueAttributes dataValueAttributes( int dataset ) const;
/**
* Retrieve the DataValueAttributes for the given index. This will fall
* back automatically to what was set at dataset or model level, if there
* are no datapoint specific settings.
* @param index The datapoint to retrieve the attributes for. With a dataset dimension
* of two, this is the index of the key of each key/value pair.
* @return The DataValueAttributes for the given index.
*/
DataValueAttributes dataValueAttributes( const QModelIndex & index ) const;
/**
* Set the pen to be used, for painting the datapoint at the given index.
* @param index The datapoint's index in the model. With a dataset dimension
* of two, this is the index of the key of each key/value pair.
* @param pen The pen to use.
*/
void setPen( const QModelIndex& index, const QPen& pen );
/**
* Set the pen to be used, for painting the given dataset.
* @param dataset The dataset to set the pen for.
* @param pen The pen to use.
*/
void setPen( int dataset, const QPen& pen );
/**
* Set the pen to be used, for painting all datasets in the model.
* @param pen The pen to use.
*/
void setPen( const QPen& pen );
/**
* Retrieve the pen to be used for painting datapoints globally. This will fall
* back automatically to the default settings, if there
* are no specific settings.
* @return The pen to use for painting.
*/
QPen pen() const;
/**
* Retrieve the pen to be used for the given dataset. This will fall
* back automatically to what was set at model level, if there
* are no dataset specific settings.
* @param dataset The dataset to retrieve the pen for.
* @return The pen to use for painting.
*/
QPen pen( int dataset ) const;
/**
* Retrieve the pen to be used, for painting the datapoint at the given
* index in the model.
* @param index The index of the datapoint in the model. With a dataset dimension
* of two, this is the index of the key of each key/value pair.
* @return The pen to use for painting.
*/
QPen pen( const QModelIndex& index ) const;
/**
* Set the brush to be used, for painting the datapoint at the given index.
* @param index The datapoint's index in the model. With a dataset dimension
* of two, this is the index of the key of each key/value pair.
* @param brush The brush to use.
*/
void setBrush( const QModelIndex& index, const QBrush& brush);
/**
* Set the brush to be used, for painting the given dataset.
* @param dataset The dataset to set the brush for.
* @param brush The brush to use.
*/
void setBrush( int dataset, const QBrush& brush );
/**
* Set the brush to be used, for painting all datasets in the model.
* @param brush The brush to use.
*/
void setBrush( const QBrush& brush);
/**
* Retrieve the brush to be used for painting datapoints globally. This will fall
* back automatically to the default settings, if there
* are no specific settings.
* @return The brush to use for painting.
*/
QBrush brush() const;
/**
* Retrieve the brush to be used for the given dataset. This will fall
* back automatically to what was set at model level, if there
* are no dataset specific settings.
* @param dataset The dataset to retrieve the brush for.
* @return The brush to use for painting.
*/
QBrush brush( int dataset ) const;
/**
* Retrieve the brush to be used, for painting the datapoint at the given
* index in the model.
* @param index The index of the datapoint in the model. With a dataset dimension
* of two, this is the index of the key of each key/value pair.
* @return The brush to use for painting.
*/
QBrush brush( const QModelIndex& index ) const;
/**
* Set the unit prefix to be used on axes for one specific column.
* @param prefix The prefix to be used.
* @param column The column which should be set.
* @param orientation The orientation of the axis to use.
*/
void setUnitPrefix( const QString& prefix, int column, Qt::Orientation orientation );
/**
* Set the unit prefix to be used on axes for all columns.
* @param prefix The prefix to be used.
* @param orientation The orientation of the axis to use.
*/
void setUnitPrefix( const QString& prefix, Qt::Orientation orientation );
/**
* Set the unit prefix to be used on axes for one specific column.
* @param suffix The suffix to be used.
* @param column The column which should be set.
* @param orientation The orientation of the axis to use.
*/
void setUnitSuffix( const QString& suffix, int column, Qt::Orientation orientation );
/**
* Set the unit prefix to be used on axes for all columns.
* @param suffix The suffix to be used.
* @param orientation The orientation of the axis to use.
*/
void setUnitSuffix( const QString& suffix, Qt::Orientation orientation );
/**
* Retrieves the axis unit prefix for a specific column.
* @param column The column whose prefix should be retrieved.
* @param orientation The orientation of the axis.
* @param fallback If true, the prefix for all columns is returned, when
* none is set for the selected column.
* @return The axis unit prefix.
*/
QString unitPrefix( int column, Qt::Orientation orientation, bool fallback = false ) const;
/**
* Retrieves the axis unit prefix.
* @param orientation The orientation of the axis.
* @return The axis unit prefix.
*/
QString unitPrefix( Qt::Orientation orientation ) const;
/**
* Retrieves the axis unit suffix for a specific column.
* @param column The column whose prefix should be retrieved.
* @param orientation The orientation of the axis.
* @param fallback If true, the suffix for all columns is returned, when
* none is set for the selected column.
* @return The axis unit suffix.
*/
QString unitSuffix( int column, Qt::Orientation orientation, bool fallback = false ) const;
/**
* Retrieves the axis unit suffix.
* @param orientation The orientation of the axis.
* @return The axis unit suffix.
*/
QString unitSuffix( Qt::Orientation orientation ) const;
/**
* Set whether data value labels are allowed to overlap.
* @param allow True means that overlapping labels are allowed.
*/
void setAllowOverlappingDataValueTexts( bool allow );
/**
* @return Whether data value labels are allowed to overlap.
*/
bool allowOverlappingDataValueTexts() const;
/**
* Set whether anti-aliasing is to be used while rendering
* this diagram.
* @param enabled True means that AA is enabled.
*/
void setAntiAliasing( bool enabled );
/**
* @return Whether anti-aliasing is to be used for rendering
* this diagram.
*/
bool antiAliasing() const;
/**
* Set the palette to be used, for painting datasets to the default
* palette.
* @see KDChart::Palette.
* FIXME: fold into one usePalette (KDChart::Palette&) method
*/
void useDefaultColors();
/**
* Set the palette to be used, for painting datasets to the rainbow
* palette.
* @see KDChart::Palette.
*/
void useRainbowColors();
/**
* Set the palette to be used, for painting datasets to the subdued
* palette.
* @see KDChart::Palette.
*/
void useSubduedColors();
/**
* The set of item row labels currently displayed, for use in Abscissa axes, etc.
* @return The set of item row labels currently displayed.
*/
QStringList itemRowLabels() const;
/**
* The set of dataset labels currently displayed, for use in legends, etc.
* @return The set of dataset labels currently displayed.
*/
QStringList datasetLabels() const;
/**
* The set of dataset brushes currently used, for use in legends, etc.
*
* @note Cell-level override brushes, if set, take precedence over the
* dataset values, so you might need to check these too, in order to find
* the brush, that is used for a single cell.
*
* @return The current set of dataset brushes.
*/
QList<QBrush> datasetBrushes() const;
/**
* The set of dataset pens currently used, for use in legends, etc.
*
* @note Cell-level override pens, if set, take precedence over the
* dataset values, so you might need to check these too, in order to find
* the pens, that is used for a single cell.
*
* @return The current set of dataset pens.
*/
QList<QPen> datasetPens() const;
/**
* The set of dataset markers currently used, for use in legends, etc.
*
* @note Cell-level override markers, if set, take precedence over the
* dataset values, so you might need to check these too, in order to find
* the marker, that is shown for a single cell.
*
* @return The current set of dataset brushes.
*/
QList<MarkerAttributes> datasetMarkers() const;
/**
* \deprecated
*
* \brief Deprecated method that turns the percent mode of this diagram on or off.
*
* This method is deprecated. Use the setType() method of a supporting diagram implementation
* instead, e.g. BarDiagram::setType().
*
* \see percentMode
*/
void setPercentMode( bool percent );
/**
* \brief Returns whether this diagram is drawn in percent mode.
*
* If true, all data points in the same column of a diagram will
* be be drawn at the same X coordinate and stacked up so that the distance from the
* last data point (or the zero line) to a data point P is always the ratio of (Y-Value of P)/
* (sum of all Y-Values in same column as P) relative to the diagrams height
* (or width, if abscissa and ordinate are swapped).
*
* Note that this property is not applicable to all diagram types.
*/
bool percentMode() const;
virtual void paintMarker( QPainter* painter,
const MarkerAttributes& markerAttributes,
const QBrush& brush, const QPen&,
const QPointF& point, const QSizeF& size );
/**
* The dataset dimension of a diagram determines how many value dimensions
* it expects each datapoint to have.
* For each dimension and data series it will expect one column of values in the model.
* If the dimension is 1, automatic values will be used for X.
*
* For example, a diagram with the default dimension of 1 will have one column
* per data series (the Y values) and will use automatic values for X
* (1, 2, 3, ... n).
* If the dimension is 2, the diagram will use the first, (and the third,
* fifth, etc) columns as X values, and the second, (and the fourth, sixth,
* etc) column as Y values.
* @return The dataset dimension of the diagram.
*/
int datasetDimension() const;
/**
* \deprecated
*
* Sets the dataset dimension of the diagram. Using this method
* is deprecated. Use the specific diagram types instead.
*/
void setDatasetDimension( int dimension );
protected:
void setDatasetDimensionInternal( int dimension );
public:
void update() const;
void paintMarker( QPainter* painter, const DataValueAttributes& a,
const QModelIndex& index,
const QPointF& pos );
void paintMarker( QPainter* painter,
const QModelIndex& index,
const QPointF& pos );
void paintDataValueText( QPainter* painter, const QModelIndex& index,
const QPointF& pos, qreal value );
// reverse mapping:
/** This method is added alongside with indexAt from QAIM,
since in kdchart multiple indexes can be displayed at the same
spot. */
QModelIndexList indexesAt( const QPoint& point ) const;
QModelIndexList indexesIn( const QRect& rect ) const;
protected:
virtual bool checkInvariants( bool justReturnTheStatus=false ) const;
virtual const QPair<QPointF, QPointF> calculateDataBoundaries() const = 0;
protected Q_SLOTS:
void setDataBoundariesDirty() const;
protected:
/**
* \deprecated
* This method is deprecated and provided for backward-compatibility only.
* Your own diagram classes should call
* d->paintDataValueTextsAndMarkers() instead
* which also is taking care for showing your cell-specific comments, if any,
*/
virtual void paintDataValueTexts( QPainter* painter );
/**
* \deprecated
* This method is deprecated and provided for backward-compatibility only.
* Your own diagram classes should call
* d->paintDataValueTextsAndMarkers() instead
* which also is taking care for showing your cell-specific comments, if any,
*/
virtual void paintMarkers( QPainter* painter );
void setAttributesModelRootIndex( const QModelIndex& );
QModelIndex attributesModelRootIndex() const;
/**
* Helper method, retrieving the data value (DisplayRole) for a given row and column
* @param row The row to query.
* @param column The column to query.
* @return The value of the display role at the given row and column as a qreal.
* @deprecated
*/
qreal valueForCell( int row, int column ) const;
Q_SIGNALS:
/** Diagrams are supposed to emit this signal, when the layout of one
of their element changes. Layouts can change, for example, when
axes are added or removed, or when the configuration was changed
in a way that the axes or the diagram itself are displayed in a
different geometry.
Changes in the diagrams coordinate system also result
in the layoutChanged() signal being emitted.
*/
void layoutChanged( AbstractDiagram* );
/**
* This signal is emitted when this diagram is being destroyed, but before all the
* data, i.e. the attributes model, is invalidated.
*/
void aboutToBeDestroyed();
/** This signal is emitted when either the model or the AttributesModel is replaced. */
void modelsChanged();
/** This signal is emitted just before the new attributes model is connected internally.
It gives you a chance to connect to its signals first or perform other setup work. */
void attributesModelAboutToChange( AttributesModel* newModel, AttributesModel* oldModel );
/** This signal is emitted, when the model data is changed. */
void modelDataChanged();
/** This signal is emitted, when the hidden status of at least one data cell was (un)set. */
void dataHidden();
/** Emitted upon change of a property of the Diagram. */
void propertiesChanged();
/** Emitted upon change of a data boundary */
void boundariesChanged();
/** Emitted upon change of the view coordinate system */
void viewportCoordinateSystemChanged();
private:
QModelIndex conditionallyMapFromSource( const QModelIndex & sourceIndex ) const;
};
typedef QList<AbstractDiagram*> AbstractDiagramList;
typedef QList<const AbstractDiagram*> ConstAbstractDiagramList;
/**
* @brief Internally used class just adding a special constructor used by AbstractDiagram
*/
class PrivateAttributesModel : public AttributesModel {
Q_OBJECT
public:
explicit PrivateAttributesModel( QAbstractItemModel* model, QObject * parent = 0 )
: AttributesModel(model,parent) {}
};
}
#endif

View file

@ -0,0 +1 @@
#include "KDChartAbstractGrid.h"

View file

@ -0,0 +1,159 @@
/****************************************************************************
** Copyright (C) 2001-2013 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 KDCHARTABSTRACTGRID_H
#define KDCHARTABSTRACTGRID_H
#include <QPair>
#include "KDChartAbstractCoordinatePlane.h"
#include "KDChartGridAttributes.h"
#include "KDChartAbstractDiagram.h"
#include "KDChartCartesianAxis.h"
namespace KDChart {
class PaintContext;
/**
* \internal
*
* \brief Abstract base class for grid classes: cartesian, polar, ...
*
* The AbstractGrid interface is the base class used by
* AbstractCoordinatePlane, for calculating and for drawing
* the grid lines of the plane.
*/
class AbstractGrid
{
public:
virtual ~AbstractGrid();
protected:
AbstractGrid ();
public:
/** \brief Returns the cached result of data calculation.
*
* For this, all derived classes need to implement the
* pure-virtual calculateGrid() method.
*/
DataDimensionsList updateData( AbstractCoordinatePlane* plane );
/**
* Doing the actual drawing.
*
* Every derived class must implement this.
*
* \note When implementing drawGrid(): Before you start drawing,
* make sure to call updateData(), to get the data boundaries
* recalculated.
* For an example, see the implementation of CartesianGrid:drawGrid().
*/
virtual void drawGrid( PaintContext* context ) = 0;
/**
* Causes grid to be recalculated upon the next call
* of updateData().
*
* \see calculateGrid
*/
void setNeedRecalculate();
/**
* Checks whether both coordinates of r are valid according
* to isValueValid
*
* \see isValueValid
*/
static bool isBoundariesValid(const QRectF& r );
/**
* Checks whether both coordinates of both points are valid
* according to isValueValid
*
* \see isValueValid
*/
static bool isBoundariesValid(const QPair<QPointF,QPointF>& b );
/**
* Checks whether all start and end properties of every
* DataDimension in the list l are valid according to
* isValueValid().
*
* \see isValueValid
*/
static bool isBoundariesValid(const DataDimensionsList& l );
/**
* Checks if r is neither NaN nor infinity.
*/
static bool isValueValid(const qreal& r );
/**
* Adjusts \a start and/or \a end so that they are a multiple of
* \a stepWidth
*/
static void adjustLowerUpperRange(
qreal& start, qreal& end,
qreal stepWidth,
bool adjustLower, bool adjustUpper );
/**
* Adjusts \a dim so that \c dim.start and/or \c dim.end are a multiple
* of \c dim.stepWidth.
*
* \see adjustLowerUpperRange
*/
static const DataDimension adjustedLowerUpperRange(
const DataDimension& dim,
bool adjustLower, bool adjustUpper );
GridAttributes gridAttributes;
protected:
DataDimensionsList mDataDimensions;
AbstractCoordinatePlane* mPlane;
private:
/**
* \brief Calculates the grid start/end/step width values.
*
* Gets the raw data dimensions - e.g. the data model's boundaries,
* together with their isCalculated flags.
*
* Returns the calculated start/end values for the grid, and their
* respective step widths.
* If at least one of the step widths is Zero, all dimensions of
* the returned list are considered invalid!
*
* \note This function needs to be implemented by all derived classes,
* like CartesianGrid, PolarGrid, ...
*/
virtual DataDimensionsList calculateGrid( const DataDimensionsList& rawDataDimensions ) const = 0;
DataDimensionsList mCachedRawDataDimensions;
};
}
#endif

View file

@ -0,0 +1 @@
#include "KDChartLayoutItems.h"

View file

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

View file

@ -0,0 +1,96 @@
/****************************************************************************
** Copyright (C) 2001-2013 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 KDCHARTABSTRACTPIEDIAGRAM_H
#define KDCHARTABSTRACTPIEDIAGRAM_H
#include "KDChartAbstractPolarDiagram.h"
namespace KDChart {
class PieAttributes;
class ThreeDPieAttributes;
/**
* @brief Base class for any diagram type
*/
class KDCHART_EXPORT AbstractPieDiagram : public AbstractPolarDiagram
{
Q_OBJECT
Q_DISABLE_COPY( AbstractPieDiagram )
KDCHART_DECLARE_DERIVED_DIAGRAM( AbstractPieDiagram, PolarCoordinatePlane )
public:
explicit AbstractPieDiagram(
QWidget* parent = 0, PolarCoordinatePlane* plane = 0 );
virtual ~AbstractPieDiagram();
/**
* Returns true if both diagrams have the same settings.
*/
bool compare( const AbstractPieDiagram* other ) const;
/** Set the granularity: the smaller the granularity the more your diagram
* segments will show facettes instead of rounded segments.
* \param value the granularity value between 0.05 (one twentieth of a degree)
* and 36.0 (one tenth of a full circle), other values will be interpreted as 1.0.
*/
void setGranularity( qreal value );
/** @return the granularity. */
qreal granularity() const;
/** \deprecated Use PolarCoordinatePlane::setStartPosition( qreal degrees ) instead. */
void setStartPosition( int degrees );
/** \deprecated Use qreal PolarCoordinatePlane::startPosition instead. */
int startPosition() const;
/** If this property is set, and if a pie's TextAttributes have no rotation set, its labels will
* automatically be rotated according to the pie's angle.
*/
void setAutoRotateLabels( bool autoRotate );
/** \see setAutoRotateLabels( bool autoRotate )
*/
bool autoRotateLabels() const;
void setPieAttributes( const PieAttributes & a );
void setPieAttributes( int column,
const PieAttributes & a );
void setPieAttributes( const QModelIndex & index,
const PieAttributes & a );
PieAttributes pieAttributes() const;
PieAttributes pieAttributes( int column ) const;
PieAttributes pieAttributes( const QModelIndex & index ) const;
void setThreeDPieAttributes( const ThreeDPieAttributes & a );
void setThreeDPieAttributes( int column,
const ThreeDPieAttributes & a );
void setThreeDPieAttributes( const QModelIndex & index,
const ThreeDPieAttributes & a );
ThreeDPieAttributes threeDPieAttributes() const;
ThreeDPieAttributes threeDPieAttributes( int column ) const;
ThreeDPieAttributes threeDPieAttributes( const QModelIndex & index ) const;
}; // End of class KDChartAbstractPieDiagram
}
#endif // KDCHARTABSTACTPIEDIAGRAM_H

View file

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

View file

@ -0,0 +1,60 @@
/****************************************************************************
** Copyright (C) 2001-2013 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 KDCHARTABSTRACTPOLARDIAGRAM_H
#define KDCHARTABSTRACTPOLARDIAGRAM_H
#include "KDChartPolarCoordinatePlane.h"
#include "KDChartAbstractDiagram.h"
namespace KDChart {
class GridAttributes;
/**
* @brief Base class for diagrams based on a polar coordinate system.
*/
class KDCHART_EXPORT AbstractPolarDiagram : public AbstractDiagram
{
Q_OBJECT
Q_DISABLE_COPY( AbstractPolarDiagram )
KDCHART_DECLARE_DERIVED_DIAGRAM( AbstractPolarDiagram, PolarCoordinatePlane )
public:
explicit AbstractPolarDiagram (
QWidget* parent = 0, PolarCoordinatePlane* plane = 0 );
virtual ~AbstractPolarDiagram() {}
virtual qreal valueTotals () const = 0;
virtual qreal numberOfValuesPerDataset() const = 0;
virtual qreal numberOfDatasets() const { return 1; };
virtual qreal numberOfGridRings() const = 0;
const PolarCoordinatePlane * polarCoordinatePlane() const;
int columnCount() const;
int rowCount() const;
};
}
#endif

View file

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

View file

@ -0,0 +1,54 @@
/****************************************************************************
** Copyright (C) 2001-2013 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 KDCHARTABSTRACTPROXYMODEL_H
#define KDCHARTABSTRACTPROXYMODEL_H
#include <QAbstractProxyModel>
#include "KDChartGlobal.h"
namespace KDChart
{
/**
* @brief Base class for all proxy models used inside KD Chart
* \internal
*/
class KDCHART_EXPORT AbstractProxyModel : public QAbstractProxyModel
{
Q_OBJECT
public:
explicit AbstractProxyModel( QObject* parent = 0 );
/*! \reimpl */
QModelIndex mapFromSource( const QModelIndex & sourceIndex ) const;
/*! \reimpl */
QModelIndex mapToSource( const QModelIndex &proxyIndex ) const;
/*! \reimpl */
QModelIndex index( int row, int col, const QModelIndex& index ) const;
/*! \reimpl */
QModelIndex parent( const QModelIndex& index ) const;
};
}
#endif /* KDCHARTABSTRACTPROXYMODEL_H */

View file

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

View file

@ -0,0 +1,63 @@
/****************************************************************************
** Copyright (C) 2001-2013 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 KDCHARTABSTRACTTERNARYDIAGRAM_H
#define KDCHARTABSTRACTTERNARYDIAGRAM_H
#include "KDChartAbstractDiagram.h"
#include "KDChartTernaryAxis.h"
namespace KDChart {
class TernaryCoordinatePlane;
class TernaryAxis;
/**
* @brief Base class for diagrams based on a ternary coordinate plane.
*/
class KDCHART_EXPORT AbstractTernaryDiagram : public AbstractDiagram
{
Q_OBJECT
Q_DISABLE_COPY( AbstractTernaryDiagram )
KDCHART_DECLARE_DERIVED_DIAGRAM( AbstractTernaryDiagram,
TernaryCoordinatePlane )
public:
explicit AbstractTernaryDiagram ( QWidget* parent = 0,
TernaryCoordinatePlane* plane = 0 );
virtual ~AbstractTernaryDiagram();
virtual void resize (const QSizeF &area) = 0;
virtual void paint (PaintContext *paintContext);
virtual void addAxis( TernaryAxis* axis );
virtual void takeAxis( TernaryAxis* axis );
virtual TernaryAxisList axes () const;
protected:
virtual const QPair< QPointF, QPointF > calculateDataBoundaries () const = 0;
};
}
#endif

View file

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

View file

@ -0,0 +1,73 @@
/****************************************************************************
** Copyright (C) 2001-2013 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 KDCHARTABSTRACTTHREEDATTRIBUTES_H
#define KDCHARTABSTRACTTHREEDATTRIBUTES_H
#include <QMetaType>
#include "KDChartGlobal.h"
namespace KDChart {
/**
* @brief Base class for 3D attributes
*/
class KDCHART_EXPORT AbstractThreeDAttributes
{
public:
AbstractThreeDAttributes();
AbstractThreeDAttributes( const AbstractThreeDAttributes& );
AbstractThreeDAttributes &operator= ( const AbstractThreeDAttributes& );
virtual ~AbstractThreeDAttributes() = 0;
void setEnabled( bool enabled );
bool isEnabled() const;
void setDepth( qreal depth );
qreal depth() const;
// returns the depth(), if is isEnabled() is true, otherwise returns 0.0
qreal validDepth() const;
bool isThreeDBrushEnabled() const;
void setThreeDBrushEnabled( bool enabled );
virtual QBrush threeDBrush( const QBrush& brush, const QRectF& rect ) const;
bool operator==( const AbstractThreeDAttributes& ) const;
inline bool operator!=( const AbstractThreeDAttributes& other ) const { return !operator==(other); }
KDCHART_DECLARE_PRIVATE_BASE_POLYMORPHIC(AbstractThreeDAttributes)
KDCHART_DECLARE_SWAP_BASE(AbstractThreeDAttributes)
}; // End of class AbstractThreeDAttributes
}
#if !defined(QT_NO_DEBUG_STREAM)
KDCHART_EXPORT QDebug operator<<(QDebug, const KDChart::AbstractThreeDAttributes& );
#endif /* QT_NO_DEBUG_STREAM */
#endif // KDCHARTABSTRACTTHREEDATTRIBUTES_H

View file

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

View file

@ -0,0 +1,152 @@
/****************************************************************************
** Copyright (C) 2001-2013 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 __KDCHART_ATTRIBUTES_MODEL_H__
#define __KDCHART_ATTRIBUTES_MODEL_H__
#include "KDChartAbstractProxyModel.h"
#include <QMap>
#include <QVariant>
#include "KDChartGlobal.h"
namespace KDChart {
/**
* @brief A proxy model used for decorating data with attributes.
*
* An AttributesModel forwards data from and to the source model and adds attributes,
* data that influences the graphical rendering of the source model data.
* The attributes are distinguished from the source model's data by their @p role values.
* Therefore this class does not need to, and does not, change the data layout from the
* source model's; indexes that refer to the same data have the same row and column
* values in both models.
* Attribute changes, that is changes to data with the attribute role, via the interface
* of this class (including setData()) are stored internally and not forwarded to the source model.
*/
class KDCHART_EXPORT AttributesModel : public AbstractProxyModel
{
Q_OBJECT
KDCHART_DECLARE_PRIVATE_BASE_POLYMORPHIC( AttributesModel )
public:
enum PaletteType {
PaletteTypeDefault = 0,
PaletteTypeRainbow = 1,
PaletteTypeSubdued = 2
};
explicit AttributesModel( QAbstractItemModel* model, QObject * parent = 0 );
~AttributesModel();
/** Copies the internal data (maps and palette) of another
* AttributesModel* into this one.
*/
void initFrom( const AttributesModel* other );
/** Returns true if both, all of the attributes set, and
* the palette set is equal in both of the AttributeModels.
*/
bool compare( const AttributesModel* other ) const;
bool compareAttributes( int role, const QVariant& a, const QVariant& b ) const;
/* Attributes Model specific API */
bool setModelData( const QVariant value, int role );
QVariant modelData( int role ) const;
/** Returns whether the given role corresponds to one of the known
* internally used ones. */
bool isKnownAttributesRole( int role ) const;
/** Sets the palettetype used by this attributesmodel */
void setPaletteType( PaletteType type );
PaletteType paletteType() const;
/** Returns the data that were specified at global level,
* or the default data, or QVariant().
*/
QVariant data(int role) const;
/** Returns the data that were specified at per column level,
* or the globally set data, or the default data, or QVariant().
*/
QVariant data(int column, int role) const;
/** \reimpl */
QVariant headerData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const;
/** \reimpl */
int rowCount(const QModelIndex& ) const;
/** \reimpl */
int columnCount(const QModelIndex& ) const;
/** \reimpl */
QVariant data(const QModelIndex&, int role = Qt::DisplayRole) const;
/** \reimpl */
bool setData ( const QModelIndex & index, const QVariant & value, int role = Qt::DisplayRole);
/** Remove any explicit attributes settings that might have been specified before. */
bool resetData ( const QModelIndex & index, int role = Qt::DisplayRole);
/** \reimpl */
bool setHeaderData ( int section, Qt::Orientation orientation, const QVariant & value,
int role = Qt::DisplayRole);
/** Returns default values for the header data. */
virtual QVariant defaultHeaderData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const;
/** Remove any explicit attributes settings that might have been specified before. */
bool resetHeaderData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole);
/** \reimpl */
void setSourceModel ( QAbstractItemModel* sourceModel );
/** Define the default value for a certain role.
Passing a default-constructed QVariant is equivalent to removing the default. */
void setDefaultForRole( int role, const QVariant& value );
/** Set the dimension of the dataset in the source model. \sa AbstractDiagram::setDatasetDimension */
void setDatasetDimension( int dimension );
int datasetDimension() const;
Q_SIGNALS:
void attributesChanged( const QModelIndex&, const QModelIndex& );
private Q_SLOTS:
void slotRowsAboutToBeInserted( const QModelIndex& parent, int start, int end );
void slotColumnsAboutToBeInserted( const QModelIndex& parent, int start, int end );
void slotRowsInserted( const QModelIndex& parent, int start, int end );
void slotColumnsInserted( const QModelIndex& parent, int start, int end );
void slotRowsAboutToBeRemoved( const QModelIndex& parent, int start, int end );
void slotColumnsAboutToBeRemoved( const QModelIndex& parent, int start, int end );
void slotRowsRemoved( const QModelIndex& parent, int start, int end );
void slotColumnsRemoved( const QModelIndex& parent, int start, int end );
void slotDataChanged( const QModelIndex& topLeft, const QModelIndex& bottomRight );
private:
// helper
QVariant defaultsForRole( int role ) const;
bool compareHeaderDataMaps( const QMap< int, QMap< int, QVariant > >& mapA,
const QMap< int, QMap< int, QVariant > >& mapB ) const;
void removeEntriesFromDataMap( int start, int end );
void removeEntriesFromDirectionDataMaps( Qt::Orientation dir, int start, int end );
};
}
#endif

View file

@ -0,0 +1 @@
#include "KDChartLayoutItems.h"

View file

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

View file

@ -0,0 +1,85 @@
/****************************************************************************
** Copyright (C) 2001-2013 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 KDCHARTBACKGROUNDATTRIBUTES_H
#define KDCHARTBACKGROUNDATTRIBUTES_H
#include <QDebug>
#include <QMetaType>
#include <QBrush>
#include "KDChartGlobal.h"
namespace KDChart {
/**
* Set of attributes usable for background pixmaps
*/
class KDCHART_EXPORT BackgroundAttributes
{
public:
BackgroundAttributes();
BackgroundAttributes( const BackgroundAttributes& );
BackgroundAttributes &operator= ( const BackgroundAttributes& );
~BackgroundAttributes();
enum BackgroundPixmapMode { BackgroundPixmapModeNone,
BackgroundPixmapModeCentered,
BackgroundPixmapModeScaled,
BackgroundPixmapModeStretched };
void setVisible( bool visible );
bool isVisible() const;
void setBrush( const QBrush &brush );
QBrush brush() const;
void setPixmapMode( BackgroundPixmapMode mode );
BackgroundPixmapMode pixmapMode() const;
void setPixmap( const QPixmap &backPixmap );
QPixmap pixmap() const;
bool operator==( const BackgroundAttributes& ) const;
inline bool operator!=( const BackgroundAttributes& other ) const { return !operator==(other); }
bool isEqualTo( const BackgroundAttributes& other, bool ignorePixmap=false ) const;
private:
KDCHART_DECLARE_PRIVATE_BASE_VALUE( BackgroundAttributes )
}; // End of class BackgroundAttributes
}
#if !defined(QT_NO_DEBUG_STREAM)
KDCHART_EXPORT QDebug operator<<(QDebug, const KDChart::BackgroundAttributes& );
#endif /* QT_NO_DEBUG_STREAM */
KDCHART_DECLARE_SWAP_SPECIALISATION( KDChart::BackgroundAttributes )
QT_BEGIN_NAMESPACE
Q_DECLARE_TYPEINFO( KDChart::BackgroundAttributes, Q_MOVABLE_TYPE );
QT_END_NAMESPACE
Q_DECLARE_METATYPE( KDChart::BackgroundAttributes )
#endif // KDCHARTBACKGROUNDATTRIBUTES_H

View file

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

View file

@ -0,0 +1,84 @@
/****************************************************************************
** Copyright (C) 2001-2013 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 KDCHARTBARATTRIBUTES_H
#define KDCHARTBARATTRIBUTES_H
#include <QMetaType>
#include "KDChartGlobal.h"
namespace KDChart {
/**
* @brief Set of attributes for changing the appearance of bar charts
*/
class KDCHART_EXPORT BarAttributes
{
public:
BarAttributes();
BarAttributes( const BarAttributes& );
BarAttributes &operator= ( const BarAttributes& );
~BarAttributes();
void setFixedDataValueGap( qreal gap );
qreal fixedDataValueGap() const;
void setUseFixedDataValueGap( bool gapIsFixed );
bool useFixedDataValueGap() const;
void setFixedValueBlockGap( qreal gap );
qreal fixedValueBlockGap() const;
void setUseFixedValueBlockGap( bool gapIsFixed );
bool useFixedValueBlockGap() const;
void setFixedBarWidth( qreal width );
qreal fixedBarWidth() const;
void setUseFixedBarWidth( bool useFixedBarWidth );
bool useFixedBarWidth() const;
void setGroupGapFactor ( qreal gapFactor );
qreal groupGapFactor() const;
void setBarGapFactor( qreal gapFactor );
qreal barGapFactor() const;
void setDrawSolidExcessArrows( bool solidArrows );
bool drawSolidExcessArrows() const;
bool operator==( const BarAttributes& ) const;
inline bool operator!=( const BarAttributes& other ) const { return !operator==(other); }
private:
class Private;
Private * _d;
Private * d_func() { return _d; }
const Private * d_func() const { return _d; }
}; // End of class BarAttributes
}
Q_DECLARE_METATYPE( KDChart::BarAttributes )
#endif // KDCHARTBARATTRIBUTES_H

View file

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

View file

@ -0,0 +1,130 @@
/****************************************************************************
** Copyright (C) 2001-2013 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 KDCHARTBARDIAGRAM_H
#define KDCHARTBARDIAGRAM_H
#include "KDChartAbstractCartesianDiagram.h"
#include "KDChartBarAttributes.h"
QT_BEGIN_NAMESPACE
class QPainter;
QT_END_NAMESPACE
namespace KDChart {
class ThreeDBarAttributes;
/**
* @brief BarDiagram defines a common bar diagram.
*
* It provides different subtypes which are set using \a setType.
*/
class KDCHART_EXPORT BarDiagram : public AbstractCartesianDiagram
{
Q_OBJECT
Q_DISABLE_COPY( BarDiagram )
KDCHART_DECLARE_DERIVED_DIAGRAM( BarDiagram, CartesianCoordinatePlane )
public:
class BarDiagramType;
friend class BarDiagramType;
explicit BarDiagram(
QWidget* parent = 0, CartesianCoordinatePlane* plane = 0 );
virtual ~BarDiagram();
virtual BarDiagram * clone() const;
/**
* Returns true if both diagrams have the same settings.
*/
bool compare( const BarDiagram* other ) const;
enum BarType { Normal,
Stacked,
Percent,
Rows ///< @deprecated Use BarDiagram::setOrientation() instead
};
void setType( const BarType type );
BarType type() const;
void setOrientation( Qt::Orientation orientation );
Qt::Orientation orientation() const;
void setBarAttributes( const BarAttributes & a );
void setBarAttributes( int column, const BarAttributes & a );
void setBarAttributes( const QModelIndex & index, const BarAttributes & a );
BarAttributes barAttributes() const;
BarAttributes barAttributes( int column ) const;
BarAttributes barAttributes( const QModelIndex & index ) const;
void setThreeDBarAttributes( const ThreeDBarAttributes & a );
void setThreeDBarAttributes( int column, const ThreeDBarAttributes & a );
void setThreeDBarAttributes( const QModelIndex & index,
const ThreeDBarAttributes & a );
ThreeDBarAttributes threeDBarAttributes() const;
ThreeDBarAttributes threeDBarAttributes( int column ) const;
ThreeDBarAttributes threeDBarAttributes( const QModelIndex & index ) const;
#if QT_VERSION < 0x040400 || defined(Q_COMPILER_MANGLES_RETURN_TYPE)
// implement AbstractCartesianDiagram
/** \reimpl */
const int numberOfAbscissaSegments () const;
/** \reimpl */
const int numberOfOrdinateSegments () const;
#else
// implement AbstractCartesianDiagram
/** \reimpl */
int numberOfAbscissaSegments () const;
/** \reimpl */
int numberOfOrdinateSegments () const;
#endif
protected:
void paint ( PaintContext* paintContext );
public:
void resize ( const QSizeF& area );
protected:
virtual qreal threeDItemDepth( const QModelIndex & index ) const;
virtual qreal threeDItemDepth( int column ) const;
/** \reimpl */
const QPair<QPointF, QPointF> calculateDataBoundaries() const;
void paintEvent ( QPaintEvent* );
void resizeEvent ( QResizeEvent* );
private:
void calculateValueAndGapWidths( int rowCount, int colCount,
qreal groupWidth,
qreal& barWidth,
qreal& spaceBetweenBars,
qreal& spaceBetweenGroups );
}; // End of class BarDiagram
}
#endif // KDCHARTBARDIAGRAM_H

View file

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

View file

@ -0,0 +1,189 @@
/****************************************************************************
** Copyright (C) 2001-2013 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 KDCHARTCARTESIANAXIS_H
#define KDCHARTCARTESIANAXIS_H
#include <QList>
#include "KDChartAbstractAxis.h"
namespace KDChart {
class AbstractCartesianDiagram;
/**
* The class for cartesian axes.
*
* For being useful, axes need to be assigned to a diagram, see
* AbstractCartesianDiagram::addAxis and AbstractCartesianDiagram::takeAxis.
*
* \sa PolarAxis, AbstractCartesianDiagram
*/
class KDCHART_EXPORT CartesianAxis : public AbstractAxis
{
Q_OBJECT
Q_DISABLE_COPY( CartesianAxis )
KDCHART_DECLARE_PRIVATE_DERIVED_PARENT( CartesianAxis, AbstractDiagram* )
public:
enum Position {
Bottom,
Top,
Right,
Left
};
/**
* C'tor of the class for cartesian axes.
*
* \note If you pass a null parent to the constructor, you need to call
* your diagram's addAxis function to add your axis to the diagram.
* Otherwise there is no need to call addAxis, since the constructor
* does it already.
*
* \sa AbstractCartesianDiagram::addAxis
*/
explicit CartesianAxis ( AbstractCartesianDiagram* diagram = 0 );
~CartesianAxis();
/**
* Returns true if both axes have the same settings.
*/
bool compare( const CartesianAxis* other ) const;
/** reimpl */
virtual void paint( QPainter* );
/** reimpl */
virtual void paintCtx( PaintContext* );
/**
* Sets the optional text displayed as chart title.
*/
void setTitleText( const QString& text );
QString titleText() const;
/**
* \deprecated
* Sets the spacing between the title and the diagram.
* Be aware that setting this value can lead to
* collisions between axis labels and the title
*/
void setTitleSpace( qreal value );
/// \deprecated
qreal titleSpace() const;
/// \deprecated \brief use setTitleTextAttributes() instead
void setTitleSize(qreal value);
/// \deprecated
qreal titleSize() const;
void setTitleTextAttributes( const TextAttributes &a );
/**
* Returns the text attributes that will be used for displaying the
* title text.
* This is either the text attributes as specified by setTitleTextAttributes,
* or (if setTitleTextAttributes() was not called) the default text attributes.
* \sa resetTitleTextAttributes, hasDefaultTitleTextAttributes
*/
TextAttributes titleTextAttributes() const;
/**
* Reset the title text attributes to the built-in default:
*
* Same font and pen as AbstractAxis::textAttributes()
* and 1.5 times their size.
*/
void resetTitleTextAttributes();
bool hasDefaultTitleTextAttributes() const;
virtual void setPosition ( Position p );
#if QT_VERSION < 0x040400 || defined(Q_COMPILER_MANGLES_RETURN_TYPE)
virtual const Position position () const;
#else
virtual Position position () const;
#endif
virtual void layoutPlanes();
virtual bool isAbscissa() const;
virtual bool isOrdinate() const;
/**
* Sets the axis annotations to \a annotations.
* Annotations are a QMap of qreals and QStrings defining special
* markers and their position.
* If you use annotations, the normal ticks and values will be invisible.
* To unset the annotations, pass an empty QMap.
*/
void setAnnotations( const QMap< qreal, QString >& annotations );
/**
* Returns the currently set axis annotations.
*/
QMap< qreal, QString > annotations() const;
/**
* Sets custom ticks on the axis.
* Ticks are a QList of qreals defining their special position.
*/
void setCustomTicks( const QList< qreal >& ticksPostions );
/**
* Returns the currently set custom ticks on the axis.
*/
QList< qreal > customTicks() const;
/**
* Sets the length of custom ticks on the axis.
*/
void setCustomTickLength(int value);
/**
* Returns the length of custom ticks on the axis.
*/
int customTickLength() const;
/** 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 */
virtual void setGeometry( const QRect& r );
/** pure virtual in QLayoutItem */
virtual QRect geometry() const;
public Q_SLOTS:
void setCachedSizeDirty() const;
virtual int tickLength( bool subUnitTicks = false ) const;
private Q_SLOTS:
void coordinateSystemChanged();
};
typedef QList<CartesianAxis*> CartesianAxisList;
}
#endif

View file

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

View file

@ -0,0 +1,505 @@
/****************************************************************************
** Copyright (C) 2001-2013 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 KDCHARTCARTESIANCOORDINATEPLANE_H
#define KDCHARTCARTESIANCOORDINATEPLANE_H
#include "KDChartAbstractCoordinatePlane.h"
namespace KDChart {
class Chart;
class PaintContext;
class AbstractDiagram;
class CartesianAxis;
class CartesianGrid;
/**
* @brief Cartesian coordinate plane
*/
class KDCHART_EXPORT CartesianCoordinatePlane : public AbstractCoordinatePlane
{
Q_OBJECT
Q_DISABLE_COPY( CartesianCoordinatePlane )
KDCHART_DECLARE_PRIVATE_DERIVED_PARENT( CartesianCoordinatePlane, Chart* )
friend class CartesianAxis;
friend class CartesianGrid;
public:
explicit CartesianCoordinatePlane ( Chart* parent = 0 );
~CartesianCoordinatePlane();
void addDiagram ( AbstractDiagram* diagram );
/**
* If @p onOff is true, enforce that X and Y distances are scaled by the same factor.
* This makes the plane's height a function of its width, and hasHeightForWidth()
* will return true.
*/
void setIsometricScaling ( bool onOff );
bool doesIsometricScaling() const;
const QPointF translate ( const QPointF& diagramPoint ) const;
/**
* \sa setZoomFactorX, setZoomCenter
*/
virtual qreal zoomFactorX() const;
/**
* \sa setZoomFactorY, setZoomCenter
*/
virtual qreal zoomFactorY() const;
/**
* \sa setZoomFactorX,setZoomFactorY
*/
virtual void setZoomFactors( qreal factorX, qreal factorY );
/**
* \sa zoomFactorX, setZoomCenter
*/
virtual void setZoomFactorX( qreal factor );
/**
* \sa zoomFactorY, setZoomCenter
*/
virtual void setZoomFactorY( qreal factor );
/**
* \sa setZoomCenter, setZoomFactorX, setZoomFactorY
*/
virtual QPointF zoomCenter() const;
/**
* \sa zoomCenter, setZoomFactorX, setZoomFactorY
*/
virtual void setZoomCenter( const QPointF& center );
/**
* Allows to specify a fixed data-space / coordinate-space relation. If set
* to true then fixed bar widths are used, so you see more bars as the window
* is made wider.
*
* This allows to completely restrict the size of bars in a graph such that,
* upon resizing a window, the graphs coordinate plane will grow (add more
* ticks to x- and y-coordinates) rather than have the image grow.
*/
void setFixedDataCoordinateSpaceRelation( bool fixed );
bool hasFixedDataCoordinateSpaceRelation() const;
/**
* Allows to fix the lower bound of X axis to zero when diagram is in first quadrant.
*
* The default behavior is to lower x or y bound to be 0. If this behaviour is not wanted,
* either \a CartesianCoordinatePlane::setHorizontalRange could be used instead of letting
* KDChart auto-adjust the ranges, or this method can be used to disable this behavior.
*/
void setXAxisStartAtZero(bool fixedStart);
bool xAxisStartAtZero() const;
/**
* \brief Set the boundaries of the visible value space displayed in horizontal direction.
*
* This is also known as the horizontal viewport.
*
* By default the horizontal range is adjusted to the range covered by the model's data,
* see setAutoAdjustHorizontalRangeToData for details.
* Calling setHorizontalRange with a valid range disables this default automatic adjusting,
* while on the other hand automatic adjusting will set these ranges.
*
* To disable use of this range you can either pass an empty pair by using the default
* constructor QPair() or you can set both values to the same which constitutes
* a null range.
*
* \note By default the visible data range often is larger than the
* range calculated from the data model (or set by setHoriz.|Vert.Range(), resp.).
* This is due to the built-in grid calculation feature: The visible start/end
* values get adjusted so that they match a main-grid line.
* You can turn this feature off for any of the four bounds by calling
* GridAttributes::setAdjustBoundsToGrid() for either the global grid-attributes
* or for the horizontal/vertical attrs separately.
*
* \note To set only one of the ends of the range to a fixed value while keeping
* the other dynamically adjusted, use std::numeric_limits< qreal >::quiet_NaN()
* for the dynamic value.
*
* \note If you use user defined vertical ranges together with logarithmic scale, only
* positive values are supported. If you set it to negative values, the result is undefined.
*
* \param range a pair of values representing the smalles and the largest
* horizontal value space coordinate displayed.
*
* \sa setAutoAdjustHorizontalRangeToData, setVerticalRange
* \sa GridAttributes::setAdjustBoundsToGrid()
*/
void setHorizontalRange( const QPair<qreal, qreal> & range );
/**
* \brief Set the boundaries of the visible value space displayed in vertical direction.
*
* This is also known as the vertical viewport.
*
* By default the vertical range is adjusted to the range covered by the model's data,
* see setAutoAdjustVerticalRangeToData for details.
* Calling setVerticalRange with a valid range disables this default automatic adjusting,
* while on the other hand automatic adjusting will set these ranges.
*
* To disable use of this range you can either pass an empty pair by using the default
* constructor QPair() or you can set setting both values to the same which constitutes
* a null range.
*
* \note By default the visible data range often is larger than the
* range calculated from the data model (or set by setHoriz.|Vert.Range(), resp.).
* This is due to the built-in grid calculation feature: The visible start/end
* values get adjusted so that they match a main-grid line.
* You can turn this feature off for any of the four bounds by calling
* GridAttributes::setAdjustBoundsToGrid() for either the global grid-attributes
* or for the horizontal/vertical attrs separately.
*
* \note To set only one of the ends of the range to a fixed value while keeping
* the other dynamically adjusted, use std::numeric_limits< qreal >::quiet_NaN()
* for the dynamic value.
*
* \note If you use user defined vertical ranges together with logarithmic scale, only
* positive values are supported. If you set it to negative values, the result is undefined.
*
* \param range a pair of values representing the smalles and the largest
* vertical value space coordinate displayed.
*
* \sa setAutoAdjustVerticalRangeToData, setHorizontalRange
* \sa GridAttributes::setAdjustBoundsToGrid()
*/
void setVerticalRange( const QPair<qreal, qreal> & range );
/**
* @return The largest and smallest visible horizontal value space
* value. If this is not explicitly set,or if both values are the same,
* the plane will use the union of the dataBoundaries of all
* associated diagrams.
* \see KDChart::AbstractDiagram::dataBoundaries
*/
QPair<qreal, qreal> horizontalRange() const;
/**
* @return The largest and smallest visible horizontal value space
* value. If this is not explicitly set, or if both values are the same,
* the plane will use the union of the dataBoundaries of all
* associated diagrams.
* \see KDChart::AbstractDiagram::dataBoundaries
*/
QPair<qreal, qreal> verticalRange() const;
/**
* \brief Automatically adjust horizontal range settings to the ranges covered by
* the model's values, when ever the data have changed, and then emit horizontalRangeAutomaticallyAdjusted.
*
* By default the horizontal range is adjusted automatically, if more than 67 percent of
* the available horizontal space would be empty otherwise.
*
* Range setting is adjusted if more than \c percentEmpty percent of the horizontal
* space covered by the coordinate plane would otherwise be empty.
* Automatic range adjusting can happen, when either all of the data are positive or all are negative.
*
* Set percentEmpty to 100 to disable automatic range adjusting.
*
* \param percentEmpty The maximal percentage of horizontal space that may be empty.
*
* \sa horizontalRangeAutomaticallyAdjusted
* \sa autoAdjustHorizontalRangeToData, adjustRangesToData
* \sa setHorizontalRange, setVerticalRange
* \sa setAutoAdjustVerticalRangeToData
*/
void setAutoAdjustHorizontalRangeToData( unsigned int percentEmpty = 67 );
/**
* \brief Automatically adjust vertical range settings to the ranges covered by
* the model's values, when ever the data have changed, and then emit verticalRangeAutomaticallyAdjusted.
*
* By default the vertical range is adjusted automatically, if more than 67 percent of
* the available vertical space would be empty otherwise.
*
* Range setting is adjusted if more than \c percentEmpty percent of the horizontal
* space covered by the coordinate plane would otherwise be empty.
* Automatic range adjusting can happen, when either all of the data are positive or all are negative.
*
* Set percentEmpty to 100 to disable automatic range adjusting.
*
* \param percentEmpty The maximal percentage of horizontal space that may be empty.
*
* \sa verticalRangeAutomaticallyAdjusted
* \sa autoAdjustVerticalRangeToData, adjustRangesToData
* \sa setHorizontalRange, setVerticalRange
* \sa setAutoAdjustHorizontalRangeToData
*/
void setAutoAdjustVerticalRangeToData( unsigned int percentEmpty = 67 );
/**
* \brief Returns the maximal allowed percent of the horizontal
* space covered by the coordinate plane that may be empty.
*
* \return A percent value indicating how much of the horizontal space may be empty.
* If more than this is empty, automatic range adjusting is applied.
* A return value of 100 indicates that no such automatic adjusting is done at all.
*
* \sa setAutoAdjustHorizontalRangeToData, adjustRangesToData
*/
unsigned int autoAdjustHorizontalRangeToData() const;
/**
* \brief Returns the maximal allowed percent of the vertical
* space covered by the coordinate plane that may be empty.
*
* \return A percent value indicating how much of the vertical space may be empty.
* If more than this is empty, automatic range adjusting is applied.
* A return value of 100 indicates that no such automatic adjusting is done at all.
*
* \sa setAutoAdjustVerticalRangeToData, adjustRangesToData
*/
unsigned int autoAdjustVerticalRangeToData() const;
/**
* Set the attributes to be used for grid lines drawn in horizontal
* direction (or in vertical direction, resp.).
*
* To disable horizontal grid painting, for example, your code should like this:
* \code
* GridAttributes ga = plane->gridAttributes( Qt::Horizontal );
* ga.setGridVisible( false );
* plane-setGridAttributes( Qt::Horizontal, ga );
* \endcode
*
* \note setGridAttributes overwrites the global attributes that
* were set by AbstractCoordinatePlane::setGlobalGridAttributes.
* To re-activate these global attributes you can call
* resetGridAttributes.
*
* \sa resetGridAttributes, gridAttributes
* \sa setAutoAdjustGridToZoom
* \sa AbstractCoordinatePlane::setGlobalGridAttributes
* \sa hasOwnGridAttributes
*/
void setGridAttributes( Qt::Orientation orientation, const GridAttributes & );
/**
* Reset the attributes to be used for grid lines drawn in horizontal
* direction (or in vertical direction, resp.).
* By calling this method you specify that the global attributes set by
* AbstractCoordinatePlane::setGlobalGridAttributes be used.
*
* \sa setGridAttributes, gridAttributes
* \sa setAutoAdjustGridToZoom
* \sa AbstractCoordinatePlane::globalGridAttributes
* \sa hasOwnGridAttributes
*/
void resetGridAttributes( Qt::Orientation orientation );
/**
* \return The attributes used for grid lines drawn in horizontal
* direction (or in vertical direction, resp.).
*
* \note This function always returns a valid set of grid attributes:
* If no special grid attributes were set foe this orientation
* the global attributes are returned, as returned by
* AbstractCoordinatePlane::globalGridAttributes.
*
* \sa setGridAttributes
* \sa resetGridAttributes
* \sa AbstractCoordinatePlane::globalGridAttributes
* \sa hasOwnGridAttributes
*/
const GridAttributes gridAttributes( Qt::Orientation orientation ) const;
/**
* \return Returns whether the grid attributes have been set for the
* respective direction via setGridAttributes( orientation ).
*
* If false, the grid will use the global attributes set
* by AbstractCoordinatePlane::globalGridAttributes (or the default
* attributes, resp.)
*
* \sa setGridAttributes
* \sa resetGridAttributes
* \sa AbstractCoordinatePlane::globalGridAttributes
*/
bool hasOwnGridAttributes( Qt::Orientation orientation ) const;
/**
* Disable / re-enable the built-in grid adjusting feature.
*
* By default additional lines will be drawn in a Linear grid when zooming in.
*
* \sa autoAdjustGridToZoom, setGridAttributes
*/
void setAutoAdjustGridToZoom( bool autoAdjust );
/**
* Return the status of the built-in grid adjusting feature.
*
* \sa setAutoAdjustGridToZoom
*/
#if QT_VERSION < 0x040400 || defined(Q_COMPILER_MANGLES_RETURN_TYPE)
const bool autoAdjustGridToZoom() const;
#else
bool autoAdjustGridToZoom() const;
#endif
AxesCalcMode axesCalcModeY() const;
AxesCalcMode axesCalcModeX() const;
/** Specifies the calculation modes for all axes */
void setAxesCalcModes( AxesCalcMode mode );
/** Specifies the calculation mode for all Ordinate axes */
void setAxesCalcModeY( AxesCalcMode mode );
/** Specifies the calculation mode for all Abscissa axes */
void setAxesCalcModeX( AxesCalcMode mode );
/** reimpl */
virtual void paint( QPainter* );
/** reimpl */
AbstractCoordinatePlane* sharedAxisMasterPlane( QPainter* p = 0 );
/**
* Returns the currently visible data range. Might be greater than the
* range of the grid.
*/
QRectF visibleDataRange() const;
/**
* Returns the logical area, i.e., the rectangle defined by the very top
* left and very bottom right coordinate.
*/
QRectF logicalArea() const;
/**
* Returns the (physical) area occupied by the diagram. Unless zoom is applied
* (which is also true when a fixed data coordinate / space relation is used),
* \code diagramArea() == drawingArea() \endcode .
* \sa setFixedDataCoordinateSpaceRelation
* \sa drawingArea
*/
QRectF diagramArea() const;
/**
* Returns the visible part of the diagram area, i.e.
* \code diagramArea().intersected( drawingArea() ) \endcode
* \sa diagramArea
*/
QRectF visibleDiagramArea() const;
/**
* Sets whether the horizontal range should be reversed or not, i.e.
* small values to the left and large values to the right (the default)
* or vice versa.
* \param reverse Whether the horizontal range should be reversed or not
*/
void setHorizontalRangeReversed( bool reverse );
/**
* \return Whether the horizontal range is reversed or not
*/
bool isHorizontalRangeReversed() const;
/**
* Sets whether the vertical range should be reversed or not, i.e.
* small values at the bottom and large values at the top (the default)
* or vice versa.
* \param reverse Whether the vertical range should be reversed or not
*/
void setVerticalRangeReversed( bool reverse );
/**
* \return Whether the vertical range is reversed or not
*/
bool isVerticalRangeReversed() const;
/**
* reimplemented from AbstractCoordinatePlane
*/
void setGeometry( const QRect& r );
// reimplemented
Qt::Orientations expandingDirections() const;
public Q_SLOTS:
/**
* \brief Adjust both, horizontal and vertical range settings to the
* ranges covered by the model's data values.
*
* \sa setHorizontalRange, setVerticalRange
* \sa adjustHorizontalRangeToData, adjustVerticalRangeToData
* \sa setAutoAdjustHorizontalRangeToData, setAutoAdjustVerticalRangeToData
*/
void adjustRangesToData();
/**
* Adjust horizontal range settings to the ranges covered by the model's data values.
* \sa adjustRangesToData
*/
void adjustHorizontalRangeToData();
/**
* Adjust vertical range settings to the ranges covered by the model's data values.
* \sa adjustRangesToData
*/
void adjustVerticalRangeToData();
protected:
QRectF getRawDataBoundingRectFromDiagrams() const;
QRectF adjustedToMaxEmptyInnerPercentage(
const QRectF& r, unsigned int percentX, unsigned int percentY ) const;
virtual QRectF calculateRawDataBoundingRect() const;
virtual DataDimensionsList getDataDimensionsList() const;
// the whole drawing area, includes diagrams and axes, but maybe smaller
// than (width, height):
virtual QRectF drawingArea() const;
public:
const QPointF translateBack( const QPointF& screenPoint ) const;
protected:
void paintEvent ( QPaintEvent* );
void layoutDiagrams();
// the following three return true if the new value is different from the old
bool doneSetZoomFactorX( qreal factor );
bool doneSetZoomFactorY( qreal factor );
bool doneSetZoomCenter( const QPointF& center );
void handleFixedDataCoordinateSpaceRelation( const QRectF& geometry );
// reimplemented from QLayoutItem, via AbstractLayoutItem, AbstractArea, AbstractCoordinatePlane
bool hasHeightForWidth() const;
int heightForWidth( int w ) const;
QSize sizeHint() const;
protected Q_SLOTS:
void slotLayoutChanged( AbstractDiagram* );
private:
void setHasOwnGridAttributes(
Qt::Orientation orientation, bool on );
};
}
#endif

View file

@ -0,0 +1 @@
#include "KDChartCartesianGrid.h"

View file

@ -0,0 +1,120 @@
/****************************************************************************
** Copyright (C) 2001-2013 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 KDCHARTCARTESIANGRID_H
#define KDCHARTCARTESIANGRID_H
#include "KDChartCartesianCoordinatePlane.h"
#include "KDChartAbstractGrid.h"
namespace KDChart {
class PaintContext;
class CartesianCoordinatePlane;
/**
* \internal
*
* \brief Class for the grid in a cartesian plane.
*
* The CartesianGrid interface is used
* for calculating and for drawing
* the horizonal grid lines, and the vertical grid lines
* of a cartesian coordinate plane.
*/
class CartesianGrid : public AbstractGrid
{
public:
CartesianGrid();
virtual ~CartesianGrid();
int minimalSteps() const;
void setMinimalSteps(int minsteps);
int maximalSteps() const;
void setMaximalSteps(int maxsteps);
void drawGrid( PaintContext* context );
private:
int m_minsteps;
int m_maxsteps;
DataDimensionsList calculateGrid(
const DataDimensionsList& rawDataDimensions ) const;
/**
* Helper function called by calculateGrid() to calculate the grid of one dimension.
*
* Classes derived from CartesianGrid can overwrite calculateGridXY() if they need
* a special way of calculating the start or end or step width of their grid lines.
*
* \param adjustLower If true, the function adjusts the start value
* so it matches the position of a grid line, if false the start value is
* the raw data dimension start value.
* \param adjustUpper If true, the function adjusts the end value
* so it matches the position of a grid line, if false the end value is
* the raw data dimension end value.
*/
virtual DataDimension calculateGridXY(
const DataDimension& rawDataDimension,
Qt::Orientation orientation,
bool adjustLower, bool adjustUpper ) const;
/**
* Helper function called by calculateGridXY().
*
* Classes derived from CartesianGrid can overwrite calculateStepWidth() if they need
* a way of calculating the step width, based upon given start/end values
* for their horizontal or vertical grid lines which is different from the default
* implementation.
*
* \note The CartesianGrid class tries to keep the displayed range as close to
* the raw data range as possible, so in most cases there should be no reason
* to change the default implementation: Using
* KDChart::GridAttributes::setGridGranularitySequence() should be sufficient.
*
* \param start The raw start value of the data range.
* \param end The raw end value of the data range.
* \param granularities The list of allowed granularities.
* \param adjustLower If true, the function adjusts the start value
* so it matches the position of a grid line, if false the start value is
* left as it is, in any case the value is adjusted for internal calculation only.
* \param adjustUpper If true, the function adjusts the end value
* so it matches the position of a grid line, if false the end value is
* left as it is, in any case the value is adjusted for internal calculation only.
*
* \returns stepWidth: One of the values from the granularities
* list, optionally multiplied by a positive (or negative, resp.)
* power of ten. subStepWidth: The matching width for sub-grid lines.
*/
virtual void calculateStepWidth(
qreal start, qreal end,
const QList<qreal>& granularities,
Qt::Orientation orientation,
qreal& stepWidth, qreal& subStepWidth,
bool adjustLower, bool adjustUpper ) const;
};
}
#endif

View file

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

View file

@ -0,0 +1,576 @@
/****************************************************************************
** Copyright (C) 2001-2013 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 KDCHARTCHART_H
#define KDCHARTCHART_H
#include <QWidget>
#include "kdchart_export.h"
#include "KDChartGlobal.h"
/*
Simplified(*) overview of object ownership in a chart:
Chart is-a QWidget
|
n CoordinatePlanes is-a AbstractArea is-a AbstractLayoutItem is-a QLayoutItem
|
n Diagrams is-a QAbstractItemView is-a QWidget
/ | \
AbstractGrid | Axes (can be shared between diagrams) is-a AbstractArea is-a... QLayoutItem
(no base class) |
Legends is-a AbstractAreaWidget is-a QWidget
(*) less important classes, including base classes, removed.
Layout rules:
In principle, every size or existence change in one of the objects listed above must be propagated
to all other objects. This could change their size.
There are also settings changes that invalidate the size of other components, where the size changes
are detected and propagated.
Painting call tree (simplified):
Chart::paint() (from users) / paintEvent() (from framework)
ChartPrivate::paintAll()-----------------------------------------------\
CoordinatePlane::paintAll() (from AbstractArea)--------\ Axis::paintAll()-\
CoordinatePlane::paint() (from AbstractLayoutItem) Grid::drawGrid() Axis::paint()
Diagram::paint( PaintContext* paintContext )
Note that grids are painted from the coordinate plane, not from the diagram as ownership would suggest.
*/
namespace KDChart {
class BackgroundAttributes;
class FrameAttributes;
class AbstractDiagram;
class AbstractCoordinatePlane;
class HeaderFooter;
class Legend;
typedef QList<AbstractCoordinatePlane*> CoordinatePlaneList;
typedef QList<HeaderFooter*> HeaderFooterList;
typedef QList<Legend*> LegendList;
/**
* @class Chart KDChartChart.h KDChartChart
* @brief A chart with one or more diagrams.
*
* The Chart class represents a drawing consisting of one or more diagrams
* and various optional elements such as legends, axes, text boxes, headers
* or footers. It takes ownership of all these elements when they are assigned
* to it. Each diagram is associated with a coordinate plane, of which the chart
* can have more than one. The coordinate planes (and thus the associated diagrams)
* can be laid out in various ways.
*
* The Chart class makes heavy use of the Qt Interview framework for model/view
* programming, and thus requires data to be presented to it in a QAbstractItemModel
* compatible way. For many simple charts, especially if the visualized data is
* static, KDChart::Widget provides an abstracted interface, that hides the complexity
* of Interview to a large extent.
*/
class KDCHART_EXPORT Chart : public QWidget
{
Q_OBJECT
// KD Chart 3.0: leading is inter-line distance of text. this here is MARGIN or SPACING.
Q_PROPERTY( int globalLeadingTop READ globalLeadingTop WRITE setGlobalLeadingTop )
Q_PROPERTY( int globalLeadingBottom READ globalLeadingBottom WRITE setGlobalLeadingBottom )
Q_PROPERTY( int globalLeadingLeft READ globalLeadingLeft WRITE setGlobalLeadingLeft )
Q_PROPERTY( int globalLeadingRight READ globalLeadingRight WRITE setGlobalLeadingRight )
Q_PROPERTY( bool useNewLayoutSystem READ useNewLayoutSystem WRITE setUseNewLayoutSystem )
KDCHART_DECLARE_PRIVATE_BASE_POLYMORPHIC_QWIDGET( Chart )
public:
explicit Chart ( QWidget* parent = 0 );
~Chart();
/**
* @brief useNewLayoutSystem
* Be very careful activating the new layout system,
* its still experimental and works only if the user knows
* what he is doing. The reason is that the system does not prevent
* the user from creating sharing graphs that are not layoutable in a
* plane and still needs assistance from the user.
*/
bool useNewLayoutSystem() const;
void setUseNewLayoutSystem( bool value );
/**
\brief Specify the frame attributes to be used, by default is it a thin black line.
To hide the frame line, you could do something like this:
\verbatim
KDChart::FrameAttributes frameAttrs( my_chart->frameAttributes() );
frameAttrs.setVisible( false );
my_chart->setFrameAttributes( frameAttrs );
\endverbatim
\sa setBackgroundAttributes
*/
void setFrameAttributes( const FrameAttributes &a );
FrameAttributes frameAttributes() const;
/**
\brief Specify the background attributes to be used, by default there is no background.
To set a light blue background, you could do something like this:
\verbatim
KDChart::BackgroundAttributes backgroundAttrs( my_chart->backgroundAttributes() );
backgroundAttrs.setVisible( true );
backgroundAttrs.setBrush( QColor(0xd0,0xd0,0xff) );
my_chart->setBackgroundAttributes( backgroundAttrs );
\endverbatim
\sa setFrameAttributes
*/
void setBackgroundAttributes( const BackgroundAttributes &a );
BackgroundAttributes backgroundAttributes() const;
/**
* Each chart must have at least one coordinate plane.
* Initially a default CartesianCoordinatePlane is created.
* Use replaceCoordinatePlane() to replace it with a different
* one, such as a PolarCoordinatePlane.
* @return The first coordinate plane of the chart.
*/
AbstractCoordinatePlane* coordinatePlane();
/**
* The list of coordinate planes.
* @return The list of coordinate planes.
*/
CoordinatePlaneList coordinatePlanes();
/**
* Adds a coordinate plane to the chart. The chart takes ownership.
* @param plane The coordinate plane to add.
*
* \sa replaceCoordinatePlane, takeCoordinatePlane
*/
void addCoordinatePlane( AbstractCoordinatePlane* plane );
/**
* Inserts a coordinate plane to the chart at index @p index.
* The chart takes ownership.
*
* @param index The index where to add the plane
* @param plane The coordinate plane to add.
*
* \sa replaceCoordinatePlane, takeCoordinatePlane
*/
void insertCoordinatePlane( int index, AbstractCoordinatePlane* plane );
/**
* Replaces the old coordinate plane, or appends the
* plane, it there is none yet.
*
* @param plane The coordinate plane to be used instead of the old plane.
* This parameter must not be zero, or the method will do nothing.
*
* @param oldPlane The coordinate plane to be removed by the new plane. This
* plane will be deleted automatically. If the parameter is omitted,
* the very first coordinate plane will be replaced. In case, there was no
* plane yet, the new plane will just be added.
*
* \note If you want to re-use the old coordinate plane, call takeCoordinatePlane and
* addCoordinatePlane, instead of using replaceCoordinatePlane.
*
* \sa addCoordinatePlane, takeCoordinatePlane
*/
void replaceCoordinatePlane( AbstractCoordinatePlane* plane,
AbstractCoordinatePlane* oldPlane = 0 );
/**
* Removes the coordinate plane from the chart, without deleting it.
*
* The chart no longer owns the plane, so it is
* the caller's responsibility to delete the plane.
*
* \sa addCoordinatePlane, takeCoordinatePlane
*/
void takeCoordinatePlane( AbstractCoordinatePlane* plane );
/**
* Set the coordinate plane layout that should be used as model for
* the internal used layout. The layout needs to be an instance of
* QHBoxLayout or QVBoxLayout.
*/
void setCoordinatePlaneLayout( QLayout * layout );
QLayout* coordinatePlaneLayout();
/**
* The first header or footer of the chart. By default there is none.
* @return The first header or footer of the chart or 0 if there was none
* added to the chart.
*/
HeaderFooter* headerFooter();
/**
* The list of headers and footers associated with the chart.
* @return The list of headers and footers associated with the chart.
*/
HeaderFooterList headerFooters();
/**
* Adds a header or a footer to the chart. The chart takes ownership.
* @param headerFooter The header (or footer, resp.) to add.
*
* \sa replaceHeaderFooter, takeHeaderFooter
*/
void addHeaderFooter( HeaderFooter* headerFooter );
/**
* Replaces the old header (or footer, resp.), or appends the
* new header or footer, it there is none yet.
*
* @param headerFooter The header or footer to be used instead of the old one.
* This parameter must not be zero, or the method will do nothing.
*
* @param oldHeaderFooter The header or footer to be removed by the new one. This
* header or footer will be deleted automatically. If the parameter is omitted,
* the very first header or footer will be replaced. In case, there was no
* header and no footer yet, the new header or footer will just be added.
*
* \note If you want to re-use the old header or footer, call takeHeaderFooter and
* addHeaderFooter, instead of using replaceHeaderFooter.
*
* \sa addHeaderFooter, takeHeaderFooter
*/
void replaceHeaderFooter ( HeaderFooter* headerFooter,
HeaderFooter* oldHeaderFooter = 0 );
/**
* Removes the header (or footer, resp.) from the chart, without deleting it.
*
* The chart no longer owns the header or footer, so it is
* the caller's responsibility to delete the header or footer.
*
* \sa addHeaderFooter, replaceHeaderFooter
*/
void takeHeaderFooter( HeaderFooter* headerFooter );
/**
* The first legend of the chart or 0 if there was none added to the chart.
* @return The first legend of the chart or 0 if none exists.
*/
Legend* legend();
/**
* The list of all legends associated with the chart.
* @return The list of all legends associated with the chart.
*/
LegendList legends();
/**
* Add the given legend to the chart. The chart takes ownership.
* @param legend The legend to add.
*
* \sa replaceLegend, takeLegend
*/
void addLegend( Legend* legend );
/**
* Replaces the old legend, or appends the
* new legend, it there is none yet.
*
* @param legend The legend to be used instead of the old one.
* This parameter must not be zero, or the method will do nothing.
*
* @param oldLegend The legend to be removed by the new one. This
* legend will be deleted automatically. If the parameter is omitted,
* the very first legend will be replaced. In case, there was no
* legend yet, the new legend will just be added.
*
* If you want to re-use the old legend, call takeLegend and
* addLegend, instead of using replaceLegend.
*
* \note Whenever addLegend is called the font sizes used by the
* Legend are set to relative and they get coupled to the Chart's size,
* with their relative values being 20 for the item texts and 24 to the
* title text. So if you want to use custom font sizes for the Legend
* make sure to set them after calling addLegend.
*
* \sa addLegend, takeLegend
*/
void replaceLegend ( Legend* legend, Legend* oldLegend = 0 );
/**
* Removes the legend from the chart, without deleting it.
*
* The chart no longer owns the legend, so it is
* the caller's responsibility to delete the legend.
*
* \sa addLegend, takeLegend
*/
void takeLegend( Legend* legend );
/**
* Set the padding between the margin of the widget and the area that
* the contents are drawn into.
* @param left The padding on the left side.
* @param top The padding at the top.
* @param right The padding on the left hand side.
* @param bottom The padding on the bottom.
*
* \note Using previous versions of KD Chart you might have called
* setGlobalLeading() to make room for long Abscissa labels (or for an
* overlapping top label of an Ordinate axis, resp.) that would not fit
* into the normal axis area. This is \em no \em longer \em needed
* because KD Chart now is using hidden auto-spacer items reserving
* as much free space as is needed for axes with overlaping content
* at the respective sides.
*
* \sa setGlobalLeadingTop, setGlobalLeadingBottom, setGlobalLeadingLeft, setGlobalLeadingRight
* \sa globalLeadingTop, globalLeadingBottom, globalLeadingLeft, globalLeadingRight
*/
void setGlobalLeading( int left, int top, int right, int bottom );
/**
* Set the padding between the start of the widget and the start
* of the area that is used for drawing on the left.
* @param leading The padding value.
*
* \sa setGlobalLeading
*/
void setGlobalLeadingLeft( int leading );
/**
* The padding between the start of the widget and the start
* of the area that is used for drawing on the left.
* @return The padding between the start of the widget and the start
* of the area that is used for drawing on the left.
*
* \sa setGlobalLeading
*/
int globalLeadingLeft() const;
/**
* Set the padding between the start of the widget and the start
* of the area that is used for drawing at the top.
* @param leading The padding value.
*
* \sa setGlobalLeading
*/
void setGlobalLeadingTop( int leading );
/**
* The padding between the start of the widget and the start
* of the area that is used for drawing at the top.
* @return The padding between the start of the widget and the start
* of the area that is used for drawing at the top.
*
* \sa setGlobalLeading
*/
int globalLeadingTop() const;
/**
* Set the padding between the start of the widget and the start
* of the area that is used for drawing on the right.
* @param leading The padding value.
*
* \sa setGlobalLeading
*/
void setGlobalLeadingRight( int leading );
/**
* The padding between the start of the widget and the start
* of the area that is used for drawing on the right.
* @return The padding between the start of the widget and the start
* of the area that is used for drawing on the right.
*
* \sa setGlobalLeading
*/
int globalLeadingRight() const;
/**
* Set the padding between the start of the widget and the start
* of the area that is used for drawing on the bottom.
* @param leading The padding value.
*
* \sa setGlobalLeading
*/
void setGlobalLeadingBottom( int leading );
/**
* The padding between the start of the widget and the start
* of the area that is used for drawing at the bottom.
* @return The padding between the start of the widget and the start
* of the area that is used for drawing at the bottom.
*
* \sa setGlobalLeading
*/
int globalLeadingBottom() const;
/**
* Paints all the contents of the chart. Use this method to make KDChart
* draw into your QPainter.
*
* \note Any global leading settings will be used by the paint method too,
* so make sure to set them to zero, if you want the drawing to have the exact
* size of the target rectangle.
*
* \param painter The painter to be drawn into.
* \param target The rectangle to be filled by the Chart's drawing.
*
* \sa setGlobalLeading
*/
void paint( QPainter* painter, const QRect& target );
void reLayoutFloatingLegends();
Q_SIGNALS:
/** Emitted upon change of a property of the Chart or any of its components. */
void propertiesChanged();
void finishedDrawing();
protected:
/**
* Adjusts the internal layout when the chart is resized.
*/
/* reimp */ void resizeEvent ( QResizeEvent * event );
/**
* @brief Draws the background and frame, then calls paint().
*
* In most cases there is no need to override this method in a derived
* class, but if you do, do not forget to call paint().
* @sa paint
*/
/* reimp */ void paintEvent( QPaintEvent* event );
/** reimp */
void mousePressEvent( QMouseEvent* event );
/** reimp */
void mouseDoubleClickEvent( QMouseEvent* event );
/** reimp */
void mouseMoveEvent( QMouseEvent* event );
/** reimp */
void mouseReleaseEvent( QMouseEvent* event );
/** reimp */
bool event( QEvent* event );
private:
// TODO move this to the private class
void addLegendInternal( Legend *legend, bool setMeasures );
};
// Here we have a few docu block to be included into the API documentation:
/**
* \dir src
* \brief Implementation directory of KDChart.
*
* This directory contains the header files and the source files of both,
* the private and the public classes.
*
* \note Only classes that have an include wrapper in the \c $KDCHARTDIR/include
* directory are part of the supported API.
* All other classes are to be considered as implemntation details, they
* could be changed in future versions of KDChart without notice.
*
* In other words: No class that is not mentioned in the \c $KDCHARTDIR/include
* directory may be directly used by your application.
*
* The recommended way to include classes of the KDChart API is including
* them by class name, so instead of including KDChartChart.h you would say:
*
\verbatim
#include <KDChartChart>
\endverbatim
*
* When following this there is no reason to include the \c $KDCHARTDIR/src
* directory, it is sufficient to include \c $KDCHARTDIR/include
*/
}
/**
* @class QAbstractItemView "(do not include)"
* @brief Class only listed here to document inheritance of some KDChart classes.
*
* Please consult the respective Qt documentation for details:
* <A HREF="http://doc.trolltech.com/">http://doc.trolltech.com/</A>
*/
/**
* @class QAbstractProxyModel "(do not include)"
* @brief Class only listed here to document inheritance of some KDChart classes.
*
* Please consult the respective Qt documentation for details:
* <A HREF="http://doc.trolltech.com/">http://doc.trolltech.com/</A>
*/
/**
* @class QFrame "(do not include)"
* @brief Class only listed here to document inheritance of some KDChart classes.
*
* Please consult the respective Qt documentation for details:
* <A HREF="http://doc.trolltech.com/">http://doc.trolltech.com/</A>
*/
/**
* @class QObject "(do not include)"
* @brief Class only listed here to document inheritance of some KDChart classes.
*
* Please consult the respective Qt documentation for details:
* <A HREF="http://doc.trolltech.com/">http://doc.trolltech.com/</A>
*/
/**
* @class QSortFilterProxyModel "(do not include)"
* @brief Class only listed here to document inheritance of some KDChart classes.
*
* Please consult the respective Qt documentation for details:
* <A HREF="http://doc.trolltech.com/">http://doc.trolltech.com/</A>
*/
/**
* @class QWidget "(do not include)"
* @brief Class only listed here to document inheritance of some KDChart classes.
*
* Please consult the respective Qt documentation for details:
* <A HREF="http://doc.trolltech.com/">http://doc.trolltech.com/</A>
*/
/**
* @class QTextDocument "(do not include)"
* @brief Class only listed here to document inheritance of some KDChart classes.
*
* Please consult the respective Qt documentation for details:
* <A HREF="http://doc.trolltech.com/">http://doc.trolltech.com/</A>
*/
/**
* @class QLayoutItem "(do not include)"
* @brief Class only listed here to document inheritance of some KDChart classes.
*
* Please consult the respective Qt documentation for details:
* <A HREF="http://doc.trolltech.com/">http://doc.trolltech.com/</A>
*/
/**
* @class QGraphicsPolygonItem "(do not include)"
* @brief Class only listed here to document inheritance of some KDChart classes.
*
* Please consult the respective Qt documentation for details:
* <A HREF="http://doc.trolltech.com/">http://doc.trolltech.com/</A>
*/
#endif

View file

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

View file

@ -0,0 +1,327 @@
/****************************************************************************
** Copyright (C) 2001-2013 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 KDCHARTDATAVALUEATTRIBUTES_H
#define KDCHARTDATAVALUEATTRIBUTES_H
#include <Qt>
#include <QMetaType>
#include "KDChartGlobal.h"
#include "KDChartEnums.h"
#include "KDChartRelativePosition.h"
/** \file KDChartDataValueAttributes.h
* \brief Declaring the class KDChart::DataValueAttributes.
*
*
*/
namespace KDChart {
class TextAttributes;
class BackgroundAttributes;
class FrameAttributes;
class MarkerAttributes;
/**
* \class DataValueAttributes KDChartDataValueAttributes.h KDChartDataValueAttributes
* \brief Diagram attributes dealing with data value labels.
*
* The DataValueAttributes group all properties that can be set
* wrt data value labels and if and how they are displayed. This
* includes things like the text attributes (font, color), what
* markers are used, how many decimal digits are displayed, etc.
*/
class KDCHART_EXPORT DataValueAttributes
{
public:
DataValueAttributes();
DataValueAttributes( const DataValueAttributes& );
DataValueAttributes &operator= ( const DataValueAttributes& );
bool operator==( const DataValueAttributes& ) const;
inline bool operator!=( const DataValueAttributes& other ) const { return !operator==(other); }
~DataValueAttributes();
static const DataValueAttributes& defaultAttributes();
static const QVariant& defaultAttributesAsVariant();
/** Set whether data value labels should be displayed.
* \param visible Whether data value labels should be displayed.
*/
void setVisible( bool visible );
/**
* @return Whether data value labels should be displayed.
*/
bool isVisible() const;
/**
* Set the text attributes to use for the data value labels.
* \param a The text attributes to set.
* \see TextAttributes
*/
void setTextAttributes( const TextAttributes &a );
/**
* \return The text attributes used for painting data value labels.
*/
TextAttributes textAttributes() const;
/**
* If true, rotation of negative value labels is negated, so that negative
* values are rotated in opposite direction of textAttributes().rotation(),
* and in this sense appear "mirrored" to positive value labels, though the
* text itself is *not* mirrored, only its rotation.
*/
bool mirrorNegativeValueTextRotation() const;
/**
* \see mirrorNegativeValueTextRotation()
*/
void setMirrorNegativeValueTextRotation( bool enable );
/**
* Set the frame attributes to use for the data value labels area.
* \param a The frame attributes to set.
* \see FrameAttributes
*/
void setFrameAttributes( const FrameAttributes &a );
/**
* \return The frame attributes used for painting the data
* value labels area.
* \see FrameAttributes
*/
FrameAttributes frameAttributes() const;
/**
* Set the background attributes to use for the data value labels area.
* \param a The background attributes to set.
* \see BackgroundAttributes
*/
void setBackgroundAttributes( const BackgroundAttributes &a );
/**
* \return The background attributes used for painting the data
* value labels area.
* \see BackgroundAttributes
*/
BackgroundAttributes backgroundAttributes() const;
/**
* Set the marker attributes to use for the data values. This includes
* the marker type.
* \param a The marker attributes to set.
* \see MarkerAttributes
*/
void setMarkerAttributes( const MarkerAttributes &a );
/**
* \return The marker attributes used for decorating the data
* values.
* \see MarkerAttributes
*/
MarkerAttributes markerAttributes() const;
/**
* Specify whether to use percentages instead of actual data point values when no
* specific label is set. In a bar or cartesian diagram, this means that the value
* will be shown in % in relation to the sum of all values in the same category, in
* a polar diagram in relation to the sum of all values in a data set.
*
* When this is turned on, the value will \b not automatically have the '%' postfix.
* \param enable Whether to enable percentage values
*/
void setUsePercentage( bool enable );
/**
* \return Whether to use percentage values
* \see setUsePercentage
*/
bool usePercentage() const;
/**
* Set how many decimal digits to display when rendering the data value
* labels. If there are no decimal digits it will not be displayed.
* \param digits The number of decimal digits to use.
*/
void setDecimalDigits( int digits );
/**
* \return The number of decimal digits displayed.
*/
int decimalDigits() const;
/**
* \brief Prepend a prefix string to the data value label
* \sa prefix
*/
void setPrefix( const QString prefix );
/**
* \brief Returns the string used as a prefix to the data value text.
* \sa setPrefix
*/
QString prefix() const;
/**
* \brief Append a suffix string to the data value label
* \sa suffix
*/
void setSuffix( const QString suffix );
/**
* \brief Returns the string used as a suffix to the data value text.
* \sa setSuffix
*/
QString suffix() const;
/**
* \brief display a string label instead of the original data value label
* Supports HTML code.
* \sa dataLabel
*/
void setDataLabel( const QString label );
/**
* \brief Returns the string displayed instead of the data value label
* \sa setDataLabel
*/
QString dataLabel() const;
/**
* \return Whether data values not different from their predecessors are drawn.
*/
bool showRepetitiveDataLabels() const;
/**
*
* Set whether data value labels not different from their predecessors should be drawn.
* \param showRepetitiveDataLabels Whether data value not different from their predecessors are drawn.
*/
void setShowRepetitiveDataLabels( bool showRepetitiveDataLabels );
/**
* \return Whether data value texts overlapping other data value texts of the same diagram are drawn.
*/
bool showOverlappingDataLabels() const;
/**
*
* Set whether data value texts overlapping other data value texts of the same diagram should be drawn.
* \param showOverlappingDataLabels Whether data texts overlapping other data value texts of the same diagram are drawn.
*/
void setShowOverlappingDataLabels( bool showOverlappingDataLabels );
/**
* \cond PLANNED_FOR_FUTURE
*
* These method are planned for future versions of KD Chart,
* so they are not part of the documented API yet.
*
*/
void setPowerOfTenDivisor( int powerOfTenDivisor );
int powerOfTenDivisor() const;
/**
* \endcond
*/
/**
* \cond PLANNED_FOR_FUTURE
*
* These method are planned for future versions of KD Chart,
* so they are not part of the documented API yet.
*/
void setShowInfinite( bool infinite );
bool showInfinite() const;
/**
* \endcond
*/
/**
* \brief Defines the relative positioning of the data value labels for negative values.
*
* The position is specified in relation to the respective data value point, or in
* relation to the respective data representation area, that's one area segment in
* a LineDiagram showing areas, or one bar in a BarDiagram, one pie slice ...
*
* See detailed description of \a KDChart::Position for an illustration of the
* different possible reference positions.
*
* \sa negativePosition
*/
void setNegativePosition( const RelativePosition& relPosition );
/**
* \brief Return the relative positioning of the data value labels
* \sa setNegativePosition
*/
const RelativePosition negativePosition() const;
/**
* \brief Defines the relative position of the data value labels for positive values.
*
* The position is specified in relation to the respective data value point, or in
* relation to the respective data representation area, that's one area segment in
* a LineDiagram showing areas, or one bar in a BarDiagram, one pie slice ...
*
* See detailed description of \a KDChart::Position for an illustration of the
* different possible reference positions.
*
* \sa positivePosition
*/
void setPositivePosition( const RelativePosition& relPosition );
/**
* \brief Return the relative positioning of the data value labels
* \sa setPositivePosition
*/
const RelativePosition positivePosition() const;
const RelativePosition position( bool positive ) const
{
return positive ? positivePosition() : negativePosition();
}
private:
KDCHART_DECLARE_PRIVATE_BASE_VALUE( DataValueAttributes )
}; // End of class DataValueAttributes
}
#if !defined(QT_NO_DEBUG_STREAM)
KDCHART_EXPORT QDebug operator<<(QDebug, const KDChart::DataValueAttributes& );
#endif /* QT_NO_DEBUG_STREAM */
KDCHART_DECLARE_SWAP_SPECIALISATION( KDChart::DataValueAttributes )
QT_BEGIN_NAMESPACE
Q_DECLARE_TYPEINFO( KDChart::DataValueAttributes, Q_MOVABLE_TYPE );
QT_END_NAMESPACE
Q_DECLARE_METATYPE( KDChart::DataValueAttributes )
#endif // KDCHARTDATAVALUEATTRIBUTES_H

View file

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

View file

@ -0,0 +1,188 @@
/****************************************************************************
** Copyright (C) 2001-2013 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 KDCHARTDATASETPROXYMODEL_H
#define KDCHARTDATASETPROXYMODEL_H
#include <QVector>
#include <QSortFilterProxyModel>
#include "kdchart_export.h"
namespace KDChart {
class IndexOutOfBoundsException;
typedef QVector<int> DatasetDescriptionVector;
/** DatasetProxyModel takes a KDChart dataset configuration and translates
it into a filtering proxy model.
The resulting model will only contain the part of the model that is
selected by the dataset, and the according row and column header
data.
Currently, this model is implemented for table models only. The way it
would work with models representing a tree is to be decided.
The column selection is configured by passing a dataset description
vector to the model. This vector (of integers) is supposed to have one
value for each column of the original model. If the value at position
x is -1, column x of the original model is not included in the
dataset. If it is between 0 and (columnCount() -1), it is the column
the source column is mapped to in the resulting model. Any other value
is an error.
*/
class KDCHART_EXPORT DatasetProxyModel : public QSortFilterProxyModel
{
Q_OBJECT
public:
/** Create a DatasetProxyModel.
Without further configuration, this model is invalid.
@see setDatasetDescriptionVector
*/
explicit DatasetProxyModel ( QObject* parent = 0 );
QModelIndex buddy( const QModelIndex& index ) const;
Qt::ItemFlags flags( const QModelIndex& index ) const;
QModelIndex index( int row, int column,
const QModelIndex &parent = QModelIndex() ) const;
QModelIndex parent(const QModelIndex &child ) const;
/** Implements the mapping from the source to the proxy indexes. */
QModelIndex mapFromSource ( const QModelIndex & sourceIndex ) const;
/** Implements the mapping from the proxy to the source indexes. */
QModelIndex mapToSource ( const QModelIndex& proxyIndex ) const;
/** Overloaded from base class. */
QVariant data(const QModelIndex &index, int role) const;
/** Overloaded from base class. */
bool setData( const QModelIndex& index, const QVariant& value, int role );
/** Overloaded from base class. */
QVariant headerData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const;
/** Overloaded from base class. */
void setSourceModel(QAbstractItemModel *sourceModel);
/** Set the root index of the table in
the source model */
void setSourceRootIndex(const QModelIndex& rootIdx);
public Q_SLOTS:
/** Reset all dataset description.
After that, the result of the proxying is an empty model (a new
dataset description needs to be set to achieve a non-empty result).
*/
void resetDatasetDescriptions();
/** Configure the dataset selection for the columns.
Every call to this method resets the previous dataset
description.
*/
void setDatasetColumnDescriptionVector ( const DatasetDescriptionVector& columnConfig );
/** Configure the dataset selection for the rows.
Every call to this method resets the previous dataset
description.
*/
void setDatasetRowDescriptionVector ( const DatasetDescriptionVector& rowConfig );
/** Convenience method to configure rows and columns in one step. */
void setDatasetDescriptionVectors (
const DatasetDescriptionVector& rowConfig,
const DatasetDescriptionVector& columnConfig );
// FIXME: add convenience methods to configure common dataset
// selections (like rectangular areas etc)
protected:
/** Decide whether the column is accepted. */
bool filterAcceptsColumn ( int sourceColumn,
const QModelIndex & ) const;
/** Decide whether the row is accepted. */
bool filterAcceptsRow ( int source_row, const QModelIndex & source_parent ) const;
private:
/** Map a proxy column to a source column. */
int mapProxyColumnToSource ( const int& proxyColumn ) const;
/** Map a source column to a proxy column. */
int mapSourceColumnToProxy ( const int& sourceColumn ) const;
/** Map a proxy row to a source row. */
int mapProxyRowToSource ( const int& proxyRow ) const;
/** Map a source row to a proxy row. */
int mapSourceRowToProxy ( const int& sourceRow ) const;
/** Initialize the transformation vectors from the dataset
description.
The input parameter "Configuration" is a vector that specifies
what srce column will be mapped to what proxy column. Example:
position: [0][1][2]
value: [2][0][1]
This will map the source column 2 to proxy column 0, source 0 to
proxy 1, and source 1 to proxy 2. Source needs to have at least 2
column. The source-to-proxy mapping looks the same, except that it
may contain values of -1, which means this column is not part of
the resulting model. The values in the configuration vector must
be unique (otherwise, a 1-to-1 mapping in both directions is
impossible).
sourceCount is the number of columns in the source model. The proxy-to-source map has
as many elements as the proxy has columns, the source-to-proxy map
has as many elements as the source has columns. Same goes for rows
(the mapping logic is the same).
*/
void initializeDatasetDecriptors (
const DatasetDescriptionVector& inConfiguration,
int sourceCount,
DatasetDescriptionVector& outSourceToProxyMap,
DatasetDescriptionVector& outProxyToSourceMap );
DatasetDescriptionVector mColSrcToProxyMap;
DatasetDescriptionVector mColProxyToSrcMap;
DatasetDescriptionVector mRowSrcToProxyMap;
DatasetDescriptionVector mRowProxyToSrcMap;
int mProxyRowCount;
int mProxyColumnCount;
QModelIndex mRootIndex;
};
}
#endif

View file

@ -0,0 +1,87 @@
/****************************************************************************
** Copyright (C) 2001-2013 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 KDCHARTDATASETSELECTOR_H
#define KDCHARTDATASETSELECTOR_H
#include <QFrame>
#include "KDChartDatasetProxyModel.h"
/**
* \cond PRIVATE_API_DOCU
*
* ( This class is used internally by DatasetSelectorWidget. )
*/
QT_BEGIN_NAMESPACE
namespace Ui {
class DatasetSelector;
}
QT_END_NAMESPACE
/**
* \endcond
*/
namespace KDChart {
class KDCHART_EXPORT DatasetSelectorWidget : public QFrame
{
Q_OBJECT
public:
explicit DatasetSelectorWidget ( QWidget* parent = 0 );
~DatasetSelectorWidget();
public Q_SLOTS:
void setSourceRowCount ( const int& rowCount );
void setSourceColumnCount ( const int& columnCount );
Q_SIGNALS:
void configureDatasetProxyModel (
const DatasetDescriptionVector& rowConfig,
const DatasetDescriptionVector& columnConfig );
void mappingDisabled ();
private Q_SLOTS:
void on_sbStartColumn_valueChanged ( int );
void on_sbStartRow_valueChanged ( int );
void on_sbColumnCount_valueChanged( int );
void on_sbRowCount_valueChanged( int );
void on_cbReverseRows_stateChanged ( int );
void on_cbReverseColumns_stateChanged ( int );
void on_groupBox_toggled ( bool );
private:
void resetDisplayValues ();
void calculateMapping();
Ui::DatasetSelector* mUi;
int mSourceRowCount;
int mSourceColumnCount;
};
}
#endif

View file

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

View file

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

View file

@ -0,0 +1,90 @@
/****************************************************************************
** Copyright (C) 2001-2013 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 __KDCHARTDIAGRAMOBSERVER_H_
#define __KDCHARTDIAGRAMOBSERVER_H_
#include "KDChartGlobal.h"
#include <QObject>
#include <QPointer>
#include <QModelIndex>
QT_BEGIN_NAMESPACE
class QAbstractItemModel;
QT_END_NAMESPACE
namespace KDChart {
class AbstractDiagram;
/**
* \brief A DiagramObserver watches the associated diagram for
* changes and deletion and emits corresponsing signals.
*/
class KDCHART_EXPORT DiagramObserver : public QObject
{
Q_OBJECT
public:
/**
* Constructs a new observer observing the given diagram.
*/
explicit DiagramObserver( AbstractDiagram * diagram, QObject* parent = 0 );
~DiagramObserver();
const AbstractDiagram* diagram() const;
AbstractDiagram* diagram();
Q_SIGNALS:
/** This signal is emitted immediately before the diagram is
* being destroyed. */
void diagramDestroyed( AbstractDiagram* diagram );
/** Emitted when a diagram is being destroyed, but before its data is invalidated **/
void diagramAboutToBeDestroyed( AbstractDiagram* diagram );
/** This signal is emitted whenever the data of the diagram changes. */
void diagramDataChanged( AbstractDiagram* diagram );
/** This signal is emitted whenever any of the data of the diagram was set (un)hidden. */
void diagramDataHidden( AbstractDiagram* diagram );
/** This signal is emitted whenever the attributes of the diagram change. */
void diagramAttributesChanged( AbstractDiagram* diagram );
private Q_SLOTS:
void slotDestroyed(QObject*);
void slotAboutToBeDestroyed();
void slotHeaderDataChanged(Qt::Orientation,int,int);
void slotDataChanged(QModelIndex,QModelIndex);
void slotDataChanged();
void slotDataHidden();
void slotAttributesChanged();
void slotAttributesChanged(QModelIndex,QModelIndex);
void slotModelsChanged();
private:
void init();
AbstractDiagram* m_diagram;
QPointer<QAbstractItemModel> m_model;
QPointer<QAbstractItemModel> m_attributesmodel;
};
}
#endif // KDChartDiagramObserver_H

View file

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

View file

@ -0,0 +1,346 @@
/****************************************************************************
** Copyright (C) 2001-2013 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 __KDCHARTENUMS_H__
#define __KDCHARTENUMS_H__
#include "KDChartGlobal.h"
#include <QRectF>
#include <QObject>
#include <QVector>
/** \file KDChartEnums.h
\brief Definition of global enums.
*/
/**
Project global class providing some enums needed both by KDChartParams
and by KDChartCustomBox.
*/
class KDCHART_EXPORT KDChartEnums :public QObject
{
Q_OBJECT
Q_ENUMS( TextLayoutPolicy )
Q_ENUMS( AreaName )
Q_ENUMS( PositionFlag )
public:
/**
GranularitySequence specifies the values, that may be applied,
to determine a step width within a given data range.
\note Granularity with can be set for Linear axis calculation mode only,
there is no way to specify a step width for Logarithmic axes.
Value occurring in the GranularitySequence names only are showing
their respective relation ship. For real data they will most times not
be used directly, but be multiplied by positive (or negative, resp.)
powers of ten.
A granularity sequence is a sequence of values from the following set:
1, 1.25, 2, 2.5, 5.
The reason for using one of the following three pre-defined granularity
sequences (instead of just using the best matching step width) is to
follow a simple rule: If scaling becomes finer (== smaller step width)
no value, that has been on a grid line before, shall loose its line
and be NOT on a grid line anymore!
This means: Smaller step width may not remove any grid lines, but it
may add additional lines in between.
\li \c GranularitySequence_10_20 Step widths can be 1, or 2, but they never can be 2.5 nor 5, nor 1.25.
\li \c GranularitySequence_10_50 Step widths can be 1, or 5, but they never can be 2, nor 2.5, nor 1.25.
\li \c GranularitySequence_25_50 Step widths can be 2.5, or 5, but they never can be 1, nor 2, nor 1.25.
\li \c GranularitySequence_125_25 Step widths can be 1.25 or 2.5 but they never can be 1, nor 2, nor 5.
\li \c GranularitySequenceIrregular Step widths can be all of these values: 1, or 1.25, or 2, or 2.5, or 5.
\note When ever possible, try to avoid using GranularitySequenceIrregular!
Allowing all possible step values, using this granularity sequence involves a
serious risk: Your users might be irritated due to 'jumping' grid lines, when step size
is changed from 2.5 to 2 (or vice versa, resp.).
In case you still want to use GranularitySequenceIrregular just make sure to NOT draw
any sub-grid lines, because in most cases you will get not-matching step widths for
the sub-grid.
In short: GranularitySequenceIrregular can safely be used if your data range is not
changing at all AND (b) you will not allow the coordinate plane to be zoomed
AND (c) you are not displaying any sub-grid lines.
Since you probably like having the value 1 as an allowed step width,
the granularity sequence decision boils down to a boolean question:
\li To get ten divided by five you use GranularitySequence_10_20, while
\li for having it divided by two GranularitySequence_10_50 is your choice.
*/
enum GranularitySequence {
GranularitySequence_10_20,
GranularitySequence_10_50,
GranularitySequence_25_50,
GranularitySequence_125_25,
GranularitySequenceIrregular };
/**
Converts the specified granularity sequence enum to a
string representation.
\param sequence the granularity sequence enum to convert
\return the string representation of the granularity sequence
*/
static QString granularitySequenceToString( GranularitySequence sequence ) {
switch ( sequence ) {
case GranularitySequence_10_20:
return QString::fromLatin1("GranularitySequence_10_20");
case GranularitySequence_10_50:
return QString::fromLatin1("GranularitySequence_10_50");
case GranularitySequence_25_50:
return QString::fromLatin1("GranularitySequence_25_50");
case GranularitySequence_125_25:
return QString::fromLatin1("GranularitySequence_125_25");
case GranularitySequenceIrregular:
return QString::fromLatin1("GranularitySequenceIrregular");
}
Q_ASSERT( !"Unknown GranularitySequenceValue" );
return QString::fromLatin1("GranularitySequence_10_20");
}
/**
Converts the specified string to a granularity sequence enum value.
\param string the string to convert
\return the granularity sequence enum value
*/
static GranularitySequence stringToGranularitySequence( const QString& string ) {
if ( string == QString::fromLatin1("GranularitySequence_10_20") )
return GranularitySequence_10_20;
if ( string == QString::fromLatin1("GranularitySequence_10_50") )
return GranularitySequence_10_50;
if ( string == QString::fromLatin1("GranularitySequence_25_50") )
return GranularitySequence_25_50;
if ( string == QString::fromLatin1("GranularitySequence_125") )
return GranularitySequence_125_25;
if ( string == QString::fromLatin1("GranularitySequenceIrregular") )
return GranularitySequenceIrregular;
// default, should not happen
return GranularitySequence_10_20;
}
/**
Text layout policy: what to do if text that is to be drawn would
cover neighboring text or neighboring areas.
\li \c LayoutJustOverwrite Just ignore the layout collision and write the text nevertheless.
\li \c LayoutPolicyRotate Try counter-clockwise rotation to make the text fit into the space.
\li \c LayoutPolicyShiftVertically Shift the text baseline upwards (or downwards, resp.) and draw a connector line between the text and its anchor.
\li \c LayoutPolicyShiftHorizontally Shift the text baseline to the left (or to the right, resp.) and draw a connector line between the text and its anchor.
\li \c LayoutPolicyShrinkFontSize Reduce the text font size.
\sa KDChartParams::setPrintDataValues
*/
enum TextLayoutPolicy { LayoutJustOverwrite,
LayoutPolicyRotate,
LayoutPolicyShiftVertically,
LayoutPolicyShiftHorizontally,
LayoutPolicyShrinkFontSize };
/**
Converts the specified text layout policy enum to a
string representation.
\param type the text layout policy to convert
\return the string representation of the text layout policy enum
*/
static QString layoutPolicyToString( TextLayoutPolicy type );
/**
Converts the specified string to a text layout policy enum value.
\param string the string to convert
\return the text layout policy enum value
*/
static TextLayoutPolicy stringToLayoutPolicy( const QString& string );
/**
Numerical values of the static KDChart::Position instances,
for using a Position::value() with a switch () statement.
\sa Position
*/
enum PositionValue {
PositionUnknown = 0,
PositionCenter = 1,
PositionNorthWest = 2,
PositionNorth = 3,
PositionNorthEast = 4,
PositionEast = 5,
PositionSouthEast = 6,
PositionSouth = 7,
PositionSouthWest = 8,
PositionWest = 9,
PositionFloating =10
};
/**
Measure calculation mode: the way how the absolute value of a KDChart::Measure is determined during KD Chart's internal geometry calculation time.
KDChart::Measure values either are relative (calculated in relation to a given AbstractArea), or they are absolute (used as fixed values).
Values stored in relative measure always are interpreted as per-mille of a reference area's height (or width, resp.) depending on the orientation set for the KDChart::Measure.
\li \c MeasureCalculationModeAbsolute Value set by setValue() is absolute, to be used unchanged.
\li \c MeasureCalculationModeRelative Value is relative, the reference area is specified by setReferenceArea(), and orientation specified by setOrientation().
\li \c MeasureCalculationModeAuto Value is relative, KD Chart will automatically determine which reference area to use, and it will determine the orientation too.
\li \c MeasureCalculationModeAutoArea Value is relative, Orientation is specified by setOrientation(), and KD Chart will automatically determine which reference area to use.
\li \c MeasureCalculationModeAutoOrientation Value is relative, Area is specified by setReferenceArea(), and KD Chart will automatically determine which orientation to use.
\sa KDChart::Measure::setCalculationMode
*/
enum MeasureCalculationMode { MeasureCalculationModeAbsolute,
MeasureCalculationModeRelative,
MeasureCalculationModeAuto,
MeasureCalculationModeAutoArea,
MeasureCalculationModeAutoOrientation };
/**
Converts the specified measure calculation mode enum to a
string representation.
\param mode the measure calculation mode to convert
\return the string representation of the Measure calculation mode enum
*/
static QString measureCalculationModeToString( MeasureCalculationMode mode ) {
switch ( mode ) {
case MeasureCalculationModeAbsolute:
return QString::fromLatin1("MeasureCalculationModeAbsolute");
case MeasureCalculationModeAuto:
return QString::fromLatin1("MeasureCalculationModeAuto");
case MeasureCalculationModeAutoArea:
return QString::fromLatin1("MeasureCalculationModeAutoArea");
case MeasureCalculationModeAutoOrientation:
return QString::fromLatin1("MeasureCalculationModeAutoOrientation");
case MeasureCalculationModeRelative:
return QString::fromLatin1("MeasureCalculationModeRelative");
}
Q_ASSERT( !"unhandled MeasureCalculationMode" );
return QString::fromLatin1("MeasureCalculationModeAuto");
}
/**
Converts the specified string to a measure calculation mode enum value.
\param string the string to convert
\return the measure calculation mode enum value
*/
static MeasureCalculationMode stringToMeasureCalculationMode( const QString& string ) {
if ( string == QString::fromLatin1("MeasureCalculationModeAbsolute") )
return MeasureCalculationModeAbsolute;
if ( string == QString::fromLatin1("MeasureCalculationModeAuto") )
return MeasureCalculationModeAuto;
if ( string == QString::fromLatin1("MeasureCalculationModeAutoArea") )
return MeasureCalculationModeAutoArea;
if ( string == QString::fromLatin1("MeasureCalculationModeAutoOrientation") )
return MeasureCalculationModeAutoOrientation;
if ( string == QString::fromLatin1("MeasureCalculationModeRelative") )
return MeasureCalculationModeRelative;
// default, should not happen
return MeasureCalculationModeAuto;
}
/**
Measure orientation mode: the way how the absolute value of a KDChart::Measure is determined during KD Chart's internal geometry calculation time.
KDChart::Measure values either are relative (calculated in relation to a given AbstractArea), or they are absolute (used as fixed values).
Values stored in relative measure take into account the width (and/or the height, resp.) of a so-called reference area,
that is either specified by KDChart::Measure::setReferenceArea, or determined by KD Chart automatically, respectively.
\li \c MeasureOrientationAuto Value is calculated, based upon the width (or on the height, resp.) of the reference area: KD Chart will automatically determie an appropriate way.
\li \c MeasureOrientationHorizontal Value is calculated, based upon the width of the reference area.
\li \c MeasureOrientationVertical Value is calculated, based upon the height of the reference area.
\li \c MeasureOrientationMinimum Value is calculated, based upon the width (or on the height, resp.) of the reference area - which ever is smaller.
\li \c MeasureOrientationMaximum Value is calculated, based upon the width (or on the height, resp.) of the reference area - which ever is smaller.
\sa KDChart::Measure::setOrientationMode
*/
enum MeasureOrientation { MeasureOrientationAuto,
MeasureOrientationHorizontal,
MeasureOrientationVertical,
MeasureOrientationMinimum,
MeasureOrientationMaximum };
/**
Converts the specified measure orientation enum to a
string representation.
\param mode the measure orientation to convert
\return the string representation of the measure orientation enum
*/
static QString measureOrientationToString( MeasureOrientation mode ) {
switch ( mode ) {
case MeasureOrientationAuto:
return QString::fromLatin1("MeasureOrientationAuto");
case MeasureOrientationHorizontal:
return QString::fromLatin1("MeasureOrientationHorizontal");
case MeasureOrientationVertical:
return QString::fromLatin1("MeasureOrientationVertical");
case MeasureOrientationMinimum:
return QString::fromLatin1("MeasureOrientationMinimum");
case MeasureOrientationMaximum:
return QString::fromLatin1("MeasureOrientationMaximum");
}
Q_ASSERT( !"Unknown MeasureOrientation value" );
return QString::fromLatin1("MeasureOrientationAuto");
}
/**
Converts the specified string to a measure orientation enum value.
\param string the string to convert
\return the measure orientation enum value
*/
static MeasureOrientation stringToMeasureOrientation( const QString& string ) {
if ( string == QString::fromLatin1("MeasureOrientationAuto") )
return MeasureOrientationAuto;
if ( string == QString::fromLatin1("MeasureOrientationHorizontal") )
return MeasureOrientationHorizontal;
if ( string == QString::fromLatin1("MeasureOrientationVertical") )
return MeasureOrientationVertical;
if ( string == QString::fromLatin1("MeasureOrientationMinimum") )
return MeasureOrientationMinimum;
if ( string == QString::fromLatin1("MeasureOrientationMaximum") )
return MeasureOrientationMaximum;
// default, should not happen
return MeasureOrientationAuto;
}
};
#endif

View file

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

View file

@ -0,0 +1,79 @@
/****************************************************************************
** Copyright (C) 2001-2013 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 KDCHARTFRAMEATTRIBUTES_H
#define KDCHARTFRAMEATTRIBUTES_H
#include <QDebug>
#include <QMetaType>
#include <QPen>
#include "KDChartGlobal.h"
namespace KDChart {
/**
* @brief A set of attributes for frames around items
*/
class KDCHART_EXPORT FrameAttributes
{
public:
FrameAttributes();
FrameAttributes( const FrameAttributes& );
FrameAttributes &operator= ( const FrameAttributes& );
~FrameAttributes();
void setVisible( bool visible );
bool isVisible() const;
void setPen( const QPen & pen );
QPen pen() const;
void setCornerRadius( qreal radius );
qreal cornerRadius() const;
void setPadding( int padding );
int padding() const;
bool operator==( const FrameAttributes& ) const;
inline bool operator!=( const FrameAttributes& other ) const { return !operator==(other); }
private:
KDCHART_DECLARE_PRIVATE_BASE_VALUE( FrameAttributes )
}; // End of class FrameAttributes
}
#if !defined(QT_NO_DEBUG_STREAM)
KDCHART_EXPORT QDebug operator<<(QDebug, const KDChart::FrameAttributes& );
#endif /* QT_NO_DEBUG_STREAM */
KDCHART_DECLARE_SWAP_SPECIALISATION( KDChart::FrameAttributes )
QT_BEGIN_NAMESPACE
Q_DECLARE_TYPEINFO( KDChart::FrameAttributes, Q_MOVABLE_TYPE );
QT_END_NAMESPACE
Q_DECLARE_METATYPE( KDChart::FrameAttributes )
#endif // KDCHARTFRAMEATTRIBUTES_H

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