summaryrefslogtreecommitdiffstats
path: root/examples/chart
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2011-07-10 15:24:15 -0500
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2011-07-10 15:24:15 -0500
commitbd0f3345a938b35ce6a12f6150373b0955b8dd12 (patch)
tree7a520322212d48ebcb9fbe1087e7fca28b76185c /examples/chart
downloadqt3-bd0f3345a938b35ce6a12f6150373b0955b8dd12.tar.gz
qt3-bd0f3345a938b35ce6a12f6150373b0955b8dd12.zip
Add Qt3 development HEAD version
Diffstat (limited to 'examples/chart')
-rw-r--r--examples/chart/canvastext.h31
-rw-r--r--examples/chart/canvasview.cpp55
-rw-r--r--examples/chart/canvasview.h36
-rw-r--r--examples/chart/chart.doc41
-rw-r--r--examples/chart/chart.pro20
-rw-r--r--examples/chart/chartform.cpp531
-rw-r--r--examples/chart/chartform.h90
-rw-r--r--examples/chart/chartform_canvas.cpp226
-rw-r--r--examples/chart/chartform_files.cpp113
-rw-r--r--examples/chart/element.cpp127
-rw-r--r--examples/chart/element.h84
-rw-r--r--examples/chart/images/chart-forms.sk256
-rw-r--r--examples/chart/images/file_new.xpm36
-rw-r--r--examples/chart/images/file_open.xpm33
-rw-r--r--examples/chart/images/file_print.xpm115
-rw-r--r--examples/chart/images/file_save.xpm33
-rw-r--r--examples/chart/images/file_saveaspostscript.xpm34
-rw-r--r--examples/chart/images/options_horizontalbarchart.xpm31
-rw-r--r--examples/chart/images/options_piechart.xpm30
-rw-r--r--examples/chart/images/options_setdata.xpm34
-rw-r--r--examples/chart/images/options_setfont.xpm27
-rw-r--r--examples/chart/images/options_setoptions.xpm32
-rw-r--r--examples/chart/images/options_verticalbarchart.xpm31
-rw-r--r--examples/chart/images/pattern01.xpm27
-rw-r--r--examples/chart/images/pattern02.xpm28
-rw-r--r--examples/chart/images/pattern03.xpm28
-rw-r--r--examples/chart/images/pattern04.xpm28
-rw-r--r--examples/chart/images/pattern05.xpm28
-rw-r--r--examples/chart/images/pattern06.xpm28
-rw-r--r--examples/chart/images/pattern07.xpm28
-rw-r--r--examples/chart/images/pattern08.xpm28
-rw-r--r--examples/chart/images/pattern09.xpm28
-rw-r--r--examples/chart/images/pattern10.xpm28
-rw-r--r--examples/chart/images/pattern11.xpm28
-rw-r--r--examples/chart/images/pattern12.xpm28
-rw-r--r--examples/chart/images/pattern13.xpm28
-rw-r--r--examples/chart/images/pattern14.xpm28
-rw-r--r--examples/chart/main.cpp21
-rw-r--r--examples/chart/optionsform.cpp135
-rw-r--r--examples/chart/optionsform.h60
-rw-r--r--examples/chart/setdataform.cpp208
-rw-r--r--examples/chart/setdataform.h47
42 files changed, 2908 insertions, 0 deletions
diff --git a/examples/chart/canvastext.h b/examples/chart/canvastext.h
new file mode 100644
index 0000000..599bd09
--- /dev/null
+++ b/examples/chart/canvastext.h
@@ -0,0 +1,31 @@
+#ifndef CANVASTEXT_H
+#define CANVASTEXT_H
+
+#include <qcanvas.h>
+
+class QFont;
+
+
+class CanvasText : public QCanvasText
+{
+public:
+ enum { CANVAS_TEXT = 1100 };
+
+ CanvasText( int index, QCanvas *canvas )
+ : QCanvasText( canvas ), m_index( index ) {}
+ CanvasText( int index, const QString& text, QCanvas *canvas )
+ : QCanvasText( text, canvas ), m_index( index ) {}
+ CanvasText( int index, const QString& text, QFont font, QCanvas *canvas )
+ : QCanvasText( text, font, canvas ), m_index( index ) {}
+
+ int index() const { return m_index; }
+ void setIndex( int index ) { m_index = index; }
+
+ int rtti() const { return CANVAS_TEXT; }
+
+private:
+ int m_index;
+};
+
+#endif
+
diff --git a/examples/chart/canvasview.cpp b/examples/chart/canvasview.cpp
new file mode 100644
index 0000000..42701f5
--- /dev/null
+++ b/examples/chart/canvasview.cpp
@@ -0,0 +1,55 @@
+#include "canvasview.h"
+#include "chartform.h"
+
+#include <qcursor.h>
+#include <qpoint.h>
+#include <qpopupmenu.h>
+#include <qstatusbar.h>
+
+
+void CanvasView::contentsContextMenuEvent( QContextMenuEvent * )
+{
+ ((ChartForm*)parent())->optionsMenu->exec( QCursor::pos() );
+}
+
+
+void CanvasView::viewportResizeEvent( QResizeEvent *e )
+{
+ canvas()->resize( e->size().width(), e->size().height() );
+ ((ChartForm*)parent())->drawElements();
+}
+
+
+void CanvasView::contentsMousePressEvent( QMouseEvent *e )
+{
+ QCanvasItemList list = canvas()->collisions( e->pos() );
+ for ( QCanvasItemList::iterator it = list.begin(); it != list.end(); ++it )
+ if ( (*it)->rtti() == CanvasText::CANVAS_TEXT ) {
+ m_movingItem = *it;
+ m_pos = e->pos();
+ return;
+ }
+ m_movingItem = 0;
+}
+
+
+void CanvasView::contentsMouseMoveEvent( QMouseEvent *e )
+{
+ if ( m_movingItem ) {
+ QPoint offset = e->pos() - m_pos;
+ m_movingItem->moveBy( offset.x(), offset.y() );
+ m_pos = e->pos();
+ ChartForm *form = (ChartForm*)parent();
+ form->setChanged( TRUE );
+ int chartType = form->chartType();
+ CanvasText *item = (CanvasText*)m_movingItem;
+ int i = item->index();
+
+ (*m_elements)[i].setProX( chartType, item->x() / canvas()->width() );
+ (*m_elements)[i].setProY( chartType, item->y() / canvas()->height() );
+
+ canvas()->update();
+ }
+}
+
+
diff --git a/examples/chart/canvasview.h b/examples/chart/canvasview.h
new file mode 100644
index 0000000..8ec2ac2
--- /dev/null
+++ b/examples/chart/canvasview.h
@@ -0,0 +1,36 @@
+#ifndef CANVASVIEW_H
+#define CANVASVIEW_H
+
+#include "element.h"
+#include "canvastext.h"
+
+#include <qcanvas.h>
+
+
+class QPoint;
+
+
+class CanvasView : public QCanvasView
+{
+ Q_OBJECT
+public:
+ CanvasView( QCanvas *canvas, ElementVector *elements,
+ QWidget* parent = 0, const char* name = "canvas view",
+ WFlags f = 0 )
+ : QCanvasView( canvas, parent, name, f ), m_movingItem(0),
+ m_elements( elements ) {}
+
+protected:
+ void viewportResizeEvent( QResizeEvent *e );
+ void contentsMousePressEvent( QMouseEvent *e );
+ void contentsMouseMoveEvent( QMouseEvent *e );
+ void contentsContextMenuEvent( QContextMenuEvent *e );
+
+private:
+ QCanvasItem *m_movingItem;
+ QPoint m_pos;
+ ElementVector *m_elements;
+};
+
+
+#endif
diff --git a/examples/chart/chart.doc b/examples/chart/chart.doc
new file mode 100644
index 0000000..c6c99f2
--- /dev/null
+++ b/examples/chart/chart.doc
@@ -0,0 +1,41 @@
+/*!
+ \page canvas-chart-example.html
+
+ \ingroup step-by-step-examples
+
+ \title A Complete Canvas Application
+
+ This is a complete example program with a main window, menus and
+ toolbars. The main widget is a QCanvas, and this example
+ demonstrates basic canvas usage.
+ \omit
+ This example is the subject of \link tutorial2.html Tutorial
+ #2\endlink.
+ \endomit
+
+ <hr>
+
+ Project file:
+
+ \include chart/chart.pro
+
+ <hr>
+
+ Header files:
+
+ \include chart/element.h
+ \include chart/chartform.h
+
+ <hr>
+
+ Implementation:
+
+ \include chart/chartform.cpp
+
+ <hr>
+
+ Main:
+
+ \include chart/main.cpp
+
+*/
diff --git a/examples/chart/chart.pro b/examples/chart/chart.pro
new file mode 100644
index 0000000..8c791e9
--- /dev/null
+++ b/examples/chart/chart.pro
@@ -0,0 +1,20 @@
+TEMPLATE = app
+
+CONFIG += warn_on
+
+REQUIRES = full-config
+
+HEADERS += element.h \
+ canvastext.h \
+ canvasview.h \
+ chartform.h \
+ optionsform.h \
+ setdataform.h
+SOURCES += element.cpp \
+ canvasview.cpp \
+ chartform.cpp \
+ chartform_canvas.cpp \
+ chartform_files.cpp \
+ optionsform.cpp \
+ setdataform.cpp \
+ main.cpp
diff --git a/examples/chart/chartform.cpp b/examples/chart/chartform.cpp
new file mode 100644
index 0000000..17c7390
--- /dev/null
+++ b/examples/chart/chartform.cpp
@@ -0,0 +1,531 @@
+#include "canvasview.h"
+#include "chartform.h"
+#include "optionsform.h"
+#include "setdataform.h"
+
+#include <qaction.h>
+#include <qapplication.h>
+#include <qcombobox.h>
+#include <qfile.h>
+#include <qfiledialog.h>
+#include <qfont.h>
+#include <qfontdialog.h>
+#include <qmenubar.h>
+#include <qmessagebox.h>
+#include <qpixmap.h>
+#include <qpopupmenu.h>
+#include <qprinter.h>
+#include <qradiobutton.h>
+#include <qsettings.h>
+#include <qspinbox.h>
+#include <qstatusbar.h>
+#include <qtoolbar.h>
+#include <qtoolbutton.h>
+
+#include "images/file_new.xpm"
+#include "images/file_open.xpm"
+#include "images/file_save.xpm"
+#include "images/file_print.xpm"
+#include "images/options_setdata.xpm"
+#include "images/options_setfont.xpm"
+#include "images/options_setoptions.xpm"
+#include "images/options_horizontalbarchart.xpm"
+#include "images/options_piechart.xpm"
+#include "images/options_verticalbarchart.xpm"
+
+
+const QString WINDOWS_REGISTRY = "/Trolltech/QtExamples";
+const QString APP_KEY = "/Chart/";
+
+
+ChartForm::ChartForm( const QString& filename )
+ : QMainWindow( 0, 0, WDestructiveClose )
+{
+ setIcon( QPixmap( options_piechart ) );
+
+ QAction *fileNewAction;
+ QAction *fileOpenAction;
+ QAction *fileSaveAction;
+ QAction *fileSaveAsAction;
+ QAction *fileSaveAsPixmapAction;
+ QAction *filePrintAction;
+ QAction *fileQuitAction;
+ QAction *optionsSetDataAction;
+ QAction *optionsSetFontAction;
+ QAction *optionsSetOptionsAction;
+
+ fileNewAction = new QAction(
+ "New Chart", QPixmap( file_new ),
+ "&New", CTRL+Key_N, this, "new" );
+ connect( fileNewAction, SIGNAL( activated() ), this, SLOT( fileNew() ) );
+
+ fileOpenAction = new QAction(
+ "Open Chart", QPixmap( file_open ),
+ "&Open...", CTRL+Key_O, this, "open" );
+ connect( fileOpenAction, SIGNAL( activated() ), this, SLOT( fileOpen() ) );
+
+ fileSaveAction = new QAction(
+ "Save Chart", QPixmap( file_save ),
+ "&Save", CTRL+Key_S, this, "save" );
+ connect( fileSaveAction, SIGNAL( activated() ), this, SLOT( fileSave() ) );
+
+ fileSaveAsAction = new QAction(
+ "Save Chart As", QPixmap( file_save ),
+ "Save &As...", 0, this, "save as" );
+ connect( fileSaveAsAction, SIGNAL( activated() ),
+ this, SLOT( fileSaveAs() ) );
+
+ fileSaveAsPixmapAction = new QAction(
+ "Save Chart As Bitmap", QPixmap( file_save ),
+ "Save As &Bitmap...", CTRL+Key_B, this, "save as bitmap" );
+ connect( fileSaveAsPixmapAction, SIGNAL( activated() ),
+ this, SLOT( fileSaveAsPixmap() ) );
+
+ filePrintAction = new QAction(
+ "Print Chart", QPixmap( file_print ),
+ "&Print Chart...", CTRL+Key_P, this, "print chart" );
+ connect( filePrintAction, SIGNAL( activated() ),
+ this, SLOT( filePrint() ) );
+
+ optionsSetDataAction = new QAction(
+ "Set Data", QPixmap( options_setdata ),
+ "Set &Data...", CTRL+Key_D, this, "set data" );
+ connect( optionsSetDataAction, SIGNAL( activated() ),
+ this, SLOT( optionsSetData() ) );
+
+
+ QActionGroup *chartGroup = new QActionGroup( this ); // Connected later
+ chartGroup->setExclusive( TRUE );
+
+ optionsPieChartAction = new QAction(
+ "Pie Chart", QPixmap( options_piechart ),
+ "&Pie Chart", CTRL+Key_I, chartGroup, "pie chart" );
+ optionsPieChartAction->setToggleAction( TRUE );
+
+ optionsHorizontalBarChartAction = new QAction(
+ "Horizontal Bar Chart", QPixmap( options_horizontalbarchart ),
+ "&Horizontal Bar Chart", CTRL+Key_H, chartGroup,
+ "horizontal bar chart" );
+ optionsHorizontalBarChartAction->setToggleAction( TRUE );
+
+ optionsVerticalBarChartAction = new QAction(
+ "Vertical Bar Chart", QPixmap( options_verticalbarchart ),
+ "&Vertical Bar Chart", CTRL+Key_V, chartGroup, "Vertical bar chart" );
+ optionsVerticalBarChartAction->setToggleAction( TRUE );
+
+
+ optionsSetFontAction = new QAction(
+ "Set Font", QPixmap( options_setfont ),
+ "Set &Font...", CTRL+Key_F, this, "set font" );
+ connect( optionsSetFontAction, SIGNAL( activated() ),
+ this, SLOT( optionsSetFont() ) );
+
+ optionsSetOptionsAction = new QAction(
+ "Set Options", QPixmap( options_setoptions ),
+ "Set &Options...", 0, this, "set options" );
+ connect( optionsSetOptionsAction, SIGNAL( activated() ),
+ this, SLOT( optionsSetOptions() ) );
+
+ fileQuitAction = new QAction( "Quit", "&Quit", CTRL+Key_Q, this, "quit" );
+ connect( fileQuitAction, SIGNAL( activated() ), this, SLOT( fileQuit() ) );
+
+
+ QToolBar* fileTools = new QToolBar( this, "file operations" );
+ fileTools->setLabel( "File Operations" );
+ fileNewAction->addTo( fileTools );
+ fileOpenAction->addTo( fileTools );
+ fileSaveAction->addTo( fileTools );
+ fileTools->addSeparator();
+ filePrintAction->addTo( fileTools );
+
+ QToolBar *optionsTools = new QToolBar( this, "options operations" );
+ optionsTools->setLabel( "Options Operations" );
+ optionsSetDataAction->addTo( optionsTools );
+ optionsTools->addSeparator();
+ optionsPieChartAction->addTo( optionsTools );
+ optionsHorizontalBarChartAction->addTo( optionsTools );
+ optionsVerticalBarChartAction->addTo( optionsTools );
+ optionsTools->addSeparator();
+ optionsSetFontAction->addTo( optionsTools );
+ optionsTools->addSeparator();
+ optionsSetOptionsAction->addTo( optionsTools );
+
+ fileMenu = new QPopupMenu( this );
+ menuBar()->insertItem( "&File", fileMenu );
+ fileNewAction->addTo( fileMenu );
+ fileOpenAction->addTo( fileMenu );
+ fileSaveAction->addTo( fileMenu );
+ fileSaveAsAction->addTo( fileMenu );
+ fileMenu->insertSeparator();
+ fileSaveAsPixmapAction->addTo( fileMenu );
+ fileMenu->insertSeparator();
+ filePrintAction->addTo( fileMenu );
+ fileMenu->insertSeparator();
+ fileQuitAction->addTo( fileMenu );
+
+ optionsMenu = new QPopupMenu( this );
+ menuBar()->insertItem( "&Options", optionsMenu );
+ optionsSetDataAction->addTo( optionsMenu );
+ optionsMenu->insertSeparator();
+ optionsPieChartAction->addTo( optionsMenu );
+ optionsHorizontalBarChartAction->addTo( optionsMenu );
+ optionsVerticalBarChartAction->addTo( optionsMenu );
+ optionsMenu->insertSeparator();
+ optionsSetFontAction->addTo( optionsMenu );
+ optionsMenu->insertSeparator();
+ optionsSetOptionsAction->addTo( optionsMenu );
+
+ menuBar()->insertSeparator();
+
+ QPopupMenu *helpMenu = new QPopupMenu( this );
+ menuBar()->insertItem( "&Help", helpMenu );
+ helpMenu->insertItem( "&Help", this, SLOT(helpHelp()), Key_F1 );
+ helpMenu->insertItem( "&About", this, SLOT(helpAbout()) );
+ helpMenu->insertItem( "About &Qt", this, SLOT(helpAboutQt()) );
+
+
+ m_printer = 0;
+ m_elements.resize( MAX_ELEMENTS );
+
+ QSettings settings;
+ settings.insertSearchPath( QSettings::Windows, WINDOWS_REGISTRY );
+ int windowWidth = settings.readNumEntry( APP_KEY + "WindowWidth", 460 );
+ int windowHeight = settings.readNumEntry( APP_KEY + "WindowHeight", 530 );
+ int windowX = settings.readNumEntry( APP_KEY + "WindowX", -1 );
+ int windowY = settings.readNumEntry( APP_KEY + "WindowY", -1 );
+ setChartType( ChartType(
+ settings.readNumEntry( APP_KEY + "ChartType", int(PIE) ) ) );
+ m_addValues = AddValuesType(
+ settings.readNumEntry( APP_KEY + "AddValues", int(NO) ));
+ m_decimalPlaces = settings.readNumEntry( APP_KEY + "Decimals", 2 );
+ m_font = QFont( "Helvetica", 18, QFont::Bold );
+ m_font.fromString(
+ settings.readEntry( APP_KEY + "Font", m_font.toString() ) );
+ for ( int i = 0; i < MAX_RECENTFILES; ++i ) {
+ QString filename = settings.readEntry( APP_KEY + "File" +
+ QString::number( i + 1 ) );
+ if ( !filename.isEmpty() )
+ m_recentFiles.push_back( filename );
+ }
+ if ( m_recentFiles.count() )
+ updateRecentFilesMenu();
+
+
+ // Connect *after* we've set the chart type on so we don't call
+ // drawElements() prematurely.
+ connect( chartGroup, SIGNAL( selected(QAction*) ),
+ this, SLOT( updateChartType(QAction*) ) );
+
+ resize( windowWidth, windowHeight );
+ if ( windowX != -1 || windowY != -1 )
+ move( windowX, windowY );
+
+ m_canvas = new QCanvas( this );
+ m_canvas->resize( width(), height() );
+ m_canvasView = new CanvasView( m_canvas, &m_elements, this );
+ setCentralWidget( m_canvasView );
+ m_canvasView->show();
+
+ if ( !filename.isEmpty() )
+ load( filename );
+ else {
+ init();
+ m_elements[0].set( 20, red, 14, "Red" );
+ m_elements[1].set( 70, cyan, 2, "Cyan", darkGreen );
+ m_elements[2].set( 35, blue, 11, "Blue" );
+ m_elements[3].set( 55, yellow, 1, "Yellow", darkBlue );
+ m_elements[4].set( 80, magenta, 1, "Magenta" );
+ drawElements();
+ }
+
+ statusBar()->message( "Ready", 2000 );
+}
+
+
+ChartForm::~ChartForm()
+{
+ delete m_printer;
+}
+
+
+void ChartForm::init()
+{
+ setCaption( "Chart" );
+ m_filename = QString::null;
+ m_changed = FALSE;
+
+ m_elements[0] = Element( Element::INVALID, red );
+ m_elements[1] = Element( Element::INVALID, cyan );
+ m_elements[2] = Element( Element::INVALID, blue );
+ m_elements[3] = Element( Element::INVALID, yellow );
+ m_elements[4] = Element( Element::INVALID, green );
+ m_elements[5] = Element( Element::INVALID, magenta );
+ m_elements[6] = Element( Element::INVALID, darkYellow );
+ m_elements[7] = Element( Element::INVALID, darkRed );
+ m_elements[8] = Element( Element::INVALID, darkCyan );
+ m_elements[9] = Element( Element::INVALID, darkGreen );
+ m_elements[10] = Element( Element::INVALID, darkMagenta );
+ m_elements[11] = Element( Element::INVALID, darkBlue );
+ for ( int i = 12; i < MAX_ELEMENTS; ++i ) {
+ double x = (double(i) / MAX_ELEMENTS) * 360;
+ int y = (int(x * 256) % 105) + 151;
+ int z = ((i * 17) % 105) + 151;
+ m_elements[i] = Element( Element::INVALID, QColor( int(x), y, z, QColor::Hsv ) );
+ }
+}
+
+void ChartForm::closeEvent( QCloseEvent * )
+{
+ fileQuit();
+}
+
+
+void ChartForm::fileNew()
+{
+ if ( okToClear() ) {
+ init();
+ drawElements();
+ }
+}
+
+
+void ChartForm::fileOpen()
+{
+ if ( !okToClear() )
+ return;
+
+ QString filename = QFileDialog::getOpenFileName(
+ QString::null, "Charts (*.cht)", this,
+ "file open", "Chart -- File Open" );
+ if ( !filename.isEmpty() )
+ load( filename );
+ else
+ statusBar()->message( "File Open abandoned", 2000 );
+}
+
+
+void ChartForm::fileSaveAs()
+{
+ QString filename = QFileDialog::getSaveFileName(
+ QString::null, "Charts (*.cht)", this,
+ "file save as", "Chart -- File Save As" );
+ if ( !filename.isEmpty() ) {
+ int answer = 0;
+ if ( QFile::exists( filename ) )
+ answer = QMessageBox::warning(
+ this, "Chart -- Overwrite File",
+ QString( "Overwrite\n\'%1\'?" ).
+ arg( filename ),
+ "&Yes", "&No", QString::null, 1, 1 );
+ if ( answer == 0 ) {
+ m_filename = filename;
+ updateRecentFiles( filename );
+ fileSave();
+ return;
+ }
+ }
+ statusBar()->message( "Saving abandoned", 2000 );
+}
+
+
+void ChartForm::fileOpenRecent( int index )
+{
+ if ( !okToClear() )
+ return;
+
+ load( m_recentFiles[index] );
+}
+
+
+void ChartForm::updateRecentFiles( const QString& filename )
+{
+ if ( m_recentFiles.find( filename ) != m_recentFiles.end() )
+ return;
+
+ m_recentFiles.push_back( filename );
+ if ( m_recentFiles.count() > MAX_RECENTFILES )
+ m_recentFiles.pop_front();
+
+ updateRecentFilesMenu();
+}
+
+
+void ChartForm::updateRecentFilesMenu()
+{
+ for ( int i = 0; i < MAX_RECENTFILES; ++i ) {
+ if ( fileMenu->findItem( i ) )
+ fileMenu->removeItem( i );
+ if ( i < int(m_recentFiles.count()) )
+ fileMenu->insertItem( QString( "&%1 %2" ).
+ arg( i + 1 ).arg( m_recentFiles[i] ),
+ this, SLOT( fileOpenRecent(int) ),
+ 0, i );
+ }
+}
+
+
+void ChartForm::fileQuit()
+{
+ if ( okToClear() ) {
+ saveOptions();
+ qApp->exit( 0 );
+ }
+}
+
+
+bool ChartForm::okToClear()
+{
+ if ( m_changed ) {
+ QString msg;
+ if ( m_filename.isEmpty() )
+ msg = "Unnamed chart ";
+ else
+ msg = QString( "Chart '%1'\n" ).arg( m_filename );
+ msg += "has been changed.";
+
+ int x = QMessageBox::information( this, "Chart -- Unsaved Changes",
+ msg, "&Save", "Cancel", "&Abandon",
+ 0, 1 );
+ switch( x ) {
+ case 0: // Save
+ fileSave();
+ break;
+ case 1: // Cancel
+ default:
+ return FALSE;
+ case 2: // Abandon
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+
+void ChartForm::saveOptions()
+{
+ QSettings settings;
+ settings.insertSearchPath( QSettings::Windows, WINDOWS_REGISTRY );
+ settings.writeEntry( APP_KEY + "WindowWidth", width() );
+ settings.writeEntry( APP_KEY + "WindowHeight", height() );
+ settings.writeEntry( APP_KEY + "WindowX", x() );
+ settings.writeEntry( APP_KEY + "WindowY", y() );
+ settings.writeEntry( APP_KEY + "ChartType", int(m_chartType) );
+ settings.writeEntry( APP_KEY + "AddValues", int(m_addValues) );
+ settings.writeEntry( APP_KEY + "Decimals", m_decimalPlaces );
+ settings.writeEntry( APP_KEY + "Font", m_font.toString() );
+ for ( int i = 0; i < int(m_recentFiles.count()); ++i )
+ settings.writeEntry( APP_KEY + "File" + QString::number( i + 1 ),
+ m_recentFiles[i] );
+}
+
+
+void ChartForm::optionsSetData()
+{
+ SetDataForm *setDataForm = new SetDataForm( &m_elements, m_decimalPlaces, this );
+ if ( setDataForm->exec() ) {
+ m_changed = TRUE;
+ drawElements();
+ }
+ delete setDataForm;
+}
+
+
+void ChartForm::setChartType( ChartType chartType )
+{
+ m_chartType = chartType;
+ switch ( m_chartType ) {
+ case PIE:
+ optionsPieChartAction->setOn( TRUE );
+ break;
+ case VERTICAL_BAR:
+ optionsVerticalBarChartAction->setOn( TRUE );
+ break;
+ case HORIZONTAL_BAR:
+ optionsHorizontalBarChartAction->setOn( TRUE );
+ break;
+ }
+}
+
+
+void ChartForm::updateChartType( QAction *action )
+{
+ if ( action == optionsPieChartAction ) {
+ m_chartType = PIE;
+ }
+ else if ( action == optionsHorizontalBarChartAction ) {
+ m_chartType = HORIZONTAL_BAR;
+ }
+ else if ( action == optionsVerticalBarChartAction ) {
+ m_chartType = VERTICAL_BAR;
+ }
+
+ drawElements();
+}
+
+
+void ChartForm::optionsSetFont()
+{
+ bool ok;
+ QFont font = QFontDialog::getFont( &ok, m_font, this );
+ if ( ok ) {
+ m_font = font;
+ drawElements();
+ }
+}
+
+
+void ChartForm::optionsSetOptions()
+{
+ OptionsForm *optionsForm = new OptionsForm( this );
+ optionsForm->chartTypeComboBox->setCurrentItem( m_chartType );
+ optionsForm->setFont( m_font );
+ switch ( m_addValues ) {
+ case NO:
+ optionsForm->noRadioButton->setChecked( TRUE );
+ break;
+ case YES:
+ optionsForm->yesRadioButton->setChecked( TRUE );
+ break;
+ case AS_PERCENTAGE:
+ optionsForm->asPercentageRadioButton->setChecked( TRUE );
+ break;
+ }
+ optionsForm->decimalPlacesSpinBox->setValue( m_decimalPlaces );
+ if ( optionsForm->exec() ) {
+ setChartType( ChartType(
+ optionsForm->chartTypeComboBox->currentItem()) );
+ m_font = optionsForm->font();
+ if ( optionsForm->noRadioButton->isChecked() )
+ m_addValues = NO;
+ else if ( optionsForm->yesRadioButton->isChecked() )
+ m_addValues = YES;
+ else if ( optionsForm->asPercentageRadioButton->isChecked() )
+ m_addValues = AS_PERCENTAGE;
+ m_decimalPlaces = optionsForm->decimalPlacesSpinBox->value();
+ drawElements();
+ }
+ delete optionsForm;
+}
+
+
+void ChartForm::helpHelp()
+{
+ statusBar()->message( "Help is not implemented yet", 2000 );
+}
+
+
+void ChartForm::helpAbout()
+{
+ QMessageBox::about( this, "Chart -- About",
+ "<center><h1><font color=blue>Chart<font></h1></center>"
+ "<p>Chart your data with <i>chart</i>.</p>"
+ );
+}
+
+
+void ChartForm::helpAboutQt()
+{
+ QMessageBox::aboutQt( this, "Chart -- About Qt" );
+}
+
diff --git a/examples/chart/chartform.h b/examples/chart/chartform.h
new file mode 100644
index 0000000..c265657
--- /dev/null
+++ b/examples/chart/chartform.h
@@ -0,0 +1,90 @@
+#ifndef CHARTFORM_H
+#define CHARTFORM_H
+
+#include "element.h"
+
+#include <qmainwindow.h>
+#include <qstringlist.h>
+
+
+class CanvasView;
+
+class QAction;
+class QCanvas;
+class QFont;
+class QPrinter;
+class QString;
+
+
+class ChartForm: public QMainWindow
+{
+ Q_OBJECT
+public:
+ enum { MAX_ELEMENTS = 100 };
+ enum { MAX_RECENTFILES = 9 }; // Must not exceed 9
+ enum ChartType { PIE, VERTICAL_BAR, HORIZONTAL_BAR };
+ enum AddValuesType { NO, YES, AS_PERCENTAGE };
+
+ ChartForm( const QString& filename );
+ ~ChartForm();
+
+ int chartType() { return m_chartType; }
+ void setChanged( bool changed = TRUE ) { m_changed = changed; }
+ void drawElements();
+
+ QPopupMenu *optionsMenu; // Why public? See canvasview.cpp
+
+protected:
+ virtual void closeEvent( QCloseEvent * );
+
+private slots:
+ void fileNew();
+ void fileOpen();
+ void fileOpenRecent( int index );
+ void fileSave();
+ void fileSaveAs();
+ void fileSaveAsPixmap();
+ void filePrint();
+ void fileQuit();
+ void optionsSetData();
+ void updateChartType( QAction *action );
+ void optionsSetFont();
+ void optionsSetOptions();
+ void helpHelp();
+ void helpAbout();
+ void helpAboutQt();
+ void saveOptions();
+
+private:
+ void init();
+ void load( const QString& filename );
+ bool okToClear();
+ void drawPieChart( const double scales[], double total, int count );
+ void drawVerticalBarChart( const double scales[], double total, int count );
+ void drawHorizontalBarChart( const double scales[], double total, int count );
+
+ QString valueLabel( const QString& label, double value, double total );
+ void updateRecentFiles( const QString& filename );
+ void updateRecentFilesMenu();
+ void setChartType( ChartType chartType );
+
+ QPopupMenu *fileMenu;
+ QAction *optionsPieChartAction;
+ QAction *optionsHorizontalBarChartAction;
+ QAction *optionsVerticalBarChartAction;
+
+
+ QString m_filename;
+ QStringList m_recentFiles;
+ QCanvas *m_canvas;
+ CanvasView *m_canvasView;
+ bool m_changed;
+ ElementVector m_elements;
+ QPrinter *m_printer;
+ ChartType m_chartType;
+ AddValuesType m_addValues;
+ int m_decimalPlaces;
+ QFont m_font;
+};
+
+#endif
diff --git a/examples/chart/chartform_canvas.cpp b/examples/chart/chartform_canvas.cpp
new file mode 100644
index 0000000..92a3aeb
--- /dev/null
+++ b/examples/chart/chartform_canvas.cpp
@@ -0,0 +1,226 @@
+#include "canvastext.h"
+#include "chartform.h"
+
+#include <qbrush.h>
+#include <qcanvas.h>
+
+#include <math.h> // sin, cos
+
+#ifndef M_PI
+#define M_PI 3.1415
+#endif
+
+void ChartForm::drawElements()
+{
+ QCanvasItemList list = m_canvas->allItems();
+ for ( QCanvasItemList::iterator it = list.begin(); it != list.end(); ++it )
+ delete *it;
+
+ // 360 * 16 for pies; Qt works with 16ths of degrees
+ int scaleFactor = m_chartType == PIE ? 5760 :
+ m_chartType == VERTICAL_BAR ? m_canvas->height() :
+ m_canvas->width();
+ double biggest = 0.0;
+ int count = 0;
+ double total = 0.0;
+ static double scales[MAX_ELEMENTS];
+
+ for ( int i = 0; i < MAX_ELEMENTS; ++i ) {
+ if ( m_elements[i].isValid() ) {
+ double value = m_elements[i].value();
+ count++;
+ total += value;
+ if ( value > biggest )
+ biggest = value;
+ scales[i] = m_elements[i].value() * scaleFactor;
+ }
+ }
+
+ if ( count ) {
+ // 2nd loop because of total and biggest
+ for ( int i = 0; i < MAX_ELEMENTS; ++i )
+ if ( m_elements[i].isValid() )
+ if ( m_chartType == PIE )
+ scales[i] = (m_elements[i].value() * scaleFactor) / total;
+ else
+ scales[i] = (m_elements[i].value() * scaleFactor) / biggest;
+
+ switch ( m_chartType ) {
+ case PIE:
+ drawPieChart( scales, total, count );
+ break;
+ case VERTICAL_BAR:
+ drawVerticalBarChart( scales, total, count );
+ break;
+ case HORIZONTAL_BAR:
+ drawHorizontalBarChart( scales, total, count );
+ break;
+ }
+ }
+
+ m_canvas->update();
+}
+
+
+void ChartForm::drawPieChart( const double scales[], double total, int )
+{
+ double width = m_canvas->width();
+ double height = m_canvas->height();
+ int size = int(width > height ? height : width);
+ int x = int(width / 2);
+ int y = int(height / 2);
+ int angle = 0;
+
+ for ( int i = 0; i < MAX_ELEMENTS; ++i ) {
+ if ( m_elements[i].isValid() ) {
+ int extent = int(scales[i]);
+ QCanvasEllipse *arc = new QCanvasEllipse(
+ size, size, angle, extent, m_canvas );
+ arc->setX( x );
+ arc->setY( y );
+ arc->setZ( 0 );
+ arc->setBrush( QBrush( m_elements[i].valueColor(),
+ BrushStyle(m_elements[i].valuePattern()) ) );
+ arc->show();
+ angle += extent;
+ QString label = m_elements[i].label();
+ if ( !label.isEmpty() || m_addValues != NO ) {
+ label = valueLabel( label, m_elements[i].value(), total );
+ CanvasText *text = new CanvasText( i, label, m_font, m_canvas );
+ double proX = m_elements[i].proX( PIE );
+ double proY = m_elements[i].proY( PIE );
+ if ( proX < 0 || proY < 0 ) {
+ // Find the centre of the pie segment
+ QRect rect = arc->boundingRect();
+ proX = ( rect.width() / 2 ) + rect.x();
+ proY = ( rect.height() / 2 ) + rect.y();
+ // Centre text over the centre of the pie segment
+ rect = text->boundingRect();
+ proX -= ( rect.width() / 2 );
+ proY -= ( rect.height() / 2 );
+ // Make proportional
+ proX /= width;
+ proY /= height;
+ }
+ text->setColor( m_elements[i].labelColor() );
+ text->setX( proX * width );
+ text->setY( proY * height );
+ text->setZ( 1 );
+ text->show();
+ m_elements[i].setProX( PIE, proX );
+ m_elements[i].setProY( PIE, proY );
+ }
+ }
+ }
+}
+
+
+void ChartForm::drawVerticalBarChart(
+ const double scales[], double total, int count )
+{
+ double width = m_canvas->width();
+ double height = m_canvas->height();
+ int prowidth = int(width / count);
+ int x = 0;
+ QPen pen;
+ pen.setStyle( NoPen );
+
+ for ( int i = 0; i < MAX_ELEMENTS; ++i ) {
+ if ( m_elements[i].isValid() ) {
+ int extent = int(scales[i]);
+ int y = int(height - extent);
+ QCanvasRectangle *rect = new QCanvasRectangle(
+ x, y, prowidth, extent, m_canvas );
+ rect->setBrush( QBrush( m_elements[i].valueColor(),
+ BrushStyle(m_elements[i].valuePattern()) ) );
+ rect->setPen( pen );
+ rect->setZ( 0 );
+ rect->show();
+ QString label = m_elements[i].label();
+ if ( !label.isEmpty() || m_addValues != NO ) {
+ double proX = m_elements[i].proX( VERTICAL_BAR );
+ double proY = m_elements[i].proY( VERTICAL_BAR );
+ if ( proX < 0 || proY < 0 ) {
+ proX = x / width;
+ proY = y / height;
+ }
+ label = valueLabel( label, m_elements[i].value(), total );
+ CanvasText *text = new CanvasText( i, label, m_font, m_canvas );
+ text->setColor( m_elements[i].labelColor() );
+ text->setX( proX * width );
+ text->setY( proY * height );
+ text->setZ( 1 );
+ text->show();
+ m_elements[i].setProX( VERTICAL_BAR, proX );
+ m_elements[i].setProY( VERTICAL_BAR, proY );
+ }
+ x += prowidth;
+ }
+ }
+}
+
+
+void ChartForm::drawHorizontalBarChart(
+ const double scales[], double total, int count )
+{
+ double width = m_canvas->width();
+ double height = m_canvas->height();
+ int proheight = int(height / count);
+ int y = 0;
+ QPen pen;
+ pen.setStyle( NoPen );
+
+ for ( int i = 0; i < MAX_ELEMENTS; ++i ) {
+ if ( m_elements[i].isValid() ) {
+ int extent = int(scales[i]);
+ QCanvasRectangle *rect = new QCanvasRectangle(
+ 0, y, extent, proheight, m_canvas );
+ rect->setBrush( QBrush( m_elements[i].valueColor(),
+ BrushStyle(m_elements[i].valuePattern()) ) );
+ rect->setPen( pen );
+ rect->setZ( 0 );
+ rect->show();
+ QString label = m_elements[i].label();
+ if ( !label.isEmpty() || m_addValues != NO ) {
+ double proX = m_elements[i].proX( HORIZONTAL_BAR );
+ double proY = m_elements[i].proY( HORIZONTAL_BAR );
+ if ( proX < 0 || proY < 0 ) {
+ proX = 0;
+ proY = y / height;
+ }
+ label = valueLabel( label, m_elements[i].value(), total );
+ CanvasText *text = new CanvasText( i, label, m_font, m_canvas );
+ text->setColor( m_elements[i].labelColor() );
+ text->setX( proX * width );
+ text->setY( proY * height );
+ text->setZ( 1 );
+ text->show();
+ m_elements[i].setProX( HORIZONTAL_BAR, proX );
+ m_elements[i].setProY( HORIZONTAL_BAR, proY );
+ }
+ y += proheight;
+ }
+ }
+}
+
+
+QString ChartForm::valueLabel(
+ const QString& label, double value, double total )
+{
+ if ( m_addValues == NO )
+ return label;
+
+ QString newLabel = label;
+ if ( !label.isEmpty() )
+ if ( m_chartType == VERTICAL_BAR )
+ newLabel += '\n';
+ else
+ newLabel += ' ';
+ if ( m_addValues == YES )
+ newLabel += QString::number( value, 'f', m_decimalPlaces );
+ else if ( m_addValues == AS_PERCENTAGE )
+ newLabel += QString::number( (value / total) * 100, 'f', m_decimalPlaces )
+ + '%';
+ return newLabel;
+}
+
diff --git a/examples/chart/chartform_files.cpp b/examples/chart/chartform_files.cpp
new file mode 100644
index 0000000..55eefbf
--- /dev/null
+++ b/examples/chart/chartform_files.cpp
@@ -0,0 +1,113 @@
+#include "canvasview.h"
+#include "chartform.h"
+
+#include <qfile.h>
+#include <qfiledialog.h>
+#include <qpainter.h>
+#include <qprinter.h>
+#include <qstatusbar.h>
+
+
+void ChartForm::load( const QString& filename )
+{
+ QFile file( filename );
+ if ( !file.open( IO_ReadOnly ) ) {
+ statusBar()->message( QString( "Failed to load \'%1\'" ).
+ arg( filename ), 2000 );
+ return;
+ }
+
+ init(); // Make sure we have colours
+ m_filename = filename;
+ QTextStream ts( &file );
+ Element element;
+ int errors = 0;
+ int i = 0;
+ while ( !ts.eof() ) {
+ ts >> element;
+ if ( element.isValid() )
+ m_elements[i++] = element;
+ else
+ errors++;
+ if ( i == MAX_ELEMENTS ) {
+ statusBar()->message(
+ QString( "Read maximum number of elements (%1)"
+ " discarding others" ).arg( i ), 2000 );
+ break;
+ }
+ }
+
+ file.close();
+
+ QString bad = "";
+ if ( errors ) {
+ bad = QString( "; skipped " ) + QString::number( errors ) + " bad record";
+ if ( errors > 1 )
+ bad += "s";
+ }
+ statusBar()->message( QString( "Read %1 values from \'%2\'%3" ).
+ arg( i ).arg( filename ).arg( bad ), 3000 );
+
+ setCaption( QString( "Chart -- %1" ).arg( filename ) );
+ updateRecentFiles( filename );
+
+ drawElements();
+ m_changed = FALSE;
+}
+
+
+void ChartForm::fileSave()
+{
+ if ( m_filename.isEmpty() ) {
+ fileSaveAs();
+ return;
+ }
+
+ QFile file( m_filename );
+ if ( !file.open( IO_WriteOnly ) ) {
+ statusBar()->message( QString( "Failed to save \'%1\'" ).
+ arg( m_filename ), 2000 );
+ return;
+ }
+ QTextStream ts( &file );
+ for ( int i = 0; i < MAX_ELEMENTS; ++i )
+ if ( m_elements[i].isValid() )
+ ts << m_elements[i];
+
+ file.close();
+
+ setCaption( QString( "Chart -- %1" ).arg( m_filename ) );
+ statusBar()->message( QString( "Saved \'%1\'" ).arg( m_filename ), 2000 );
+ m_changed = FALSE;
+}
+
+
+void ChartForm::fileSaveAsPixmap()
+{
+ QString filename = QFileDialog::getSaveFileName(
+ QString::null, "Images (*.png *.xpm *.jpg)",
+ this, "file save as bitmap",
+ "Chart -- File Save As Bitmap" );
+ if ( QPixmap::grabWidget( m_canvasView ).
+ save( filename,
+ filename.mid( filename.findRev( '.' ) + 1 ).upper() ) )
+ statusBar()->message( QString( "Wrote \'%1\'" ).arg( filename ), 2000 );
+ else
+ statusBar()->message( QString( "Failed to write \'%1\'" ).
+ arg( filename ), 2000 );
+}
+
+void ChartForm::filePrint()
+{
+ if ( !m_printer )
+ m_printer = new QPrinter;
+ if ( m_printer->setup() ) {
+ QPainter painter( m_printer );
+ m_canvas->drawArea( QRect( 0, 0, m_canvas->width(), m_canvas->height() ),
+ &painter, FALSE );
+ if ( !m_printer->outputFileName().isEmpty() )
+ statusBar()->message( QString( "Printed \'%1\'" ).
+ arg( m_printer->outputFileName() ), 2000 );
+ }
+}
+
diff --git a/examples/chart/element.cpp b/examples/chart/element.cpp
new file mode 100644
index 0000000..c29b238
--- /dev/null
+++ b/examples/chart/element.cpp
@@ -0,0 +1,127 @@
+#include "element.h"
+
+#include <qstringlist.h>
+#include <qtextstream.h>
+
+const char FIELD_SEP = ':';
+const char PROPOINT_SEP = ';';
+const char XY_SEP = ',';
+
+
+void Element::init( double value, QColor valueColor, int valuePattern,
+ const QString& label, QColor labelColor )
+{
+ m_value = value;
+ m_valueColor = valueColor;
+ if ( valuePattern < Qt::SolidPattern || valuePattern > Qt::DiagCrossPattern )
+ valuePattern = Qt::SolidPattern;
+ m_valuePattern = valuePattern;
+ m_label = label;
+ m_labelColor = labelColor;
+}
+
+
+void Element::setValuePattern( int valuePattern )
+{
+ if ( valuePattern < Qt::SolidPattern || valuePattern > Qt::DiagCrossPattern )
+ valuePattern = Qt::SolidPattern;
+ m_valuePattern = valuePattern;
+}
+
+
+double Element::proX( int index ) const
+{
+ Q_ASSERT(index >= 0 && index < MAX_PROPOINTS);
+ return m_propoints[2 * index];
+}
+
+
+double Element::proY( int index ) const
+{
+ Q_ASSERT(index >= 0 && index < MAX_PROPOINTS);
+ return m_propoints[(2 * index) + 1];
+}
+
+
+void Element::setProX( int index, double value )
+{
+ Q_ASSERT(index >= 0 && index < MAX_PROPOINTS);
+ m_propoints[2 * index] = value;
+}
+
+
+void Element::setProY( int index, double value )
+{
+ Q_ASSERT(index >= 0 && index < MAX_PROPOINTS);
+ m_propoints[(2 * index) + 1] = value;
+}
+
+
+QTextStream &operator<<( QTextStream &s, const Element &element )
+{
+ s << element.value() << FIELD_SEP
+ << element.valueColor().name() << FIELD_SEP
+ << element.valuePattern() << FIELD_SEP
+ << element.labelColor().name() << FIELD_SEP;
+
+ for ( int i = 0; i < Element::MAX_PROPOINTS; ++i ) {
+ s << element.proX( i ) << XY_SEP << element.proY( i );
+ s << ( i == Element::MAX_PROPOINTS - 1 ? FIELD_SEP : PROPOINT_SEP );
+ }
+
+ s << element.label() << '\n';
+
+ return s;
+}
+
+
+QTextStream &operator>>( QTextStream &s, Element &element )
+{
+ QString data = s.readLine();
+ element.setValue( Element::INVALID );
+
+ int errors = 0;
+ bool ok;
+
+ QStringList fields = QStringList::split( FIELD_SEP, data );
+ if ( fields.count() >= 4 ) {
+ double value = fields[0].toDouble( &ok );
+ if ( !ok )
+ errors++;
+ QColor valueColor = QColor( fields[1] );
+ if ( !valueColor.isValid() )
+ errors++;
+ int valuePattern = fields[2].toInt( &ok );
+ if ( !ok )
+ errors++;
+ QColor labelColor = QColor( fields[3] );
+ if ( !labelColor.isValid() )
+ errors++;
+ QStringList propoints = QStringList::split( PROPOINT_SEP, fields[4] );
+ QString label = data.section( FIELD_SEP, 5 );
+
+ if ( !errors ) {
+ element.set( value, valueColor, valuePattern, label, labelColor );
+ int i = 0;
+ for ( QStringList::iterator point = propoints.begin();
+ i < Element::MAX_PROPOINTS && point != propoints.end();
+ ++i, ++point ) {
+ errors = 0;
+ QStringList xy = QStringList::split( XY_SEP, *point );
+ double x = xy[0].toDouble( &ok );
+ if ( !ok || x <= 0.0 || x >= 1.0 )
+ errors++;
+ double y = xy[1].toDouble( &ok );
+ if ( !ok || y <= 0.0 || y >= 1.0 )
+ errors++;
+ if ( errors )
+ x = y = Element::NO_PROPORTION;
+ element.setProX( i, x );
+ element.setProY( i, y );
+ }
+ }
+ }
+
+ return s;
+}
+
diff --git a/examples/chart/element.h b/examples/chart/element.h
new file mode 100644
index 0000000..f6b2b5b
--- /dev/null
+++ b/examples/chart/element.h
@@ -0,0 +1,84 @@
+#ifndef ELEMENT_H
+#define ELEMENT_H
+
+#include <qcolor.h>
+#include <qnamespace.h>
+#include <qstring.h>
+#include <qvaluevector.h>
+
+class Element;
+
+typedef QValueVector<Element> ElementVector;
+
+/*
+ Elements are valid if they have a value which is > EPSILON.
+*/
+const double EPSILON = 0.0000001; // Must be > INVALID.
+
+
+class Element
+{
+public:
+ enum { INVALID = -1 };
+ enum { NO_PROPORTION = -1 };
+ enum { MAX_PROPOINTS = 3 }; // One proportional point per chart type
+
+ Element( double value = INVALID, QColor valueColor = Qt::gray,
+ int valuePattern = Qt::SolidPattern,
+ const QString& label = QString::null,
+ QColor labelColor = Qt::black ) {
+ init( value, valueColor, valuePattern, label, labelColor );
+ for ( int i = 0; i < MAX_PROPOINTS * 2; ++i )
+ m_propoints[i] = NO_PROPORTION;
+ }
+ ~Element() {}
+
+ bool isValid() const { return m_value > EPSILON; }
+
+ double value() const { return m_value; }
+ QColor valueColor() const { return m_valueColor; }
+ int valuePattern() const { return m_valuePattern; }
+ QString label() const { return m_label; }
+ QColor labelColor() const { return m_labelColor; }
+ double proX( int index ) const;
+ double proY( int index ) const;
+
+ void set( double value = INVALID, QColor valueColor = Qt::gray,
+ int valuePattern = Qt::SolidPattern,
+ const QString& label = QString::null,
+ QColor labelColor = Qt::black ) {
+ init( value, valueColor, valuePattern, label, labelColor );
+ }
+ void setValue( double value ) { m_value = value; }
+ void setValueColor( QColor valueColor ) { m_valueColor = valueColor; }
+ void setValuePattern( int valuePattern );
+ void setLabel( const QString& label ) { m_label = label; }
+ void setLabelColor( QColor labelColor ) { m_labelColor = labelColor; }
+ void setProX( int index, double value );
+ void setProY( int index, double value );
+
+#ifdef Q_FULL_TEMPLATE_INSTANTIATION
+ // xlC 3.x workaround
+ Q_DUMMY_COMPARISON_OPERATOR(Element)
+ bool operator!=( const Element& e) const {
+ return ( !(e == *this) );
+ }
+#endif
+
+private:
+ void init( double value, QColor valueColor, int valuePattern,
+ const QString& label, QColor labelColor );
+
+ double m_value;
+ QColor m_valueColor;
+ int m_valuePattern;
+ QString m_label;
+ QColor m_labelColor;
+ double m_propoints[2 * MAX_PROPOINTS];
+};
+
+
+QTextStream &operator<<( QTextStream&, const Element& );
+QTextStream &operator>>( QTextStream&, Element& );
+
+#endif
diff --git a/examples/chart/images/chart-forms.sk b/examples/chart/images/chart-forms.sk
new file mode 100644
index 0000000..d9087b4
--- /dev/null
+++ b/examples/chart/images/chart-forms.sk
@@ -0,0 +1,256 @@
+##Sketch 1 2
+document()
+layout('A4',0)
+layer('Layer 1',1,1,0,0,(0,0,0))
+fp((0.9,0.9,0.9))
+le()
+lw(1.41732)
+la2(([(-4.0, 3.0), (2.0, 0.0), (-4.0, -3.0), (-4.0, 3.0)], 1))
+r(188.034,0,0,-149.201,526.688,-521.707)
+fp((0.9,0.9,0.9))
+le()
+lw(1.41732)
+la2(([(-4.0, 3.0), (2.0, 0.0), (-4.0, -3.0), (-4.0, 3.0)], 1))
+r(128.762,0,0,-92.995,341.407,-572.49)
+fp((0.9,0.9,0.9))
+le()
+lw(1.41732)
+la2(([(-4.0, 3.0), (2.0, 0.0), (-4.0, -3.0), (-4.0, 3.0)], 1))
+r(128.762,0,0,-92.995,768.68,-572.934)
+fp((0.9,0.9,0.9))
+le()
+lw(1.41732)
+la2(([(-4.0, 3.0), (2.0, 0.0), (-4.0, -3.0), (-4.0, 3.0)], 1))
+e(31.6796,0,0,31.6796,635.564,-722.4)
+fp((0.8,0.8,0.8))
+lw(1.41732)
+la2(([(-4.0, 3.0), (2.0, 0.0), (-4.0, -3.0), (-4.0, 3.0)], 1))
+r(188.034,0,0,-149.201,518.884,-513.603)
+fp((1,1,1))
+lw(1.41732)
+la2(([(-4.0, 3.0), (2.0, 0.0), (-4.0, -3.0), (-4.0, 3.0)], 1))
+r(158.398,0,0,-106.28,533.702,-545.185)
+fp((0,0,0))
+le()
+lw(1)
+Fn('Helvetica-Narrow-Bold')
+Fs(18)
+txt('ChartForm',(575.182,-535.064))
+fp((0.8,0.8,0.8))
+lw(1.41732)
+la2(([(-4.0, 3.0), (2.0, 0.0), (-4.0, -3.0), (-4.0, 3.0)], 1))
+r(128.762,0,0,-92.995,335.96,-566.743)
+fp((0,0,0))
+le()
+lw(1)
+Fn('Helvetica-Narrow-Bold')
+Fs(18)
+txt('OptionsForm',(354.009,-589.226))
+fp((0.8,0.8,0.8))
+lw(1.41732)
+la2(([(-4.0, 3.0), (2.0, 0.0), (-4.0, -3.0), (-4.0, 3.0)], 1))
+r(128.762,0,0,-92.995,763.221,-566.743)
+fp((0,0,0))
+le()
+lw(1)
+Fn('Helvetica-Narrow-Bold')
+Fs(18)
+txt('SetDataForm',(781.675,-587.279))
+fp((1,0,1))
+lw(1.41732)
+la2(([(-4.0, 3.0), (2.0, 0.0), (-4.0, -3.0), (-4.0, 3.0)], 1))
+e(31.6796,0,0,31.6796,631.296,-719.01)
+fp((0,0,0))
+le()
+lw(1)
+Fn('Helvetica-Narrow-BoldOblique')
+Fs(18)
+txt('chart',(613.251,-723.609))
+G()
+fp((0,0,0))
+le()
+lw(1)
+Fn('Helvetica-Narrow-Bold')
+Fs(18)
+txt('CanvasView',(569.827,-575.941))
+fp((0,0,0))
+le()
+lw(1)
+Fn('Helvetica-Narrow-Bold')
+Fs(18)
+txt('depicting a',(573.94,-595.357))
+fp((0,0,0))
+le()
+lw(1)
+Fn('Helvetica-Narrow-Bold')
+Fs(18)
+txt('QCanvas',(580.906,-614.774))
+G_()
+lw(1.41732)
+la2(([(-4.0, 3.0), (2.0, 0.0), (-4.0, -3.0), (-4.0, 3.0)], 1))
+b()
+bs(662.975,-716.966,0)
+bc(669.107,-712.686,671.463,-709.765,672.485,-707.625,2)
+bc(673.507,-705.485,677.438,-697.225,677.438,-696.155,2)
+bc(677.438,-695.085,679.326,-682.725,679.326,-682.725,2)
+bc(679.326,-682.725,679.326,-670.955,679.326,-670.955,2)
+bc(679.326,-670.955,679.326,-665.605,679.326,-664.535,2)
+lw(1.41732)
+la1(([(-4.0, 3.0), (2.0, 0.0), (-4.0, -3.0), (-4.0, 3.0)], 1))
+la2(([(-4.0, 3.0), (2.0, 0.0), (-4.0, -3.0), (-4.0, 3.0)], 1))
+b()
+bs(710.729,-618.861,0)
+bs(759.036,-618.861,0)
+lw(1.41732)
+la1(([(-4.0, 3.0), (2.0, 0.0), (-4.0, -3.0), (-4.0, 3.0)], 1))
+la2(([(-4.0, 3.0), (2.0, 0.0), (-4.0, -3.0), (-4.0, 3.0)], 1))
+b()
+bs(515.603,-617.742,0)
+bs(467.885,-617.742,0)
+G()
+fp((0,0.392,0))
+lw(1.41732)
+la2(([(-4.0, 3.0), (2.0, 0.0), (-4.0, -3.0), (-4.0, 3.0)], 1))
+e(29.7517,0,0,-7.65884,468.929,-768.389)
+fp((0,0.392,0))
+le()
+lw(1.41732)
+la2(([(-4.0, 3.0), (2.0, 0.0), (-4.0, -3.0), (-4.0, 3.0)], 1))
+r(58.9143,0,0,-44.1857,439.032,-724.349)
+fp((0,0.392,0))
+lw(1.41732)
+la2(([(-4.0, 3.0), (2.0, 0.0), (-4.0, -3.0), (-4.0, 3.0)], 1))
+e(29.7517,0,0,-7.65884,468.929,-722.581)
+G_()
+lw(1.41732)
+la1(([(-4.0, 3.0), (2.0, 0.0), (-4.0, -3.0), (-4.0, 3.0)], 1))
+la2(([(-4.0, 3.0), (2.0, 0.0), (-4.0, -3.0), (-4.0, 3.0)], 1))
+b()
+bs(499.125,-739.077,0)
+bc(507.548,-735.049,508.671,-732.747,512.04,-728.144,2)
+bc(515.409,-723.54,519.901,-717.21,520.463,-716.059,2)
+bc(521.024,-714.909,531.132,-689.589,531.132,-689.589,2)
+bc(531.132,-689.589,533.378,-679.231,533.378,-679.231,2)
+bc(533.378,-679.231,535.062,-671.175,535.062,-671.175,2)
+bc(535.062,-671.175,535.062,-664.845,535.062,-664.845,2)
+fp((1,1,1))
+le()
+lw(1)
+Fn('Helvetica-Narrow-Bold')
+Fs(18)
+txt('disk',(453.761,-753.806))
+fp((0,0,0))
+le()
+lw(1)
+Fn('Helvetica-Narrow')
+Fs(18)
+txt('run',(681.17,-700.783))
+fp((0,0,0))
+le()
+lw(1)
+Fn('Helvetica-Narrow')
+Fs(18)
+txt('save',(524.007,-725.891))
+fp((0,0,0))
+le()
+lw(1)
+Fn('Helvetica-Narrow')
+Fs(18)
+txt('load',(494.295,-706.489))
+fp((0.9,0.9,0.9))
+le()
+lw(1.41732)
+la2(([(-4.0, 3.0), (2.0, 0.0), (-4.0, -3.0), (-4.0, 3.0)], 1))
+r(143.737,0,0,-67.586,525.422,-405.581)
+fp((0.596,0.984,0.596))
+lw(1.41732)
+la2(([(-4.0, 3.0), (2.0, 0.0), (-4.0, -3.0), (-4.0, 3.0)], 1))
+r(143.737,0,0,-67.586,519.327,-401.081)
+fp((0,0,0))
+le()
+lw(1)
+Fn('Helvetica-Narrow')
+Fs(18)
+txt('getOpenFileName()',(526.396,-420.297))
+fp((0.9,0.9,0.9))
+le()
+lw(1.41732)
+la2(([(-4.0, 3.0), (2.0, 0.0), (-4.0, -3.0), (-4.0, 3.0)], 1))
+r(143.737,0,0,-67.586,704.655,-405.581)
+fp((0.596,0.984,0.596))
+lw(1.41732)
+la2(([(-4.0, 3.0), (2.0, 0.0), (-4.0, -3.0), (-4.0, 3.0)], 1))
+r(143.737,0,0,-67.586,698.561,-401.081)
+fp((0,0,0))
+le()
+lw(1)
+Fn('Helvetica-Narrow')
+Fs(18)
+txt('getSaveFileName()',(706.863,-420.39))
+fp((0.9,0.9,0.9))
+le()
+lw(1.41732)
+la2(([(-4.0, 3.0), (2.0, 0.0), (-4.0, -3.0), (-4.0, 3.0)], 1))
+r(100.503,0,0,-67.586,375.286,-429.722)
+fp((0.529,0.808,0.98))
+lw(1.41732)
+la2(([(-4.0, 3.0), (2.0, 0.0), (-4.0, -3.0), (-4.0, 3.0)], 1))
+r(100.503,0,0,-67.586,371.024,-425.223)
+fp((0,0,0))
+le()
+lw(1)
+Fn('Helvetica-Narrow')
+Fs(18)
+txt('getFont()',(391.333,-444.571))
+fp((0.9,0.9,0.9))
+le()
+lw(1.41732)
+la2(([(-4.0, 3.0), (2.0, 0.0), (-4.0, -3.0), (-4.0, 3.0)], 1))
+r(100.503,0,0,-67.586,935.176,-580.856)
+fp((1,0.753,0.796))
+lw(1.41732)
+la2(([(-4.0, 3.0), (2.0, 0.0), (-4.0, -3.0), (-4.0, 3.0)], 1))
+r(100.503,0,0,-67.586,930.915,-576.357)
+fp((0,0,0))
+le()
+lw(1)
+Fn('Helvetica-Narrow')
+Fs(18)
+txt('getColor()',(948.361,-598.303))
+lw(1.41732)
+ld((1, 1))
+la1(([(-4.0, 3.0), (2.0, 0.0), (-4.0, -3.0), (-4.0, 3.0)], 1))
+la2(([(-4.0, 3.0), (2.0, 0.0), (-4.0, -3.0), (-4.0, 3.0)], 1))
+b()
+bs(591.836,-511.466,0)
+bs(591.836,-471.702,0)
+lw(1.41732)
+ld((1, 1))
+la1(([(-4.0, 3.0), (2.0, 0.0), (-4.0, -3.0), (-4.0, 3.0)], 1))
+la2(([(-4.0, 3.0), (2.0, 0.0), (-4.0, -3.0), (-4.0, 3.0)], 1))
+b()
+bs(674.96,-513.083,0)
+bs(749.29,-470.169,0)
+lw(1.41732)
+ld((1, 1))
+la1(([(-4.0, 3.0), (2.0, 0.0), (-4.0, -3.0), (-4.0, 3.0)], 1))
+la2(([(-4.0, 3.0), (2.0, 0.0), (-4.0, -3.0), (-4.0, 3.0)], 1))
+b()
+bs(538.877,-513.083,0)
+bs(472.859,-474.968,0)
+lw(1.41732)
+ld((1, 1))
+la1(([(-4.0, 3.0), (2.0, 0.0), (-4.0, -3.0), (-4.0, 3.0)], 1))
+la2(([(-4.0, 3.0), (2.0, 0.0), (-4.0, -3.0), (-4.0, 3.0)], 1))
+b()
+bs(410.746,-562.437,0)
+bs(410.746,-494.504,0)
+lw(1.41732)
+ld((1, 1))
+la1(([(-4.0, 3.0), (2.0, 0.0), (-4.0, -3.0), (-4.0, 3.0)], 1))
+la2(([(-4.0, 3.0), (2.0, 0.0), (-4.0, -3.0), (-4.0, 3.0)], 1))
+b()
+bs(895.423,-617.315,0)
+bs(928.721,-617.315,0)
+guidelayer('Guide Lines',1,0,0,1,(0,0,1))
+grid((0,0,20,20),0,(0,0,1),'Grid')
diff --git a/examples/chart/images/file_new.xpm b/examples/chart/images/file_new.xpm
new file mode 100644
index 0000000..8537176
--- /dev/null
+++ b/examples/chart/images/file_new.xpm
@@ -0,0 +1,36 @@
+/* XPM */
+static const char *file_new[] = {
+"20 20 12 1",
+" c white",
+"! c None",
+"# c #000",
+"$ c #2e2e2e2e2e2e",
+"% c #ffffffffffff",
+"& c #5c5c5c5c5c5c",
+"( c #878787878787",
+") c #c2c2c2c2c2c2",
+"* c black",
+"+ c #00C900",
+", c #ffff00",
+"- c red",
+"!!!!!!!!!!!!!!!!!!!!",
+"!!##########$!!!!!!!",
+"!!#%%%%%%%%#&$!!!!!!",
+"!!#%%%%%%%%#(&$!!!!!",
+"!!#%%%%%%%%#)(&$!!!!",
+"!!#%%%%%%%%#%)(&$!!!",
+"!!#%%%%*****#####!!!",
+"!!#%%%*+++++*%%%#!!!",
+"!!#%%*,++++++*%%#!!!",
+"!!#%*,,,++++++*%#!!!",
+"!!#%*,,,,+++++*%#!!!",
+"!!#%*,,,,-++++*%#!!!",
+"!!#%*,,,---+++*%#!!!",
+"!!#%*,,-----++*%#!!!",
+"!!#%%*-------*%%#!!!",
+"!!#%%%*-----*%%%#!!!",
+"!!#%%%%*****%%%%#!!!",
+"!!#%%%%%%%%%%%%%#!!!",
+"!!###############!!!",
+"!!!!!!!!!!!!!!!!!!!!"
+};
diff --git a/examples/chart/images/file_open.xpm b/examples/chart/images/file_open.xpm
new file mode 100644
index 0000000..7a7b681
--- /dev/null
+++ b/examples/chart/images/file_open.xpm
@@ -0,0 +1,33 @@
+/* XPM */
+static const char *file_open[] = {
+"20 20 9 1",
+" c white",
+"! c None",
+"# c #002EFF",
+"$ c #000",
+"% c #ffffffff0",
+"& c #ffffffffffff",
+"( c #00C900",
+") c #ffff00",
+"* c #A500FF",
+"!!!!!!!!!!####!!!!#!",
+"!!!!!!!!!#!!!!##!##!",
+"!!!!!!!!!!!!!!!!###!",
+"!!!!!!!!!!!!!!!####!",
+"!!!!!!!!!!!!!!#####!",
+"!$$$$!!!!!!!!!!!!!!!",
+"$%&%&$$$$$$$$!!!!!!!",
+"$&%&%&%&%&%&$!!!!!!!",
+"$%&&&$$$$$&&$!!!!!!!",
+"$&&&$((((($&$!!!!!!!",
+"$%&$)(($$$$$$$$$$$$$",
+"$&$)))$***********$$",
+"$%$))$***********$$!",
+"$&$)$***********$$!!",
+"$%$$***********$$!!!",
+"$&$***********$$!!!!",
+"$$***********$$!!!!!",
+"$$***********$!!!!!!",
+"$$$$$$$$$$$$$!!!!!!!",
+"!!!!!!!!!!!!!!!!!!!!"
+};
diff --git a/examples/chart/images/file_print.xpm b/examples/chart/images/file_print.xpm
new file mode 100644
index 0000000..915f65b
--- /dev/null
+++ b/examples/chart/images/file_print.xpm
@@ -0,0 +1,115 @@
+/* XPM */
+static const char *file_print[] = {
+/* columns rows colors chars-per-pixel */
+"20 20 89 1",
+" c Gray0",
+". c #101008081010",
+"X c #101010101010",
+"o c #101010101818",
+"O c #181810101818",
+"+ c #181818181818",
+"@ c #181818182121",
+"# c #212118182121",
+"$ c Gray13",
+"% c #212121212929",
+"& c #292921212929",
+"* c Gray16",
+"= c #292929293131",
+"- c #313129293131",
+"; c #313131313131",
+": c #313131313939",
+"> c #393931313939",
+", c #393939393939",
+"< c #393939394242",
+"1 c #424239394242",
+"2 c Gray26",
+"3 c #4a4a4a4a5252",
+"4 c #5a5a52525a5a",
+"5 c #5a5a5a5a6363",
+"6 c #6b6b63636b6b",
+"7 c Gray42",
+"8 c #6b6b6b6b7373",
+"9 c #73736b6b7373",
+"0 c #7b7b73737b7b",
+"q c #7b7b73738484",
+"w c #0808ffff0808",
+"e c #2929ffff2929",
+"r c #3131ffff3131",
+"t c #5a5acece5a5a",
+"y c #6b6bffff6363",
+"u c #7b7bffff7b7b",
+"i c #84847b7b8484",
+"p c #84847b7b8c8c",
+"a c #8c8c7b7b9494",
+"s c #848484848c8c",
+"d c #8c8c84848c8c",
+"f c Gray55",
+"g c #8c8c84849494",
+"h c #8c8c8c8c9494",
+"j c #94948c8c9494",
+"k c #94948c8c9c9c",
+"l c Gray58",
+"z c #949494949c9c",
+"x c #9c9c94949c9c",
+"c c Gray61",
+"v c #9c9c9494a5a5",
+"b c #9c9c9c9ca5a5",
+"n c #a5a59c9ca5a5",
+"m c #a5a59c9cadad",
+"M c #adad9c9cadad",
+"N c #a5a5a5a5a5a5",
+"B c #a5a5a5a5adad",
+"V c #adada5a5adad",
+"C c Gray68",
+"Z c #adadadadb5b5",
+"A c #b5b5adadb5b5",
+"S c Gray71",
+"D c Gray74",
+"F c #9494c6c69494",
+"G c #9c9ccecea5a5",
+"H c #bdbdd6d6bdbd",
+"J c #c0c0c0c0c0c0",
+"K c #c6c6c6c6c6c6",
+"L c #cecec6c6cece",
+"P c #cececececece",
+"I c #cecececed6d6",
+"U c #d6d6ceced6d6",
+"Y c #d6d6cecedede",
+"T c Gray84",
+"R c #d6d6d6d6dede",
+"E c #deded6d6dede",
+"W c Gray87",
+"Q c #deded6d6e7e7",
+"! c #dedededee7e7",
+"~ c #d6d6ffffd6d6",
+"^ c #e7e7dedee7e7",
+"/ c #e7e7e7e7e7e7",
+"( c #e7e7e7e7efef",
+") c #efefe7e7efef",
+"_ c #efefefefefef",
+"` c #e7e7ffffe7e7",
+"' c Gray97",
+"] c Gray100",
+"[ c None",
+/* pixels */
+"[[[[[[SDPPKKDDCD[[[[",
+"[[[[[[D_///___WD[[[[",
+"[[[[[[DKKPKKKKDK[[[[",
+"[[[[[[SDDSDDSSCD[[[[",
+"[[[[[KCKDKDDDKS[[[[[",
+"[[[[[KDDDDDDDDS[[[[[",
+"[[[[[CP/WWWWTWNNZ[[[",
+"[[[Dc9STPTPTWWj427S[",
+"[[Dziq00000pag8<%@2N",
+"[DcE(!ERRUYGtFn2##O<",
+"Db)]]]]]]]~ewePa;@X#",
+"V']]]]]]]]`yru]Q0@ #",
+"BRILITRRWE!RHUILhO @",
+"jAZVBmBnmmnmMvzh6o #",
+"jZZmBnnnbbbbvxxg6o +",
+"lmmnbnbbbvxxxvjs6O 3",
+"jBnnvcvxvxvxzjhd8o+C",
+"lsdgfgdhghjhjkhg6+l[",
+"S9%@$%&&&-::>>:-:l[[",
+"[[C511,:;**%++.2c[[["
+};
diff --git a/examples/chart/images/file_save.xpm b/examples/chart/images/file_save.xpm
new file mode 100644
index 0000000..6163899
--- /dev/null
+++ b/examples/chart/images/file_save.xpm
@@ -0,0 +1,33 @@
+/* XPM */
+static const char *file_save[] = {
+"20 20 9 1",
+" c white",
+"! c #000",
+"# c #002EFF",
+"$ c #999999999999",
+"% c None",
+"& c #00C900",
+"( c #ffff00",
+") c red1",
+"* c black",
+"!!!!!!!!!!!!!!!!!!!!",
+"!##!$$$!!!!!!$$$!%%!",
+"!##!$$!&&&&&&!$$!%%!",
+"!##!$!(&&&&&&&!$!!!!",
+"!##!!(((&&&&&&&!!##!",
+"!##!!((((&&&&&&!!##!",
+"!##!!((((()&&&&!!##!",
+"!##!!((())))&&&!!##!",
+"!##!!(())))))&&!!##!",
+"!##!$!))))))))!$!##!",
+"!###!$!))))))!$*###!",
+"!####***!!!!!***###!",
+"!##################!",
+"!###!!!!!!!!!!!!!##!",
+"!###!!!!!!!!!$$$!##!",
+"!###!!!!!!!!!$$$!##!",
+"!###!!!!!!!!!$$$!##!",
+"!###!!!!!!!!!$$$!##!",
+"!###!!!!!!!!!$$$!##!",
+"%!!!!!!!!!!!!!!!!!!%"
+};
diff --git a/examples/chart/images/file_saveaspostscript.xpm b/examples/chart/images/file_saveaspostscript.xpm
new file mode 100644
index 0000000..7dd75fc
--- /dev/null
+++ b/examples/chart/images/file_saveaspostscript.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *file_saveaspostscript[] = {
+"20 20 10 1",
+" c white",
+"! c #000",
+"# c #002EFF",
+"$ c #999999999999",
+"% c None",
+"& c #00C900",
+"( c #ffff00",
+") c red1",
+"* c black",
+"+ c grey100",
+"!!!!!!!!!!!!!!!!!!!!",
+"!##!$$$!!!!!!$$$!%%!",
+"!##!$$!&&&&&&!$$!%%!",
+"!##!$!(&&&&&&&!$!!!!",
+"!##!!(((&&&&&&&!!##!",
+"!##!!((((&&&&&&!!##!",
+"!##!!((((()&&&&!!##!",
+"!##!!((())))&&&!!##!",
+"!##!!(())))))&&!!##!",
+"!##!$!))))))))!$!##!",
+"!###!$!))))))!$*###!",
+"!####***!!!!!***###!",
+"!##################!",
+"!###!!!!!!!!!!!!!##!",
+"!###!+++!+++!$$$!##!",
+"!###!+!+!+!!!$$$!##!",
+"!###!+++!+++!$$$!##!",
+"!###!+!!!!!+!$$$!##!",
+"!###!+!!!+++!$$$!##!",
+"%!!!!!!!!!!!!!!!!!!%"
+};
diff --git a/examples/chart/images/options_horizontalbarchart.xpm b/examples/chart/images/options_horizontalbarchart.xpm
new file mode 100644
index 0000000..afb06ff
--- /dev/null
+++ b/examples/chart/images/options_horizontalbarchart.xpm
@@ -0,0 +1,31 @@
+/* XPM */
+static const char *options_horizontalbarchart[] = {
+"20 20 7 1",
+"( c #A500FF",
+" c white",
+"! c red1",
+"# c None",
+"$ c #E9FF00",
+"% c #00C900",
+"& c #002EFF",
+"!!!!!!!!!!!!!!######",
+"!!!!!!!!!!!!!!######",
+"!!!!!!!!!!!!!!######",
+"!!!!!!!!!!!!!!######",
+"$$$$$$$$$$$$$$$$$###",
+"$$$$$$$$$$$$$$$$$###",
+"$$$$$$$$$$$$$$$$$###",
+"$$$$$$$$$$$$$$$$$###",
+"%%%%%%%%%%%%%%%%%%%%",
+"%%%%%%%%%%%%%%%%%%%%",
+"%%%%%%%%%%%%%%%%%%%%",
+"%%%%%%%%%%%%%%%%%%%%",
+"&&&&&&&&&&&&&&######",
+"&&&&&&&&&&&&&&######",
+"&&&&&&&&&&&&&&######",
+"&&&&&&&&&&&&&&######",
+"(((((((((((#########",
+"(((((((((((#########",
+"(((((((((((#########",
+"(((((((((((#########"
+};
diff --git a/examples/chart/images/options_piechart.xpm b/examples/chart/images/options_piechart.xpm
new file mode 100644
index 0000000..221c78d
--- /dev/null
+++ b/examples/chart/images/options_piechart.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static const char *options_piechart[] = {
+"20 20 6 1",
+" c white",
+"! c None",
+"# c black",
+"$ c #00C900",
+"% c #E9FF00",
+"& c red1",
+"!!!!!!#######!!!!!!!",
+"!!!!##$$$$$$$##!!!!!",
+"!!!#%$$$$$$$$$$#!!!!",
+"!!#%%%$$$$$$$$$$#!!!",
+"!#%%%%%$$$$$$$$$$#!!",
+"!#%%%%%$$$$$$$$$$#!!",
+"#%%%%%%%$$$$$$$$$$#!",
+"#%%%%%%%%$$$$$$$$$#!",
+"#%%%%%%%%$$$$$$$$$#!",
+"#%%%%%%%%%$$$$$$$$#!",
+"#%%%%%%%%&&$$$$$$$#!",
+"#%%%%%%%&&&&$$$$$$#!",
+"#%%%%%%&&&&&&&$$$$#!",
+"#%%%%%&&&&&&&&&$$$#!",
+"!#%%%&&&&&&&&&&&&#!!",
+"!#%%&&&&&&&&&&&&&#!!",
+"!!#&&&&&&&&&&&&&#!!!",
+"!!!#&&&&&&&&&&&#!!!!",
+"!!!!##&&&&&&&##!!!!!",
+"!!!!!!#######!!!!!!!"
+};
diff --git a/examples/chart/images/options_setdata.xpm b/examples/chart/images/options_setdata.xpm
new file mode 100644
index 0000000..4ff70a5
--- /dev/null
+++ b/examples/chart/images/options_setdata.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static const char *options_setdata[] = {
+"20 20 10 1",
+" c white",
+"! c None",
+"# c grey40",
+"$ c #002EFF",
+"% c black",
+"& c red1",
+"( c #00C900",
+") c #A500FF",
+"* c #E9FF00",
+"+ c cyan1",
+"!!!!!!!!!!!!!!!!!!!!",
+"!#####!$$!!#####!%%!",
+"!#####!$$!!#####!%%!",
+"!!!!!!!!!!!!!!!!!!!!",
+"!#####!&&!!#####!%%!",
+"!#####!&&!!#####!%%!",
+"!!!!!!!!!!!!!!!!!!!!",
+"!#####!((!!#####!%%!",
+"!#####!((!!#####!%%!",
+"!!!!!!!!!!!!!!!!!!!!",
+"!#####!))!!#####!%%!",
+"!#####!))!!#####!%%!",
+"!!!!!!!!!!!!!!!!!!!!",
+"!#####!**!!#####!%%!",
+"!#####!**!!#####!%%!",
+"!!!!!!!!!!!!!!!!!!!!",
+"!#####!++!!#####!%%!",
+"!#####!++!!#####!%%!",
+"!!!!!!!!!!!!!!!!!!!!",
+"!!!!!!!!!!!!!!!!!!!!"
+};
diff --git a/examples/chart/images/options_setfont.xpm b/examples/chart/images/options_setfont.xpm
new file mode 100644
index 0000000..ab55224
--- /dev/null
+++ b/examples/chart/images/options_setfont.xpm
@@ -0,0 +1,27 @@
+/* XPM */
+static const char *options_setfont[] = {
+"20 20 3 1",
+" c white",
+"! c None",
+"# c #002EFF",
+"!!!!!!!!!!!!!!!!!!!!",
+"!!!!!!!!!!!!#####!!!",
+"!!!!!!!!!!!#######!!",
+"!!!!!!!!!!!##!!!!##!",
+"!!!!!!!!!!##!!!!###!",
+"!!!!!!!!!!##!!!!###!",
+"!!!!!!!!!###!!!!!!!!",
+"!!!!!!!!!##!!!!!!!!!",
+"!!!!!#############!!",
+"!!!!###!!########!!!",
+"!!!##!!!!##!!!!!!!!!",
+"!!!##!!!!#!!!!!!!!!!",
+"!!!!!!!!##!!!!!!!!!!",
+"!!!!!!!!##!!!!!!!!!!",
+"!!!!!!!###!!!!!!!!!!",
+"!!!!!!!##!!!!!!!!!!!",
+"!!!!!!##!!!!!!!!!!!!",
+"!#!!!###!!!!!!!!!!!!",
+"!######!!!!!!!!!!!!!",
+"!!####!!!!!!!!!!!!!!"
+};
diff --git a/examples/chart/images/options_setoptions.xpm b/examples/chart/images/options_setoptions.xpm
new file mode 100644
index 0000000..029cf47
--- /dev/null
+++ b/examples/chart/images/options_setoptions.xpm
@@ -0,0 +1,32 @@
+/* XPM */
+static const char *options_setoptions[] = {
+"20 20 8 1",
+"( c #A500FF",
+" c white",
+") c grey30",
+"! c None",
+"# c #000",
+"$ c grey60",
+"% c grey100",
+"& c black",
+"!!!!!!!!!!!!!!!!!!!!",
+"!#############$$$$$!",
+"!#%%%%%%%%%%%%&$$$$!",
+"!#%%%%%%%%%%%%%&$$$!",
+"!#%%%%%%%%%%%%%%&$$!",
+"!#%%%%%%%%%%%%%%%&$!",
+"!#%%((%%%%%%%%%%%%#!",
+"!#%%((%%%%%%%%%%%%#!",
+"!#%%((%%%%%%%%%%%%#!",
+"!#(((((((%%%%%%%%%#!",
+"!#(((((((%%%%%%%%%#!",
+"!#%%((%%%%%)%))))%#!",
+"!#%%((%%%%%%%%%%%%#!",
+"!#%%((%)))%)))%))%#!",
+"!#%%%%%%%%%%%%%%%%#!",
+"!#%%))%)%))))%))%%#!",
+"!#%%%%%%%%%%%%%%%%#!",
+"!#%%%%%%%%%%%%%%%%#!",
+"!##################!",
+"!!!!!!!!!!!!!!!!!!!!"
+};
diff --git a/examples/chart/images/options_verticalbarchart.xpm b/examples/chart/images/options_verticalbarchart.xpm
new file mode 100644
index 0000000..e812f0f
--- /dev/null
+++ b/examples/chart/images/options_verticalbarchart.xpm
@@ -0,0 +1,31 @@
+/* XPM */
+static const char *options_verticalbarchart[] = {
+"20 20 7 1",
+"( c #A500FF",
+" c white",
+"! c None",
+"# c #00C900",
+"$ c #E9FF00",
+"% c red1",
+"& c #002EFF",
+"!!!!!!!!####!!!!!!!!",
+"!!!!!!!!####!!!!!!!!",
+"!!!!!!!!####!!!!!!!!",
+"!!!!$$$$####!!!!!!!!",
+"!!!!$$$$####!!!!!!!!",
+"!!!!$$$$####!!!!!!!!",
+"%%%%$$$$####&&&&!!!!",
+"%%%%$$$$####&&&&!!!!",
+"%%%%$$$$####&&&&!!!!",
+"%%%%$$$$####&&&&((((",
+"%%%%$$$$####&&&&((((",
+"%%%%$$$$####&&&&((((",
+"%%%%$$$$####&&&&((((",
+"%%%%$$$$####&&&&((((",
+"%%%%$$$$####&&&&((((",
+"%%%%$$$$####&&&&((((",
+"%%%%$$$$####&&&&((((",
+"%%%%$$$$####&&&&((((",
+"%%%%$$$$####&&&&((((",
+"%%%%$$$$####&&&&(((("
+};
diff --git a/examples/chart/images/pattern01.xpm b/examples/chart/images/pattern01.xpm
new file mode 100644
index 0000000..26a70cb
--- /dev/null
+++ b/examples/chart/images/pattern01.xpm
@@ -0,0 +1,27 @@
+/* XPM */
+static const char *pattern01[] = {
+/* columns rows colors chars-per-pixel */
+"40 20 1 1",
+" c black",
+/* pixels */
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" "
+};
diff --git a/examples/chart/images/pattern02.xpm b/examples/chart/images/pattern02.xpm
new file mode 100644
index 0000000..cc5b794
--- /dev/null
+++ b/examples/chart/images/pattern02.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+static const char *pattern02[] = {
+/* columns rows colors chars-per-pixel */
+"40 20 2 1",
+" c black",
+". c white",
+/* pixels */
+". . . . . . . . . . ",
+" ",
+" ",
+" ",
+". . . . . . . . . . ",
+" ",
+" ",
+" ",
+". . . . . . . . . . ",
+" ",
+" ",
+" ",
+". . . . . . . . . . ",
+" ",
+" ",
+" ",
+". . . . . . . . . . ",
+" ",
+" ",
+" "
+};
diff --git a/examples/chart/images/pattern03.xpm b/examples/chart/images/pattern03.xpm
new file mode 100644
index 0000000..d9fc57a
--- /dev/null
+++ b/examples/chart/images/pattern03.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+static const char *pattern03[] = {
+/* columns rows colors chars-per-pixel */
+"40 20 2 1",
+" c black",
+". c white",
+/* pixels */
+" . . . . . . . . . . ",
+" ",
+". . . . . . . . . . ",
+" ",
+" . . . . . . . . . . ",
+" ",
+". . . . . . . . . . ",
+" ",
+" . . . . . . . . . . ",
+" ",
+". . . . . . . . . . ",
+" ",
+" . . . . . . . . . . ",
+" ",
+". . . . . . . . . . ",
+" ",
+" . . . . . . . . . . ",
+" ",
+". . . . . . . . . . ",
+" "
+};
diff --git a/examples/chart/images/pattern04.xpm b/examples/chart/images/pattern04.xpm
new file mode 100644
index 0000000..85b9223
--- /dev/null
+++ b/examples/chart/images/pattern04.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+static const char *pattern04[] = {
+/* columns rows colors chars-per-pixel */
+"40 20 2 1",
+" c black",
+". c white",
+/* pixels */
+". . . . . . . . . . ",
+" . . . . . . . . . . . . . . . . . . . .",
+" . . . . . . . . . . ",
+" . . . . . . . . . . . . . . . . . . . .",
+". . . . . . . . . . ",
+" . . . . . . . . . . . . . . . . . . . .",
+" . . . . . . . . . . ",
+" . . . . . . . . . . . . . . . . . . . .",
+". . . . . . . . . . ",
+" . . . . . . . . . . . . . . . . . . . .",
+" . . . . . . . . . . ",
+" . . . . . . . . . . . . . . . . . . . .",
+". . . . . . . . . . ",
+" . . . . . . . . . . . . . . . . . . . .",
+" . . . . . . . . . . ",
+" . . . . . . . . . . . . . . . . . . . .",
+". . . . . . . . . . ",
+" . . . . . . . . . . . . . . . . . . . .",
+" . . . . . . . . . . ",
+" . . . . . . . . . . . . . . . . . . . ."
+};
diff --git a/examples/chart/images/pattern05.xpm b/examples/chart/images/pattern05.xpm
new file mode 100644
index 0000000..cc7beee
--- /dev/null
+++ b/examples/chart/images/pattern05.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+static const char *pattern05[] = {
+/* columns rows colors chars-per-pixel */
+"40 20 2 1",
+" c black",
+". c white",
+/* pixels */
+" . . . . . . . . . . . . . . . . . . . .",
+". . . . . . . . . . . . . . . . . . . . ",
+" . . . . . . . . . . . . . . . . . . . .",
+". . . . . . . . . . . . . . . . . . . . ",
+" . . . . . . . . . . . . . . . . . . . .",
+". . . . . . . . . . . . . . . . . . . . ",
+" . . . . . . . . . . . . . . . . . . . .",
+". . . . . . . . . . . . . . . . . . . . ",
+" . . . . . . . . . . . . . . . . . . . .",
+". . . . . . . . . . . . . . . . . . . . ",
+" . . . . . . . . . . . . . . . . . . . .",
+". . . . . . . . . . . . . . . . . . . . ",
+" . . . . . . . . . . . . . . . . . . . .",
+". . . . . . . . . . . . . . . . . . . . ",
+" . . . . . . . . . . . . . . . . . . . .",
+". . . . . . . . . . . . . . . . . . . . ",
+" . . . . . . . . . . . . . . . . . . . .",
+". . . . . . . . . . . . . . . . . . . . ",
+" . . . . . . . . . . . . . . . . . . . .",
+". . . . . . . . . . . . . . . . . . . . "
+};
diff --git a/examples/chart/images/pattern06.xpm b/examples/chart/images/pattern06.xpm
new file mode 100644
index 0000000..ad8b055
--- /dev/null
+++ b/examples/chart/images/pattern06.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+static const char *pattern06[] = {
+/* columns rows colors chars-per-pixel */
+"40 20 2 1",
+" c black",
+". c white",
+/* pixels */
+".. ... ... ... ... ... ... ... ... ... .",
+". . . . . . . . . . . . . . . . . . . . ",
+" ... ... ... ... ... ... ... ... ... ...",
+". . . . . . . . . . . . . . . . . . . . ",
+".. ... ... ... ... ... ... ... ... ... .",
+". . . . . . . . . . . . . . . . . . . . ",
+" ... ... ... ... ... ... ... ... ... ...",
+". . . . . . . . . . . . . . . . . . . . ",
+".. ... ... ... ... ... ... ... ... ... .",
+". . . . . . . . . . . . . . . . . . . . ",
+" ... ... ... ... ... ... ... ... ... ...",
+". . . . . . . . . . . . . . . . . . . . ",
+".. ... ... ... ... ... ... ... ... ... .",
+". . . . . . . . . . . . . . . . . . . . ",
+" ... ... ... ... ... ... ... ... ... ...",
+". . . . . . . . . . . . . . . . . . . . ",
+".. ... ... ... ... ... ... ... ... ... .",
+". . . . . . . . . . . . . . . . . . . . ",
+" ... ... ... ... ... ... ... ... ... ...",
+". . . . . . . . . . . . . . . . . . . . "
+};
diff --git a/examples/chart/images/pattern07.xpm b/examples/chart/images/pattern07.xpm
new file mode 100644
index 0000000..d01c55f
--- /dev/null
+++ b/examples/chart/images/pattern07.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+static const char *pattern07[] = {
+/* columns rows colors chars-per-pixel */
+"40 20 2 1",
+" c black",
+". c white",
+/* pixels */
+" ... ... ... ... ... ... ... ... ... ...",
+"........................................",
+".. ... ... ... ... ... ... ... ... ... .",
+"........................................",
+" ... ... ... ... ... ... ... ... ... ...",
+"........................................",
+".. ... ... ... ... ... ... ... ... ... .",
+"........................................",
+" ... ... ... ... ... ... ... ... ... ...",
+"........................................",
+".. ... ... ... ... ... ... ... ... ... .",
+"........................................",
+" ... ... ... ... ... ... ... ... ... ...",
+"........................................",
+".. ... ... ... ... ... ... ... ... ... .",
+"........................................",
+" ... ... ... ... ... ... ... ... ... ...",
+"........................................",
+".. ... ... ... ... ... ... ... ... ... .",
+"........................................"
+};
diff --git a/examples/chart/images/pattern08.xpm b/examples/chart/images/pattern08.xpm
new file mode 100644
index 0000000..b0ce09f
--- /dev/null
+++ b/examples/chart/images/pattern08.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+static const char *pattern08[] = {
+/* columns rows colors chars-per-pixel */
+"40 20 2 1",
+" c black",
+". c white",
+/* pixels */
+"........................................",
+"........................................",
+"... ... ... ... ... ... ... ... ... ... ",
+"........................................",
+"........................................",
+"........................................",
+"... ... ... ... ... ... ... ... ... ... ",
+"........................................",
+"........................................",
+"........................................",
+"... ... ... ... ... ... ... ... ... ... ",
+"........................................",
+"........................................",
+"........................................",
+"... ... ... ... ... ... ... ... ... ... ",
+"........................................",
+"........................................",
+"........................................",
+"... ... ... ... ... ... ... ... ... ... ",
+"........................................"
+};
diff --git a/examples/chart/images/pattern09.xpm b/examples/chart/images/pattern09.xpm
new file mode 100644
index 0000000..7d34bc4
--- /dev/null
+++ b/examples/chart/images/pattern09.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+static const char *pattern09[] = {
+/* columns rows colors chars-per-pixel */
+"40 20 2 1",
+" c black",
+". c white",
+/* pixels */
+"........................................",
+" ",
+"........................................",
+"........................................",
+"........................................",
+"........................................",
+"........................................",
+" ",
+"........................................",
+"........................................",
+"........................................",
+"........................................",
+"........................................",
+" ",
+"........................................",
+"........................................",
+"........................................",
+"........................................",
+"........................................",
+" "
+};
diff --git a/examples/chart/images/pattern10.xpm b/examples/chart/images/pattern10.xpm
new file mode 100644
index 0000000..c908016
--- /dev/null
+++ b/examples/chart/images/pattern10.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+static const char *pattern10[] = {
+/* columns rows colors chars-per-pixel */
+"40 20 2 1",
+" c black",
+". c white",
+/* pixels */
+".. ..... ..... ..... ..... ..... ..... .",
+".. ..... ..... ..... ..... ..... ..... .",
+".. ..... ..... ..... ..... ..... ..... .",
+".. ..... ..... ..... ..... ..... ..... .",
+".. ..... ..... ..... ..... ..... ..... .",
+".. ..... ..... ..... ..... ..... ..... .",
+".. ..... ..... ..... ..... ..... ..... .",
+".. ..... ..... ..... ..... ..... ..... .",
+".. ..... ..... ..... ..... ..... ..... .",
+".. ..... ..... ..... ..... ..... ..... .",
+".. ..... ..... ..... ..... ..... ..... .",
+".. ..... ..... ..... ..... ..... ..... .",
+".. ..... ..... ..... ..... ..... ..... .",
+".. ..... ..... ..... ..... ..... ..... .",
+".. ..... ..... ..... ..... ..... ..... .",
+".. ..... ..... ..... ..... ..... ..... .",
+".. ..... ..... ..... ..... ..... ..... .",
+".. ..... ..... ..... ..... ..... ..... .",
+".. ..... ..... ..... ..... ..... ..... .",
+".. ..... ..... ..... ..... ..... ..... ."
+};
diff --git a/examples/chart/images/pattern11.xpm b/examples/chart/images/pattern11.xpm
new file mode 100644
index 0000000..8feda9a
--- /dev/null
+++ b/examples/chart/images/pattern11.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+static const char *pattern11[] = {
+/* columns rows colors chars-per-pixel */
+"40 20 2 1",
+" c black",
+". c white",
+/* pixels */
+". ..... ..... ..... ..... ..... ..... ..",
+". ..... ..... ..... ..... ..... ..... ..",
+" ",
+". ..... ..... ..... ..... ..... ..... ..",
+". ..... ..... ..... ..... ..... ..... ..",
+". ..... ..... ..... ..... ..... ..... ..",
+". ..... ..... ..... ..... ..... ..... ..",
+". ..... ..... ..... ..... ..... ..... ..",
+" ",
+". ..... ..... ..... ..... ..... ..... ..",
+". ..... ..... ..... ..... ..... ..... ..",
+". ..... ..... ..... ..... ..... ..... ..",
+". ..... ..... ..... ..... ..... ..... ..",
+". ..... ..... ..... ..... ..... ..... ..",
+" ",
+". ..... ..... ..... ..... ..... ..... ..",
+". ..... ..... ..... ..... ..... ..... ..",
+". ..... ..... ..... ..... ..... ..... ..",
+". ..... ..... ..... ..... ..... ..... ..",
+". ..... ..... ..... ..... ..... ..... .."
+};
diff --git a/examples/chart/images/pattern12.xpm b/examples/chart/images/pattern12.xpm
new file mode 100644
index 0000000..a57233f
--- /dev/null
+++ b/examples/chart/images/pattern12.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+static const char *pattern12[] = {
+/* columns rows colors chars-per-pixel */
+"40 20 2 1",
+" c black",
+". c white",
+/* pixels */
+"..... ....... ....... ....... ....... ..",
+".... ....... ....... ....... ....... ...",
+"... ....... ....... ....... ....... ....",
+".. ....... ....... ....... ....... .....",
+". ....... ....... ....... ....... ......",
+" ....... ....... ....... ....... .......",
+"....... ....... ....... ....... ....... ",
+"...... ....... ....... ....... ....... .",
+"..... ....... ....... ....... ....... ..",
+".... ....... ....... ....... ....... ...",
+"... ....... ....... ....... ....... ....",
+".. ....... ....... ....... ....... .....",
+". ....... ....... ....... ....... ......",
+" ....... ....... ....... ....... .......",
+"....... ....... ....... ....... ....... ",
+"...... ....... ....... ....... ....... .",
+"..... ....... ....... ....... ....... ..",
+".... ....... ....... ....... ....... ...",
+"... ....... ....... ....... ....... ....",
+".. ....... ....... ....... ....... ....."
+};
diff --git a/examples/chart/images/pattern13.xpm b/examples/chart/images/pattern13.xpm
new file mode 100644
index 0000000..97f874f
--- /dev/null
+++ b/examples/chart/images/pattern13.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+static const char *pattern13[] = {
+/* columns rows colors chars-per-pixel */
+"40 20 2 1",
+" c black",
+". c white",
+/* pixels */
+" ....... ....... ....... ....... .......",
+". ....... ....... ....... ....... ......",
+".. ....... ....... ....... ....... .....",
+"... ....... ....... ....... ....... ....",
+".... ....... ....... ....... ....... ...",
+"..... ....... ....... ....... ....... ..",
+"...... ....... ....... ....... ....... .",
+"....... ....... ....... ....... ....... ",
+" ....... ....... ....... ....... .......",
+". ....... ....... ....... ....... ......",
+".. ....... ....... ....... ....... .....",
+"... ....... ....... ....... ....... ....",
+".... ....... ....... ....... ....... ...",
+"..... ....... ....... ....... ....... ..",
+"...... ....... ....... ....... ....... .",
+"....... ....... ....... ....... ....... ",
+" ....... ....... ....... ....... .......",
+". ....... ....... ....... ....... ......",
+".. ....... ....... ....... ....... .....",
+"... ....... ....... ....... ....... ...."
+};
diff --git a/examples/chart/images/pattern14.xpm b/examples/chart/images/pattern14.xpm
new file mode 100644
index 0000000..e9e6884
--- /dev/null
+++ b/examples/chart/images/pattern14.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+static const char *pattern14[] = {
+/* columns rows colors chars-per-pixel */
+"40 20 2 1",
+" c black",
+". c white",
+/* pixels */
+"... . ..... . ..... . ..... . ..... . ..",
+".. ... ... ... ... ... ... ... ... ... .",
+". ..... . ..... . ..... . ..... . ..... ",
+" ....... ....... ....... ....... .......",
+". ..... . ..... . ..... . ..... . ..... ",
+".. ... ... ... ... ... ... ... ... ... .",
+"... . ..... . ..... . ..... . ..... . ..",
+".... ....... ....... ....... ....... ...",
+"... . ..... . ..... . ..... . ..... . ..",
+".. ... ... ... ... ... ... ... ... ... .",
+". ..... . ..... . ..... . ..... . ..... ",
+" ....... ....... ....... ....... .......",
+". ..... . ..... . ..... . ..... . ..... ",
+".. ... ... ... ... ... ... ... ... ... .",
+"... . ..... . ..... . ..... . ..... . ..",
+".... ....... ....... ....... ....... ...",
+"... . ..... . ..... . ..... . ..... . ..",
+".. ... ... ... ... ... ... ... ... ... .",
+". ..... . ..... . ..... . ..... . ..... ",
+" ....... ....... ....... ....... ......."
+};
diff --git a/examples/chart/main.cpp b/examples/chart/main.cpp
new file mode 100644
index 0000000..dde8033
--- /dev/null
+++ b/examples/chart/main.cpp
@@ -0,0 +1,21 @@
+#include <qapplication.h>
+#include "chartform.h"
+
+
+int main( int argc, char *argv[] )
+{
+ QApplication app( argc, argv );
+
+ QString filename;
+ if ( app.argc() > 1 ) {
+ filename = app.argv()[1];
+ if ( !filename.endsWith( ".cht" ) )
+ filename = QString::null;
+ }
+
+ ChartForm *cf = new ChartForm( filename );
+ app.setMainWidget( cf );
+ cf->show();
+
+ return app.exec();
+}
diff --git a/examples/chart/optionsform.cpp b/examples/chart/optionsform.cpp
new file mode 100644
index 0000000..5228bc3
--- /dev/null
+++ b/examples/chart/optionsform.cpp
@@ -0,0 +1,135 @@
+#include "optionsform.h"
+
+#include <qbuttongroup.h>
+#include <qcombobox.h>
+#include <qfontdialog.h>
+#include <qframe.h>
+#include <qimage.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qpushbutton.h>
+#include <qradiobutton.h>
+#include <qspinbox.h>
+
+#include "images/options_horizontalbarchart.xpm"
+#include "images/options_piechart.xpm"
+#include "images/options_verticalbarchart.xpm"
+
+
+OptionsForm::OptionsForm( QWidget* parent, const char* name,
+ bool modal, WFlags f )
+ : QDialog( parent, name, modal, f )
+{
+ setCaption( "Chart -- Options" );
+ resize( 320, 290 );
+
+ optionsFormLayout = new QVBoxLayout( this, 11, 6 );
+
+ chartTypeLayout = new QHBoxLayout( 0, 0, 6 );
+
+ chartTypeTextLabel = new QLabel( "&Chart Type", this );
+ chartTypeLayout->addWidget( chartTypeTextLabel );
+
+ chartTypeComboBox = new QComboBox( FALSE, this );
+ chartTypeComboBox->insertItem( QPixmap( options_piechart ), "Pie Chart" );
+ chartTypeComboBox->insertItem( QPixmap( options_verticalbarchart ),
+ "Vertical Bar Chart" );
+ chartTypeComboBox->insertItem( QPixmap( options_horizontalbarchart ),
+ "Horizontal Bar Chart" );
+ chartTypeLayout->addWidget( chartTypeComboBox );
+ optionsFormLayout->addLayout( chartTypeLayout );
+
+ fontLayout = new QHBoxLayout( 0, 0, 6 );
+
+ fontPushButton = new QPushButton( "&Font...", this );
+ fontLayout->addWidget( fontPushButton );
+ QSpacerItem* spacer = new QSpacerItem( 0, 0,
+ QSizePolicy::Expanding,
+ QSizePolicy::Minimum );
+ fontLayout->addItem( spacer );
+
+ fontTextLabel = new QLabel( this ); // Must be set by caller via setFont()
+ fontLayout->addWidget( fontTextLabel );
+ optionsFormLayout->addLayout( fontLayout );
+
+ addValuesFrame = new QFrame( this );
+ addValuesFrame->setFrameShape( QFrame::StyledPanel );
+ addValuesFrame->setFrameShadow( QFrame::Sunken );
+ addValuesFrameLayout = new QVBoxLayout( addValuesFrame, 11, 6 );
+
+ addValuesButtonGroup = new QButtonGroup( "Show Values", addValuesFrame );
+ addValuesButtonGroup->setColumnLayout(0, Qt::Vertical );
+ addValuesButtonGroup->layout()->setSpacing( 6 );
+ addValuesButtonGroup->layout()->setMargin( 11 );
+ addValuesButtonGroupLayout = new QVBoxLayout(
+ addValuesButtonGroup->layout() );
+ addValuesButtonGroupLayout->setAlignment( Qt::AlignTop );
+
+ noRadioButton = new QRadioButton( "&No", addValuesButtonGroup );
+ noRadioButton->setChecked( TRUE );
+ addValuesButtonGroupLayout->addWidget( noRadioButton );
+
+ yesRadioButton = new QRadioButton( "&Yes", addValuesButtonGroup );
+ addValuesButtonGroupLayout->addWidget( yesRadioButton );
+
+ asPercentageRadioButton = new QRadioButton( "As &Percentage",
+ addValuesButtonGroup );
+ addValuesButtonGroupLayout->addWidget( asPercentageRadioButton );
+ addValuesFrameLayout->addWidget( addValuesButtonGroup );
+
+ decimalPlacesLayout = new QHBoxLayout( 0, 0, 6 );
+
+ decimalPlacesTextLabel = new QLabel( "&Decimal Places", addValuesFrame );
+ decimalPlacesLayout->addWidget( decimalPlacesTextLabel );
+
+ decimalPlacesSpinBox = new QSpinBox( addValuesFrame );
+ decimalPlacesSpinBox->setMinValue( 0 );
+ decimalPlacesSpinBox->setMaxValue( 9 );
+ decimalPlacesLayout->addWidget( decimalPlacesSpinBox );
+
+ addValuesFrameLayout->addLayout( decimalPlacesLayout );
+
+ optionsFormLayout->addWidget( addValuesFrame );
+
+ buttonsLayout = new QHBoxLayout( 0, 0, 6 );
+ spacer = new QSpacerItem( 0, 0,
+ QSizePolicy::Expanding, QSizePolicy::Minimum );
+ buttonsLayout->addItem( spacer );
+
+ okPushButton = new QPushButton( "OK", this );
+ okPushButton->setDefault( TRUE );
+ buttonsLayout->addWidget( okPushButton );
+
+ cancelPushButton = new QPushButton( "Cancel", this );
+ buttonsLayout->addWidget( cancelPushButton );
+ optionsFormLayout->addLayout( buttonsLayout );
+
+ connect( fontPushButton, SIGNAL( clicked() ), this, SLOT( chooseFont() ) );
+ connect( okPushButton, SIGNAL( clicked() ), this, SLOT( accept() ) );
+ connect( cancelPushButton, SIGNAL( clicked() ), this, SLOT( reject() ) );
+
+ chartTypeTextLabel->setBuddy( chartTypeComboBox );
+ decimalPlacesTextLabel->setBuddy( decimalPlacesSpinBox );
+}
+
+
+void OptionsForm::chooseFont()
+{
+ bool ok;
+ QFont font = QFontDialog::getFont( &ok, m_font, this );
+ if ( ok )
+ setFont( font );
+}
+
+
+void OptionsForm::setFont( QFont font )
+{
+ QString label = font.family() + " " +
+ QString::number( font.pointSize() ) + "pt";
+ if ( font.bold() )
+ label += " Bold";
+ if ( font.italic() )
+ label += " Italic";
+ fontTextLabel->setText( label );
+ m_font = font;
+}
diff --git a/examples/chart/optionsform.h b/examples/chart/optionsform.h
new file mode 100644
index 0000000..cceddca
--- /dev/null
+++ b/examples/chart/optionsform.h
@@ -0,0 +1,60 @@
+#ifndef OPTIONSFORM_H
+#define OPTIONSFORM_H
+
+#include <qdialog.h>
+
+class QButtonGroup;
+class QComboBox;
+class QFrame;
+class QGridLayout;
+class QHBoxLayout;
+class QLabel;
+class QPushButton;
+class QRadioButton;
+class QSpinBox;
+class QVBoxLayout;
+
+
+class OptionsForm : public QDialog
+{
+ Q_OBJECT
+public:
+ OptionsForm( QWidget* parent = 0, const char* name = "options form",
+ bool modal = FALSE, WFlags f = 0 );
+ ~OptionsForm() {}
+
+ QFont font() const { return m_font; }
+ void setFont( QFont font );
+
+ QLabel *chartTypeTextLabel;
+ QComboBox *chartTypeComboBox;
+ QPushButton *fontPushButton;
+ QLabel *fontTextLabel;
+ QFrame *addValuesFrame;
+ QButtonGroup *addValuesButtonGroup;
+ QRadioButton *noRadioButton;
+ QRadioButton *yesRadioButton;
+ QRadioButton *asPercentageRadioButton;
+ QLabel *decimalPlacesTextLabel;
+ QSpinBox *decimalPlacesSpinBox;
+ QPushButton *okPushButton;
+ QPushButton *cancelPushButton;
+
+protected slots:
+ void chooseFont();
+
+protected:
+ QVBoxLayout *optionsFormLayout;
+ QHBoxLayout *chartTypeLayout;
+ QHBoxLayout *fontLayout;
+ QVBoxLayout *addValuesFrameLayout;
+ QVBoxLayout *addValuesButtonGroupLayout;
+ QHBoxLayout *decimalPlacesLayout;
+ QHBoxLayout *buttonsLayout;
+
+private:
+ QFont m_font;
+};
+
+#endif
+
diff --git a/examples/chart/setdataform.cpp b/examples/chart/setdataform.cpp
new file mode 100644
index 0000000..9910541
--- /dev/null
+++ b/examples/chart/setdataform.cpp
@@ -0,0 +1,208 @@
+#include "setdataform.h"
+#include "chartform.h"
+
+#include <qcolordialog.h>
+#include <qcombobox.h>
+#include <qlayout.h>
+#include <qpixmap.h>
+#include <qpushbutton.h>
+#include <qtable.h>
+
+#include "images/pattern01.xpm"
+#include "images/pattern02.xpm"
+#include "images/pattern03.xpm"
+#include "images/pattern04.xpm"
+#include "images/pattern05.xpm"
+#include "images/pattern06.xpm"
+#include "images/pattern07.xpm"
+#include "images/pattern08.xpm"
+#include "images/pattern09.xpm"
+#include "images/pattern10.xpm"
+#include "images/pattern11.xpm"
+#include "images/pattern12.xpm"
+#include "images/pattern13.xpm"
+#include "images/pattern14.xpm"
+
+const int MAX_PATTERNS = 14;
+
+
+SetDataForm::SetDataForm( ElementVector *elements, int decimalPlaces,
+ QWidget* parent, const char* name,
+ bool modal, WFlags f )
+ : QDialog( parent, name, modal, f )
+
+{
+ m_elements = elements;
+ m_decimalPlaces = decimalPlaces;
+
+ setCaption( "Chart -- Set Data" );
+ resize( 540, 440 );
+
+ tableButtonBox = new QVBoxLayout( this, 11, 6, "table button box layout" );
+
+ table = new QTable( this, "data table" );
+ table->setNumCols( 5 );
+ table->setNumRows( ChartForm::MAX_ELEMENTS );
+ table->setColumnReadOnly( 1, TRUE );
+ table->setColumnReadOnly( 2, TRUE );
+ table->setColumnReadOnly( 4, TRUE );
+ table->setColumnWidth( 0, 80 );
+ table->setColumnWidth( 1, 60 ); // Columns 1 and 4 must be equal
+ table->setColumnWidth( 2, 60 );
+ table->setColumnWidth( 3, 200 );
+ table->setColumnWidth( 4, 60 );
+ QHeader *th = table->horizontalHeader();
+ th->setLabel( 0, "Value" );
+ th->setLabel( 1, "Color" );
+ th->setLabel( 2, "Pattern" );
+ th->setLabel( 3, "Label" );
+ th->setLabel( 4, "Color" );
+ tableButtonBox->addWidget( table );
+
+ buttonBox = new QHBoxLayout( 0, 0, 6, "button box layout" );
+
+ colorPushButton = new QPushButton( this, "color button" );
+ colorPushButton->setText( "&Color..." );
+ colorPushButton->setEnabled( FALSE );
+ buttonBox->addWidget( colorPushButton );
+
+ QSpacerItem *spacer = new QSpacerItem( 0, 0, QSizePolicy::Expanding,
+ QSizePolicy::Minimum );
+ buttonBox->addItem( spacer );
+
+ okPushButton = new QPushButton( this, "ok button" );
+ okPushButton->setText( "OK" );
+ okPushButton->setDefault( TRUE );
+ buttonBox->addWidget( okPushButton );
+
+ cancelPushButton = new QPushButton( this, "cancel button" );
+ cancelPushButton->setText( "Cancel" );
+ cancelPushButton->setAccel( Key_Escape );
+ buttonBox->addWidget( cancelPushButton );
+
+ tableButtonBox->addLayout( buttonBox );
+
+ connect( table, SIGNAL( clicked(int,int,int,const QPoint&) ),
+ this, SLOT( setColor(int,int) ) );
+ connect( table, SIGNAL( currentChanged(int,int) ),
+ this, SLOT( currentChanged(int,int) ) );
+ connect( table, SIGNAL( valueChanged(int,int) ),
+ this, SLOT( valueChanged(int,int) ) );
+ connect( colorPushButton, SIGNAL( clicked() ), this, SLOT( setColor() ) );
+ connect( okPushButton, SIGNAL( clicked() ), this, SLOT( accept() ) );
+ connect( cancelPushButton, SIGNAL( clicked() ), this, SLOT( reject() ) );
+
+ QPixmap patterns[MAX_PATTERNS];
+ patterns[0] = QPixmap( pattern01 );
+ patterns[1] = QPixmap( pattern02 );
+ patterns[2] = QPixmap( pattern03 );
+ patterns[3] = QPixmap( pattern04 );
+ patterns[4] = QPixmap( pattern05 );
+ patterns[5] = QPixmap( pattern06 );
+ patterns[6] = QPixmap( pattern07 );
+ patterns[7] = QPixmap( pattern08 );
+ patterns[8] = QPixmap( pattern09 );
+ patterns[9] = QPixmap( pattern10 );
+ patterns[10] = QPixmap( pattern11 );
+ patterns[11] = QPixmap( pattern12 );
+ patterns[12] = QPixmap( pattern13 );
+ patterns[13] = QPixmap( pattern14 );
+
+ QRect rect = table->cellRect( 0, 1 );
+ QPixmap pix( rect.width(), rect.height() );
+
+ for ( int i = 0; i < ChartForm::MAX_ELEMENTS; ++i ) {
+ Element element = (*m_elements)[i];
+
+ if ( element.isValid() )
+ table->setText(
+ i, 0,
+ QString( "%1" ).arg( element.value(), 0, 'f',
+ m_decimalPlaces ) );
+
+ QColor color = element.valueColor();
+ pix.fill( color );
+ table->setPixmap( i, 1, pix );
+ table->setText( i, 1, color.name() );
+
+ QComboBox *combobox = new QComboBox;
+ for ( int j = 0; j < MAX_PATTERNS; ++j )
+ combobox->insertItem( patterns[j] );
+ combobox->setCurrentItem( element.valuePattern() - 1 );
+ table->setCellWidget( i, 2, combobox );
+
+ table->setText( i, 3, element.label() );
+
+ color = element.labelColor();
+ pix.fill( color );
+ table->setPixmap( i, 4, pix );
+ table->setText( i, 4, color.name() );
+ }
+
+}
+
+
+void SetDataForm::currentChanged( int, int col )
+{
+ colorPushButton->setEnabled( col == 1 || col == 4 );
+}
+
+
+void SetDataForm::valueChanged( int row, int col )
+{
+ if ( col == 0 ) {
+ bool ok;
+ double d = table->text( row, col ).toDouble( &ok );
+ if ( ok && d > EPSILON )
+ table->setText(
+ row, col, QString( "%1" ).arg(
+ d, 0, 'f', m_decimalPlaces ) );
+ else if ( !table->text( row, col ).isEmpty() )
+ table->setText( row, col, table->text( row, col ) + "?" );
+ }
+}
+
+
+void SetDataForm::setColor()
+{
+ setColor( table->currentRow(), table->currentColumn() );
+ table->setFocus();
+}
+
+
+void SetDataForm::setColor( int row, int col )
+{
+ if ( !( col == 1 || col == 4 ) )
+ return;
+
+ QColor color = QColorDialog::getColor(
+ QColor( table->text( row, col ) ),
+ this, "color dialog" );
+ if ( color.isValid() ) {
+ QPixmap pix = table->pixmap( row, col );
+ pix.fill( color );
+ table->setPixmap( row, col, pix );
+ table->setText( row, col, color.name() );
+ }
+}
+
+
+void SetDataForm::accept()
+{
+ bool ok;
+ for ( int i = 0; i < ChartForm::MAX_ELEMENTS; ++i ) {
+ Element &element = (*m_elements)[i];
+ double d = table->text( i, 0 ).toDouble( &ok );
+ if ( ok )
+ element.setValue( d );
+ else
+ element.setValue( Element::INVALID );
+ element.setValueColor( QColor( table->text( i, 1 ) ) );
+ element.setValuePattern(
+ ((QComboBox*)table->cellWidget( i, 2 ))->currentItem() + 1 );
+ element.setLabel( table->text( i, 3 ) );
+ element.setLabelColor( QColor( table->text( i, 4 ) ) );
+ }
+
+ QDialog::accept();
+}
diff --git a/examples/chart/setdataform.h b/examples/chart/setdataform.h
new file mode 100644
index 0000000..39ff2b2
--- /dev/null
+++ b/examples/chart/setdataform.h
@@ -0,0 +1,47 @@
+#ifndef SETDATAFORM_H
+#define SETDATAFORM_H
+
+#include "element.h"
+
+#include <qdialog.h>
+
+class QHBoxLayout;
+class QPushButton;
+class QTable;
+class QVBoxLayout;
+
+
+class SetDataForm: public QDialog
+{
+ Q_OBJECT
+public:
+ SetDataForm( ElementVector *elements, int decimalPlaces,
+ QWidget *parent = 0, const char *name = "set data form",
+ bool modal = TRUE, WFlags f = 0 );
+ ~SetDataForm() {}
+
+public slots:
+ void setColor();
+ void setColor( int row, int col );
+ void currentChanged( int row, int col );
+ void valueChanged( int row, int col );
+
+protected slots:
+ void accept();
+
+private:
+ QTable *table;
+ QPushButton *colorPushButton;
+ QPushButton *okPushButton;
+ QPushButton *cancelPushButton;
+
+protected:
+ QVBoxLayout *tableButtonBox;
+ QHBoxLayout *buttonBox;
+
+private:
+ ElementVector *m_elements;
+ int m_decimalPlaces;
+};
+
+#endif