You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
489 lines
17 KiB
489 lines
17 KiB
15 years ago
|
class ChartForm < Qt::MainWindow
|
||
|
|
||
|
slots 'fileNew()',
|
||
|
'fileOpen()',
|
||
|
'fileOpenRecent( int )',
|
||
|
'fileSave()',
|
||
|
'fileSaveAs()',
|
||
|
'fileSaveAsPixmap()',
|
||
|
'filePrint()',
|
||
|
'fileQuit()',
|
||
|
'optionsSetData()',
|
||
|
'updateChartType( QAction * )',
|
||
|
'optionsSetFont()',
|
||
|
'optionsSetOptions()',
|
||
|
'helpHelp()',
|
||
|
'helpAbout()',
|
||
|
'helpAboutQt()',
|
||
|
'saveOptions()'
|
||
|
|
||
|
attr_accessor :changed
|
||
|
attr_reader :chartType, :optionsMenu
|
||
|
|
||
|
MAX_ELEMENTS = 100
|
||
|
MAX_RECENTFILES = 9 # Must not exceed 9
|
||
|
|
||
|
PIE = 0
|
||
|
VERTICAL_BAR = 1
|
||
|
HORIZONTAL_BAR = 2
|
||
|
|
||
|
NO = 0
|
||
|
YES = 1
|
||
|
AS_PERCENTAGE = 2
|
||
|
|
||
|
WINDOWS_REGISTRY = "/Trolltech/QtExamples"
|
||
|
APP_KEY = "/Chart/"
|
||
|
|
||
|
def initialize( filename )
|
||
|
super( nil, nil, WDestructiveClose )
|
||
|
@filename = filename
|
||
|
setIcon( Qt::Pixmap.new( "images/options_piechart.xpm" ) )
|
||
|
|
||
|
fileNewAction = Qt::Action.new(
|
||
|
"New Chart", Qt::IconSet.new(Qt::Pixmap.new( "images/file_new.xpm" )),
|
||
|
"&New", Qt::KeySequence.new(CTRL+Key_N), self, "new" )
|
||
|
connect( fileNewAction, SIGNAL( 'activated()' ), self, SLOT( 'fileNew()' ) )
|
||
|
|
||
|
fileOpenAction = Qt::Action.new(
|
||
|
"Open Chart", Qt::IconSet.new(Qt::Pixmap.new( "images/file_open.xpm" )),
|
||
|
"&Open...", Qt::KeySequence.new(CTRL+Key_O), self, "open" )
|
||
|
connect( fileOpenAction, SIGNAL( 'activated()' ), self, SLOT( 'fileOpen()' ) )
|
||
|
|
||
|
fileSaveAction = Qt::Action.new(
|
||
|
"Save Chart", Qt::IconSet.new(Qt::Pixmap.new( "images/file_save.xpm" )),
|
||
|
"&Save", Qt::KeySequence.new(CTRL+Key_S), self, "save" )
|
||
|
connect( fileSaveAction, SIGNAL( 'activated()' ), self, SLOT( 'fileSave()' ) )
|
||
|
|
||
|
fileSaveAsAction = Qt::Action.new(
|
||
|
"Save Chart As", Qt::IconSet.new(Qt::Pixmap.new( "images/file_save.xpm" )),
|
||
|
"Save &As...", Qt::KeySequence.new(0), self, "save as" )
|
||
|
connect( fileSaveAsAction, SIGNAL( 'activated()' ),
|
||
|
self, SLOT( 'fileSaveAs()' ) )
|
||
|
|
||
|
fileSaveAsPixmapAction = Qt::Action.new(
|
||
|
"Save Chart As Bitmap", Qt::IconSet.new(Qt::Pixmap.new( "images/file_save.xpm" )),
|
||
|
"Save As &Bitmap...", Qt::KeySequence.new(CTRL+Key_B), self, "save as bitmap" )
|
||
|
connect( fileSaveAsPixmapAction, SIGNAL( 'activated()' ),
|
||
|
self, SLOT( 'fileSaveAsPixmap()' ) )
|
||
|
|
||
|
filePrintAction = Qt::Action.new(
|
||
|
"Print Chart", Qt::IconSet.new(Qt::Pixmap.new( "images/file_print.xpm" )),
|
||
|
"&Print Chart...", Qt::KeySequence.new(CTRL+Key_P), self, "print chart" )
|
||
|
connect( filePrintAction, SIGNAL( 'activated()' ),
|
||
|
self, SLOT( 'filePrint()' ) )
|
||
|
|
||
|
optionsSetDataAction = Qt::Action.new(
|
||
|
"Set Data", Qt::IconSet.new(Qt::Pixmap.new( "images/options_setdata.xpm" )),
|
||
|
"Set &Data...", Qt::KeySequence.new(CTRL+Key_D), self, "set data" )
|
||
|
connect( optionsSetDataAction, SIGNAL( 'activated()' ),
|
||
|
self, SLOT( 'optionsSetData()' ) )
|
||
|
|
||
|
|
||
|
chartGroup = Qt::ActionGroup.new( self ) # Connected later
|
||
|
chartGroup.setExclusive( true )
|
||
|
|
||
|
@optionsPieChartAction = Qt::Action.new(
|
||
|
"Pie Chart", Qt::IconSet.new(Qt::Pixmap.new( "images/options_piechart.xpm" )),
|
||
|
"&Pie Chart", Qt::KeySequence.new(CTRL+Key_I), chartGroup, "pie chart" )
|
||
|
@optionsPieChartAction.setToggleAction( true )
|
||
|
|
||
|
@optionsHorizontalBarChartAction = Qt::Action.new(
|
||
|
"Horizontal Bar Chart", Qt::IconSet.new(Qt::Pixmap.new( "images/options_horizontalbarchart.xpm" )),
|
||
|
"&Horizontal Bar Chart", Qt::KeySequence.new(CTRL+Key_H), chartGroup,
|
||
|
"horizontal bar chart" )
|
||
|
@optionsHorizontalBarChartAction.setToggleAction( true )
|
||
|
|
||
|
@optionsVerticalBarChartAction = Qt::Action.new(
|
||
|
"Vertical Bar Chart", Qt::IconSet.new(Qt::Pixmap.new( "images/options_verticalbarchart.xpm" )),
|
||
|
"&Vertical Bar Chart", Qt::KeySequence.new(CTRL+Key_V), chartGroup, "Vertical bar chart" )
|
||
|
@optionsVerticalBarChartAction.setToggleAction( true )
|
||
|
|
||
|
|
||
|
optionsSetFontAction = Qt::Action.new(
|
||
|
"Set Font", Qt::IconSet.new(Qt::Pixmap.new( "images/options_setfont.xpm" )),
|
||
|
"Set &Font...", Qt::KeySequence.new(CTRL+Key_F), self, "set font" )
|
||
|
connect( optionsSetFontAction, SIGNAL( 'activated()' ),
|
||
|
self, SLOT( 'optionsSetFont()' ) )
|
||
|
|
||
|
optionsSetOptionsAction = Qt::Action.new(
|
||
|
"Set Options", Qt::IconSet.new(Qt::Pixmap.new( "images/options_setoptions.xpm" )),
|
||
|
"Set &Options...", Qt::KeySequence.new(0), self, "set options" )
|
||
|
connect( optionsSetOptionsAction, SIGNAL( 'activated()' ),
|
||
|
self, SLOT( 'optionsSetOptions()' ) )
|
||
|
|
||
|
fileQuitAction = Qt::Action.new( "Quit", "&Quit", Qt::KeySequence.new(CTRL+Key_Q), self, "quit" )
|
||
|
connect( fileQuitAction, SIGNAL( 'activated()' ), self, SLOT( 'fileQuit()' ) )
|
||
|
|
||
|
|
||
|
fileTools = Qt::ToolBar.new( self, "file operations" )
|
||
|
fileTools.setLabel( "File Operations" )
|
||
|
fileNewAction.addTo( fileTools )
|
||
|
fileOpenAction.addTo( fileTools )
|
||
|
fileSaveAction.addTo( fileTools )
|
||
|
fileTools.addSeparator()
|
||
|
filePrintAction.addTo( fileTools )
|
||
|
|
||
|
optionsTools = Qt::ToolBar.new( self, "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 = Qt::PopupMenu.new( self )
|
||
|
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 = Qt::PopupMenu.new( self )
|
||
|
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()
|
||
|
|
||
|
helpMenu = Qt::PopupMenu.new( self )
|
||
|
menuBar().insertItem( "&Help", helpMenu )
|
||
|
helpMenu.insertItem( "&Help", self, SLOT('helpHelp()'), Qt::KeySequence.new(Key_F1) )
|
||
|
helpMenu.insertItem( "&About", self, SLOT('helpAbout()') )
|
||
|
helpMenu.insertItem( "About &Qt", self, SLOT('helpAboutQt()') )
|
||
|
|
||
|
|
||
|
@printer = nil
|
||
|
@elements = Array.new(MAX_ELEMENTS)
|
||
|
|
||
|
settings = Qt::Settings.new
|
||
|
settings.insertSearchPath( Qt::Settings::Windows, WINDOWS_REGISTRY )
|
||
|
windowWidth = settings.readNumEntry( APP_KEY + "WindowWidth", 460 )
|
||
|
windowHeight = settings.readNumEntry( APP_KEY + "WindowHeight", 530 )
|
||
|
windowX = settings.readNumEntry( APP_KEY + "WindowX", -1 )
|
||
|
windowY = settings.readNumEntry( APP_KEY + "WindowY", -1 )
|
||
|
setChartType( settings.readNumEntry( APP_KEY + "ChartType", PIE ) )
|
||
|
@addValues = settings.readNumEntry( APP_KEY + "AddValues", NO )
|
||
|
@decimalPlaces = settings.readNumEntry( APP_KEY + "Decimals", 2 )
|
||
|
@font = Qt::Font.new( "Helvetica", 18, Qt::Font::Bold )
|
||
|
@font.fromString(
|
||
|
settings.readEntry( APP_KEY + "Font", @font.toString() ) )
|
||
|
@recentFiles = []
|
||
|
for i in 0...MAX_RECENTFILES
|
||
|
filename = settings.readEntry( APP_KEY + "File" + ( i + 1 ).to_s )
|
||
|
if !filename.nil?
|
||
|
@recentFiles.push( filename )
|
||
|
end
|
||
|
end
|
||
|
if @recentFiles.length() > 0
|
||
|
updateRecentFilesMenu()
|
||
|
end
|
||
|
|
||
|
|
||
|
# Connect *after* we've set the chart type on so we don't call
|
||
|
# drawElements() prematurely.
|
||
|
connect( chartGroup, SIGNAL( 'selected(QAction*)' ),
|
||
|
self, SLOT( 'updateChartType(QAction*)' ) )
|
||
|
|
||
|
resize( windowWidth, windowHeight )
|
||
|
if windowX != -1 || windowY != -1
|
||
|
move( windowX, windowY )
|
||
|
end
|
||
|
|
||
|
@canvas = Qt::Canvas.new( self )
|
||
|
@canvas.resize( width(), height() )
|
||
|
@canvasView = CanvasView.new( @canvas, @elements, self )
|
||
|
setCentralWidget( @canvasView )
|
||
|
@canvasView.show()
|
||
|
|
||
|
if ! @filename.nil?
|
||
|
load( @filename )
|
||
|
else
|
||
|
init()
|
||
|
@elements[0].set( 20, red, 14, "Red" )
|
||
|
@elements[1].set( 70, cyan, 2, "Cyan", darkGreen )
|
||
|
@elements[2].set( 35, blue, 11, "Blue" )
|
||
|
@elements[3].set( 55, yellow, 1, "Yellow", darkBlue )
|
||
|
@elements[4].set( 80, magenta, 1, "Magenta" )
|
||
|
drawElements()
|
||
|
end
|
||
|
|
||
|
statusBar().message( "Ready", 2000 )
|
||
|
end
|
||
|
|
||
|
|
||
|
|
||
|
def init()
|
||
|
setCaption( "Chart" )
|
||
|
@filename = nil
|
||
|
@changed = false
|
||
|
|
||
|
@elements[0] = Element.new( Element::INVALID, red )
|
||
|
@elements[1] = Element.new( Element::INVALID, cyan )
|
||
|
@elements[2] = Element.new( Element::INVALID, blue )
|
||
|
@elements[3] = Element.new( Element::INVALID, yellow )
|
||
|
@elements[4] = Element.new( Element::INVALID, green )
|
||
|
@elements[5] = Element.new( Element::INVALID, magenta )
|
||
|
@elements[6] = Element.new( Element::INVALID, darkYellow )
|
||
|
@elements[7] = Element.new( Element::INVALID, darkRed )
|
||
|
@elements[8] = Element.new( Element::INVALID, darkCyan )
|
||
|
@elements[9] = Element.new( Element::INVALID, darkGreen )
|
||
|
@elements[10] = Element.new( Element::INVALID, darkMagenta )
|
||
|
@elements[11] = Element.new( Element::INVALID, darkBlue )
|
||
|
for i in 12...MAX_ELEMENTS
|
||
|
x = (i.to_f / MAX_ELEMENTS) * 360
|
||
|
y = ((x * 256) % 105) + 151
|
||
|
z = ((i * 17) % 105) + 151;
|
||
|
@elements[i] = Element.new( Element::INVALID, Qt::Color.new( x, y, z, Qt::Color::Hsv ) )
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def closeEvent( e )
|
||
|
fileQuit()
|
||
|
end
|
||
|
|
||
|
|
||
|
def fileNew()
|
||
|
if okToClear()
|
||
|
init()
|
||
|
drawElements()
|
||
|
end
|
||
|
end
|
||
|
|
||
|
|
||
|
def fileOpen()
|
||
|
if !okToClear()
|
||
|
return
|
||
|
end
|
||
|
|
||
|
filename = Qt::FileDialog.getOpenFileName(
|
||
|
nil, "Charts (*.cht)", self,
|
||
|
"file open", "Chart -- File Open" )
|
||
|
if !filename.nil?
|
||
|
load( filename )
|
||
|
else
|
||
|
statusBar().message( "File Open abandoned", 2000 )
|
||
|
end
|
||
|
end
|
||
|
|
||
|
|
||
|
def fileSaveAs()
|
||
|
filename = Qt::FileDialog.getSaveFileName(
|
||
|
nil, "Charts (*.cht)", self,
|
||
|
"file save as", "Chart -- File Save As" )
|
||
|
if !filename.nil?
|
||
|
answer = 0
|
||
|
if Qt::File.exists( filename )
|
||
|
answer = Qt::MessageBox.warning(
|
||
|
self, "Chart -- Overwrite File",
|
||
|
"Overwrite\n\'#{filename}\'?",
|
||
|
"&Yes", "&No", nil, 1, 1 )
|
||
|
end
|
||
|
if answer == 0
|
||
|
@filename = filename
|
||
|
updateRecentFiles( filename )
|
||
|
fileSave()
|
||
|
return
|
||
|
end
|
||
|
end
|
||
|
statusBar().message( "Saving abandoned", 2000 )
|
||
|
end
|
||
|
|
||
|
|
||
|
def fileOpenRecent( index )
|
||
|
if !okToClear()
|
||
|
return
|
||
|
end
|
||
|
|
||
|
load( @recentFiles[index] )
|
||
|
end
|
||
|
|
||
|
|
||
|
def updateRecentFiles( filename )
|
||
|
if @recentFiles.include?( filename )
|
||
|
return
|
||
|
end
|
||
|
|
||
|
@recentFiles.push( filename )
|
||
|
if @recentFiles.length() > MAX_RECENTFILES
|
||
|
@recentFiles.shift()
|
||
|
end
|
||
|
|
||
|
updateRecentFilesMenu()
|
||
|
end
|
||
|
|
||
|
|
||
|
def updateRecentFilesMenu()
|
||
|
for i in 0...MAX_RECENTFILES
|
||
|
if @fileMenu.findItem( i )
|
||
|
@fileMenu.removeItem( i )
|
||
|
end
|
||
|
if i < @recentFiles.length()
|
||
|
@fileMenu.insertItem( "&%d %s" % [i + 1, @recentFiles[i]],
|
||
|
self, SLOT( 'fileOpenRecent(int)' ),
|
||
|
Qt::KeySequence.new(0), i )
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
|
||
|
def fileQuit()
|
||
|
if okToClear()
|
||
|
saveOptions()
|
||
|
$qApp.exit( 0 )
|
||
|
end
|
||
|
end
|
||
|
|
||
|
|
||
|
def okToClear()
|
||
|
if @changed
|
||
|
if @filename.nil?
|
||
|
msg = "Unnamed chart "
|
||
|
else
|
||
|
msg = "Chart '#{@filename}'\n"
|
||
|
end
|
||
|
msg += "has been changed."
|
||
|
|
||
|
x = Qt::MessageBox.information( self, "Chart -- Unsaved Changes",
|
||
|
msg, "&Save", "Cancel", "&Abandon",
|
||
|
0, 1 )
|
||
|
case x
|
||
|
when 0 # Save
|
||
|
fileSave()
|
||
|
when 1 # Cancel
|
||
|
when 2 # Abandon
|
||
|
else
|
||
|
return false
|
||
|
end
|
||
|
end
|
||
|
return true
|
||
|
end
|
||
|
|
||
|
|
||
|
def saveOptions()
|
||
|
settings = Qt::Settings.new
|
||
|
settings.insertSearchPath( Qt::Settings::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", @chartType )
|
||
|
settings.writeEntry( APP_KEY + "AddValues", @addValues )
|
||
|
settings.writeEntry( APP_KEY + "Decimals", @decimalPlaces )
|
||
|
settings.writeEntry( APP_KEY + "Font", @font.toString() )
|
||
|
for i in 0...@recentFiles.length
|
||
|
settings.writeEntry( APP_KEY + "File" + ( i + 1 ).to_s,
|
||
|
@recentFiles[i] )
|
||
|
end
|
||
|
end
|
||
|
|
||
|
|
||
|
def optionsSetData()
|
||
|
setDataForm = SetDataForm.new( @elements, @decimalPlaces, self )
|
||
|
if setDataForm.exec()
|
||
|
@changed = true
|
||
|
drawElements()
|
||
|
end
|
||
|
end
|
||
|
|
||
|
|
||
|
def setChartType( chartType )
|
||
|
@chartType = chartType;
|
||
|
case @chartType
|
||
|
when PIE
|
||
|
@optionsPieChartAction.setOn( true )
|
||
|
when VERTICAL_BAR:
|
||
|
@optionsVerticalBarChartAction.setOn( true )
|
||
|
when HORIZONTAL_BAR:
|
||
|
@optionsHorizontalBarChartAction.setOn( true )
|
||
|
end
|
||
|
end
|
||
|
|
||
|
|
||
|
def updateChartType( action )
|
||
|
if action == @optionsPieChartAction
|
||
|
@chartType = PIE
|
||
|
elsif action == @optionsHorizontalBarChartAction
|
||
|
@chartType = HORIZONTAL_BAR
|
||
|
elsif action == @optionsVerticalBarChartAction
|
||
|
@chartType = VERTICAL_BAR
|
||
|
end
|
||
|
|
||
|
drawElements()
|
||
|
end
|
||
|
|
||
|
|
||
|
def optionsSetFont()
|
||
|
ok = Qt::Boolean.new
|
||
|
font = Qt::FontDialog.getFont( ok, @font, self )
|
||
|
if !ok.nil?
|
||
|
@font = font
|
||
|
drawElements()
|
||
|
end
|
||
|
end
|
||
|
|
||
|
|
||
|
def optionsSetOptions()
|
||
|
optionsForm = OptionsForm.new( self )
|
||
|
optionsForm.chartTypeComboBox.setCurrentItem( @chartType )
|
||
|
optionsForm.font = @font
|
||
|
case @addValues
|
||
|
when NO
|
||
|
optionsForm.noRadioButton.setChecked( true )
|
||
|
when YES
|
||
|
optionsForm.yesRadioButton.setChecked( true )
|
||
|
when AS_PERCENTAGE
|
||
|
optionsForm.asPercentageRadioButton.setChecked( true )
|
||
|
end
|
||
|
optionsForm.decimalPlacesSpinBox.setValue( @decimalPlaces )
|
||
|
if optionsForm.exec()
|
||
|
setChartType( optionsForm.chartTypeComboBox.currentItem() )
|
||
|
@font = optionsForm.font
|
||
|
if optionsForm.noRadioButton.isChecked()
|
||
|
@addValues = NO
|
||
|
elsif optionsForm.yesRadioButton.isChecked()
|
||
|
@addValues = YES
|
||
|
elsif optionsForm.asPercentageRadioButton.isChecked()
|
||
|
@addValues = AS_PERCENTAGE
|
||
|
end
|
||
|
@decimalPlaces = optionsForm.decimalPlacesSpinBox.value()
|
||
|
drawElements()
|
||
|
end
|
||
|
end
|
||
|
|
||
|
|
||
|
def helpHelp()
|
||
|
statusBar().message( "Help is not implemented yet", 2000 )
|
||
|
end
|
||
|
|
||
|
|
||
|
def helpAbout()
|
||
|
Qt::MessageBox.about( self, "Chart -- About",
|
||
|
"<center><h1><font color=blue>Chart<font></h1></center>" +
|
||
|
"<p>Chart your data with <i>chart</i>.</p>" )
|
||
|
end
|
||
|
|
||
|
|
||
|
def helpAboutQt()
|
||
|
Qt::MessageBox.aboutQt( self, "Chart -- About Qt" )
|
||
|
end
|
||
|
|
||
|
end
|
||
|
|