From 5de3dd4762ca33a0f92e79ffa4fe2ff67069d531 Mon Sep 17 00:00:00 2001 From: tpearson Date: Wed, 24 Feb 2010 01:49:02 +0000 Subject: Added KDE3 version of ktechlab git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/ktechlab@1095338 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- src/gui/Makefile.am | 23 ++ src/gui/asmformattingwidget.ui | 213 +++++++++++++ src/gui/colorcombo.cpp | 194 ++++++++++++ src/gui/colorcombo.h | 79 +++++ src/gui/contexthelp.cpp | 107 +++++++ src/gui/contexthelp.h | 58 ++++ src/gui/createsubprojectwidget.ui | 99 ++++++ src/gui/doublespinbox.cpp | 278 +++++++++++++++++ src/gui/doublespinbox.h | 131 ++++++++ src/gui/generaloptionswidget.ui | 269 ++++++++++++++++ src/gui/gpasmsettingswidget.ui | 288 +++++++++++++++++ src/gui/itemeditor.cpp | 156 ++++++++++ src/gui/itemeditor.h | 82 +++++ src/gui/itemselector.cpp | 372 ++++++++++++++++++++++ src/gui/itemselector.h | 167 ++++++++++ src/gui/linkeroptionswidget.ui | 179 +++++++++++ src/gui/logicwidget.ui | 276 +++++++++++++++++ src/gui/logview.cpp | 132 ++++++++ src/gui/logview.h | 85 +++++ src/gui/microselectwidget.cpp | 129 ++++++++ src/gui/microselectwidget.h | 73 +++++ src/gui/microsettingsdlg.cpp | 437 ++++++++++++++++++++++++++ src/gui/microsettingsdlg.h | 105 +++++++ src/gui/microsettingswidget.ui | 197 ++++++++++++ src/gui/newfiledlg.cpp | 151 +++++++++ src/gui/newfiledlg.h | 55 ++++ src/gui/newfilewidget.ui | 195 ++++++++++++ src/gui/newpinmappingwidget.ui | 130 ++++++++ src/gui/newprojectwidget.ui | 110 +++++++ src/gui/orientationwidget.cpp | 255 +++++++++++++++ src/gui/orientationwidget.h | 56 ++++ src/gui/oscilloscope.cpp | 354 +++++++++++++++++++++ src/gui/oscilloscope.h | 192 ++++++++++++ src/gui/oscilloscopeview.cpp | 431 ++++++++++++++++++++++++++ src/gui/oscilloscopeview.h | 65 ++++ src/gui/oscilloscopewidget.ui | 289 +++++++++++++++++ src/gui/outputmethoddlg.cpp | 162 ++++++++++ src/gui/outputmethoddlg.h | 98 ++++++ src/gui/outputmethodwidget.ui | 182 +++++++++++ src/gui/picprogrammerconfigwidget.ui | 285 +++++++++++++++++ src/gui/pieditor.cpp | 294 ++++++++++++++++++ src/gui/pieditor.h | 188 +++++++++++ src/gui/plvitem.cpp | 90 ++++++ src/gui/plvitem.h | 66 ++++ src/gui/probepositioner.cpp | 210 +++++++++++++ src/gui/probepositioner.h | 77 +++++ src/gui/processingoptionswidget.ui | 98 ++++++ src/gui/programmerdlg.cpp | 90 ++++++ src/gui/programmerdlg.h | 54 ++++ src/gui/programmerwidget.ui | 123 ++++++++ src/gui/projectdlgs.cpp | 275 ++++++++++++++++ src/gui/projectdlgs.h | 159 ++++++++++ src/gui/propertieslistview.cpp | 328 ++++++++++++++++++++ src/gui/propertieslistview.h | 75 +++++ src/gui/sdccoptionswidget.ui | 586 +++++++++++++++++++++++++++++++++++ src/gui/settingsdlg.cpp | 386 +++++++++++++++++++++++ src/gui/settingsdlg.h | 69 +++++ src/gui/symbolviewer.cpp | 218 +++++++++++++ src/gui/symbolviewer.h | 103 ++++++ 59 files changed, 10628 insertions(+) create mode 100644 src/gui/Makefile.am create mode 100644 src/gui/asmformattingwidget.ui create mode 100644 src/gui/colorcombo.cpp create mode 100644 src/gui/colorcombo.h create mode 100644 src/gui/contexthelp.cpp create mode 100644 src/gui/contexthelp.h create mode 100644 src/gui/createsubprojectwidget.ui create mode 100644 src/gui/doublespinbox.cpp create mode 100644 src/gui/doublespinbox.h create mode 100644 src/gui/generaloptionswidget.ui create mode 100644 src/gui/gpasmsettingswidget.ui create mode 100644 src/gui/itemeditor.cpp create mode 100644 src/gui/itemeditor.h create mode 100644 src/gui/itemselector.cpp create mode 100644 src/gui/itemselector.h create mode 100644 src/gui/linkeroptionswidget.ui create mode 100644 src/gui/logicwidget.ui create mode 100644 src/gui/logview.cpp create mode 100644 src/gui/logview.h create mode 100644 src/gui/microselectwidget.cpp create mode 100644 src/gui/microselectwidget.h create mode 100644 src/gui/microsettingsdlg.cpp create mode 100644 src/gui/microsettingsdlg.h create mode 100644 src/gui/microsettingswidget.ui create mode 100644 src/gui/newfiledlg.cpp create mode 100644 src/gui/newfiledlg.h create mode 100644 src/gui/newfilewidget.ui create mode 100644 src/gui/newpinmappingwidget.ui create mode 100644 src/gui/newprojectwidget.ui create mode 100644 src/gui/orientationwidget.cpp create mode 100644 src/gui/orientationwidget.h create mode 100644 src/gui/oscilloscope.cpp create mode 100644 src/gui/oscilloscope.h create mode 100644 src/gui/oscilloscopeview.cpp create mode 100644 src/gui/oscilloscopeview.h create mode 100644 src/gui/oscilloscopewidget.ui create mode 100644 src/gui/outputmethoddlg.cpp create mode 100644 src/gui/outputmethoddlg.h create mode 100644 src/gui/outputmethodwidget.ui create mode 100644 src/gui/picprogrammerconfigwidget.ui create mode 100644 src/gui/pieditor.cpp create mode 100644 src/gui/pieditor.h create mode 100644 src/gui/plvitem.cpp create mode 100644 src/gui/plvitem.h create mode 100644 src/gui/probepositioner.cpp create mode 100644 src/gui/probepositioner.h create mode 100644 src/gui/processingoptionswidget.ui create mode 100644 src/gui/programmerdlg.cpp create mode 100644 src/gui/programmerdlg.h create mode 100644 src/gui/programmerwidget.ui create mode 100644 src/gui/projectdlgs.cpp create mode 100644 src/gui/projectdlgs.h create mode 100644 src/gui/propertieslistview.cpp create mode 100644 src/gui/propertieslistview.h create mode 100644 src/gui/sdccoptionswidget.ui create mode 100644 src/gui/settingsdlg.cpp create mode 100644 src/gui/settingsdlg.h create mode 100644 src/gui/symbolviewer.cpp create mode 100644 src/gui/symbolviewer.h (limited to 'src/gui') diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am new file mode 100644 index 0000000..07b9dbb --- /dev/null +++ b/src/gui/Makefile.am @@ -0,0 +1,23 @@ +INCLUDES = -I$(top_srcdir)/src -I$(top_srcdir)/src/core \ + -I$(top_srcdir)/src/electronics -I$(top_srcdir)/src/electronics/components \ + -I$(top_srcdir)/src/electronics/simulation -I$(top_srcdir)/src/flowparts -I$(top_srcdir)/src/gui \ + -I$(top_srcdir)/src/languages -I$(top_srcdir)/src/mechanics -I$(top_srcdir)/src/micro \ + -I$(top_srcdir)/gpsim-interface $(all_includes) +METASOURCES = AUTO +noinst_LTLIBRARIES = libgui.la +libgui_la_SOURCES = contexthelp.cpp doublespinbox.cpp itemeditor.cpp \ + itemselector.cpp microsettingsdlg.cpp newfiledlg.cpp orientationwidget.cpp \ + outputmethoddlg.cpp pieditor.cpp plvitem.cpp propertieslistview.cpp asmformattingwidget.ui \ + gpasmsettingswidget.ui logicwidget.ui newfilewidget.ui newprojectwidget.ui \ + outputmethodwidget.ui microsettingswidget.ui settingsdlg.cpp oscilloscope.cpp \ + oscilloscopewidget.ui oscilloscopeview.cpp probepositioner.cpp generaloptionswidget.ui \ + logview.cpp createsubprojectwidget.ui processingoptionswidget.ui \ + sdccoptionswidget.ui projectdlgs.cpp linkeroptionswidget.ui microselectwidget.cpp \ + symbolviewer.cpp picprogrammerconfigwidget.ui newpinmappingwidget.ui programmerwidget.ui \ + programmerdlg.cpp colorcombo.cpp + +libgui_la_PCH = AUTO + +noinst_HEADERS = settingsdlg.h oscilloscope.h oscilloscopeview.h \ + probepositioner.h projectdlgs.h microselectwidget.h symbolviewer.h programmerdlg.h \ + colorcombo.h diff --git a/src/gui/asmformattingwidget.ui b/src/gui/asmformattingwidget.ui new file mode 100644 index 0000000..ecfa529 --- /dev/null +++ b/src/gui/asmformattingwidget.ui @@ -0,0 +1,213 @@ + +AsmFormattingWidget + + + AsmFormattingWidget + + + + 0 + 0 + 425 + 219 + + + + Asm Formatting + + + The values control the indentation from the left margin of the various types of assembly code. + + + + unnamed + + + 0 + + + + groupBox64 + + + Output Code Indentation + + + + unnamed + + + + textLabel11 + + + 'equ' Value + + + + + textLabel8 + + + Instruction Data + + + + + textLabel9 + + + Comment + + + + + textLabel10 + + + 'equ' + + + + + textLabel7 + + + Instruction Name + + + + + kcfg_IndentAsmName + + + + 5 + 0 + 0 + 0 + + + + 4 + + + + + + + + kcfg_IndentAsmData + + + + 5 + 0 + 0 + 0 + + + + 14 + + + + + kcfg_IndentEqu + + + + 5 + 0 + 0 + 0 + + + + 14 + + + + + kcfg_IndentEquValue + + + + 5 + 0 + 0 + 0 + + + + 20 + + + + + kcfg_IndentComment + + + + 5 + 0 + 0 + 0 + + + + -1 + + + 40 + + + + + + + kcfg_AutoFormatMBOutput + + + &Automatically format Microbe output + + + Alt+A + + + + + spacer57 + + + Vertical + + + Expanding + + + + 20 + 484 + + + + + + + kcfg_IndentAsmName + kcfg_IndentAsmData + kcfg_IndentEquValue + kcfg_IndentEqu + kcfg_IndentComment + kcfg_AutoFormatMBOutput + + + + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + + diff --git a/src/gui/colorcombo.cpp b/src/gui/colorcombo.cpp new file mode 100644 index 0000000..aec39ae --- /dev/null +++ b/src/gui/colorcombo.cpp @@ -0,0 +1,194 @@ +/*************************************************************************** + * Copyright (C) 2005 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#include "colorcombo.h" + +#include +#include +#include + +bool ColorCombo::createdPalettes = false; +QColor * ColorCombo::palette[ NumberOfSchemes ]; +int ColorCombo::paletteSize[ NumberOfSchemes ]; + +ColorCombo::ColorCombo( ColorScheme colorScheme, QWidget *parent, const char *name ) + : QComboBox( parent, name ) +{ + m_colorScheme = colorScheme; + + customColor.setRgb( 255, 255, 255 ); + internalColor.setRgb( 255, 255, 255 ); + + createPalettes(); + + addColors(); + + connect( this, SIGNAL( activated(int) ), SLOT( slotActivated(int) ) ); + connect( this, SIGNAL( highlighted(int) ), SLOT( slotHighlighted(int) ) ); +} + + +ColorCombo::~ColorCombo() +{ +} + + +void ColorCombo::createPalettes() +{ + if ( createdPalettes ) + return; + createdPalettes = true; + + paletteSize[ QtStandard ] = 17; + palette[ QtStandard ] = new QColor[ paletteSize[ QtStandard ] ]; + + int i = 0; + + palette[ QtStandard ][i++] = Qt::red; + palette[ QtStandard ][i++] = Qt::green; + palette[ QtStandard ][i++] = Qt::blue; + palette[ QtStandard ][i++] = Qt::cyan; + palette[ QtStandard ][i++] = Qt::magenta; + palette[ QtStandard ][i++] = Qt::yellow; + palette[ QtStandard ][i++] = Qt::darkRed; + palette[ QtStandard ][i++] = Qt::darkGreen; + palette[ QtStandard ][i++] = Qt::darkBlue; + palette[ QtStandard ][i++] = Qt::darkCyan; + palette[ QtStandard ][i++] = Qt::darkMagenta; + palette[ QtStandard ][i++] = Qt::darkYellow; + palette[ QtStandard ][i++] = Qt::white; + palette[ QtStandard ][i++] = Qt::lightGray; + palette[ QtStandard ][i++] = Qt::gray; + palette[ QtStandard ][i++] = Qt::darkGray; + palette[ QtStandard ][i++] = Qt::black; + + + paletteSize[ LED ] = 6; + palette[ LED ] = new QColor[ paletteSize[ LED ] ]; + + i = 0; + palette[ LED ][i++] = "#f62a2a"; + palette[ LED ][i++] = "#ff7733"; + palette[ LED ][i++] = "#ffbb33"; + palette[ LED ][i++] = "#eeee22"; + palette[ LED ][i++] = "#4cc308"; + palette[ LED ][i++] = "#22aaee"; +} + + +void ColorCombo::setColor( const QColor &col ) +{ + internalColor = col; + addColors(); +} + + +void ColorCombo::resizeEvent( QResizeEvent *re ) +{ + QComboBox::resizeEvent( re ); + addColors(); +} + + +void ColorCombo::slotActivated( int index ) +{ + if ( index == 0 ) + { + if ( KColorDialog::getColor( customColor, this ) == QDialog::Accepted ) + { + QPainter painter; + QPen pen; + QRect rect( 0, 0, width(), QFontMetrics(painter.font()).height()+4); + QPixmap pixmap( rect.width(), rect.height() ); + + if ( qGray( customColor.rgb() ) < 128 ) + pen.setColor( white ); + else + pen.setColor( black ); + + painter.begin( &pixmap ); + QBrush brush( customColor ); + painter.fillRect( rect, brush ); + painter.setPen( pen ); + painter.drawText( 2, QFontMetrics(painter.font()).ascent()+2, i18n("Custom...") ); + painter.end(); + + changeItem( pixmap, 0 ); + pixmap.detach(); + } + + internalColor = customColor; + } + else + internalColor = palette[ m_colorScheme ][ index - 1 ]; + + emit activated( internalColor ); +} + +void ColorCombo::slotHighlighted( int index ) +{ + if ( index == 0 ) + internalColor = customColor; + else + internalColor = palette[ m_colorScheme ][ index - 1 ]; + + emit highlighted( internalColor ); +} + +void ColorCombo::addColors() +{ + QPainter painter; + QPen pen; + QRect rect( 0, 0, width(), QFontMetrics(painter.font()).height()+4 ); + QPixmap pixmap( rect.width(), rect.height() ); + int i; + + clear(); + + createPalettes(); + + for ( i = 0; i < paletteSize[ m_colorScheme ]; i++ ) + if ( palette[ m_colorScheme ][i] == internalColor ) break; + + if ( i == paletteSize[ m_colorScheme ] ) + customColor = internalColor; + + if ( qGray( customColor.rgb() ) < 128 ) + pen.setColor( white ); + else + pen.setColor( black ); + + painter.begin( &pixmap ); + QBrush brush( customColor ); + painter.fillRect( rect, brush ); + painter.setPen( pen ); + painter.drawText( 2, QFontMetrics(painter.font()).ascent()+2, i18n("Custom...") ); + painter.end(); + + insertItem( pixmap ); + pixmap.detach(); + + for ( i = 0; i < paletteSize[ m_colorScheme ]; i++ ) + { + painter.begin( &pixmap ); + QBrush brush( palette[ m_colorScheme ][i] ); + painter.fillRect( rect, brush ); + painter.end(); + + insertItem( pixmap ); + pixmap.detach(); + + if ( palette[ m_colorScheme ][i] == internalColor ) + setCurrentItem( i + 1 ); + } +} + + +#include "colorcombo.moc" diff --git a/src/gui/colorcombo.h b/src/gui/colorcombo.h new file mode 100644 index 0000000..65b2714 --- /dev/null +++ b/src/gui/colorcombo.h @@ -0,0 +1,79 @@ +/*************************************************************************** + * Copyright (C) 2005 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#ifndef COLORCOMBO_H +#define COLORCOMBO_H + +#include +#include + +/** +Based on KColorCombo, Copyright (C) 1997 Martin Jones (mjones@kde.org). Allows +which colours are displayed to be changed. + +@author David Saxton +*/ +class ColorCombo : public QComboBox +{ + Q_OBJECT + Q_PROPERTY( QColor color READ color WRITE setColor ) + + public: + enum ColorScheme + { + QtStandard = 0, + LED = 1, + NumberOfSchemes = 2, ///< for internal usage; this should be one less than the number of items in the enum + }; + + /** + * Constructs a color combo box. + */ + ColorCombo( ColorScheme colorScheme, QWidget *parent, const char *name = 0L ); + ~ColorCombo(); + + /** + * Selects the color @p col. + */ + void setColor( const QColor & col ); + /** + * Returns the currently selected color. + **/ + QColor color() const { return internalColor; } + + signals: + /** + * Emitted when a new color box has been selected. + */ + void activated( const QColor &col ); + /** + * Emitted when a new item has been highlighted. + */ + void highlighted( const QColor &col ); + + protected slots: + void slotActivated( int index ); + void slotHighlighted( int index ); + + protected: + virtual void resizeEvent( QResizeEvent *re ); + void addColors(); + void createPalettes(); + + QColor customColor; + QColor internalColor; + ColorScheme m_colorScheme; + + static bool createdPalettes; + static QColor * palette[ NumberOfSchemes ]; + static int paletteSize[ NumberOfSchemes ]; +}; + +#endif diff --git a/src/gui/contexthelp.cpp b/src/gui/contexthelp.cpp new file mode 100644 index 0000000..3444737 --- /dev/null +++ b/src/gui/contexthelp.cpp @@ -0,0 +1,107 @@ +/*************************************************************************** + * Copyright (C) 2003-2005 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#include "cnitem.h" +#include "cnitemgroup.h" +#include "contexthelp.h" +#include "itemlibrary.h" +#include "katemdi.h" + +#include + +#include +#include +#include +#include +#include + +#include + +ContextHelp * ContextHelp::m_pSelf = 0l; + +ContextHelp * ContextHelp::self( KateMDI::ToolView * parent ) +{ + if (!m_pSelf) + { + assert(parent); + m_pSelf = new ContextHelp(parent); + } + return m_pSelf; +} + + +ContextHelp::ContextHelp( KateMDI::ToolView * parent ) + : QWidget( parent, "Context Help" ) +{ + QWhatsThis::add( this, i18n("Provides context-sensitive help relevant to the current editing being performed.") ); + + QVBoxLayout *vlayout = new QVBoxLayout( this, 0, 6 ); + + m_nameLbl = new QLabel( this, "" ); + vlayout->addWidget(m_nameLbl); + vlayout->addSpacing(8); + + m_info = new QTextBrowser( this, "" ); + vlayout->addWidget(m_info); + m_info->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding ); + + QSpacerItem *spacer3 = new QSpacerItem( 1, 1, QSizePolicy::Preferred, QSizePolicy::Preferred ); + vlayout->addItem(spacer3); + + slotClear(); +} + + +ContextHelp::~ContextHelp() +{ +} + + +void ContextHelp::slotUpdate( Item *item ) +{ + if (!item) + { + slotClear(); + return; + } + m_nameLbl->setText("

"+item->name()+"

"); + m_info->setText( ""+item->description() ); +} + + +void ContextHelp::slotClear() +{ + m_nameLbl->setText(i18n("

No Item Selected

")); + m_info->setText(""); +} + + +void ContextHelp::slotMultipleSelected() +{ + m_nameLbl->setText(i18n("

Multiple Items

")); + m_info->setText(""); +} + + +void ContextHelp::setContextHelp(const QString& name, const QString& help) +{ + m_nameLbl->setText("

"+name+"

"); + QString parsed = help; + parseInfo(parsed); + m_info->setText( ""+parsed ); +} + +void ContextHelp::parseInfo( QString &info ) +{ + info.replace("","

Example:
"); + info.replace("","
"); +} + +#include "contexthelp.moc" diff --git a/src/gui/contexthelp.h b/src/gui/contexthelp.h new file mode 100644 index 0000000..90159b7 --- /dev/null +++ b/src/gui/contexthelp.h @@ -0,0 +1,58 @@ +/*************************************************************************** + * Copyright (C) 2003-2005 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#ifndef CONTEXTHELP_H +#define CONTEXTHELP_H + +#include + +class Item; +class ContextHelp; +class QLabel; +class QTextBrowser; +namespace KateMDI { class ToolView; } + +/** +Sidebar that provides context-sensitive help for whatever the user is currently +helping (e.g. pinouts, command references, etc). Not to be confused with +ItemEditor, which which allows editing of data specific to the selected CNItem +in a ICNDocument. + +@author David Saxton +*/ +class ContextHelp : public QWidget +{ + Q_OBJECT + public: + static ContextHelp * self( KateMDI::ToolView * parent = 0l ); + static QString toolViewIdentifier() { return "ContextHelp"; } + + ~ContextHelp(); + /** + * Replace special tags with appropriate html formatting code. + */ + void parseInfo( QString &info ); + + public slots: + void slotClear(); + void slotMultipleSelected(); + void slotUpdate( Item *item ); + void setContextHelp(const QString& name, const QString &help); + + private: + ContextHelp( KateMDI::ToolView * parent ); + + QLabel *m_nameLbl; + QTextBrowser *m_info; + static ContextHelp * m_pSelf; +}; + +#endif + diff --git a/src/gui/createsubprojectwidget.ui b/src/gui/createsubprojectwidget.ui new file mode 100644 index 0000000..267739e --- /dev/null +++ b/src/gui/createsubprojectwidget.ui @@ -0,0 +1,99 @@ + +CreateSubprojectWidget + + + CreateSubprojectWidget + + + + 0 + 0 + 489 + 82 + + + + Create Subproject + + + + unnamed + + + 0 + + + + textLabel1 + + + + 1 + + + + Subproject Details + + + + + textLabel2 + + + Target File: + + + + + textLabel1_2 + + + Type: + + + + + + Program + + + + + Library + + + + m_typeCombo + + + + + m_targetFile + + + + + spacer3 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + + kurlrequester.h + klineedit.h + kpushbutton.h + + diff --git a/src/gui/doublespinbox.cpp b/src/gui/doublespinbox.cpp new file mode 100644 index 0000000..b8672b5 --- /dev/null +++ b/src/gui/doublespinbox.cpp @@ -0,0 +1,278 @@ +/*************************************************************************** + * Copyright (C) 2003-2004 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#include "cnitem.h" +#include "doublespinbox.h" + +#include +#include +#include + +#include +#include +#include + +#include +#include +using namespace std; + + +inline int roundDouble( double val ) +{ + return (val > 0) ? int(val+0.5) : int(val-0.5); +} + + +DoubleSpinBox::DoubleSpinBox( double lower, double upper, double minAbs, double value, const QString &unit, QWidget * parent ) + : QSpinBox( parent ) +{ + m_lastEmittedValue = value; + m_unit = unit; + m_minValue = lower; + m_maxValue = upper; + m_minAbsValue = minAbs; + m_queuedSuffix = QString::null; + + editor()->setAlignment( Qt::AlignRight ); + + connect( this, SIGNAL(valueChanged(int)), this, SLOT(checkIfChanged()) ); + QSpinBox::setMinValue( -(1<<30) ); + QSpinBox::setMaxValue( +(1<<30) ); + setValue( value ); + + setValidator( 0 ); +} + + +DoubleSpinBox::~DoubleSpinBox() +{ +} + + +double DoubleSpinBox::value() +{ + return getDisplayedNumber( 0 ) * getMult(); +} + + +void DoubleSpinBox::setValue( double value ) +{ + if ( value > maxValue() ) + value = maxValue(); + + else if ( value < minValue() ) + value = minValue(); + + if ( std::abs(value) < m_minAbsValue*0.9999 ) + value = 0.0; + + updateSuffix( value ); + + QSpinBox::setValue( roundDouble( (value / Item::getMultiplier( value )) * 100 ) ); +} + + +void DoubleSpinBox::setUnit( const QString & unit ) +{ + updateSuffix( value() ); + m_unit = unit; +} + + +void DoubleSpinBox::updateSuffix( double value ) +{ + m_queuedSuffix = " " + CNItem::getNumberMag( value ) + m_unit; + + // Set suffix to be empty if it is nothing but white space + if ( m_queuedSuffix.stripWhiteSpace().isEmpty() ) + m_queuedSuffix = ""; + + QTimer::singleShot( 0, this, SLOT(setQueuedSuffix()) ); +} + + +void DoubleSpinBox::setQueuedSuffix() +{ + bool changed = false; + if ( !m_queuedSuffix.isNull() && suffix() != m_queuedSuffix ) + { + setSuffix( m_queuedSuffix ); + changed = true; + } + m_queuedSuffix = QString::null; + + if ( changed ) + emit valueChanged( value() ); +} + + +double DoubleSpinBox::getMult() +{ + QString text = this->text().stripWhiteSpace(); + if ( !m_queuedSuffix.isNull() ) + { + QString nsSuffix = suffix().stripWhiteSpace(); + + if ( nsSuffix.isEmpty() ) + text.append( m_queuedSuffix ); + else + text.replace( nsSuffix, m_queuedSuffix ); + } + + if ( text.length() == 0 ) + return 1.0; + + if ( text.endsWith( m_unit, false ) ) + text = text.remove( text.length() - m_unit.length(), m_unit.length() ); + + text.stripWhiteSpace(); + + QChar siExp = text[ text.length()-1 ]; + + if ( siExp.isLetter() || siExp.isSymbol() ) + return CNItem::getMultiplier((QString)siExp); + + else + return 1; +} + + +double DoubleSpinBox::getDisplayedNumber( bool * ok ) +{ + KLocale * locale = KGlobal::locale(); + + // Fetch the characters that we don't want to discard + const QString exclude = locale->decimalSymbol() + + locale->thousandsSeparator() + + locale->positiveSign() + + locale->negativeSign(); + + QString number = cleanText().remove( QRegExp("[^"+exclude+"\\d]") ); + + return locale->readNumber( number, ok ); +} + + +int DoubleSpinBox::mapTextToValue( bool * ok ) +{ + (void)ok; + + double value = this->value(); + + if ( value > maxValue() ) + value = maxValue(); + + else if ( value < minValue() ) + value = minValue(); + + if ( std::abs(value) < m_minAbsValue*0.9999 ) + value = 0.0; + + updateSuffix( value ); + + value /= Item::getMultiplier( value ); + + // Precision of 2 extra digits + return int( value * 100 ); +} + + +QString DoubleSpinBox::mapValueToText( int v ) +{ + double val = double(v)/100.0; + + int leftDigits = (int)floor( log10( abs(val) ) ) + 1; + if ( leftDigits < 0 ) + leftDigits = 0; + else if ( leftDigits > 3 ) + leftDigits = 3; + + KLocale * locale = KGlobal::locale(); + return locale->formatNumber( val, 3-leftDigits ); +} + + +void DoubleSpinBox::checkIfChanged() +{ + double newValue = value(); + + if ( m_lastEmittedValue == newValue ) + return; + + m_lastEmittedValue = newValue; + emit valueChanged( m_lastEmittedValue ); +} + + +double DoubleSpinBox::roundToOneSF( double value ) +{ + if ( value == 0.0 ) + return 0.0; + + value *= 1.000001; + double tens = pow( 10.0, floor(log10( abs(value) )) ); + + return int ( value / tens ) * tens; +} + + +void DoubleSpinBox::stepUp() +{ + double value = roundToOneSF( this->value() ); + + if ( value == 0 ) + value = m_minAbsValue; + + else if ( value > 0 ) + value += std::pow( 10., std::floor( std::log10(value) ) ); + + else + { + double sub = std::pow(10., std::floor( std::log10(std::abs(value))-1) ); + value += std::pow( 10., std::floor( std::log10(std::abs(value)-sub) ) ); + } + + value *= 1.00001; + + if ( std::abs(value) < m_minAbsValue ) + value = 0.; + + setValue( value ); +} + + +void DoubleSpinBox::stepDown() +{ + double value = roundToOneSF( this->value() ); + + if ( value == 0 ) + value = -m_minAbsValue; + + else if ( value > 0 ) + { + double sub = std::pow(10., std::floor( std::log10(value)-1) ); + value -= std::pow( 10., std::floor( std::log10(value-sub) ) ); + } + else + { + double add = std::pow(10., std::floor( std::log10(std::abs(value))-1) ); + value -= std::pow( 10., std::floor( std::log10(std::abs(value)+add) ) ); + } + + value *= 1.00001; + + if ( std::abs(value) < m_minAbsValue ) + value = 0.; + + setValue( value ); +} + +#include "doublespinbox.moc" + diff --git a/src/gui/doublespinbox.h b/src/gui/doublespinbox.h new file mode 100644 index 0000000..75f6c90 --- /dev/null +++ b/src/gui/doublespinbox.h @@ -0,0 +1,131 @@ +/*************************************************************************** + * Copyright (C) 2003-2004 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#ifndef DOUBLESPINBOX_H +#define DOUBLESPINBOX_H + +#include + +/** +Where appropriate, function names with value in them should +be prefixed with "real" - e.g. realValue() - to get the value stored in the +spin box plus the SI magnitude symbol it is showing + +@author David Saxton +*/ +class DoubleSpinBox : public QSpinBox +{ + Q_OBJECT + public: + DoubleSpinBox( double lower, double upper, double minAbs, double value, const QString & unit, QWidget * parent = 0 ); + virtual ~DoubleSpinBox(); + + /** + * The minimum value is the lowest number that the user can enter. + */ + double minValue() const { return m_minValue; } + /** + * @see minValue + */ + void setMinValue( double minValue ) { m_minValue = minValue; } + /** + * The minimum value is the lowest number that the user can enter. + */ + void setMinValue( int minValue ) { m_minValue = minValue; } + /** + * The maximum value is the highest number that the user can enter. + */ + double maxValue() const { return m_maxValue; } + /** + * @see maxValue + */ + void setMaxValue( double maxValue ) { m_maxValue = maxValue; } + /** + * @see maxValue + */ + void setMaxValue( int maxValue ) { m_maxValue = maxValue; } + /** + * The minimum absolute value is the smallest value that the user can + * enter before the value is considered 0. + */ + void setMinAbsValue( double minAbsValue ) { m_minAbsValue = minAbsValue; } + /** + * The actual value that the user has entered - e.g. if the spinbox + * displays "100 kF", then the value returned will be 1e5. + */ + double value(); + /** + * Set the value to be displayed - e.g. if value is 1e5, then the + * spinbox might display "100 kF". + */ + void setValue( double value ); + /** + * Sets the unit used, e.g. "F" + */ + void setUnit( const QString & unit ); + + public slots: + virtual void stepUp(); + virtual void stepDown(); + + signals: + /** + * This value is emitted whenever the value of the spinbox changes. + */ + void valueChanged( double value ); + + protected slots: + /** + * Checks if the value has changed - and if so, emits a valueChanged + * signal. + */ + void checkIfChanged(); + /** + * Sets the suffix from m_queuedSuffix. Called from QTimer::singleShot + * to avoid strange recursion problems. + */ + void setQueuedSuffix(); + + protected: + /** + * Updates the suffix using m_unit and value. + */ + void updateSuffix( double value ); + /** + * Returns the multiplication number from what is displayed + * in the box, e.g. "10 kV" will return "1000" due to the letter "k" presence + */ + double getMult(); + /** + * Returns the number currently displayed in the spin box. + */ + double getDisplayedNumber( bool * ok ); + /** + * Overloaded the method in QSpinxBox to allow SI prefixes to be entered + */ + virtual int mapTextToValue( bool * ok ); + /** + * Overloaded the method in QSpinxBox to allow SI prefixes to be entered + */ + virtual QString mapValueToText( int v ); + /** + * Returns value rounded off to one significant figure. + */ + double roundToOneSF( double value ); + + QString m_queuedSuffix; ///< Used + QString m_unit; + double m_minValue; + double m_maxValue; + double m_minAbsValue; + double m_lastEmittedValue; +}; + +#endif diff --git a/src/gui/generaloptionswidget.ui b/src/gui/generaloptionswidget.ui new file mode 100644 index 0000000..0f3ee2a --- /dev/null +++ b/src/gui/generaloptionswidget.ui @@ -0,0 +1,269 @@ + +GeneralOptionsWidget + + + GeneralOptionsWidget + + + + 0 + 0 + 456 + 488 + + + + General Options + + + + unnamed + + + 0 + + + + kcfg_ReuseSameViewForOutput + + + Reuse the same output view for code generation + + + + + + + + kcfg_ShowVoltageBars + + + Show voltage bars &on electronic components + + + Alt+O + + + + + kcfg_GridColor + + + Grid Colour + + + The grid color in the work area. + + + + + kcfg_ShowGrid + + + Show &grid: + + + Alt+G + + + + + kcfg_MaxUndo + + + + 5 + 0 + 0 + 0 + + + + 100000 + + + + + textLabel1 + + + Maximum undo steps for work area: + + + Maximum undo steps for work area. This doesn't apply to text documents - that is configurable seperately under Configure Editor. + + + + + groupBox4 + + + Convenience + + + + unnamed + + + + kcfg_RestoreDocumentsOnStartup + + + Restore opened doc&uments on startup + + + Alt+U + + + + + kcfg_RaiseItemSelectors + + + Raise the &appropriate item selector on creating a new document + + + Alt+A + + + + + kcfg_RaiseMessagesLog + + + Raise the &Messages log when compiling + + + Alt+M + + + + + + + groupBox21 + + + Display Refresh Rate + + + + unnamed + + + + layout8_2 + + + + unnamed + + + + refreshRateSlider + + + 4 + + + 1 + + + 2 + + + Horizontal + + + Below + + + + + textLabel3_2 + + + Refresh rate: + + + + + refreshRateLabel + + + Medium (50 FPS) + + + + + + + textLabel9_2 + + + + 5 + 1 + 0 + 0 + + + + This is the number of times per second that the work area view is updated; a compromise between CPU usage and smoothness of display. + + + PlainText + + + false + + + WordBreak|AlignVCenter + + + + + + + spacer3 + + + Vertical + + + Expanding + + + + 20 + 40 + + + + + + + + kcfg_ShowGrid + toggled(bool) + kcfg_GridColor + setEnabled(bool) + + + + kcfg_ReuseSameViewForOutput + kcfg_ShowVoltageBars + kcfg_ShowGrid + kcfg_GridColor + kcfg_MaxUndo + kcfg_RestoreDocumentsOnStartup + kcfg_RaiseItemSelectors + kcfg_RaiseMessagesLog + refreshRateSlider + + + + kcolorbutton.h + knuminput.h + + diff --git a/src/gui/gpasmsettingswidget.ui b/src/gui/gpasmsettingswidget.ui new file mode 100644 index 0000000..069711f --- /dev/null +++ b/src/gui/gpasmsettingswidget.ui @@ -0,0 +1,288 @@ + +GpasmSettingsWidget + + + GpasmSettingsWidget + + + + 0 + 0 + 278 + 168 + + + + Gpasm Settings + + + + + + + unnamed + + + 0 + + + + textLabel2 + + + Radix (-r): + + + + + textLabel3 + + + Warning level (-w): + + + + + textLabel1 + + + Hex Format (-a): + + + + + kcfg_IgnoreCase + + + Ign&ore case (-i) + + + Alt+O + + + All user defined symbols and macros are case sensitive. This option makes them case insensitive. + + + + + kcfg_DosFormat + + + Generate DOS-formated hex file (-&n) + + + Alt+N + + + By default, gpasm generates hex files using ISO format. However, some device programmers required a DOS formatted file. This option will cause gpasm to generate a DOS formatted hex file. + + + + + spacer18 + + + Vertical + + + Expanding + + + + 20 + 16 + + + + + + + inhx32 + + + + + inhx8m + + + + + inhx8s + + + + + inhx16 + + + + kcfg_HexFormat + + + + 1 + 0 + 0 + 0 + + + + AtBottom + + + GPASM supports inhx8m, inhx8s, inhx16, and inhx32 hex file formats. This option controls which hex file format is used. + + + + + + Decimal + + + + + Binary + + + + + Octal + + + + + Hexadecimal + + + + kcfg_Radix + + + + 1 + 0 + 0 + 0 + + + + + + + All + + + + + Warnings + + + + + Errors + + + + kcfg_GpasmWarningLevel + + + + 1 + 0 + 0 + 0 + + + + This sets the threshold of messages displayed in the log view.<ul><li>"All" will display all output - information, warnings and errors.<li>"Warnings" will supress messages. <li>"Errors" will supress both messages and warnings.</ul> + + + + + spacer10 + + + Horizontal + + + Expanding + + + + 40 + 20 + + + + + + spacer11 + + + Horizontal + + + Expanding + + + + 40 + 20 + + + + + + spacer12 + + + Horizontal + + + Expanding + + + + 40 + 20 + + + + + + textLabel1_2 + + + Other options: + + + + + kcfg_MiscGpasmOptions + + + + 7 + 0 + 0 + 0 + + + + + + + kcfg_HexFormat + kcfg_Radix + kcfg_GpasmWarningLevel + kcfg_IgnoreCase + kcfg_DosFormat + + + + kcombobox.h + kcombobox.h + kcombobox.h + klineedit.h + + diff --git a/src/gui/itemeditor.cpp b/src/gui/itemeditor.cpp new file mode 100644 index 0000000..bdfe539 --- /dev/null +++ b/src/gui/itemeditor.cpp @@ -0,0 +1,156 @@ +/*************************************************************************** + * Copyright (C) 2003-2004 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#include "cnitem.h" +#include "cnitemgroup.h" +#include "itemeditor.h" +#include "orientationwidget.h" +#include "propertieslistview.h" + +#include +#include + +#include +#include +#include +#include + +#include + +ItemEditor * ItemEditor::m_pSelf = 0l; + +ItemEditor * ItemEditor::self( KateMDI::ToolView * parent ) +{ + if (!m_pSelf) + { + assert(parent); + m_pSelf = new ItemEditor(parent); + } + return m_pSelf; +} + + +ItemEditor::ItemEditor( KateMDI::ToolView * parent ) + : QWidget( (QWidget*)parent, "Item Editor" ) +{ + QWhatsThis::add( this, i18n("This allows editing of advanced properties of the selected item(s). Right click on the picture of the item to set the orientation.") ); + + QVBoxLayout *vlayout = new QVBoxLayout( this, 0, 6 ); + + m_nameLbl = new QLabel( this, "" ); + vlayout->addWidget(m_nameLbl); + vlayout->addSpacing(8); + + propList = new PropertiesListView(this); + vlayout->addWidget(propList); + QWhatsThis::add(propList,i18n("Shows properties associated with the currently selected item(s).

Select a property to change its value. If multiple items are selected with different values then the property will appear greyed out, use ""Merge Properties"" to make them the same.

Select ""Defaults to set all properties to their default values""")); + + QHBoxLayout *h1Layout = new QHBoxLayout( vlayout, 4 ); + QSpacerItem *spacer1 = new QSpacerItem( 1, 1 ); + h1Layout->addItem(spacer1); + + m_defaultsBtn = new QPushButton( i18n("Defaults"), this); + m_defaultsBtn->setEnabled(false); + connect(m_defaultsBtn,SIGNAL(clicked()),propList,SLOT(slotSetDefaults())); + h1Layout->addWidget(m_defaultsBtn); + + m_mergeBtn = new QPushButton( i18n("Merge properties"), this ); + m_mergeBtn->setEnabled(false); + connect(m_mergeBtn,SIGNAL(clicked()),this,SLOT(mergeProperties())); + h1Layout->addWidget(m_mergeBtn); + + // Orientation widget stuff + QHBoxLayout *h2Layout = new QHBoxLayout( vlayout, 6 ); + QSpacerItem *spacer2 = new QSpacerItem( 1, 1 ); + h2Layout->addItem(spacer2); + m_orientationWidget = new OrientationWidget(this); + h2Layout->addWidget(m_orientationWidget); + QWhatsThis::add(m_orientationWidget,i18n("Change the orientation of the selected item by selecting the appropriate button")); + QSpacerItem *spacer3 = new QSpacerItem( 1, 1 ); + h2Layout->addItem(spacer3); + + slotClear(); +} + + +ItemEditor::~ItemEditor() +{ +} + + +void ItemEditor::mergeProperties() +{ + propList->slotMergeProperties(); + m_mergeBtn->setEnabled(false); +} + + +void ItemEditor::slotClear() +{ + propList->slotClear(); + m_orientationWidget->slotClear(); + m_defaultsBtn->setEnabled(false); + m_mergeBtn->setEnabled(false); + updateNameLabel(0l); +} + + +void ItemEditor::slotMultipleSelected() +{ + slotClear(); + m_nameLbl->setText( i18n("

Multiple Items

") ); +} + + +void ItemEditor::slotUpdate( ItemGroup *itemGroup ) +{ + if (!itemGroup) { + slotClear(); + return; + } + + updateMergeDefaults(itemGroup); + propList->slotCreate(itemGroup); + updateNameLabel(itemGroup->activeItem()); +} + + +void ItemEditor::updateMergeDefaults( ItemGroup *itemGroup ) +{ + if (!itemGroup) + { + m_defaultsBtn->setEnabled(false); + m_mergeBtn->setEnabled(false); + return; + } + + m_mergeBtn->setEnabled( !itemGroup->itemsHaveSameData() ); + m_defaultsBtn->setEnabled( !itemGroup->itemsHaveDefaultData() ); + propList->slotUpdate(itemGroup); +} + + +void ItemEditor::slotUpdate( CNItem *item ) +{ + m_orientationWidget->slotUpdate(item); +} + + +void ItemEditor::updateNameLabel( Item *item ) +{ + if (item) { + m_nameLbl->setText( "

" + item->name() + "

" ); + } else { + m_nameLbl->setText( i18n("

No Item Selected

") ); + } +} + + +#include "itemeditor.moc" diff --git a/src/gui/itemeditor.h b/src/gui/itemeditor.h new file mode 100644 index 0000000..8c21e49 --- /dev/null +++ b/src/gui/itemeditor.h @@ -0,0 +1,82 @@ +/*************************************************************************** + * Copyright (C) 2003-2004 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#ifndef ITEMEDITOR_H +#define ITEMEDITOR_H + +#include +#include + +class ItemEditor; + +class CNItem; +class CNItemGroup; +class Item; +class CNItemGroup; +class ICNDocument; +class ItemGroup; +class OrientationWidget; +class PropertiesListView; +class QPushButton; +class QLabel; + +namespace KateMDI { class ToolView; } + +/** +@author Daniel Clarke +@author David Saxton +*/ +class ItemEditor : public QWidget +{ + Q_OBJECT + public: + static ItemEditor * self( KateMDI::ToolView * parent = 0l ); + ~ItemEditor(); + static QString toolViewIdentifier() { return "ItemEditor"; } + + public slots: + /** + * Update the Properties Editor + */ + void slotUpdate( ItemGroup *itemGroup ); + /** + * Update the orientation widget + */ + void slotUpdate( CNItem *item ); + /** + * Clear the properties editor and orientation widget + */ + void slotClear(); + void slotMultipleSelected(); + /** + * Updates the merge / reset data parts (e.g. enabling or disabling the + * "Defaults" button) + */ + void updateMergeDefaults( ItemGroup *itemGroup ); + + protected: + void updateNameLabel( Item *item ); + PropertiesListView * propList; + static ItemEditor * m_pSelf; + + private slots: + void mergeProperties(); + + private: + ItemEditor( KateMDI::ToolView * parent ); + + QLabel *m_nameLbl; + QPushButton *m_defaultsBtn; + QPushButton *m_mergeBtn; + OrientationWidget *m_orientationWidget; +}; + + +#endif diff --git a/src/gui/itemselector.cpp b/src/gui/itemselector.cpp new file mode 100644 index 0000000..f85756e --- /dev/null +++ b/src/gui/itemselector.cpp @@ -0,0 +1,372 @@ +/*************************************************************************** + * Copyright (C) 2003,2005 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#include // Temporay fix for pthread.h problem +#include "circuitdocument.h" +#include "docmanager.h" +#include "flowcodedocument.h" +#include "itemdocument.h" +#include "itemlibrary.h" +#include "itemselector.h" +#include "libraryitem.h" +#include "mechanicsdocument.h" + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +ILVItem::ILVItem( QListView* parent, const QString &id ) + : KListViewItem( parent, 0 ) +{ + m_id = id; + b_isRemovable = false; + m_pProjectItem = 0l; +} + +ILVItem::ILVItem( QListViewItem* parent, const QString &id ) + : KListViewItem( parent, 0 ) +{ + m_id = id; + b_isRemovable = false; + m_pProjectItem = 0l; +} + + +ItemSelector::ItemSelector( QWidget *parent, const char *name ) + : KListView( parent, name ) +{ + addColumn( i18n( "Component" ) ); + setFullWidth(true); + setSorting( -1, FALSE ); + setRootIsDecorated(true); + setDragEnabled(true); + +// connect( this, SIGNAL(executed(QListViewItem*) ), this, SLOT(slotItemExecuted(QListViewItem*)) ); + connect( this, SIGNAL(clicked(QListViewItem*)), this, SLOT(slotItemClicked(QListViewItem*)) ); + connect( this, SIGNAL(doubleClicked(QListViewItem*)), this, SLOT(slotItemDoubleClicked(QListViewItem*)) ); + connect( this, SIGNAL(contextMenuRequested(QListViewItem*, const QPoint&, int )), this, SLOT(slotContextMenuRequested(QListViewItem*, const QPoint&, int )) ); +} + +ItemSelector::~ItemSelector() +{ + writeOpenStates(); +} + + +void ItemSelector::clear() +{ + m_categories.clear(); + KListView::clear(); +} + + +void ItemSelector::addItem( const QString & caption, const QString & id, const QString & _category, const QPixmap & icon, bool removable ) +{ + ILVItem *parentItem = 0L; + + QString category = _category; + if ( !category.startsWith("/") ) { + category.prepend('/'); + } + + do + { + category.remove(0,1); + QString cat; + category.replace( "\\/", "|" ); + int pos = category.find('/'); + if ( pos == -1 ) cat = category; + else cat = category.left( pos ); + + cat.replace( "|", "/" ); + + if ( m_categories.findIndex(cat) == -1 ) + { + m_categories.append(cat); + + if (parentItem) { + parentItem = new ILVItem( parentItem, "" ); + } + else { + parentItem = new ILVItem( this, "" ); + } + parentItem->setOpen( readOpenState(cat) ); + + parentItem->setExpandable(true); + parentItem->setText( 0, cat ); + } + else + { + parentItem = (ILVItem*)findItem( cat, 0 ); + } + + category.remove( 0, pos ); + } while ( category.contains('/') ); + + if ( !parentItem ) + { + kdError() << "Unexpected error in finding parent item for category list"<setPixmap( 0, icon ); + item->setText( 0, caption ); + item->setRemovable(removable); +} + + +void ItemSelector::writeOpenStates() +{ + KConfig *config = kapp->config(); + config->setGroup( name() ); + + const QStringList::iterator end = m_categories.end(); + for ( QStringList::iterator it = m_categories.begin(); it != end; ++it ) + { + QListViewItem *item = findItem( *it, 0 ); + if (item) { + config->writeEntry( *it+"IsOpen", item->isOpen() ); + } + } +} + + +bool ItemSelector::readOpenState( const QString &id ) +{ + KConfig *config = kapp->config(); + config->setGroup( name() ); + + return config->readBoolEntry( id+"IsOpen", true ); +} + + +void ItemSelector::slotContextMenuRequested( QListViewItem* item, const QPoint& pos, int /*col*/ ) +{ + if ( !item || !(static_cast(item))->isRemovable() ) { + return; + } + + QPopupMenu *menu = new QPopupMenu(this); + menu->insertItem( i18n("Remove %1").arg(item->text(0)), this, SLOT(slotRemoveSelectedItem()), Qt::Key_Delete ); + menu->popup(pos); +} + + +void ItemSelector::slotRemoveSelectedItem() +{ + ILVItem *item = dynamic_cast(selectedItem()); + if (!item) + return; + + emit itemRemoved( item->key( 0, 0 ) ); + ILVItem *parent = dynamic_cast(item->QListViewItem::parent()); + delete item; + // Get rid of the category as well if it has no children + if ( parent && !parent->firstChild() ) + { + m_categories.remove(parent->text(0)); + delete parent; + } +} + + +void ItemSelector::setListCaption( const QString &caption ) +{ + setColumnText( 0, caption ); +} + + + +void ItemSelector::slotItemClicked( QListViewItem *item ) +{ + if (!item) + return; + + if ( ItemDocument * itemDocument = dynamic_cast(DocManager::self()->getFocusedDocument()) ) + itemDocument->slotUnsetRepeatedItemId(); + + emit itemClicked( item->key( 0, 0 ) ); +} + + +void ItemSelector::slotItemDoubleClicked( QListViewItem *item ) +{ + if (!item) + return; + + QString id = item->key( 0, 0 ); + + if ( Document * doc = DocManager::self()->getFocusedDocument() ) + { + if ( doc->type() == Document::dt_flowcode && id.startsWith("flow/") ) + (static_cast(doc))->slotSetRepeatedItemId(id); + + else if ( doc->type() == Document::dt_circuit && (id.startsWith("ec/") || id.startsWith("sc/")) ) + (static_cast(doc))->slotSetRepeatedItemId(id); + + else if ( doc->type() == Document::dt_mechanics && id.startsWith("mech/") ) + (static_cast(doc))->slotSetRepeatedItemId(id); + } + + emit itemDoubleClicked(id); +} + + +QDragObject* ItemSelector::dragObject() +{ + const QString id = currentItem()->key(0,0); + + QStoredDrag * d = 0l; + + if ( id.startsWith("flow/") ) + d = new QStoredDrag( "ktechlab/flowpart", this ); + + else if ( id.startsWith("ec/") ) + d = new QStoredDrag( "ktechlab/component", this ); + + else if ( id.startsWith("sc/") ) + d = new QStoredDrag( "ktechlab/subcircuit", this ); + + else if ( id.startsWith("mech/") ) + d = new QStoredDrag( "ktechlab/mechanical", this ); + + if (d) + { + QByteArray data; + QDataStream stream( data, IO_WriteOnly ); + stream << id; + d->setEncodedData(data); + } + + // A pixmap cursor is often hard to make out +// QPixmap *pixmap = const_cast(currentItem()->pixmap(0)); +// if (pixmap) d->setPixmap(*pixmap); + + return d; +} + + + +//BEGIN class ComponentSelector +ComponentSelector * ComponentSelector::m_pSelf = 0l; + + +ComponentSelector * ComponentSelector::self( KateMDI::ToolView * parent ) +{ + if (!m_pSelf) + { + assert(parent); + m_pSelf = new ComponentSelector(parent); + } + return m_pSelf; +} + + +ComponentSelector::ComponentSelector( KateMDI::ToolView * parent ) + : ItemSelector( (QWidget*)parent, "Component Selector" ) +{ + QWhatsThis::add( this, i18n( + "Add components to the circuit diagram by dragging them into the circuit.

" + + "To add more than one component of the same type, doubleclick on a component, and click repeatedly in the circuit to place the component. Right click to stop placement.

" + + "Some components (such as subcircuits) can be removed by right clicking on the item and selecting \"Remove\"." + ) ); + + setListCaption( i18n("Component") ); + + LibraryItemList *items = itemLibrary()->items(); + const LibraryItemList::iterator end = items->end(); + for ( LibraryItemList::iterator it = items->begin(); it != end; ++it ) + { + if ( (*it)->type() == LibraryItem::lit_component ) + addItem( (*it)->name(), (*it)->activeID(), (*it)->category(), (*it)->icon16() ); + } +} +//END class ComponentSelector + + + +//BEGIN class FlowPartSelector +FlowPartSelector * FlowPartSelector::m_pSelf = 0l; + + +FlowPartSelector * FlowPartSelector::self( KateMDI::ToolView * parent ) +{ + if (!m_pSelf) + { + assert(parent); + m_pSelf = new FlowPartSelector(parent); + } + return m_pSelf; +} + + +FlowPartSelector::FlowPartSelector( KateMDI::ToolView * parent ) + : ItemSelector( (QWidget*)parent, "Part Selector" ) +{ + QWhatsThis::add( this, i18n("Add FlowPart to the FlowCode document by dragging them there.

To add more than one FlowPart of the same type, doubleclick on a FlowPart, and click repeatedly in the FlowChart to place the component. Right click to stop placement.") ); + + setListCaption( i18n("Flow Part") ); + + LibraryItemList *items = itemLibrary()->items(); + const LibraryItemList::iterator end = items->end(); + for ( LibraryItemList::iterator it = items->begin(); it != end; ++it ) + { + if ( (*it)->type() == LibraryItem::lit_flowpart ) + addItem( (*it)->name(), (*it)->activeID(), (*it)->category(), (*it)->icon16() ); + } +} +//END class FlowPartSelector + + +//BEGIN class MechanicsSelector +MechanicsSelector * MechanicsSelector::m_pSelf = 0l; + + +MechanicsSelector * MechanicsSelector::self( KateMDI::ToolView * parent ) +{ + if (!m_pSelf) + { + assert(parent); + m_pSelf = new MechanicsSelector( (QWidget*)parent ); + } + return m_pSelf; +} + + +MechanicsSelector::MechanicsSelector( QWidget *parent ) + : ItemSelector( (QWidget*)parent, "Mechanics Selector" ) +{ + QWhatsThis::add( this, i18n("Add mechanical parts to the mechanics work area by dragging them there.") ); + + LibraryItemList *items = itemLibrary()->items(); + const LibraryItemList::iterator end = items->end(); + for ( LibraryItemList::iterator it = items->begin(); it != end; ++it ) + { + if ( (*it)->type() == LibraryItem::lit_mechanical ) + { + addItem( (*it)->name(), (*it)->activeID(), (*it)->category(), (*it)->icon16() ); + } + } +} +//END class MechanicsSelector + + +#include "itemselector.moc" diff --git a/src/gui/itemselector.h b/src/gui/itemselector.h new file mode 100644 index 0000000..ab9c11c --- /dev/null +++ b/src/gui/itemselector.h @@ -0,0 +1,167 @@ +/*************************************************************************** + * Copyright (C) 2003,2005 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#ifndef ITEMSELECTOR_H +#define ITEMSELECTOR_H + +#include + +#include +#include + +class ProjectItem; +class QStoredDrag; +namespace KateMDI { class ToolView; } + +/** +@short Contains info about item for ItemSelector +@author David Saxton +*/ +class ILVItem : public QObject, public KListViewItem +{ + public: + ILVItem( QListView *parent, const QString &id ); + ILVItem( QListViewItem *parent, const QString &id ); + + void setProjectItem( ProjectItem * projectItem ) { m_pProjectItem = projectItem; } + ProjectItem * projectItem() const { return m_pProjectItem; } + + QString id() const { return m_id; } + + QString key( int, bool ) const { return m_id; } + /** + * Set whether the item can be removed from the listview by the user + */ + void setRemovable( bool isRemovable ) { b_isRemovable = isRemovable; } + /** + * Whether the item can be removed from the listview by the user + */ + bool isRemovable() const { return b_isRemovable; } + + protected: + QString m_id; + bool b_isRemovable; + ProjectItem * m_pProjectItem; +}; + +/** +@short Allows selection of generic items for dragging / clicking +@author David Saxton +*/ +class ItemSelector : public KListView +{ + Q_OBJECT + public: + ItemSelector( QWidget *parent, const char *name ); + ~ItemSelector(); + /** + * Adds a listview item to the ListView + * @param caption The displayed text + * @param id A unique identification for when it is dragged or activated + * @param category The category it is in, eg "Integrated Circuits + * @param icon The icon to be displayed to the left of the text + * @param removable Whether the user can right-click on the item and select Remove + */ + void addItem( const QString & caption, const QString & id, const QString & category, const QPixmap & icon = QPixmap(), bool removable = false ); + + public slots: + virtual void slotContextMenuRequested( QListViewItem *item, const QPoint &pos, int col ); + virtual void clear(); + void slotRemoveSelectedItem(); + + signals: + /** + * Emitted when a user selects an item and removes it + */ + void itemRemoved( const QString &id ); + void itemDoubleClicked( const QString &id ); + void itemClicked( const QString &id ); + + protected: + /** + * Sets the caption of the ListView (eg 'Components' or 'Files') + */ + void setListCaption( const QString &caption ); + /** + * Writes the open status (folded or unfolded) of "parent" items in the view + * to the config file. + */ + void writeOpenStates(); + /** + * Reads the open status (folded or unfolded) of the given item. The default + * status for non-existant items is true. + */ + bool readOpenState( const QString &id ); + + private slots: + void slotItemClicked( QListViewItem *item ); + void slotItemDoubleClicked( QListViewItem *item ); + + private: + /** + * @return a dragobject encoding the currently selected component item. + */ + QDragObject * dragObject(); + + QStringList m_categories; +}; + + +/** +@short Allows selection of electrical components +@author David Saxton + */ +class ComponentSelector : public ItemSelector +{ + Q_OBJECT + public: + static ComponentSelector * self( KateMDI::ToolView * parent = 0l ); + static QString toolViewIdentifier() { return "ComponentSelector"; } + + private: + ComponentSelector( KateMDI::ToolView * parent ); + static ComponentSelector * m_pSelf; +}; + + +/** +@short Allows selection of PIC parts (eg 'Pause') +@author David Saxton + */ +class FlowPartSelector : public ItemSelector +{ + Q_OBJECT + public: + static FlowPartSelector * self( KateMDI::ToolView * parent = 0l ); + static QString toolViewIdentifier() { return "FlowPartSelector"; } + + private: + FlowPartSelector( KateMDI::ToolView * parent ); + static FlowPartSelector * m_pSelf; +}; + + +/** +@author David Saxton + */ +class MechanicsSelector : public ItemSelector +{ + Q_OBJECT + public: + static MechanicsSelector * self( KateMDI::ToolView * parent = 0l ); + static QString toolViewIdentifier() { return "MechanicsSelector"; } + + private: + MechanicsSelector( QWidget *parent = 0L ); + static MechanicsSelector * m_pSelf; +}; + + +#endif diff --git a/src/gui/linkeroptionswidget.ui b/src/gui/linkeroptionswidget.ui new file mode 100644 index 0000000..e2c48d8 --- /dev/null +++ b/src/gui/linkeroptionswidget.ui @@ -0,0 +1,179 @@ + +LinkerOptionsWidget + + + LinkerOptionsWidget + + + + 0 + 0 + 401 + 475 + + + + Linker Options + + + + unnamed + + + 0 + + + + + inhx32 + + + + + inhx8m + + + + + inhx8s + + + + + inhx16 + + + + m_pHexFormat + + + AtBottom + + + GPASM supports inhx8m, inhx8s, inhx16, and inhx32 hex file formats. This option controls which hex file format is used. + + + + + textLabel3 + + + Library Directory (-I): + + + + + m_pLibraryDir + + + + + textLabel1 + + + Hex Format (-a): + + + + + m_pOutputMap + + + &Output a map file (-m) + + + Alt+O + + + + + textLabel8 + + + Linker Script (-s): + + + + + m_pLinkerScript + + + + + m_pOther + + + + + textLabel4 + + + Other: + + + + + groupBox2 + + + Link libraries inside project + + + + unnamed + + + + + Library + + + true + + + true + + + + m_pInternalLibraries + + + NoSelection + + + LastColumn + + + 0 + + + + + + + m_pExternalLibraries + + + + + + + + + m_pHexFormat + m_pOutputMap + m_pLibraryDir + m_pLinkerScript + m_pOther + m_pInternalLibraries + + + + kcombobox.h + klineedit.h + klineedit.h + klistview.h + keditlistbox.h + klineedit.h + + diff --git a/src/gui/logicwidget.ui b/src/gui/logicwidget.ui new file mode 100644 index 0000000..18c1860 --- /dev/null +++ b/src/gui/logicwidget.ui @@ -0,0 +1,276 @@ + +LogicWidget + + + LogicWidget + + + + 0 + 0 + 338 + 347 + + + + Logic + + + + unnamed + + + 0 + + + + groupBox3 + + + Input + + + + unnamed + + + + kcfg_LogicRisingTrigger + + + 0.3 + + + 0.1 + + + 1.5 + + + V + + + 1 + + + Required voltage level before the input will be considered high. + + + + + + + + textLabel2_2 + + + Falling Trigger Threshold: + + + Required voltage level before an input will be considered low. + + + + + kcfg_LogicFallingTrigger + + + 0.2 + + + 0.1 + + + 1.6 + + + V + + + 1 + + + Required voltage level before an input will be considered low. + + + + + + + + textLabel1 + + + Rising Trigger Threshold: + + + Required voltage level before the input will be considered high. + + + + + + + groupBox4 + + + Output + + + + unnamed + + + + textLabel2 + + + Output High: + + + Voltage level for high on logic components. + + + + + kcfg_LogicOutputHigh + + + 0.5 + + + 0.1 + + + 1.6 + + + V + + + 1 + + + Voltage level for high on logic components. + + + + + + + + textLabel4 + + + High Output Impedance: + + + This is the output impedance when the output is high. + + + + + textLabel1_2 + + + Low Output Impedance: + + + This is the output impedance when the output is low. + + + + + kcfg_LogicOutputHighImpedance + + + + + + 1000000000 + + + 1 + + + 15 + + + This is the output impedance when the output is high. + + + + + + + + kcfg_LogicOutputLowImpedance + + + + + + Floating + + + 1000000000 + + + 0 + + + 0 + + + This is the output impedance when the output is low. + + + + + + + + + + textLabel2_3 + + + Here, you can configure the behaviour of logic components. + +These values will apply to all components, apart from the PIC, whose pins' impedances depend on the pin in use. + + + WordBreak|AlignVCenter + + + + + spacer10 + + + Vertical + + + Expanding + + + + 20 + 16 + + + + + + + + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + + diff --git a/src/gui/logview.cpp b/src/gui/logview.cpp new file mode 100644 index 0000000..fcb8caf --- /dev/null +++ b/src/gui/logview.cpp @@ -0,0 +1,132 @@ +/*************************************************************************** + * Copyright (C) 2003-2005 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#include "logview.h" + +#include +#include +#include +#include +#include + + +//BEGIN class LogView +LogView::LogView( KateMDI::ToolView * parent, const char *name ) + : KTextEdit( parent, name ) +{ + setReadOnly(true); + setPaper( Qt::white ); + setTextFormat( LogText ); + setWordWrap( WidgetWidth ); + + // Connect up signal emitted when the user doubleclicks on a paragraph in the log view + connect( this, SIGNAL(clicked(int,int)), this, SLOT(slotParaClicked(int,int)) ); +} + + +LogView::~LogView() +{ +} + + +void LogView::clear() +{ + m_messageInfoMap.clear(); + KTextEdit::clear(); +} + + +void LogView::addOutput( QString text, OutputType outputType, MessageInfo messageInfo ) +{ + tidyText(text); + switch(outputType) + { + case LogView::ot_important: + append( QString("%1").arg(text) ); + break; + + case LogView::ot_info: + append( QString("%1").arg(text) ); + break; + + case LogView::ot_message: + append( QString("%1").arg(text) ); + break; + + case LogView::ot_warning: + append( QString("%1").arg(text) ); + break; + + case LogView::ot_error: + append( QString("%1").arg(text) ); + break; + } + + m_messageInfoMap[ paragraphs()-1 ] = messageInfo; +} + + +void LogView::slotParaClicked( int para, int /*pos*/ ) +{ + QString t = text(para); + untidyText(t); + emit paraClicked( t, m_messageInfoMap[para] ); +} + + +void LogView::tidyText( QString &t ) +{ + t.replace( "&", "&" ); + t.replace( "<", "<" ); + t.replace( ">", ">" ); +} + + +void LogView::untidyText( QString &t ) +{ + t.replace( "<", "<" ); + t.replace( ">", ">" ); + t.replace( "&", "&" ); +} + + +QPopupMenu * LogView::createPopupMenu( const QPoint & pos ) +{ + QPopupMenu * menu = KTextEdit::createPopupMenu( pos ); + + menu->insertSeparator(); + int id = menu->insertItem( i18n("Clear All"), this, SLOT(clear()) ); + + // "an empty textedit is always considered to have one paragraph" - qt documentation + // although this does not always seem to be the case, so I don't know... + menu->setItemEnabled( id, paragraphs() > 1 ); + + return menu; +} +//END class LogView + + + +//BEGIN class MessageInfo +MessageInfo::MessageInfo() +{ + m_fileLine = -1; +} + + +MessageInfo::MessageInfo( QString fileURL, int fileLine ) +{ + m_fileURL = fileURL; + m_fileLine = fileLine; +} +//END class MessageInfo + + +#include "logview.moc" diff --git a/src/gui/logview.h b/src/gui/logview.h new file mode 100644 index 0000000..c568da8 --- /dev/null +++ b/src/gui/logview.h @@ -0,0 +1,85 @@ +/*************************************************************************** + * Copyright (C) 2003-2005 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#ifndef LOGVIEW_H +#define LOGVIEW_H + +class KTechlab; + +#include +#include + +namespace KateMDI { class ToolView; } + +class MessageInfo +{ + public: + MessageInfo(); + MessageInfo( QString fileURL, int fileLine ); + + QString fileURL() const { return m_fileURL; } + int fileLine() const { return m_fileLine; } + + protected: + QString m_fileURL; + int m_fileLine; +}; +typedef QMap MessageInfoMap; + + +/** +Base class for logviews (eg GpasmInterface) which output information, warnings, errors to a viewable log +@short Dockable logview +@author David Saxton +*/ +class LogView : public KTextEdit +{ + Q_OBJECT + public: + LogView( KateMDI::ToolView * parent, const char *name = 0 ); + ~LogView(); + + enum OutputType + { + ot_important, // Bold + ot_info, // Italic + ot_message, // Plain + ot_warning, // Grey + ot_error // Red + }; + + signals: + /** + * Emitted when the user clicks on a paragraph in the log view + */ + void paraClicked( const QString &text, MessageInfo messageInfo ); + + public slots: + virtual void clear(); + void addOutput( QString text, OutputType outputType, MessageInfo messageInfo = MessageInfo() ); + + protected: + virtual QPopupMenu * createPopupMenu( const QPoint & pos ); + /** + * Replaces "&" with &, "<" with <, etc + */ + void tidyText( QString &t ); + /** + * Replaces "<" with "<", "&" with "&", etc + */ + void untidyText( QString &t ); + + MessageInfoMap m_messageInfoMap; + + private slots: + void slotParaClicked( int para, int pos ); +}; + +#endif diff --git a/src/gui/microselectwidget.cpp b/src/gui/microselectwidget.cpp new file mode 100644 index 0000000..1c4150b --- /dev/null +++ b/src/gui/microselectwidget.cpp @@ -0,0 +1,129 @@ +/*************************************************************************** + * Copyright (C) 2005 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#include "asminfo.h" +#include "microinfo.h" +#include "microlibrary.h" +#include "microselectwidget.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +MicroSelectWidget::MicroSelectWidget( QWidget* parent, const char* name, WFlags ) + : QGroupBox( 4, Qt::Horizontal, i18n("Microprocessor"), parent, name ) +{ + m_allowedAsmSet = AsmInfo::AsmSetAll; + m_allowedGpsimSupport = m_allowedFlowCodeSupport = m_allowedMicrobeSupport = MicroInfo::AllSupport; + + if ( !name ) + setName( "MicroSelectWidget" ); + + m_pMicroFamilyLabel = new QLabel( this, "m_pMicroFamilyLabel" ); + m_pMicroFamilyLabel->setText( i18n("Family") ); + + m_pMicroFamily = new KComboBox( FALSE, this, "m_pMicroFamily" ); + m_pMicroFamily->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Preferred ); + + m_pMicroLabel = new QLabel( this, "m_pMicroLabel" ); + m_pMicroLabel->setText( i18n("Micro") ); + + m_pMicro = new KComboBox( FALSE, this, "m_pMicro" ); + m_pMicro->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Preferred ); + m_pMicro->setEditable( TRUE ); + m_pMicro->setAutoCompletion(true); + updateFromAllowed(); + setMicro("P16F84"); + connect( m_pMicroFamily, SIGNAL(activated(const QString & )), this, SLOT(microFamilyChanged(const QString& )) ); +} + + +MicroSelectWidget::~MicroSelectWidget() +{ +} + +void MicroSelectWidget::setAllowedAsmSet( unsigned allowed ) +{ + m_allowedAsmSet = allowed; + updateFromAllowed(); +} +void MicroSelectWidget::setAllowedGpsimSupport( unsigned allowed ) +{ + m_allowedGpsimSupport = allowed; + updateFromAllowed(); +} +void MicroSelectWidget::setAllowedFlowCodeSupport( unsigned allowed ) +{ + m_allowedFlowCodeSupport = allowed; + updateFromAllowed(); +} +void MicroSelectWidget::setAllowedMicrobeSupport( unsigned allowed ) +{ + m_allowedMicrobeSupport = allowed; + updateFromAllowed(); +} + + +void MicroSelectWidget::updateFromAllowed() +{ + QString oldFamily = m_pMicroFamily->currentText(); + + m_pMicroFamily->clear(); + +#define CHECK_ADD(family) if ( (m_allowedAsmSet & AsmInfo::family) && !MicroLibrary::self()->microIDs( AsmInfo::family, m_allowedGpsimSupport, m_allowedFlowCodeSupport, m_allowedMicrobeSupport ).isEmpty() ) m_pMicroFamily->insertItem( AsmInfo::setToString(AsmInfo::family) ); + CHECK_ADD(PIC12) + CHECK_ADD(PIC14) + CHECK_ADD(PIC16); +#undef CHECK_ADD + + if ( m_pMicroFamily->contains(oldFamily) ) + m_pMicroFamily->setCurrentText(oldFamily); + + microFamilyChanged(oldFamily); +} + + +void MicroSelectWidget::setMicro( const QString & id ) +{ + MicroInfo * info = MicroLibrary::self()->microInfoWithID(id); + if (!info) + return; + + m_pMicro->clear(); + m_pMicro->insertStringList( MicroLibrary::self()->microIDs( info->instructionSet()->set() ) ); + m_pMicro->setCurrentText(id); + + m_pMicroFamily->setCurrentText( AsmInfo::setToString( info->instructionSet()->set() ) ); +} + + +QString MicroSelectWidget::micro() const +{ + return m_pMicro->currentText(); +} + + +void MicroSelectWidget::microFamilyChanged( const QString & family ) +{ + QString oldID = m_pMicro->currentText(); + + m_pMicro->clear(); + m_pMicro->insertStringList( MicroLibrary::self()->microIDs( AsmInfo::stringToSet(family), m_allowedGpsimSupport, m_allowedFlowCodeSupport, m_allowedMicrobeSupport ) ); + + if ( m_pMicro->contains(oldID) ) + m_pMicro->setCurrentText(oldID); +} + +#include "microselectwidget.moc" diff --git a/src/gui/microselectwidget.h b/src/gui/microselectwidget.h new file mode 100644 index 0000000..3730c8f --- /dev/null +++ b/src/gui/microselectwidget.h @@ -0,0 +1,73 @@ +/*************************************************************************** + * Copyright (C) 2005 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#ifndef MICROSELECTWIDGET_H +#define MICROSELECTWIDGET_H + +#include + +class QVBoxLayout; +class QHBoxLayout; +class QGridLayout; +class QSpacerItem; +class QGroupBox; +class QLabel; +class KComboBox; + +/** +@author David Saxton +*/ +class MicroSelectWidget : public QGroupBox +{ + Q_OBJECT + + public: + MicroSelectWidget( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 ); + ~MicroSelectWidget(); + + void setMicro( const QString & id ); + QString micro() const; + + /** + * @see MicroLibrary::microIDs + */ + void setAllowedAsmSet( unsigned allowed ); + /** + * @see MicroLibrary::microIDs + */ + void setAllowedGpsimSupport( unsigned allowed ); + /** + * @see MicroLibrary::microIDs + */ + void setAllowedFlowCodeSupport( unsigned allowed ); + /** + * @see MicroLibrary::microIDs + */ + void setAllowedMicrobeSupport( unsigned allowed ); + + protected slots: + void microFamilyChanged( const QString & family ); + + protected: + void updateFromAllowed(); + + unsigned int m_allowedAsmSet; + unsigned int m_allowedGpsimSupport; + unsigned int m_allowedFlowCodeSupport; + unsigned int m_allowedMicrobeSupport; + + QHBoxLayout * m_pWidgetLayout; + QLabel * m_pMicroFamilyLabel; + KComboBox * m_pMicroFamily; + QLabel * m_pMicroLabel; + KComboBox * m_pMicro; +}; + +#endif diff --git a/src/gui/microsettingsdlg.cpp b/src/gui/microsettingsdlg.cpp new file mode 100644 index 0000000..c3915e8 --- /dev/null +++ b/src/gui/microsettingsdlg.cpp @@ -0,0 +1,437 @@ +/*************************************************************************** + * Copyright (C) 2003-2005 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#include "microinfo.h" +#include "microsettings.h" +#include "microsettingsdlg.h" +#include "microsettingswidget.h" +#include "micropackage.h" +#include "newpinmappingwidget.h" +#include "pinmapping.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +MicroSettingsDlg::MicroSettingsDlg( MicroSettings * microSettings, QWidget *parent, const char *name ) + : KDialogBase( parent, name, true, i18n("PIC Settings"), KDialogBase::Ok|KDialogBase::Apply|KDialogBase::Cancel, KDialogBase::Ok, true ) +{ + m_pMicroSettings = microSettings; + m_pNewPinMappingWidget = 0l; + m_pNewPinMappingDlg = 0l; + m_pWidget = new MicroSettingsWidget(this); + + QWhatsThis::add( this, i18n("This dialog allows editing of the initial properties of the PIC") ); + QWhatsThis::add( m_pWidget->portsGroupBox, i18n("Edit the initial value of the ports here. For each binary number, the order from right-to-left is pins 0 through 7.

The \"Type (TRIS)\" edit shows the initial input/output state of the ports; 1 represents an input, and 0 an output.

The \"State (PORT)\" edit shows the initial high/low state of the ports; 1 represents a high, and 0 a low.") ); + QWhatsThis::add( m_pWidget->variables, i18n("Edit the initial value of the variables here.

Note that the value of the variable can only be in the range 0->255. These variables will be initialized before any other code is executed.") ); + + + //BEGIN Initialize initial port settings + m_portNames = microSettings->microInfo()->package()->portNames(); + + m_portTypeEdit.resize( m_portNames.size(), 0 ); + m_portStateEdit.resize( m_portNames.size(), 0 ); + + uint row = 0; + QStringList::iterator end = m_portNames.end(); + for ( QStringList::iterator it = m_portNames.begin(); it != end; ++it, ++row ) + { + //BEGIN Get current Type / State text + QString portType = QString::number( microSettings->portType(*it), 2 ); + QString portState = QString::number( microSettings->portState(*it), 2 ); + + QString fill; + fill.fill( '0', 8-portType.length() ); + portType.prepend(fill); + fill.fill( '0', 8-portState.length() ); + portState.prepend(fill); + //END Get current Type / State text + + + QGroupBox * groupBox = new QGroupBox( *it, m_pWidget->portsGroupBox ); + + groupBox->setColumnLayout(0, Qt::Vertical ); + groupBox->layout()->setSpacing( 6 ); + groupBox->layout()->setMargin( 11 ); + QGridLayout * groupBoxLayout = new QGridLayout( groupBox->layout() ); + groupBoxLayout->setAlignment( Qt::AlignTop ); + + // TODO: replace this with i18n( "the type", "Type (TRIS register):" ); + groupBoxLayout->addWidget( new QLabel( i18n("Type (TRIS register):"), groupBox ), 0, 0 ); + groupBoxLayout->addWidget( new QLabel( i18n("State (PORT register):"), groupBox ), 1, 0 ); + + m_portTypeEdit[row] = new KLineEdit( portType, groupBox ); + groupBoxLayout->addWidget( m_portTypeEdit[row], 0, 1 ); + + m_portStateEdit[row] = new KLineEdit( portState, groupBox ); + groupBoxLayout->addWidget( m_portStateEdit[row], 1, 1 ); + +// (dynamic_cast(m_pWidget->portsGroupBox->layout()))->insertWidget( row, groupBox ); + (dynamic_cast(m_pWidget->portsGroupBox->layout()))->addWidget( groupBox ); + } + //END Initialize initial port settings + + + + //BEGIN Initialize initial variable settings + // Hide row headers + m_pWidget->variables->setLeftMargin(0); + + // Make columns as thin as possible + m_pWidget->variables->setColumnStretchable( 0, true ); + m_pWidget->variables->setColumnStretchable( 1, true ); + + QStringList variables = microSettings->variableNames(); + row = 0; + end = variables.end(); + for ( QStringList::iterator it = variables.begin(); it != end; ++it ) + { + VariableInfo *info = microSettings->variableInfo(*it); + if (info) + { + m_pWidget->variables->insertRows( row, 1 ); + m_pWidget->variables->setText( row, 0, *it ); + m_pWidget->variables->setText( row, 1, info->valueAsString() ); + ++row; + } + } + m_pWidget->variables->insertRows( row, 1 ); + + connect( m_pWidget->variables, SIGNAL(valueChanged(int,int)), this, SLOT(checkAddVariableRow()) ); + //END Initialize initial variable settings + + + + //BEGIN Initialize pin maps + connect( m_pWidget->pinMapAdd, SIGNAL(clicked()), this, SLOT(slotCreatePinMap()) ); + connect( m_pWidget->pinMapModify, SIGNAL(clicked()), this, SLOT(slotModifyPinMap()) ); + connect( m_pWidget->pinMapRename, SIGNAL(clicked()), this, SLOT(slotRenamePinMap()) ); + connect( m_pWidget->pinMapRemove, SIGNAL(clicked()), this, SLOT(slotRemovePinMap()) ); + + m_pinMappings = microSettings->pinMappings(); + m_pWidget->pinMapCombo->insertStringList( m_pinMappings.keys() ); + + updatePinMapButtons(); + //END Initialize pin maps + + + enableButtonSeparator( false ); + setMainWidget(m_pWidget); + m_pWidget->adjustSize(); + adjustSize(); + + connect( this, SIGNAL(applyClicked()), this, SLOT(slotSaveStuff()) ); +} + + +MicroSettingsDlg::~MicroSettingsDlg() +{ +} + + +void MicroSettingsDlg::accept() +{ + hide(); + slotSaveStuff(); + deleteLater(); +} + + +void MicroSettingsDlg::slotSaveStuff() +{ + for ( unsigned i = 0; i < m_portNames.size(); i++ ) + savePort(i); + + m_pMicroSettings->removeAllVariables(); + for ( int i=0; i< m_pWidget->variables->numRows(); i++ ) + saveVariable(i); + + m_pMicroSettings->setPinMappings( m_pinMappings ); +} + + +void MicroSettingsDlg::reject() +{ + deleteLater(); +} + + +QValidator::State MicroSettingsDlg::validatePinMapName( QString & name ) const +{ + name.replace( ' ', '_' ); + + if ( name.isEmpty() ) + return QValidator::Intermediate; + + for ( unsigned i = 0; i < name.length(); ++i ) + { + if ( !name[i].isLetterOrNumber() && name[i] != '_' ) + return QValidator::Invalid; + } + + if ( name[0].isNumber() ) + return QValidator::Intermediate; + + if ( m_pWidget->pinMapCombo->contains( name ) ) + return QValidator::Intermediate; + + return QValidator::Acceptable; +} + + +class PinMappingNameValidator : public QValidator +{ + public: + /** + * Create a validator. If oldName is not empty, then the input is + * allowed to be oldName. + */ + PinMappingNameValidator( MicroSettingsDlg * dlg, const QString & oldName = 0 ) + : QValidator(0) + { + m_pDlg = dlg; + m_oldName = oldName; + } + + virtual State validate( QString & input, int & ) const + { + if ( (!m_oldName.isEmpty()) && (input == m_oldName) ) + return QValidator::Acceptable; + + return m_pDlg->validatePinMapName( input ); + } + + protected: + MicroSettingsDlg * m_pDlg; + QString m_oldName; +}; + + +void MicroSettingsDlg::slotCheckNewPinMappingName( const QString & name ) +{ + // Validate name might change the name so that it is valid + QString newName = name; + + if ( m_pNewPinMappingWidget ) + m_pNewPinMappingDlg->enableButtonOK( validatePinMapName( newName ) == QValidator::Acceptable ); + + if ( newName != name ) + m_pNewPinMappingWidget->nameEdit->setText( newName ); +} + + +void MicroSettingsDlg::slotCreatePinMap() +{ + m_pNewPinMappingDlg = new KDialogBase( this, "New Pin Mapping Dlg", true, i18n("New Pin Mapping"), Ok | Cancel ); + m_pNewPinMappingDlg->setButtonText( Ok, i18n("Create") ); + m_pNewPinMappingWidget = new NewPinMappingWidget( m_pNewPinMappingDlg ); + m_pNewPinMappingDlg->setMainWidget( m_pNewPinMappingWidget ); + + PinMappingNameValidator * validator = new PinMappingNameValidator( this ); + m_pNewPinMappingWidget->nameEdit->setValidator( validator ); + + connect( m_pNewPinMappingWidget->nameEdit, SIGNAL(textChanged(const QString &)), this, SLOT(slotCheckNewPinMappingName(const QString &)) ); + slotCheckNewPinMappingName( 0 ); + + int accepted = m_pNewPinMappingDlg->exec(); + unsigned selectedType = m_pNewPinMappingWidget->typeCombo->currentItem(); + QString name = m_pNewPinMappingWidget->nameEdit->text(); + + delete m_pNewPinMappingDlg; + delete validator; + m_pNewPinMappingDlg = 0l; + m_pNewPinMappingWidget = 0l; + if ( accepted != QDialog::Accepted ) + return; + + PinMapping::Type type = PinMapping::Invalid; + + switch ( selectedType ) + { + case 0: + type = PinMapping::SevenSegment; + break; + + case 1: + type = PinMapping::Keypad_4x3; + break; + + case 2: + type = PinMapping::Keypad_4x4; + break; + + default: + kdError() << k_funcinfo << "Unknown selected type " << type << endl; + break; + } + + m_pinMappings[name] = PinMapping( type ); + m_pWidget->pinMapCombo->insertItem( name ); + m_pWidget->pinMapCombo->setCurrentItem( m_pWidget->pinMapCombo->count() - 1 ); + + updatePinMapButtons(); + slotModifyPinMap(); +} + + +void MicroSettingsDlg::slotRenamePinMap() +{ + KComboBox * combo = m_pWidget->pinMapCombo; + + QString oldName = combo->currentText(); + if ( oldName.isEmpty() ) + return; + + PinMappingNameValidator * validator = new PinMappingNameValidator( this, oldName ); + + bool ok = false; + QString newName = KInputDialog::getText( i18n("New Pin Map Name"), i18n("Name"), oldName, & ok, this, 0, validator ); + + delete validator; + + if ( !ok ) + return; + + if ( newName == oldName ) + return; + + m_pinMappings[ newName ] = m_pinMappings[ oldName ]; + m_pinMappings.remove( oldName ); + + combo->setCurrentText( newName ); +} + + +void MicroSettingsDlg::slotModifyPinMap() +{ + QString name = m_pWidget->pinMapCombo->currentText(); + PinMapping pinMapping = m_pinMappings[ name ]; + + PinMapEditor * pinMapEditor = new PinMapEditor( & pinMapping, m_pMicroSettings->microInfo(), this, "PinMapEditor" ); + int accepted = pinMapEditor->exec(); + + delete pinMapEditor; + + if ( accepted != QDialog::Accepted ) + return; + + m_pinMappings[ name ] = pinMapping; +} + + +void MicroSettingsDlg::slotRemovePinMap() +{ + KComboBox * combo = m_pWidget->pinMapCombo; + + QString pinMapID = combo->currentText(); + if ( pinMapID.isEmpty() ) + return; + + m_pinMappings.remove( pinMapID ); + combo->removeItem( combo->currentItem() ); + + updatePinMapButtons(); +} + + +void MicroSettingsDlg::updatePinMapButtons() +{ + bool havePinMaps = (m_pWidget->pinMapCombo->count() != 0); + + m_pWidget->pinMapModify->setEnabled( havePinMaps ); + m_pWidget->pinMapRename->setEnabled( havePinMaps ); + m_pWidget->pinMapRemove->setEnabled( havePinMaps ); +} + + +void MicroSettingsDlg::savePort( int row ) +{ + QString port = m_portNames[row]; + + int type, state; + + QString typeText = m_portTypeEdit[row]->text(); + bool typeOk = true; + if ( typeText.startsWith( "0x", false ) ) type = typeText.remove(0,2).toInt( &typeOk, 16 ); + else if ( typeText.contains( QRegExp("[^01]") ) ) type = typeText.toInt( &typeOk, 10 ); + else type = typeText.toInt( &typeOk, 2 ); + + if ( !typeOk ) + { +// KMessageBox::sorry( this, i18n("Unregnised Port Type: %1").arg(typeText) ); + return; + } + + + QString stateText = m_portStateEdit[row]->text(); + bool stateOk = true; + if ( stateText.startsWith( "0x", false ) ) state = stateText.remove(0,2).toInt( &stateOk, 16 ); + else if ( stateText.contains( QRegExp("[^01]") ) ) state = stateText.toInt( &stateOk, 10 ); + else state = stateText.toInt( &stateOk, 2 ); + + if ( !stateOk ) + { +// KMessageBox::sorry( this, i18n("Unregnised Port State: %1").arg(stateText) ); + return; + } + + m_pMicroSettings->setPortState( port, state ); + m_pMicroSettings->setPortType( port, type ); +} + + +void MicroSettingsDlg::saveVariable( int row ) +{ + QString name = m_pWidget->variables->text( row, 0 ); + if ( name.isEmpty() ) return; + + QString valueText = m_pWidget->variables->text( row, 1 ); + int value; + bool ok = true; + if ( valueText.startsWith( "0x", false ) ) value = valueText.remove(0,2).toInt( &ok, 16 ); + else value = valueText.toInt( &ok, 10 ); + + if (!ok) + { + KMessageBox::sorry( this, i18n("Invalid variable value: %1").arg(valueText) ); + return; + } + + m_pMicroSettings->setVariable( name, value, true ); + VariableInfo *info = m_pMicroSettings->variableInfo(name); + if ( info && info->valueAsString().toInt() != value ) + { +// info->setValue(value); +// info->permanent = true; + info->initAtStart = true; + } +} + + +void MicroSettingsDlg::checkAddVariableRow() +{ + int lastRow = m_pWidget->variables->numRows()-1; + if ( !m_pWidget->variables->text( lastRow, 0 ).isEmpty() ) m_pWidget->variables->insertRows( lastRow+1, 1 ); +} + + + +#include "microsettingsdlg.moc" diff --git a/src/gui/microsettingsdlg.h b/src/gui/microsettingsdlg.h new file mode 100644 index 0000000..54582dd --- /dev/null +++ b/src/gui/microsettingsdlg.h @@ -0,0 +1,105 @@ +/*************************************************************************** + * Copyright (C) 2003-2005 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#ifndef MICROSETTINGSDLG_H +#define MICROSETTINGSDLG_H + +#include + +#include +#include +#include + +class KLineEdit; +class MicroSettings; +class MicroSettingsWidget; +class NewPinMappingWidget; +class PinMapping; + +typedef QMap< QString, PinMapping > PinMappingMap; + +/** +@author David Saxton +*/ +class MicroSettingsDlg : public KDialogBase +{ + Q_OBJECT + public: + MicroSettingsDlg( MicroSettings *_microSettings, QWidget *parent = 0L, const char *name = 0L ); + ~MicroSettingsDlg(); + + void reject(); + void accept(); + + /** + * @param pinMapName the pinMapName; may be changed to make it valid + * (e.g. spaces replaced with underscores). + * @returns Invalid for a pinMapName containing a non-variable name, + * Intermediate for a pinMapName that starts with a number or is already + * in use, and Acceptable otherwise. + */ + QValidator::State validatePinMapName( QString & pinMapName ) const; + + public slots: + /** + * Saves the port details in the given row to the MicroSettings class. + * Usually called when the value is changed, or on 'Apply' of the + * dialog. + */ + void savePort( int row ); + /** + * Saves the variable details to the MicroSettings class. + */ + void saveVariable( int row ); + /** + * Adds an extra row to the list of variable if one is required. + */ + void checkAddVariableRow(); + /** + * Called when the pinMapAdd button is pressed. + */ + void slotCreatePinMap(); + /** + * Called when the pinMapModify button is pressed. + */ + void slotModifyPinMap(); + /** + * Called when the pinMapRename button is pressed. + */ + void slotRenamePinMap(); + /** + * Called when the pinMapRemove button is pressed. + */ + void slotRemovePinMap(); + /** + * Called when the dialog is Applied or OK'd. + */ + void slotSaveStuff(); + + protected slots: + void slotCheckNewPinMappingName( const QString & name ); + + protected: + /** + * Set each button enabled / disabled as appropriate. + */ + void updatePinMapButtons(); + + NewPinMappingWidget * m_pNewPinMappingWidget; // Used for checking that the variable name is ok + KDialogBase * m_pNewPinMappingDlg; + MicroSettingsWidget * m_pWidget; + MicroSettings * m_pMicroSettings; + PinMappingMap m_pinMappings; + QValueVector< KLineEdit * > m_portTypeEdit; + QValueVector< KLineEdit * > m_portStateEdit; + QStringList m_portNames; +}; + +#endif diff --git a/src/gui/microsettingswidget.ui b/src/gui/microsettingswidget.ui new file mode 100644 index 0000000..5c63a1b --- /dev/null +++ b/src/gui/microsettingswidget.ui @@ -0,0 +1,197 @@ + +MicroSettingsWidget + + + MicroSettingsWidget + + + + 0 + 0 + 447 + 401 + + + + + 1 + 1 + 0 + 0 + + + + PIC Settings + + + + unnamed + + + 0 + + + + portsGroupBox + + + Initial Port Settings + + + + unnamed + + + + textLabel1 + + + + 3 + 1 + 0 + 0 + + + + Tip: Toggle the initial state (high/low) of a pin by clicking its picture. +Drag it to set the type (input/output). + + + PlainText + + + + + + + groupBox6 + + + + 1 + 1 + 0 + 0 + + + + Initial Variable Values + + + + unnamed + + + + + Variable + + + + + Value + + + + variables + + + + 0 + 64 + + + + 0 + + + 2 + + + + + + + groupBox3 + + + Pin Map Definitions + + + + unnamed + + + + pinMapCombo + + + + + pinMapRemove + + + Remove + + + + + spacer3 + + + Horizontal + + + Expanding + + + + 60 + 20 + + + + + + pinMapAdd + + + Create + + + + + pinMapModify + + + Modif&y + + + Alt+Y + + + + + pinMapRename + + + Rename + + + + + + + + + + + + kcombobox.h + kpushbutton.h + kpushbutton.h + kpushbutton.h + kpushbutton.h + + diff --git a/src/gui/newfiledlg.cpp b/src/gui/newfiledlg.cpp new file mode 100644 index 0000000..485b3bf --- /dev/null +++ b/src/gui/newfiledlg.cpp @@ -0,0 +1,151 @@ +/*************************************************************************** + * Copyright (C) 2003-2005 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#include "config.h" +#include "document.h" +#include "microinfo.h" +#include "newfiledlg.h" +#include "newfilewidget.h" +#include "microlibrary.h" +#include "microselectwidget.h" +#include "projectmanager.h" +#include "textdocument.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + + +NewFileDlg::NewFileDlg( QWidget *parent ) + : KDialogBase( parent, "newfiledlg", true, "New File", KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Ok, true ) +{ + m_pMainParent = parent; + m_bAccepted = false; + m_pNewFileWidget = new NewFileWidget(this); + + m_pNewFileWidget->typeIconView->setSelectionMode(QIconView::Single); + m_pNewFileWidget->typeIconView->setMode(KIconView::Select); + + KIconLoader *loader = KGlobal::iconLoader(); + + QValueList items; + + items << new QIconViewItem(m_pNewFileWidget->typeIconView,"Assembly Code (.asm)", loader->loadIcon( "source", KIcon::NoGroup, KIcon::SizeHuge ) ); + items << new QIconViewItem(m_pNewFileWidget->typeIconView,"C (.c)", loader->loadIcon( "source_c", KIcon::NoGroup, KIcon::SizeHuge ) ); + items << new QIconViewItem(m_pNewFileWidget->typeIconView,"Circuit (.circuit)", loader->loadIcon( "ktechlab_circuit", KIcon::NoGroup, KIcon::SizeHuge ) ); + items << new QIconViewItem(m_pNewFileWidget->typeIconView,"FlowCode (.flowcode)", loader->loadIcon( "ktechlab_flowcode", KIcon::NoGroup, KIcon::SizeHuge ) ); +#ifdef MECHANICS + items << new QIconViewItem(m_pNewFileWidget->typeIconView,"Mechanics (.mechanics)", loader->loadIcon( "exec", KIcon::NoGroup, KIcon::SizeHuge ) ); +#endif + items << new QIconViewItem(m_pNewFileWidget->typeIconView,"Microbe (.microbe)", loader->loadIcon( "ktechlab_microbe", KIcon::NoGroup, KIcon::SizeHuge ) ); + + unsigned minWidth = 20 + m_pNewFileWidget->typeIconView->spacing() * items.size(); + int minHeight = 0; + + const QValueList::iterator end = items.end(); + for ( QValueList::iterator it = items.begin(); it != end; ++it ) + { + (*it)->setDragEnabled(false); + minWidth += (*it)->width(); + minHeight = QMAX( minHeight, (*it)->height()+20 ); + } + + m_pNewFileWidget->typeIconView->setMinimumSize( minWidth, minHeight ); + m_pNewFileWidget->typeIconView->setCurrentItem(items[3]); + m_pNewFileWidget->addToProjectCheck->setChecked( ProjectManager::self()->currentProject() ); + m_pNewFileWidget->addToProjectCheck->setEnabled( ProjectManager::self()->currentProject() ); + microSelectWidget()->setAllowedFlowCodeSupport( MicroInfo::FullSupport | MicroInfo::PartialSupport ); + + setMainWidget(m_pNewFileWidget); + + // Our behaviour is to have single click selects and double click accepts the dialog + connect( m_pNewFileWidget->typeIconView, SIGNAL(selectionChanged(QIconViewItem*)), this, SLOT(fileTypeChanged(QIconViewItem*)) ); + connect( m_pNewFileWidget->typeIconView, SIGNAL(doubleClicked(QIconViewItem*)), this, SLOT(accept())); + + setAcceptDrops(true); + + m_pNewFileWidget->typeIconView->adjustSize(); + m_pNewFileWidget->adjustSize(); + adjustSize(); +} + +void NewFileDlg::accept() +{ + hide(); + m_bAccepted = true; + + const QString fileText = m_pNewFileWidget->typeIconView->currentItem()->text(); + + if ( fileText.contains(".flowcode") ) + m_fileType = Document::dt_flowcode; + + else if ( fileText.contains(".circuit") ) + m_fileType = Document::dt_circuit; + + else if ( fileText.contains(".mechanics") ) + m_fileType = Document::dt_mechanics; + + else if ( fileText.contains(".asm") ) + { + m_fileType = Document::dt_text; + m_codeType = TextDocument::ct_asm; + } + + else if ( fileText.contains(".basic") || fileText.contains(".microbe") ) + { + m_fileType = Document::dt_text; + m_codeType = TextDocument::ct_microbe; + } + + else if (fileText.contains(".c") ) + { + m_fileType = Document::dt_text; + m_codeType = TextDocument::ct_c; + } + + else + m_fileType = Document::dt_text; + + m_bAddToProject = m_pNewFileWidget->addToProjectCheck->isChecked(); + + m_microID = m_pNewFileWidget->m_pMicroSelect->micro(); +} + + +void NewFileDlg::reject() +{ + m_bAccepted = false; +} + + +void NewFileDlg::fileTypeChanged( QIconViewItem *item ) +{ + m_pNewFileWidget->m_pMicroSelect->setEnabled( + item->text().contains(".flowcode") ); +} + + +MicroSelectWidget * NewFileDlg::microSelectWidget() const +{ + return m_pNewFileWidget->m_pMicroSelect; +} + + +#include "newfiledlg.moc" diff --git a/src/gui/newfiledlg.h b/src/gui/newfiledlg.h new file mode 100644 index 0000000..fc20800 --- /dev/null +++ b/src/gui/newfiledlg.h @@ -0,0 +1,55 @@ +/*************************************************************************** + * Copyright (C) 2003-2005 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#ifndef NEWFILEDLG_H +#define NEWFILEDLG_H + +#include + +class MicroSelectWidget; +class NewFileWidget; +class QIconViewItem; + +/** +A standard dialog for getting file details from the user for a new project +@short Dialog for new file details +@author David Saxton +*/ +class NewFileDlg : public KDialogBase +{ + Q_OBJECT + public: + NewFileDlg( QWidget *parent ); + + void reject(); + void accept(); + + bool accepted() const { return m_bAccepted; } + int fileType() const { return m_fileType; } + int codeType() const { return m_codeType; } + bool addToProject() const { return m_bAddToProject; } + QString microID() const { return m_microID; } + MicroSelectWidget * microSelectWidget() const; + + public slots: + void fileTypeChanged( QIconViewItem *item ); + + protected: + bool m_bAccepted; + int m_fileType; + int m_codeType; + bool m_bAddToProject; + QString m_microID; + + NewFileWidget * m_pNewFileWidget; + QWidget * m_pMainParent; +}; + +#endif diff --git a/src/gui/newfilewidget.ui b/src/gui/newfilewidget.ui new file mode 100644 index 0000000..0e02524 --- /dev/null +++ b/src/gui/newfilewidget.ui @@ -0,0 +1,195 @@ + +NewFileWidget + + + NewFileWidget + + + + 0 + 0 + 600 + 213 + + + + New File + + + Select the type of file you wish to create.<br> +<p> +<b>Pic Program</b><br> +Creates a new PIC program, with flow chart editor. Select the target device for your program below. +<p> +<b>Circuit</b><br> +Creates a new circuit, with drag and drop editor. Real time simulation of the circuit occurs automatically. + + + + unnamed + + + 0 + + + + textLabel1 + + + + 5 + 4 + 0 + 0 + + + + + 1 + + + + New File Details + + + + + textLabel1_2_2 + + + File Type: + + + AlignVCenter + + + + + typeIconView + + + + 1 + 1 + 0 + 0 + + + + + 500 + 150 + + + + false + + + AutoOneFit + + + true + + + false + + + + + addToProjectCheck + + + + 1 + 0 + 0 + 0 + + + + &Add to project + + + Alt+A + + + true + + + + + m_pMicroSelect + + + + 5 + 5 + 0 + 0 + + + + + 0 + 0 + + + + + 32767 + 32767 + + + + + + spacer1 + + + Vertical + + + Expanding + + + + 20 + 0 + + + + + + + + MicroSelectWidget +
microselectwidget.h
+ + -1 + -1 + + 0 + + 5 + 5 + 0 + 0 + + image0 +
+
+ + + 89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000042949444154388db5954d6c545514c77ff7de37eff1a6a550da994e5ba798868f948fc847a2a2911816c436b0a02ed0083161a1981877ee10d90aa94656063491882c5cd4c4b8103f20cd806909a98604da8482341de80cb69de9bcd799799d79efba980f1da3a80b4f727273939bdff99f9b93f3175a6b6a21849080020c4002a29a8f0a5dcd002803bed63a1035f0d0d0504b6f6fef51d7758fa4d3e98d8ee3fc03af128ee3303939399548242eb8aefb09300f78464de9f0f0f0d148cc7caf3d5424de97a7ec17104220242805520a44557bbd4b21f083801d33e63a6d1bc7bf19c6064e0319a35a58b9ae7ba43d54e4d7c54b64dc097c7f09d30ef04b36736983cc7c11b4456b9b492c5e20dc54a6540e00896a8268a7017010f8bcae1830d2e9f4c69ebe3c197782b2ce60d94ddc9b30f9feeb45ae5d7181c5ead35636ef08d3ffe26a76ee3208b4031a56d80aa00768fda362e9380e25bf80ef3b587613d7afc099533380a4b5dda46fcb5aa42998b9eb7173dce5e6788e434763ec7fc942532008ea436003660d2caa7f8d69c3bd8910674e4d033e83877ad8d36fb0aa4d6058658ac5358c5df6383bf480f31fdda5a3632bbbfb6da4ccd5c00a10b2012cc12fd97cfb5516f0187c25cee0619396480ec3ca909d0f3372d1e5f9fe66de3ad605587c712ec55256a2540d5519d19ae24a29057329839f7ecc138944d833102290f3184ae1e6d6f0e98739c61229e6d21eafbed1c9c8c5558c8f3ee4ceed76946a1c43d97091828585223e2eebfbc295f60d45de89707628cb58224577bc85a79e5d4d786581cddb9b0148259711b20145836221400416e0232d1f6595c9ce4538773ac7b54406f0b15784e8e80aa1ac2594190220d021e49f2437960156b70ba095e95f96f18acd8c263cc6122962b1167a7ba34cdd7ec8c977a699bed546722a8fc2a02b6e2185fff78ab586ce78894ddb9ab9f5738ed14b1e030756929d8ff2e4ae5544632b38f96e89a99b298ebd6950cc2d12ed0eb3618b26f520788462ad09877df60db600f0f1fb49c646f21c7ebd836dcf94e9d9b4c0db27d6d3bd36c6426a96bce731703046d7da129a4670836284a054869d4f1b1c7e2dca67676ef3c1898091ef5ad8bc358c3205c93bf7c9a40ad4c660f4728edd7bbb3142ea2fc1da711cfc200011e08b45f6bd1c261adbce9717928c5f9d63fc6a19f0014567773303073790f8214bd6f5282dfbb8b9fa1f6b40d7c1939393533b92e63ad9240990484aec7e41b27d579cbb531e0f67023492d86316ebb768ba1e0f786e6f37e56550c62237aee7011e54abd7c1412291b8a06de378b4d3c0b215da9708e5a3a442192085404a83d4accfecac067c0c43e13a70e3fa12e96409e0325000966bbb354465339d04a6f9dd15fe6dde07ce030780278088d05ad72cc9a6b2f2daaaa74d75a1f0e8d0d5f60b40868a8364ead6248430000b0857a126ffcdf396abf03ce089ffcb4c7f033046c6b4a995e7a00000000049454e44ae426082 + + + + typeIconView + addToProjectCheck + + + + kiconview.h + microselectwidget.h + +
diff --git a/src/gui/newpinmappingwidget.ui b/src/gui/newpinmappingwidget.ui new file mode 100644 index 0000000..4ac5932 --- /dev/null +++ b/src/gui/newpinmappingwidget.ui @@ -0,0 +1,130 @@ + +NewPinMappingWidget + + + NewPinMappingWidget + + + + 0 + 0 + 350 + 80 + + + + New Pin Mapping + + + + unnamed + + + 0 + + + + textLabel2 + + + Type: + + + + + textLabel1 + + + Name: + + + + + textLabel3 + + + + 1 + + + + New Pin Mapping + + + PlainText + + + + + spacer6 + + + Vertical + + + Expanding + + + + 20 + 21 + + + + + + nameEdit + + + + 3 + 0 + 0 + 0 + + + + + 300 + 0 + + + + The variable name of the pin mapping - this must be a valid Microbe variable name. + + + + + + Seven Segment + + + + + Keypad (4x3) + + + + + Keypad (4x4) + + + + typeCombo + + + + 200 + 0 + + + + + + + + + + klineedit.h + + diff --git a/src/gui/newprojectwidget.ui b/src/gui/newprojectwidget.ui new file mode 100644 index 0000000..9d8648f --- /dev/null +++ b/src/gui/newprojectwidget.ui @@ -0,0 +1,110 @@ + +NewProjectWidget + + + NewProjectWidget + + + + 0 + 0 + 532 + 103 + + + + New Project + + + + unnamed + + + 0 + + + + textLabel8 + + + Final location: + + + + + locationLabel + + + / + + + + + spacer2 + + + Vertical + + + Expanding + + + + 20 + 16 + + + + + + textLabel4 + + + Location: + + + + + textLabel1 + + + + 1 + + + + New Project Details + + + + + textLabel10 + + + Project Name: + + + + + projectNameEdit + + + + + projectLocationURL + + + + + + projectNameEdit + projectLocationURL + + + + klineedit.h + kurlrequester.h + klineedit.h + kpushbutton.h + + diff --git a/src/gui/orientationwidget.cpp b/src/gui/orientationwidget.cpp new file mode 100644 index 0000000..28e10c7 --- /dev/null +++ b/src/gui/orientationwidget.cpp @@ -0,0 +1,255 @@ +/*************************************************************************** + * Copyright (C) 2003-2004 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#include "cnitem.h" +#include "cnitemgroup.h" +#include "component.h" +#include "flowpart.h" +#include "iteminterface.h" +#include "itemlibrary.h" +#include "orientationwidget.h" +#include "node.h" + +#include +#include +#include +#include +#include +#include +#include + +const int _size = 44; + +OrientationWidget::OrientationWidget(QWidget *parent, const char *name) + : QWidget(parent, name) +{ + QGridLayout *layout = new QGridLayout( this, 2, 4, 0, 4 ); + p_activeFlowPart = 0l; + + for ( int row=0; row<2; ++row ) + { + for ( int col=0; col<4; ++col ) + { + QPushButton *btn = new QPushButton(this); + m_toolBtn[row][col] = btn; + layout->addWidget( btn, row, col ); + btn->setFixedSize( _size+6, _size+6 ); +// btn->setFlat(true); + btn->setEnabled(false); + } + } + + connect( m_toolBtn[0][0], SIGNAL(clicked()), this, SLOT(set_cio_noflip_0()) ); + connect( m_toolBtn[0][1], SIGNAL(clicked()), this, SLOT(set_cio_noflip_90()) ); + connect( m_toolBtn[0][2], SIGNAL(clicked()), this, SLOT(set_cio_noflip_180()) ); + connect( m_toolBtn[0][3], SIGNAL(clicked()), this, SLOT(set_cio_noflip_270()) ); + connect( m_toolBtn[1][0], SIGNAL(clicked()), this, SLOT(set_cio_flip_0()) ); + connect( m_toolBtn[1][1], SIGNAL(clicked()), this, SLOT(set_cio_flip_90()) ); + connect( m_toolBtn[1][2], SIGNAL(clicked()), this, SLOT(set_cio_flip_180()) ); + connect( m_toolBtn[1][3], SIGNAL(clicked()), this, SLOT(set_cio_flip_270()) ); +} + + +OrientationWidget::~OrientationWidget() +{ +} + +void OrientationWidget::slotUpdate( CNItem *activeCNItem ) +{ + p_activeFlowPart = dynamic_cast(activeCNItem); + if (p_activeFlowPart) + { + initFromFlowPart(p_activeFlowPart); + return; + } + + Component *activeComponent = dynamic_cast(activeCNItem); + + if ( activeComponent && (activeComponent->canRotate() || activeComponent->canFlip()) ) + { + initFromComponent(activeComponent); + return; + } + + slotClear(); +} + + +void OrientationWidget::initFromFlowPart( FlowPart *flowPart ) +{ + if (!flowPart) + return; + + uint valid = flowPart->allowedOrientations(); + +// m_toolBtn[0][0]->setText("b00"); + for ( uint i=0; i<2; ++i ) + { + for ( uint j=0; j<4; ++j ) + { + uint o = j + 4*i; + if ( valid & (1<setEnabled(true); + QPixmap pm( 50, 50 ); + flowPart->orientationPixmap( o, pm ); + m_toolBtn[i][j]->setPixmap(pm); + } + } + } +} + + +void OrientationWidget::initFromComponent( Component *component ) +{ + const QImage im = itemLibrary()->itemImage(component); + + QRect bound = component->boundingRect(); + + // We want a nice square bounding rect + const int dy = bound.width() - bound.height(); + if ( dy > 0 ) + { + bound.setTop( bound.top()-(dy/2) ); + bound.setBottom( bound.bottom()+(dy/2) ); + } + else if ( dy < 0 ) + { + bound.setLeft( bound.left()+(dy/2) ); + bound.setRight( bound.right()-(dy/2) ); + } + + + QPixmap tbPm; + tbPm.convertFromImage(im); + m_toolBtn[0][0]->setPixmap(tbPm); + m_toolBtn[0][0]->setEnabled(true); + + if ( component->canRotate() ) + { +// QPixmap tbPm; + tbPm.convertFromImage( im.xForm( Component::transMatrix( 90, false, bound.width()/2, bound.height()/2 ) ) ); + m_toolBtn[0][1]->setPixmap(tbPm); + m_toolBtn[0][1]->setEnabled(true); + +// QPixmap tbPm; + tbPm.convertFromImage( im.xForm( Component::transMatrix( 180, false, bound.width()/2, bound.height()/2 ) ) ); + m_toolBtn[0][2]->setPixmap(tbPm); + m_toolBtn[0][2]->setEnabled(true); + +// QPixmap tbPm; + tbPm.convertFromImage( im.xForm( Component::transMatrix( 270, false, bound.width()/2, bound.height()/2 ) ) ); + m_toolBtn[0][3]->setPixmap(tbPm); + m_toolBtn[0][3]->setEnabled(true); + } + + if ( component->canFlip() ) + { +// QPixmap tbPm; + tbPm.convertFromImage( im.xForm( Component::transMatrix( 0, true, bound.width()/2, bound.height()/2 ) ) ); + m_toolBtn[1][0]->setPixmap(tbPm); + m_toolBtn[1][0]->setEnabled(true); + + if ( component->canRotate() ) + { +// QPixmap tbPm; + tbPm.convertFromImage( im.xForm( Component::transMatrix( 90, true, bound.width()/2, bound.height()/2 ) ) ); + m_toolBtn[1][1]->setPixmap(tbPm); + m_toolBtn[1][1]->setEnabled(true); + +// QPixmap tbPm; + tbPm.convertFromImage( im.xForm( Component::transMatrix( 180, true, bound.width()/2, bound.height()/2 ) ) ); + m_toolBtn[1][2]->setPixmap(tbPm); + m_toolBtn[1][2]->setEnabled(true); + +// QPixmap tbPm; + tbPm.convertFromImage( im.xForm( Component::transMatrix( 270, true, bound.width()/2, bound.height()/2 ) ) ); + m_toolBtn[1][3]->setPixmap(tbPm); + m_toolBtn[1][3]->setEnabled(true); + } + } +} + + +void OrientationWidget::slotClear() +{ + for ( int row=0; row<2; ++row ) + { + for ( int col=0; col<4; ++col ) + { + // Hmm...this line has crashed before + m_toolBtn[row][col]->setPixmap( QPixmap::QPixmap() ); + m_toolBtn[row][col]->setEnabled(false); + } + } +} + + +void OrientationWidget::set_cio_noflip_0() +{ + if (p_activeFlowPart) + ItemInterface::self()->setFlowPartOrientation(0); + else + ItemInterface::self()->setComponentOrientation( 0, false ); +} +void OrientationWidget::set_cio_noflip_90() +{ + if (p_activeFlowPart) + ItemInterface::self()->setFlowPartOrientation(1); + else + ItemInterface::self()->setComponentOrientation( 90, false ); +} +void OrientationWidget::set_cio_noflip_180() +{ + if (p_activeFlowPart) + ItemInterface::self()->setFlowPartOrientation(2); + else + ItemInterface::self()->setComponentOrientation( 180, false ); +} +void OrientationWidget::set_cio_noflip_270() +{ + if (p_activeFlowPart) + ItemInterface::self()->setFlowPartOrientation(3); + else + ItemInterface::self()->setComponentOrientation( 270, false ); +} +void OrientationWidget::set_cio_flip_0() +{ + if (p_activeFlowPart) + ItemInterface::self()->setFlowPartOrientation(4); + else + ItemInterface::self()->setComponentOrientation( 0, true ); +} +void OrientationWidget::set_cio_flip_90() +{ + if (p_activeFlowPart) + ItemInterface::self()->setFlowPartOrientation(5); + else + ItemInterface::self()->setComponentOrientation( 90, true ); +} +void OrientationWidget::set_cio_flip_180() +{ + if (p_activeFlowPart) + ItemInterface::self()->setFlowPartOrientation(6); + else + ItemInterface::self()->setComponentOrientation( 180, true ); +} +void OrientationWidget::set_cio_flip_270() +{ + if (p_activeFlowPart) + ItemInterface::self()->setFlowPartOrientation(7); + else + ItemInterface::self()->setComponentOrientation( 270, true ); +} + +#include "orientationwidget.moc" + + + diff --git a/src/gui/orientationwidget.h b/src/gui/orientationwidget.h new file mode 100644 index 0000000..6a6b6ce --- /dev/null +++ b/src/gui/orientationwidget.h @@ -0,0 +1,56 @@ +/*************************************************************************** + * Copyright (C) 2003-2004 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#ifndef ORIENTATIONWIDGET_H +#define ORIENTATIONWIDGET_H + +#include +#include + +class CNItem; +class CNItemGroup; +class FlowPart; +class QPushButton; + +/** +@author David Saxton +*/ +class OrientationWidget : public QWidget +{ +Q_OBJECT +public: + OrientationWidget( QWidget *parent = 0l, const char *name = 0l ); + ~OrientationWidget(); + +public slots: + void slotUpdate( CNItem *item ); + void slotClear(); + + void set_cio_noflip_0(); + void set_cio_noflip_90(); + void set_cio_noflip_180(); + void set_cio_noflip_270(); + void set_cio_flip_0(); + void set_cio_flip_90(); + void set_cio_flip_180(); + void set_cio_flip_270(); + +signals: + void orientationSelected( uint orientation ); + +protected: + void initFromComponent( Component *component ); + void initFromFlowPart( FlowPart *flowPart ); + + QPushButton *m_toolBtn[2][4]; + QGuardedPtr p_activeFlowPart; +}; + +#endif diff --git a/src/gui/oscilloscope.cpp b/src/gui/oscilloscope.cpp new file mode 100644 index 0000000..e969f72 --- /dev/null +++ b/src/gui/oscilloscope.cpp @@ -0,0 +1,354 @@ +/*************************************************************************** + * Copyright (C) 2005 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#include "oscilloscope.h" +#include "oscilloscopedata.h" +#include "oscilloscopeview.h" +#include "probe.h" +#include "probepositioner.h" +#include "simulator.h" +#include "ktechlab.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +//BEGIN Oscilloscope Class +QColor probeColors[9] = { + QColor( 0x52, 0x22, 0x00 ), + QColor( 0xB5, 0x00, 0x2F ), + QColor( 0xF9, 0xBA, 0x07 ), + QColor( 0x53, 0x93, 0x16 ), + QColor( 0x00, 0x66, 0x2F ), + QColor( 0x00, 0x41, 0x88 ), + QColor( 0x1B, 0x2D, 0x83 ), + QColor( 0x55, 0x12, 0x7B ), + QColor( 0x7B, 0x0C, 0x82 ) }; + +Oscilloscope * Oscilloscope::m_pSelf = 0l; + +Oscilloscope * Oscilloscope::self( KateMDI::ToolView * parent ) +{ + if ( !m_pSelf ) + { + assert(parent); + m_pSelf = new Oscilloscope(parent); + } + return m_pSelf; +} + + +Oscilloscope::Oscilloscope( KateMDI::ToolView * parent ) + : OscilloscopeWidget(parent) +{ + m_nextColor = 0; + m_nextId = 1; + m_oldestId = -1; + m_oldestProbe = 0l; +// b_isPaused = false; + m_zoomLevel = 0.5; + m_pSimulator = Simulator::self(); + + horizontalScroll->setLineStep(32); + horizontalScroll->setPageStep( oscilloscopeView->width() ); + + connect( resetBtn, SIGNAL(clicked()), this, SLOT(reset()) ); + connect( zoomSlider, SIGNAL(valueChanged(int)), this, SLOT(slotZoomSliderChanged(int)) ); + connect( horizontalScroll, SIGNAL(valueChanged(int )), this, SLOT(slotSliderValueChanged(int )) ); + +// connect( pauseBtn, SIGNAL(clicked()), this, SLOT(slotTogglePause()) ); + + QTimer * updateScrollTmr = new QTimer(this); + connect( updateScrollTmr, SIGNAL(timeout()), this, SLOT(updateScrollbars()) ); + updateScrollTmr->start(20); + + KGlobal::config()->setGroup("Oscilloscope"); + setZoomLevel( KGlobal::config()->readDoubleNumEntry( "ZoomLevel", 0.5 ) ); + + connect( this, SIGNAL(probeRegistered(int, ProbeData *)), probePositioner, SLOT(slotProbeDataRegistered(int, ProbeData *)) ); + connect( this, SIGNAL(probeUnregistered(int )), probePositioner, SLOT(slotProbeDataUnregistered(int )) ); +} + + +Oscilloscope::~Oscilloscope() +{ +} + + +void Oscilloscope::slotTogglePause() +{ +// b_isPaused = !b_isPaused; +// pauseBtn->setText( b_isPaused ? i18n("Resume") : i18n("Pause") ); +// const ProbeDataMap::iterator end = m_probeDataMap.end(); +// for ( ProbeDataMap::iterator it = m_probeDataMap.begin(); it != end; ++it ) +// (*it)->setPaused(b_isPaused); +} + + +int Oscilloscope::sliderTicksPerSecond() const +{ + return int(1e4); +} + + +void Oscilloscope::setZoomLevel( double zoomLevel ) +{ + if ( zoomLevel < 0.0 ) + zoomLevel = 0.0; + + else if ( zoomLevel > 1.0 ) + zoomLevel = 1.0; + + KGlobal::config()->setGroup("Oscilloscope"); + KGlobal::config()->writeEntry( "ZoomLevel", zoomLevel ); + + // We want to maintain the position of the *center* of the view, not the + // left edge, so have to record time at center of view... We also have to + // handle the case where the scroll is at the end separately. + bool wasAtUpperEnd = horizontalScroll->maxValue() == horizontalScroll->value(); + int pageLength = int(oscilloscopeView->width()*sliderTicksPerSecond()/pixelsPerSecond()); + int at_ticks = horizontalScroll->value() + (pageLength/2); + + m_zoomLevel = zoomLevel; + zoomSlider->setValue( int((double(zoomSlider->maxValue())*zoomLevel)+0.5) ); + updateScrollbars(); + + // And restore the center position of the slider + if (!wasAtUpperEnd) + { + int pageLength = int(oscilloscopeView->width()*sliderTicksPerSecond()/pixelsPerSecond()); + horizontalScroll->setValue( at_ticks - (pageLength/2) ); + oscilloscopeView->updateView(); + } +} + + +void Oscilloscope::slotZoomSliderChanged( int value ) +{ + setZoomLevel( double(value)/double(zoomSlider->maxValue()) ); +} + + +ProbeData * Oscilloscope::registerProbe( Probe * probe ) +{ + if (!probe) + return 0l; + + const uint id = m_nextId++; + + ProbeData * probeData = 0l; + + if ( dynamic_cast(probe) ) + { + probeData = new LogicProbeData(id); + m_logicProbeDataMap[id] = static_cast(probeData); + } + + else + { + probeData = new FloatingProbeData(id); + m_floatingProbeDataMap[id] = static_cast(probeData); + } + + m_probeDataMap[id] = probeData; + + if (!m_oldestProbe) + { + m_oldestProbe = probeData; + m_oldestId = id; + } + + probeData->setColor( probeColors[m_nextColor] ); + m_nextColor = (m_nextColor+1)%9; +// probeData->setPaused(b_isPaused); + + emit probeRegistered( id, probeData ); + return probeData; +} + + +void Oscilloscope::unregisterProbe( int id ) +{ + ProbeDataMap::iterator it = m_probeDataMap.find(id); + + if ( it == m_probeDataMap.end() ) + return; + + m_logicProbeDataMap.remove(id); + m_floatingProbeDataMap.remove(id); + + bool oldestDestroyed = it.data() == m_oldestProbe; + + if ( it != m_probeDataMap.end() ) + m_probeDataMap.erase(it); + + if (oldestDestroyed) + getOldestProbe(); + + emit probeUnregistered(id); +} + + +ProbeData * Oscilloscope::probeData( int id ) const +{ + const ProbeDataMap::const_iterator bit = m_probeDataMap.find(id); + if ( bit != m_probeDataMap.end() ) + return bit.data(); + + return 0l; +} + + +int Oscilloscope::probeNumber( int id ) const +{ + const ProbeDataMap::const_iterator end = m_probeDataMap.end(); + int i=0; + for ( ProbeDataMap::const_iterator it = m_probeDataMap.begin(); it != end; ++it ) + { + if ( it.key() == id ) + return i; + i++; + } + return -1; +} + + +int Oscilloscope::numberOfProbes() const +{ + return m_probeDataMap.size(); +} + + +void Oscilloscope::getOldestProbe() +{ + if ( m_probeDataMap.isEmpty() ) + { + m_oldestProbe = 0l; + m_oldestId = -1; + return; + } + + m_oldestProbe = m_probeDataMap.begin().data(); + m_oldestId = m_probeDataMap.begin().key(); +} + + +void Oscilloscope::reset() +{ + const ProbeDataMap::iterator end = m_probeDataMap.end(); + for ( ProbeDataMap::iterator it = m_probeDataMap.begin(); it != end; ++it ) + (*it)->eraseData(); + + oscilloscopeView->updateView(); +} + + +void Oscilloscope::slotSliderValueChanged( int value ) +{ + Q_UNUSED(value); + oscilloscopeView->updateView(); +} + + +void Oscilloscope::updateScrollbars() +{ + bool wasAtUpperEnd = horizontalScroll->maxValue() == horizontalScroll->value(); + + const float pps = pixelsPerSecond(); + + int pageLength = int(oscilloscopeView->width()*sliderTicksPerSecond()/pps); + llong timeAsTicks = time()*sliderTicksPerSecond()/LOGIC_UPDATE_RATE; + llong upper = (timeAsTicks > pageLength) ? (timeAsTicks - pageLength) : 0; + horizontalScroll->setRange( 0, upper ); + + horizontalScroll->setPageStep( ullong(oscilloscopeView->width()*sliderTicksPerSecond()/pps) ); + + if (wasAtUpperEnd) + { + horizontalScroll->setValue( horizontalScroll->maxValue() ); + oscilloscopeView->updateView(); + } +} + + +ullong Oscilloscope::time() const +{ + if (!m_oldestProbe) + return 0; + + return ullong( m_pSimulator->time() - m_oldestProbe->resetTime() ); +} + + +llong Oscilloscope::scrollTime() const +{ +// if ( b_isPaused || numberOfProbes() == 0 ) +// return 0; + + if ( numberOfProbes() == 0 ) + return 0; + + if ( horizontalScroll->maxValue() == 0 ) + { + llong lengthAsTime = llong( oscilloscopeView->width() * LOGIC_UPDATE_RATE / pixelsPerSecond() ); + return m_pSimulator->time() - lengthAsTime; + } + + else + return llong( m_oldestProbe->resetTime() + (llong(horizontalScroll->value()) * LOGIC_UPDATE_RATE / sliderTicksPerSecond()) ); +} + + +double Oscilloscope::pixelsPerSecond() const +{ + return 2 * MIN_BITS_PER_S * std::pow( 2.0, m_zoomLevel * MIN_MAX_LOG_2_DIFF ); +} +//END Oscilloscope Class + + + +void addOscilloscopeAsToolView( KTechlab *ktechlab ) +{ + KateMDI::ToolView * tv; + tv = ktechlab->createToolView( Oscilloscope::toolViewIdentifier(), + KMultiTabBar::Bottom, + KGlobal::iconLoader()->loadIcon( "oscilloscope", KIcon::Small ), + i18n("Oscilloscope") ); + + Oscilloscope::self(tv); +} + + +ProbeData * registerProbe( Probe * probe ) +{ + return Oscilloscope::self()->registerProbe(probe); +} + + +void unregisterProbe( int id ) +{ + Oscilloscope::self()->unregisterProbe(id); +} + + +#include "oscilloscope.moc" diff --git a/src/gui/oscilloscope.h b/src/gui/oscilloscope.h new file mode 100644 index 0000000..79e0dbd --- /dev/null +++ b/src/gui/oscilloscope.h @@ -0,0 +1,192 @@ +/*************************************************************************** + * Copyright (C) 2005 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#ifndef OSCILLOSCOPE_H +#define OSCILLOSCOPE_H + +#ifndef PROBE_H +#ifndef KTECHLAB_H +#ifndef OSCILLOSCOPEDATA_H +#include "oscilloscopewidget.h" +#endif +#endif +#endif + +#include "simulator.h" +#include + +class FloatingProbeData; +class LogicProbe; +class LogicProbeData; +class KTechlab; +class Oscilloscope; +class Probe; +class ProbeData; +class VoltageProbe; +class QTimer; +namespace KateMDI { class ToolView; } + +typedef QMap< int, ProbeData * > ProbeDataMap; +typedef QMap< int, LogicProbeData * > LogicProbeDataMap; +typedef QMap< int, FloatingProbeData * > FloatingProbeDataMap; + +typedef unsigned long long ullong; +typedef long long llong; + + +#if 0 +const double MAX_BITS_PER_S = 100000; + +// NOTE: The 10 has to agree with the 2^10 = 1024.0 +const int MIN_MAX_LOG_2_DIFF = 10; +const double MIN_BITS_PER_S = MAX_BITS_PER_S / 1024.0; +#else +const double MAX_BITS_PER_S = LOGIC_UPDATE_RATE * 4; + +// NOTE: The 18 has to agree with the 2^18 = 262144.0 +const int MIN_MAX_LOG_2_DIFF = 18; +const double MIN_BITS_PER_S = MAX_BITS_PER_S / 262144.0; +#endif + + +/* +Due to strangeness with generation of .[cpp/h] files from .ui files (that is, +my inability to sort it out neatly), files other than those in /src/gui can't +see header files such as "oscilloscopewidget.h", so we have to provide some +interface functions for accessing the functionality in this class +*/ +ProbeData * registerProbe( Probe * probe ); +void unregisterProbe( int id ); +void addOscilloscopeAsToolView( KTechlab *ktechlab ); + + +#ifndef PROBE_H +#ifndef KTECHLAB_H +#ifndef OSCILLOSCOPEDATA_H +/** +@author David Saxton +*/ +class Oscilloscope : public OscilloscopeWidget +{ + Q_OBJECT + public: + static Oscilloscope * self( KateMDI::ToolView * parent = 0l ); + static QString toolViewIdentifier() { return "Oscilloscope"; } + virtual ~Oscilloscope(); + + /** + * Register a probe (that outputs boolean data) with the oscilloscope. + * Returns a unique id that the probe can use to add data points + */ + ProbeData * registerProbe( Probe * probe ); + void unregisterProbe( int id ); + /** + * Returns the Simulator time since recording started. + */ + ullong time() const; + /** + * Returns how much of an increment in value of the oscilloscope slider + * is equivalent to one second. + */ + int sliderTicksPerSecond() const; + /** + * Returns the number of pixels per second the user has requested to be + * displayed. + */ + double pixelsPerSecond() const; + /** + * Zoom level; a value between 0 and 1. 0 is maximum zoom out, and 1 is + * maximum zoom in. + */ + double zoomLevel() const { return m_zoomLevel; } + /** + * Sets the zoom level (and in the process, checks that it is within the + * bounds allowed). + */ + void setZoomLevel( double zoomLevel ); + /** + * Returns the Simulator time as given by the current scrollbar + * position. + */ + llong scrollTime() const; + /** + * @returns pointer to probe with given id, or NULL if no such probe exists + */ + ProbeData * probeData( int id ) const; + /** + * @returns the total number of probes + */ + int numberOfProbes() const; + /** + * @returns number of the probe with the given id, starting from 0, or -1 if no such probe + */ + int probeNumber( int id ) const; + + signals: + /** + * Emitted when a probe is registered + */ + void probeRegistered( int id, ProbeData * probe ); + /** + * Emitted when a probe is unregistered + */ + void probeUnregistered( int id ); + + public slots: + /** + * Resets all recorded data + */ + void reset(); + /** + * Called when the zoom slider value was changed. + */ + void slotZoomSliderChanged( int value ); + /** + * Called when the horizontal scrollbar was scrolled by the user + */ + void slotSliderValueChanged( int value ); + /** + * Pause the data capture (e.g. user clicked on pause button) + */ + void slotTogglePause(); + + protected: + void getOldestProbe(); + +// bool b_isPaused; + int m_nextId; + ProbeData * m_oldestProbe; + int m_oldestId; + int m_nextColor; // For giving the probes colours + + ProbeDataMap m_probeDataMap; + LogicProbeDataMap m_logicProbeDataMap; + FloatingProbeDataMap m_floatingProbeDataMap; + + Simulator * m_pSimulator; + + protected slots: + void updateScrollbars(); + + private: + Oscilloscope( KateMDI::ToolView * parent ); + + static Oscilloscope * m_pSelf; + double m_zoomLevel; + + friend class OscilloscopeView; + friend class ProbePositioner; +}; + +#endif // OSCILLOSCOPEDATA_H +#endif // KTECHLAB_H +#endif // PROBE_H + +#endif // OSCILLOSCOPE_H diff --git a/src/gui/oscilloscopeview.cpp b/src/gui/oscilloscopeview.cpp new file mode 100644 index 0000000..3d2a40a --- /dev/null +++ b/src/gui/oscilloscopeview.cpp @@ -0,0 +1,431 @@ +/*************************************************************************** + * Copyright (C) 2005 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#include "oscilloscope.h" +#include "oscilloscopedata.h" +#include "oscilloscopeview.h" +#include "probepositioner.h" +#include "simulator.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +inline ullong min( ullong a, ullong b ) +{ + return a < b ? a : b; +} + + +OscilloscopeView::OscilloscopeView( QWidget *parent, const char *name ) + : QFrame( parent, name, WNoAutoErase ), + b_needRedraw(true), + m_pixmap(0l), + m_fps(10), + m_sliderValueAtClick(-1), + m_clickOffsetPos(-1), + m_pSimulator( Simulator::self() ), + m_halfOutputHeight(0.0) +{ + KGlobal::config()->setGroup("Oscilloscope"); + m_fps = KGlobal::config()->readNumEntry( "FPS", 25 ); + + setBackgroundMode(NoBackground); + setMouseTracking(true); + + m_updateViewTmr = new QTimer(this); + connect( m_updateViewTmr, SIGNAL(timeout()), this, SLOT(updateViewTimeout()) ); +} + + +OscilloscopeView::~OscilloscopeView() +{ + delete m_pixmap; + m_pixmap = 0l; +} + + +void OscilloscopeView::updateView() +{ + if (m_updateViewTmr->isActive() ) + return; + + m_updateViewTmr->start( 1000/m_fps, true ); +} + + +void OscilloscopeView::updateViewTimeout() +{ + b_needRedraw = true; + repaint(false); + updateTimeLabel(); +} + + +void OscilloscopeView::updateTimeLabel() +{ + if ( hasMouse() ) + { + int x = mapFromGlobal( QCursor::pos() ).x(); + double time = (double(Oscilloscope::self()->scrollTime()) / LOGIC_UPDATE_RATE) + (x / Oscilloscope::self()->pixelsPerSecond()); + Oscilloscope::self()->timeLabel->setText( QString::number( time, 'f', 6 ) ); + } + + else + Oscilloscope::self()->timeLabel->setText( QString::null ); +} + + +void OscilloscopeView::resizeEvent( QResizeEvent *e ) +{ + delete m_pixmap; + m_pixmap = new QPixmap( e->size() ); + b_needRedraw = true; + QFrame::resizeEvent(e); +} + + +void OscilloscopeView::mousePressEvent( QMouseEvent *event ) +{ + switch ( event->button() ) + { + case Qt::LeftButton: + { + event->accept(); + m_clickOffsetPos = event->pos().x(); + m_sliderValueAtClick = Oscilloscope::self()->horizontalScroll->value(); + setCursor( Qt::SizeAllCursor ); + return; + } + + case Qt::RightButton: + { + event->accept(); + + KPopupMenu fpsMenu; + fpsMenu.insertTitle( i18n("Framerate") ); + + const int fps[] = { 10, 25, 50, 75, 100 }; + + for ( uint i=0; i<5; ++i ) + { + const int num = fps[i]; + fpsMenu.insertItem( i18n("%1 fps").arg(num), num ); + fpsMenu.setItemChecked( num, num == m_fps ); + } + + connect( &fpsMenu, SIGNAL(activated(int )), this, SLOT(slotSetFrameRate(int )) ); + fpsMenu.exec( event->globalPos() ); + return; + } + + default: + { + QFrame::mousePressEvent(event); + return; + } + } +} + + +void OscilloscopeView::mouseMoveEvent( QMouseEvent *event ) +{ + event->accept(); + updateTimeLabel(); + + if ( m_sliderValueAtClick != -1 ) + { + int dx = event->pos().x() - m_clickOffsetPos; + int dTick = int( dx * Oscilloscope::self()->sliderTicksPerSecond() / Oscilloscope::self()->pixelsPerSecond() ); + Oscilloscope::self()->horizontalScroll->setValue( m_sliderValueAtClick - dTick ); + } +} + + +void OscilloscopeView::mouseReleaseEvent( QMouseEvent *event ) +{ + if ( m_sliderValueAtClick == -1 ) + return QFrame::mouseReleaseEvent(event); + + event->accept(); + m_sliderValueAtClick = -1; + setCursor( Qt::ArrowCursor ); +} + + +void OscilloscopeView::slotSetFrameRate( int fps ) +{ + m_fps = fps; + KGlobal::config()->setGroup("Oscilloscope"); + KGlobal::config()->writeEntry( "FPS", m_fps ); +} + + +// returns a % b +static double lld_modulus( llong a, double b ) +{ + return double(a) - llong(a/b)*b; +} + + +void OscilloscopeView::paintEvent( QPaintEvent *e ) +{ + QRect r = e->rect(); + + if (b_needRedraw) + { + updateOutputHeight(); + const double pixelsPerSecond = Oscilloscope::self()->pixelsPerSecond(); + + QPainter p; + m_pixmap->fill( paletteBackgroundColor() ); + p.begin(m_pixmap); + p.setClipRegion(e->region()); + + //BEGIN Draw vertical marker lines + const double divisions = 5.0; + const double min_sep = 10.0; + + double spacing = pixelsPerSecond/(std::pow( divisions, std::floor(std::log(pixelsPerSecond/min_sep)/std::log(divisions)) )); + + // Pixels offset is the number of pixels that the view is scrolled along + const llong pixelsOffset = llong(Oscilloscope::self()->scrollTime()*pixelsPerSecond/LOGIC_UPDATE_RATE); + double linesOffset = - lld_modulus( pixelsOffset, spacing ); + + int blackness = 256 - int(184.0 * spacing / (min_sep*divisions*divisions)); + p.setPen( QColor( blackness, blackness, blackness ) ); + + for ( double i = linesOffset; i <= frameRect().width(); i += spacing ) + p.drawLine( int(i), 1, int(i), frameRect().height()-2 ); + + + + spacing *= divisions; + linesOffset = - lld_modulus( pixelsOffset, spacing ); + + blackness = 256 - int(184.0 * spacing / (min_sep*divisions*divisions)); + p.setPen( QColor( blackness, blackness, blackness ) ); + + for ( double i = linesOffset; i <= frameRect().width(); i += spacing ) + p.drawLine( int(i), 1, int(i), frameRect().height()-2 ); + + + + spacing *= divisions; + linesOffset = - lld_modulus( pixelsOffset, spacing ); + + blackness = 256 - int(184.0); + p.setPen( QColor( blackness, blackness, blackness ) ); + + for ( double i = linesOffset; i <= frameRect().width(); i += spacing ) + p.drawLine( int(i), 1, int(i), frameRect().height()-2 ); + //END Draw vertical marker lines + + drawLogicData(p); + drawFloatingData(p); + + p.setPen(Qt::black); + p.drawRect( frameRect() ); + + b_needRedraw = false; + } + + bitBlt( this, r.x(), r.y(), m_pixmap, r.x(), r.y(), r.width(), r.height() ); +} + + +void OscilloscopeView::updateOutputHeight() +{ + m_halfOutputHeight = int((Oscilloscope::self()->probePositioner->probeOutputHeight() - (probeArrowWidth/Oscilloscope::self()->numberOfProbes()))/2)-1; +} + + +void OscilloscopeView::drawLogicData( QPainter & p ) +{ + const double pixelsPerSecond = Oscilloscope::self()->pixelsPerSecond(); + + const LogicProbeDataMap::iterator end = Oscilloscope::self()->m_logicProbeDataMap.end(); + for ( LogicProbeDataMap::iterator it = Oscilloscope::self()->m_logicProbeDataMap.begin(); it != end; ++it ) + { + // When searching for the next logic value to display, we look along + // until there is a recorded point which is at least one pixel along + // If we are zoomed out far, there might be thousands of data points + // between each pixel. It is time consuming searching for the next point + // to display one at a time, so we record the average number of data points + // between pixels ( = deltaAt / totalDeltaAt ) + llong deltaAt = 1; + int totalDeltaAt = 1; + + LogicProbeData * probe = it.data(); + StoredData * data = &(probe->m_data); + + if ( data->allocatedUpTo() == 0 ) + continue; + + const int midHeight = Oscilloscope::self()->probePositioner->probePosition(probe); + const llong timeOffset = Oscilloscope::self()->scrollTime(); + + // Draw the horizontal line indicating the midpoint of our output + p.setPen( QColor( 228, 228, 228 ) ); + p.drawLine( 0, midHeight, width(), midHeight ); + + // Set the pen colour according to the colour the user has selected for the probe + p.setPen( probe->color() ); + + // The smallest time step that will display in our oscilloscope + const int minTimeStep = int(LOGIC_UPDATE_RATE/pixelsPerSecond); + + llong at = probe->findPos(timeOffset); + const llong maxAt = probe->insertPos(); + llong prevTime = data->dataAt(at).time; + int prevX = (at > 0) ? 0 : int((prevTime - timeOffset)*(pixelsPerSecond/LOGIC_UPDATE_RATE)); + bool prevHigh = data->dataAt(at).value; + int prevY = midHeight + int(prevHigh ? -m_halfOutputHeight : +m_halfOutputHeight); + while ( at < maxAt ) + { + // Search for the next pos which will show up at our zoom level + llong previousAt = at; + llong dAt = deltaAt / totalDeltaAt; + + while ( (dAt > 1) && (at < maxAt) && ( (llong(data->dataAt(at).time) - prevTime) != minTimeStep ) ) + { + // Search forwards until we overshoot + while ( at < maxAt && ( llong(data->dataAt(at).time) - prevTime ) < minTimeStep ) + at += dAt; + dAt /= 2; + + // Search backwards until we undershoot + while ( (at < maxAt) && ( llong(data->dataAt(at).time) - prevTime ) > minTimeStep ) + { + at -= dAt; + if ( at < 0 ) + at = 0; + } + dAt /= 2; + } + + // Possibly increment the value of at found by one (or more if this is the first go) + while ( (previousAt == at) || ((at < maxAt) && ( llong(data->dataAt(at).time) - prevTime ) < minTimeStep) ) + at++; + + if ( at >= maxAt ) + break; + + // Update the average values + deltaAt += at - previousAt; + totalDeltaAt++; + + bool nextHigh = data->dataAt(at).value; + if ( nextHigh == prevHigh ) + continue; + llong nextTime = data->dataAt(at).time; + int nextX = int((nextTime - timeOffset)*(pixelsPerSecond/LOGIC_UPDATE_RATE)); + int nextY = midHeight + int(nextHigh ? -m_halfOutputHeight : +m_halfOutputHeight); + + p.drawLine( prevX, prevY, nextX, prevY ); + p.drawLine( nextX, prevY, nextX, nextY ); + + prevHigh = nextHigh; + prevTime = nextTime; + prevX = nextX; + prevY = nextY; + + if ( nextX > width() ) + break; + }; + + // If we could not draw right to the end; it is because we exceeded + // maxAt + if ( prevX < width() ) + p.drawLine( prevX, prevY, width(), prevY ); + } +} + + +#define v_to_y int(midHeight - (logarithmic ? ( (v>0) ? log(v/lowerAbsValue) : -log(-v/lowerAbsValue) ) : v) * sf) + + +void OscilloscopeView::drawFloatingData( QPainter & p ) +{ + const double pixelsPerSecond = Oscilloscope::self()->pixelsPerSecond(); + + const FloatingProbeDataMap::iterator end = Oscilloscope::self()->m_floatingProbeDataMap.end(); + for ( FloatingProbeDataMap::iterator it = Oscilloscope::self()->m_floatingProbeDataMap.begin(); it != end; ++it ) + { + FloatingProbeData * probe = it.data(); + StoredData * data = &(probe->m_data); + + if ( data->allocatedUpTo() == 0 ) + continue; + + bool logarithmic = probe->scaling() == FloatingProbeData::Logarithmic; + double lowerAbsValue = probe->lowerAbsValue(); + double sf = m_halfOutputHeight / (logarithmic ? log(probe->upperAbsValue()/lowerAbsValue) : probe->upperAbsValue()); + + const int midHeight = Oscilloscope::self()->probePositioner->probePosition(probe); + const llong timeOffset = Oscilloscope::self()->scrollTime(); + + // Draw the horizontal line indicating the midpoint of our output + p.setPen( QColor( 228, 228, 228 ) ); + p.drawLine( 0, midHeight, width(), midHeight ); + + // Set the pen colour according to the colour the user has selected for the probe + p.setPen( probe->color() ); + + llong at = probe->findPos(timeOffset); + const llong maxAt = probe->insertPos(); + llong prevTime = probe->toTime(at); + + double v = data->dataAt((at>0)?at:0); + int prevY = v_to_y; + int prevX = int((prevTime - timeOffset)*(pixelsPerSecond/LOGIC_UPDATE_RATE)); + + while ( at < maxAt-1 ) + { + at++; + + ullong nextTime = prevTime + ullong(LOGIC_UPDATE_RATE/LINEAR_UPDATE_RATE); + + double v = data->dataAt((at>0)?at:0); + int nextY = v_to_y; + int nextX = int((nextTime - timeOffset)*(pixelsPerSecond/LOGIC_UPDATE_RATE)); + + p.drawLine( prevX, prevY, nextX, nextY ); + + prevTime = nextTime; + prevX = nextX; + prevY = nextY; + + if ( nextX > width() ) + break; + }; + + // If we could not draw right to the end; it is because we exceeded + // maxAt + if ( prevX < width() ) + p.drawLine( prevX, prevY, width(), prevY ); + } +} + + +#include "oscilloscopeview.moc" diff --git a/src/gui/oscilloscopeview.h b/src/gui/oscilloscopeview.h new file mode 100644 index 0000000..97cb595 --- /dev/null +++ b/src/gui/oscilloscopeview.h @@ -0,0 +1,65 @@ +/*************************************************************************** + * Copyright (C) 2005 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#ifndef OSCILLOSCOPEVIEW_H +#define OSCILLOSCOPEVIEW_H + +#include + +class Oscilloscope; +class Simulator; +class QMouseEvent; +class QPaintEvent; +class QPixmap; +class QTimer; + +/** +@author David Saxton +*/ +class OscilloscopeView : public QFrame +{ + Q_OBJECT + public: + OscilloscopeView( QWidget *parent, const char *name = 0 ); + virtual ~OscilloscopeView(); + + public slots: + /** + * Sets the needRedraw flag to true, and then class repaint + */ + void updateView(); + void slotSetFrameRate( int fps ); + + protected slots: + void updateViewTimeout(); + + protected: + virtual void mousePressEvent( QMouseEvent *event ); + virtual void mouseMoveEvent( QMouseEvent *event ); + virtual void mouseReleaseEvent( QMouseEvent *event ); + virtual void paintEvent( QPaintEvent *event ); + virtual void resizeEvent( QResizeEvent *event ); + + void drawLogicData( QPainter & p ); + void drawFloatingData( QPainter & p ); + void updateOutputHeight(); + void updateTimeLabel(); + + bool b_needRedraw; + QPixmap *m_pixmap; + QTimer *m_updateViewTmr; + int m_fps; + int m_sliderValueAtClick; + int m_clickOffsetPos; + Simulator * m_pSimulator; + double m_halfOutputHeight; +}; + +#endif diff --git a/src/gui/oscilloscopewidget.ui b/src/gui/oscilloscopewidget.ui new file mode 100644 index 0000000..eb8002b --- /dev/null +++ b/src/gui/oscilloscopewidget.ui @@ -0,0 +1,289 @@ + +OscilloscopeWidget + + + OscilloscopeWidget + + + + 0 + 0 + 563 + 195 + + + + Form1 + + + + unnamed + + + 0 + + + 0 + + + + layout7 + + + + unnamed + + + 0 + + + + oscilloscopeView + + + + 3 + 3 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 255 + 255 + 255 + + + + + + probePositioner + + + + 16 + 0 + + + + + 16 + 32767 + + + + + + horizontalScroll + + + Horizontal + + + + + + + layout9 + + + + unnamed + + + 0 + + + 0 + + + + textLabel1 + + + Zoom + + + AlignCenter + + + + + zoomSlider + + + + 4 + 0 + 0 + 0 + + + + 1000 + + + 10 + + + 50 + + + Horizontal + + + + + spacer1 + + + Vertical + + + MinimumExpanding + + + + 20 + 30 + + + + + + timeLabel + + + + + + AlignCenter + + + + + spacer1_2 + + + Vertical + + + Fixed + + + + 20 + 6 + + + + + + resetBtn + + + + 1 + 1 + 0 + 0 + + + + Reset + + + + + + + + + + spacer2_3 + + + Horizontal + + + Fixed + + + + 6 + 6 + + + + + + spacer2_2 + + + Vertical + + + Fixed + + + + 6 + 6 + + + + + + + + OscilloscopeView +
oscilloscopeview.h
+ + -1 + -1 + + 0 + + 1 + 3 + 0 + 0 + + image0 +
+ + ProbePositioner +
probepositioner.h
+ + 14 + -1 + + 0 + + 0 + 5 + 0 + 0 + + image0 +
+
+ + + 89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000042c49444154388db5954f6c14551cc73fefcd7476b65bdaae4bb78bb5502a14d404e4801c88182d1c4c2c693da847400f9c24c68b878684238660e2b1e01f12c19493012ef2478c814412d354a46017a8a564bb6da5bbedccee767776e63d0ffb073751d483bfe49799974c3eeffb7ebf37df9fd05a530b2184040cc0042420aaf9a4d0d554800f045a6b256ae0e1e1e1d6bebebe838ee31c48a7d39b5cd7fd075e251cc7617272f2ded8d8d819cff33e0316819259537aead4a9839d5dd6d1784f91f55b0a94830242088404d304292bef68a89f520802a598fecddaa04f1a876f5c250c7c0a64cdeac686e33807e23d45e6b297c8b877f1831542614550b6599835c83c2a81b6786a75134faf2f1169f12997350881d9021d0903e06de0745d3160a6d3e94dbd5b0a64dcbb94b5831d0e3375ab892b1772dcf9790528543f8dd0d367b36768153b5e31503a0f1aecb004580b44ffac58baae8b1714f0833c7638cc8dab303a320f4822ab4c7a37c69196203de3319d5ce1c4d13c733331dedc67a129a154fd128401ab0616d55a130ac3d42d93d1913940d13fd0c9ee0183685c60da01c5421bd72f7a8c8efccef9afd374267ad93d642365be0636a0d28ec7600941d9e6f23917f0e97f23ce5bef35d19ec863da0ed9059b2be70bec196c66dfa10ec0e49b338f7017258651bf95021035c595429bb0903248fe52a2b5b595dd7b4d945cc2340cdca536be389ee3f67886c5798f773fe8e0dac508c989659277a2180da4ca4ff07821058b8b251445d63d6b13ed1098a6417e39cac85197dbe31962ab9bd9f1f22a226d45366f6d0620fdb08c900d281af6110284b20085b414861d905d88f2e52739ee8cbb8022143259d3dd84691730aa2d52da441a8de0c6958068870022a41e9629ad3473fd3b8fdbe319dadb9b4924da994d2d716c7896fbe35152f78b48245d6b2da4507faf582be8eaf159b721cc837b05ae7debb1f79d08cb8b515edad942a22bc4b1c33eb3d34b1c797f06af90a72d16e2f96d9a74aa11dca8586b222d01af0fb60070f6c402d72f15d97f28c6f6d7027a5f5ce6c3233dc4e2ede496b278be4fff608cee8d3e1add806aeca51094cbb06397c1ecc328e746537c7e3ccdb5cb1136bf60635882d4d41c6ec6836ab37efa214f72208ed9f4d7cdd38ee310280542e38b1c43fb6de26b3672e1ec3cc99bcb246f66a938a3241ab3e91f7c861fbf77710b1e5e49915bae974203ba0e9e9c9cbc373d6d6d305a040a89c2a77f50b27d5782bbbf7acccf28349235dd16cf6dd374f7295e1de8a45c02d37499182b01cc0201a085d61a2144d8b2ac8fb6ed340e77240c4261890e04c250185262546d534a032154b59e0ad394e41c98182bf268ce6721ed9f064e0253356f6da2e24c1f030f783c15fe6da680af8021602bd051532ca9b8521488559f61aa86c29343578fbf0264a94c906c7d3409214c20043457a116ff6de6795578012889ff6b98fe016ea0ce1c6a2573410000000049454e44ae426082 + + + + + oscilloscopeview.h + probepositioner.h + +
diff --git a/src/gui/outputmethoddlg.cpp b/src/gui/outputmethoddlg.cpp new file mode 100644 index 0000000..bcb189e --- /dev/null +++ b/src/gui/outputmethoddlg.cpp @@ -0,0 +1,162 @@ +/*************************************************************************** + * Copyright (C) 2003-2004 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#include "docmanager.h" +#include "filemetainfo.h" +#include "textdocument.h" +#include "outputmethodwidget.h" +#include "outputmethoddlg.h" +#include "microlibrary.h" +#include "microselectwidget.h" +#include "projectmanager.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + + +//BEGIN class OutputMethodInfo +OutputMethodInfo::OutputMethodInfo() +{ + m_method = Method::Direct; + m_bAddToProject = false; +} + + +void OutputMethodInfo::initialize( OutputMethodDlg * dlg ) +{ + if ( dlg->m_widget->displayDirectCheck->isChecked() ) + { + m_method = Method::Direct; + KTempFile f( QString::null, dlg->m_outputExtension ); + f.close(); + m_outputFile = f.name(); + m_bAddToProject = false; + } + + else + { + if ( dlg->m_widget->loadFileCheck->isChecked() ) + m_method = Method::SaveAndLoad; + + else + m_method = Method::SaveAndForget; + + m_outputFile = dlg->m_widget->outputFileURL->url(); + m_bAddToProject = dlg->m_widget->addToProjectCheck->isChecked(); + } + + m_picID = dlg->m_widget->m_pMicroSelect->micro(); +} +//END class OutputMethodInfo + + + +//BEGIN class OutputMethodDlg +OutputMethodDlg::OutputMethodDlg( const QString &caption, const KURL & inputURL, bool showPICSelect, QWidget *parent, const char *name ) + : KDialogBase( parent, name, true, caption, Ok|Cancel ) +{ + m_inputURL = inputURL; + m_bAccepted = false; + m_widget = new OutputMethodWidget(this); + + m_widget->addToProjectCheck->setEnabled( ProjectManager::self()->currentProject() ); + + if (!showPICSelect) + { + m_widget->m_pMicroSelect->hide(); + m_widget->adjustSize(); + } + + fileMetaInfo()->initializeFromMetaInfo( m_inputURL, this ); + + setMainWidget(m_widget); +} + + +OutputMethodDlg::~OutputMethodDlg() +{ +} + + +void OutputMethodDlg::setOutputExtension( const QString & extension ) +{ + m_outputExtension = extension; +} + + +void OutputMethodDlg::setFilter( const QString &filter ) +{ + m_widget->outputFileURL->setFilter(filter); +} + + +void OutputMethodDlg::setMethod( OutputMethodInfo::Method::Type m ) +{ + switch (m) + { + case OutputMethodInfo::Method::Direct: + m_widget->displayDirectCheck->setChecked(true); + break; + + case OutputMethodInfo::Method::SaveAndForget: + m_widget->saveFileCheck->setChecked(true); + m_widget->loadFileCheck->setChecked(false); + break; + + case OutputMethodInfo::Method::SaveAndLoad: + m_widget->saveFileCheck->setChecked(true); + m_widget->loadFileCheck->setChecked(true); + break; + }; +} + + +void OutputMethodDlg::setPicID( const QString & id ) +{ + m_widget->m_pMicroSelect->setMicro(id); +} + + +void OutputMethodDlg::setOutputFile( const KURL & out ) +{ + m_widget->outputFileURL->setURL(out.prettyURL()); +} + + +void OutputMethodDlg::accept() +{ + m_bAccepted = true; + m_outputMethodInfo.initialize(this); + fileMetaInfo()->grabMetaInfo( m_inputURL, this ); + hide(); +} + + +void OutputMethodDlg::reject() +{ + m_bAccepted = false; +} + + +MicroSelectWidget * OutputMethodDlg::microSelect() const +{ + return m_widget->m_pMicroSelect; +} +//END class OutputMethodDlg + + +#include "outputmethoddlg.moc" diff --git a/src/gui/outputmethoddlg.h b/src/gui/outputmethoddlg.h new file mode 100644 index 0000000..14dff25 --- /dev/null +++ b/src/gui/outputmethoddlg.h @@ -0,0 +1,98 @@ +/*************************************************************************** + * Copyright (C) 2003-2004 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#ifndef OUTPUTMETHODDLG_H +#define OUTPUTMETHODDLG_H + +#include +#include + +class TextDocument; +class KTechlab; +class MicroSelectWidget; +class OutputMethodDlg; +class OutputMethodWidget; + +class OutputMethodInfo +{ + public: + class Method + { + public: + enum Type + { + Direct, + SaveAndForget, + SaveAndLoad + }; + }; + + OutputMethodInfo(); + void initialize( OutputMethodDlg * dlg ); + + Method::Type method() const { return m_method; } + void setMethod( Method::Type method ) { m_method = method; } + + bool addToProject() const { return m_bAddToProject; } + void setAddToProject( bool add ) { m_bAddToProject = add; } + + QString picID() const { return m_picID; } + void setPicID( const QString & id ) { m_picID = id; } + + KURL outputFile() const { return m_outputFile; } + void setOutputFile( const KURL & outputFile ) { m_outputFile = outputFile; } + + protected: + Method::Type m_method; + bool m_bAddToProject; + QString m_picID; + KURL m_outputFile; +}; + +/** +@author David Saxton +*/ +class OutputMethodDlg : public KDialogBase +{ + Q_OBJECT + public: + /** + * @param Caption The caption of the dialog window + * @param inputURL Used for saving/restoring previous options the user has selected for this file; set this to null if temporary file + * @param showPICSelect Whether to show the combo boxes for selecting a PIC + */ + OutputMethodDlg( const QString & caption, const KURL & inputURL, bool showPICSelect = false, QWidget *parent = 0, const char *name = 0); + ~OutputMethodDlg(); + + void setOutputExtension( const QString & outputExtension ); + void setFilter( const QString &filter ); + void setMethod( OutputMethodInfo::Method::Type m ); + void setOutputFile( const KURL & out ); + void setPicID( const QString & id ); + + virtual void reject(); + virtual void accept(); + bool isAccepted() const { return m_bAccepted; } + + OutputMethodInfo info() const { return m_outputMethodInfo; } + + MicroSelectWidget * microSelect() const; + + protected: + OutputMethodWidget *m_widget; + QString m_outputExtension; + KURL m_inputURL; + OutputMethodInfo m_outputMethodInfo; + bool m_bAccepted; + + friend class OutputMethodInfo; +}; + +#endif diff --git a/src/gui/outputmethodwidget.ui b/src/gui/outputmethodwidget.ui new file mode 100644 index 0000000..0182105 --- /dev/null +++ b/src/gui/outputmethodwidget.ui @@ -0,0 +1,182 @@ + +OutputMethodWidget + + + OutputMethodWidget + + + + 0 + 0 + 450 + 208 + + + + + 5 + 5 + 0 + 0 + + + + + 450 + 0 + + + + Output Method + + + + unnamed + + + 0 + + + + buttonGroup2 + + + Output Method + + + false + + + + unnamed + + + + displayDirectCheck + + + Displa&y directly + + + true + + + + + saveFileCheck + + + Save to file + + + false + + + + + groupBox16 + + + false + + + Output File Options + + + + unnamed + + + + outputFileURL + + + + + loadFileCheck + + + Load File in &New View + + + + + addToProjectCheck + + + &Add to Project + + + + + + + + + m_pMicroSelect + + + + 0 + 0 + + + + + + spacer14 + + + Vertical + + + Expanding + + + + 20 + 0 + + + + + + + + MicroSelectWidget +
microselectwidget.h
+ + -1 + -1 + + 0 + + 5 + 5 + 0 + 0 + + image0 +
+
+ + + 89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000042949444154388db5954d6c545514c77ff7de37eff1a6a550da994e5ba798868f948fc847a2a2911816c436b0a02ed0083161a1981877ee10d90aa94656063491882c5cd4c4b8103f20cd806909a98604da8482341de80cb69de9bcd799799d79efba980f1da3a80b4f727273939bdff99f9b93f3175a6b6a21849080020c4002a29a8f0a5dcd002803bed63a1035f0d0d0504b6f6fef51d7758fa4d3e98d8ee3fc03af128ee3303939399548242eb8aefb09300f78464de9f0f0f0d148cc7caf3d5424de97a7ec17104220242805520a44557bbd4b21f083801d33e63a6d1bc7bf19c6064e0319a35a58b9ae7ba43d54e4d7c54b64dc097c7f09d30ef04b36736983cc7c11b4456b9b492c5e20dc54a6540e00896a8268a7017010f8bcae1830d2e9f4c69ebe3c197782b2ce60d94ddc9b30f9feeb45ae5d7181c5ead35636ef08d3ffe26a76ee3208b4031a56d80aa00768fda362e9380e25bf80ef3b587613d7afc099533380a4b5dda46fcb5aa42998b9eb7173dce5e6788e434763ec7fc942532008ea436003660d2caa7f8d69c3bd8910674e4d033e83877ad8d36fb0aa4d6058658ac5358c5df6383bf480f31fdda5a3632bbbfb6da4ccd5c00a10b2012cc12fd97cfb5516f0187c25cee0619396480ec3ca909d0f3372d1e5f9fe66de3ad605587c712ec55256a2540d5519d19ae24a29057329839f7ecc138944d833102290f3184ae1e6d6f0e98739c61229e6d21eafbed1c9c8c5558c8f3ee4ceed76946a1c43d97091828585223e2eebfbc295f60d45de89707628cb58224577bc85a79e5d4d786581cddb9b0148259711b20145836221400416e0232d1f6595c9ce4538773ac7b54406f0b15784e8e80aa1ac2594190220d021e49f2437960156b70ba095e95f96f18acd8c263cc6122962b1167a7ba34cdd7ec8c977a699bed546722a8fc2a02b6e2185fff78ab586ce78894ddb9ab9f5738ed14b1e030756929d8ff2e4ae5544632b38f96e89a99b298ebd6950cc2d12ed0eb3618b26f520788462ad09877df60db600f0f1fb49c646f21c7ebd836dcf94e9d9b4c0db27d6d3bd36c6426a96bce731703046d7da129a4670836284a054869d4f1b1c7e2dca67676ef3c1898091ef5ad8bc358c3205c93bf7c9a40ad4c660f4728edd7bbb3142ea2fc1da711cfc200011e08b45f6bd1c261adbce9717928c5f9d63fc6a19f0014567773303073790f8214bd6f5282dfbb8b9fa1f6b40d7c1939393533b92e63ad9240990484aec7e41b27d579cbb531e0f67023492d86316ebb768ba1e0f786e6f37e56550c62237aee7011e54abd7c1412291b8a06de378b4d3c0b215da9708e5a3a442192085404a83d4accfecac067c0c43e13a70e3fa12e96409e0325000966bbb354465339d04a6f9dd15fe6dde07ce030780278088d05ad72cc9a6b2f2daaaa74d75a1f0e8d0d5f60b40868a8364ead6248430000b0857a126ffcdf396abf03ce089ffcb4c7f033046c6b4a995e7a00000000049454e44ae426082 + + + + + saveFileCheck + toggled(bool) + groupBox16 + setEnabled(bool) + + + + + kurlrequester.h + klineedit.h + kpushbutton.h + microselectwidget.h + +
diff --git a/src/gui/picprogrammerconfigwidget.ui b/src/gui/picprogrammerconfigwidget.ui new file mode 100644 index 0000000..64c5ac8 --- /dev/null +++ b/src/gui/picprogrammerconfigwidget.ui @@ -0,0 +1,285 @@ + +PicProgrammerConfigWidget + + + PicProgrammerConfigWidget + + + + 0 + 0 + 464 + 493 + + + + PIC Programmer Config + + + + unnamed + + + 0 + + + + groupBox3 + + + Programmer Configuration + + + + unnamed + + + + spacer3 + + + Horizontal + + + Expanding + + + + 295 + 20 + + + + + + addButton + + + &Add ... + + + Alt+A + + + + + removeButton + + + Re&move + + + Alt+M + + + + + textLabel1_3 + + + Program: + + + + + kcfg_PicProgrammerProgram + + + + 1 + 0 + 1 + 0 + + + + false + + + + + m_pProgrammerDescription + + + (Program Description) + + + + + + + commandsGroupBox + + + Commands + + + + unnamed + + + + textLabel1_2 + + + Initialization: + + + + + verifyCommand + + + + + writeCommand + + + + + readCommand + + + + + initCommand + + + + + textLabel4 + + + Read: + + + + + textLabel3 + + + Write: + + + + + blankCheckCommand + + + + + eraseCommand + + + + + textLabel2 + + + The following strings will be replaced when the command is run: +<ul> +<li><b>%port</b> - Port that the programmer is connected to</li> +<li><b>%device</b> - PIC device</li> +<li><b>%file</b> - File to read from or write to</li> +</ul> + + + RichText + + + + + textLabel5 + + + Erase: + + + + + textLabel2_3 + + + Verify: + + + + + textLabel1_4 + + + Blank Check: + + + + + + + layout5 + + + + unnamed + + + + textLabel1 + + + Default port: + + + + + kcfg_PicProgrammerPort + + + true + + + + + + + spacer2 + + + Vertical + + + Expanding + + + + 20 + 16 + + + + + + + kcfg_PicProgrammerProgram + addButton + removeButton + initCommand + readCommand + writeCommand + verifyCommand + blankCheckCommand + eraseCommand + kcfg_PicProgrammerPort + + + + kpushbutton.h + kpushbutton.h + kcombobox.h + klineedit.h + klineedit.h + klineedit.h + klineedit.h + klineedit.h + klineedit.h + + diff --git a/src/gui/pieditor.cpp b/src/gui/pieditor.cpp new file mode 100644 index 0000000..b7ca0e5 --- /dev/null +++ b/src/gui/pieditor.cpp @@ -0,0 +1,294 @@ +/*************************************************************************** + * Copyright (C) 2003-2004 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#include "colorcombo.h" +#include "doublespinbox.h" +#include "pieditor.h" +#include "variant.h" + +#include +#include +#include +#include +#include +#include + +//BEGIN class PIEditor +PIEditor::PIEditor(QString id, Variant *data, QWidget *parent, const char *name) + : QWidget(parent, name) +{ + m_id = id; + m_data = data; + connect(m_data,SIGNAL(valueChanged(QVariant, QVariant )),this,SLOT(valueChanged(QVariant))); + setFocus(); + update(); + //show(); +} + +PIEditor::~PIEditor() +{ +} + +void PIEditor::valueChanged( QVariant /*variant*/ ) +{ +} +//END class PIEditor + + +//BEGIN class PIBool +PIBool::PIBool(QString id, Variant *data, QWidget *parent, const char *name ) + : PIEditor( id, data, parent, name ) +{ + QHBoxLayout *layout = new QHBoxLayout(this); + layout->setAutoAdd(true); + + m_comboBox = new KComboBox(this); + m_comboBox->insertItem( i18n("True"), 0 ); + m_comboBox->insertItem( i18n("False"), 1 ); + m_comboBox->setCurrentItem( m_data->value().toBool() ? 0 : 1 ); + + connect( m_comboBox, SIGNAL(activated(int )), this, SLOT(selectChanged(int )) ); +} + +PIBool::~PIBool() +{ +} + +void PIBool::popup() +{ + m_comboBox->popup(); +} + +void PIBool::selectChanged( int index ) +{ + emit editorDataChanged( m_id, QVariant( index == 0 ) ); +} + +void PIBool::valueChanged( QVariant /*variant*/ ) +{ + m_comboBox->setCurrentItem( m_data->value().toBool() ? 0 : 1 ); +} +//END class PIBool + + +//BEGIN class PIColor +PIColor::PIColor(QString id, Variant *data, QWidget *parent, const char *name ) + : PIEditor(id,data,parent, name) +{ + QHBoxLayout *layout = new QHBoxLayout(this); + layout->setAutoAdd(true); + + m_combo = new ColorCombo( (ColorCombo::ColorScheme)m_data->colorScheme(), this ); + m_combo->setColor(m_data->value().toColor()); + + connect(m_combo,SIGNAL(activated(const QColor&)),this,SLOT(colorChanged(const QColor&))); +// connect(m_combo,SIGNAL(highlighted(const QColor&)),this,SLOT(colorChanged(const QColor&))); +} + +PIColor::~PIColor() +{ +} + +void PIColor::popup() +{ + m_combo->popup(); +} + +void PIColor::colorChanged(const QColor &col) +{ + emit editorDataChanged(m_id,QVariant(col)); +} + +void PIColor::valueChanged( QVariant /*variant*/ ) +{ + m_combo->setColor(m_data->value().toColor()); +} +//END class PIColor + + +//BEGIN class PIDouble +PIDouble::PIDouble(QString id, Variant *data, QWidget *parent, const char *name ) + : PIEditor(id,data,parent, name) +{ + QHBoxLayout *layout = new QHBoxLayout(this); + layout->setAutoAdd(true); + + spin = new DoubleSpinBox(m_data->minValue(),m_data->maxValue(),m_data->minAbsValue(),m_data->value().toDouble(),m_data->unit(),this); + + connect(spin,SIGNAL(valueChanged(double)),this,SLOT(spinValueChanged(double))); +} + +PIDouble::~PIDouble() +{ +} + +void PIDouble::spinValueChanged(double value) +{ + emit editorDataChanged(m_id,QVariant(value)); +} + +void PIDouble::valueChanged( QVariant /*variant*/ ) +{ + spin->setValue(m_data->value().toDouble()); +} +//END class PIDouble + + +//BEGIN class PIFileName +PIFilename::PIFilename(QString id, Variant *data, QWidget *parent, const char *name ) + : PIEditor(id,data,parent, name) +{ + QHBoxLayout *layout = new QHBoxLayout(this); + layout->setAutoAdd(true); + + m_combo = 0L; + if( m_data->allowed().count() == 0 ) + { + m_combo = new KComboBox(this); + m_combo->insertStringList( m_data->allowed() ); + m_urlreq = new KURLRequester(m_combo, this); + } + else m_urlreq = new KURLRequester(this); + + m_urlreq->setURL( m_data->value().toString() ); + m_urlreq->setFilter( m_data->filter() ); + + connect(m_urlreq,SIGNAL(urlSelected(const QString&)),this,SLOT(slotURLChanged(const QString&))); + //connect(m_urlreq,SIGNAL(openFileDialog(KURLRequester*)),this,SLOT(slotOpenFileDialog(KURLRequester* ))); +} + +PIFilename::~PIFilename() +{ +} + +void PIFilename::slotURLChanged(const QString &url) +{ + emit editorDataChanged(m_id,QVariant(url)); +} + +void PIFilename::valueChanged( QVariant /*variant*/ ) +{ + if(m_combo) m_combo->setCurrentItem( m_data->value().toString() ); + m_urlreq->setURL( m_data->value().toString() ); +} + +/* //FIXME Reintroduce this code if deciding not to go with dropping cod files + onto the PIC componenent ?? */ +// +// void PIFilename::slotOpenFileDialog(KURLRequester *kurlreq) +// { +// // If no file has been selected so far then it seems +// // to make most sense to open the dialog at the directory +// // of the current project if open. +// if(kurlreq->url() == m_data->defaultValue().toString() && !ProjectManager::self()->directory().isEmpty() ) kurlreq->setURL(ProjectManager::self()->directory()); +// } +//END class PIFileName + + +//BEGIN class PIInt +PIInt::PIInt( const QString &id, Variant *data, QWidget *parent, const char *name ) + : PIEditor( id, data, parent, name ) +{ + QHBoxLayout *layout = new QHBoxLayout(this); + layout->setAutoAdd(true); + + spin = new KIntSpinBox( (int)m_data->minValue(), (int)m_data->maxValue(), 1, m_data->value().toInt(), 10, this ); + + connect( spin, SIGNAL(valueChanged(int)), this, SLOT(spinValueChanged(int))); +} + +PIInt::~PIInt() +{ +} + +void PIInt::spinValueChanged( int value ) +{ + emit editorDataChanged( m_id, QVariant(value) ); +} + +void PIInt::valueChanged( QVariant /*variant*/ ) +{ + spin->setValue( m_data->value().toInt() ); +} +//END class PIInt + + +//BEGIN class PILineEdit +PILineEdit::PILineEdit(QString id, Variant *data, QWidget *parent, const char *name) + : PIEditor( id, data, parent, name) +{ + QHBoxLayout *layout = new QHBoxLayout(this); + layout->setAutoAdd(true); + m_edit = new KLineEdit( m_data->value().toString() , this ); + connect(m_edit,SIGNAL(textChanged(const QString&)),this,SLOT(slotEditTextChanged())); +} + + +PILineEdit::~PILineEdit() +{ +} + +void PILineEdit::slotEditTextChanged() +{ + emit editorDataChanged(m_id,QVariant(m_edit->text())); +} + +void PILineEdit::valueChanged( QVariant /*variant*/ ) +{ + m_edit->setText(m_data->value().toString()); +} +//END class PILineEdit + + +//BEGIN class PIStringCombo +PIStringCombo::PIStringCombo(QString id, Variant *data, QWidget *parent, const char *name) + : PIEditor( id, data, parent, name) +{ + QHBoxLayout *layout = new QHBoxLayout(this); + layout->setAutoAdd(true); + + m_combo = new KComboBox( this ); + m_combo->insertStringList(m_data->allowed()); + m_combo->setCurrentItem(m_data->value().toString()); + const Variant::Type::Value type = m_data->type(); + m_combo->setEditable( type == Variant::Type::Combo || + type == Variant::Type::FileName || + type == Variant::Type::VarName ); + + connect(m_combo,SIGNAL(highlighted(const QString&)),this,SLOT(slotComboChanged())); + connect(m_combo,SIGNAL(activated(const QString&)),this,SLOT(slotComboChanged())); +} + + +PIStringCombo::~PIStringCombo() +{ +} + +void PIStringCombo::popup() +{ + m_combo->popup(); +} + +void PIStringCombo::slotComboChanged() +{ + emit editorDataChanged(m_id,QVariant(m_combo->currentText())); +} + +void PIStringCombo::valueChanged( QVariant /*variant*/ ) +{ + m_combo->setCurrentItem(m_data->value().toString()); +} +//END class PIStringCombo + + + + +#include "pieditor.moc" + diff --git a/src/gui/pieditor.h b/src/gui/pieditor.h new file mode 100644 index 0000000..8423c7d --- /dev/null +++ b/src/gui/pieditor.h @@ -0,0 +1,188 @@ +/*************************************************************************** + * Copyright (C) 2003-2004 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#ifndef PIEDITOR_H +#define PIEDITOR_H + +#include +#include +#include + +class DoubleSpinBox; +class ColorCombo; +class KComboBox; +class KIntSpinBox; +class KLineEdit; +class KURLRequester; +class Variant; + + +/** +@author Daniel Clarke +*/ +class PIEditor : public QWidget +{ + Q_OBJECT + public: + PIEditor(QString id, Variant *data, QWidget *parent = 0, const char *name = 0); + ~PIEditor(); + + public slots: + virtual void valueChanged( QVariant variant ); + + signals: + void editorDataChanged(const QString &id, QVariant data); + + protected: + QString m_id; + Variant *m_data; +}; + + +/** +@author David Saxton + */ +class PIBool : public PIEditor +{ + Q_OBJECT + public: + PIBool( QString id, Variant *data, QWidget *parent = 0, const char *name = 0 ); + ~PIBool(); + + void popup(); + + protected slots: + void selectChanged( int index ); + virtual void valueChanged( QVariant variant ); + + protected: + KComboBox *m_comboBox; +}; + +/** +@author Daniel Clarke + */ +class PIColor : public PIEditor +{ + Q_OBJECT + public: + PIColor(QString id, Variant *data, QWidget *parent = 0, const char *name = 0); + ~PIColor(); + void popup(); + + protected slots: + void colorChanged(const QColor &col); + virtual void valueChanged( QVariant variant ); + + protected: + ColorCombo *m_combo; +}; + + +/** +Allows the editing of double precision numerical values, using the DoubleNum widget +@author Daniel Clarke + */ +class PIDouble : public PIEditor +{ + Q_OBJECT + public: + PIDouble(QString id, Variant *data, QWidget *parent = 0, const char *name = 0); + ~PIDouble(); + + protected slots: + void spinValueChanged(double value); + virtual void valueChanged( QVariant variant ); + + protected: + DoubleSpinBox *spin; +}; + + +/** +@author Daniel Clarke + */ +class PIFilename : public PIEditor +{ + Q_OBJECT + public: + PIFilename(QString id, Variant *data, QWidget *parent = 0, const char *name = 0); + ~PIFilename(); + + protected slots: + void slotURLChanged(const QString &url); + virtual void valueChanged( QVariant variant ); + // see comments in implementation. + //void slotOpenFileDialog(KURLRequester *kurlreq); + + protected: + KURLRequester *m_urlreq; + KComboBox *m_combo; +}; + +/** +@author David Saxton + */ +class PIInt : public PIEditor +{ + Q_OBJECT + public: + PIInt( const QString &id, Variant *data, QWidget *parent = 0, const char *name = 0); + ~PIInt(); + + protected slots: + void spinValueChanged( int value ); + virtual void valueChanged( QVariant variant ); + + protected: + KIntSpinBox *spin; +}; + + +/** +@author Daniel Clarke + */ +class PILineEdit : public PIEditor +{ + Q_OBJECT + public: + PILineEdit(QString id, Variant *data, QWidget *parent = 0, const char *name = 0); + ~PILineEdit(); + + protected slots: + void slotEditTextChanged(); + virtual void valueChanged( QVariant variant ); + + protected: + KLineEdit *m_edit; +}; + + +/** +@author Daniel Clarke + */ +class PIStringCombo : public PIEditor +{ + Q_OBJECT + public: + PIStringCombo(QString id, Variant *data, QWidget *parent, const char *name = 0); + ~PIStringCombo(); + void popup(); + + public slots: + virtual void valueChanged( QVariant variant ); + void slotComboChanged(); + + protected: + KComboBox *m_combo; + +}; + +#endif diff --git a/src/gui/plvitem.cpp b/src/gui/plvitem.cpp new file mode 100644 index 0000000..420259b --- /dev/null +++ b/src/gui/plvitem.cpp @@ -0,0 +1,90 @@ +/*************************************************************************** + * Copyright (C) 2003-2004 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#include "plvitem.h" +#include "variant.h" + +#include +#include +#include + +//BEGIN class PLVItem +PLVItem::PLVItem(KListView *listview, const QString &id, Variant *data) + : KListViewItem(listview, data->editorCaption()) +{ + p_data = data; + m_id = id; + setText(1,p_data->displayString() ); + + connect(data,SIGNAL(valueChanged(QVariant, QVariant )),this,SLOT(updateData(QVariant ))); + + //setHeight(100); +} + + +PLVItem::~PLVItem() +{ +} + +void PLVItem::updateData(QVariant /*value*/) +{ + if (!p_data) + return; + setText(1,p_data->displayString() ); +} + + +int PLVItem::width ( const QFontMetrics & fm, const QListView * lv, int c ) const +{ + if ( c == 0 ) + return 100; +// return KListViewItem::width( fm, lv, c ); + else + return 200; +} +//END class PLVitem + + + +//BEGIN class PLVColorItem +PLVColorItem::PLVColorItem(KListView *listview, const QString &id, Variant *data) + : PLVItem(listview,id,data) +{ +} + + +PLVColorItem::~PLVColorItem() +{ +} + +void PLVColorItem::paintCell ( QPainter * p, const QColorGroup & cg, int column, int width, int align ) +{ + if (!p_data) + return; + // we only draw column 1 "Data" ourselves, otherwise + // we leave it up to KDE + if (column == 1) + { + p->setBackgroundColor( p_data->value().toColor() ); + QBrush brush( p_data->value().toColor() ); + p->fillRect(QRect(0,0,listView()->columnWidth(1),KListViewItem::height()),brush); + } + else + KListViewItem::paintCell(p,cg,column,width,align); +} + +void PLVColorItem::updateData(QVariant value) +{ + listView()->triggerUpdate(); + PLVItem::updateData(value); +} +//END class PLVColorItem + +#include "plvitem.moc" diff --git a/src/gui/plvitem.h b/src/gui/plvitem.h new file mode 100644 index 0000000..fd48845 --- /dev/null +++ b/src/gui/plvitem.h @@ -0,0 +1,66 @@ +/*************************************************************************** + * Copyright (C) 2003-2004 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#ifndef PLVITEM_H +#define PLVITEM_H + +#include +#include +#include +#include + +class Variant; + +/** +@author David Saxton + +PropertiesListView Item +Basic item, which holds the Variant data and Id for an item +*/ +class PLVItem : public QObject, public KListViewItem +{ + Q_OBJECT + public: + PLVItem( KListView *listview, const QString &id, Variant * data ); + ~PLVItem(); + + QString id() const { return m_id; } + Variant * data() const { return p_data; } + + virtual int width ( const QFontMetrics & fm, const QListView * lv, int c ) const; + + public slots: + /** + * Call to change the data held by an item, and update the display + * accordingly. + */ + virtual void updateData(QVariant value); + + protected: + QString m_id; + QGuardedPtr p_data; +}; + +/** +@author Daniel Clarke + */ +class PLVColorItem : public PLVItem +{ + public: + PLVColorItem( KListView *listview, const QString &id, Variant *data ); + ~PLVColorItem(); + + void updateData(QVariant value); + + protected: + virtual void paintCell( QPainter * p, const QColorGroup & cg, int column, int width, int align ); +}; + +#endif diff --git a/src/gui/probepositioner.cpp b/src/gui/probepositioner.cpp new file mode 100644 index 0000000..1ea2606 --- /dev/null +++ b/src/gui/probepositioner.cpp @@ -0,0 +1,210 @@ +/*************************************************************************** + * Copyright (C) 2005 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#include "oscilloscope.h" +#include "oscilloscopedata.h" +#include "oscilloscopeview.h" +#include "probepositioner.h" + +#include +#include +#include + +#include +#include + +ProbePositioner::ProbePositioner(QWidget *parent, const char *name) + : QWidget( parent, name, WNoAutoErase ) +{ + m_probePosOffset = 0; + p_draggedProbe = 0l; + setFixedWidth( int(probeArrowWidth) ); + setBackgroundMode(NoBackground); + b_needRedraw = true; + m_pixmap = 0l; +} + + +ProbePositioner::~ProbePositioner() +{ + delete m_pixmap; +} + + +void ProbePositioner::forceRepaint() +{ + b_needRedraw = true; + repaint(false); +} + + +int ProbePositioner::probeOutputHeight() const +{ + int height = int( Oscilloscope::self()->oscilloscopeView->height() - probeArrowHeight ); + int numProbes = Oscilloscope::self()->numberOfProbes(); + if ( numProbes == 0 ) + numProbes = 1; + return height / numProbes; +} + + +int ProbePositioner::probePosition( ProbeData *probeData ) const +{ + if (!probeData) + return -1; + + int spacing = probeOutputHeight(); + int probeNum = Oscilloscope::self()->probeNumber(probeData->id()); + + return int( probeArrowHeight/2 + spacing*( probeNum + probeData->drawPosition() ) ); +} + + +void ProbePositioner::setProbePosition( ProbeData *probeData, int position ) +{ + if (!probeData) + return; + + int height = int( Oscilloscope::self()->oscilloscopeView->height() - probeArrowHeight ); + int numProbes = Oscilloscope::self()->numberOfProbes(); + int spacing = height / numProbes; + int probeNum = Oscilloscope::self()->probeNumber(probeData->id()); + + int minPos = int(probeArrowHeight/2); + int maxPos = int(Oscilloscope::self()->oscilloscopeView->height() - (probeArrowHeight/2)) - 1; + if ( position < minPos ) + position = minPos; + else if ( position > maxPos ) + position = maxPos; + + probeData->setDrawPosition( float(position - probeArrowHeight/2)/float(spacing) - probeNum ); + + forceRepaint(); + Oscilloscope::self()->oscilloscopeView->updateView(); +} + + +ProbeData* ProbePositioner::probeAtPosition( const QPoint &pos ) +{ + int relativeArrowHeight = int( probeArrowHeight * ( 1. - float(pos.x()/probeArrowWidth) ) ); + + const ProbeDataMap::const_iterator end = m_probeDataMap.end(); + for ( ProbeDataMap::const_iterator it = m_probeDataMap.begin(); it != end; ++it ) + { + ProbeData *probeData = it.data(); + int currentPos = probePosition(probeData); + m_probePosOffset = pos.y() - currentPos; + if ( std::abs(m_probePosOffset) <= relativeArrowHeight ) + return probeData; + } + m_probePosOffset = 0; + return 0l; +} + + +void ProbePositioner::slotProbeDataRegistered( int id, ProbeData *probe ) +{ + m_probeDataMap[id] = probe; + connect( probe, SIGNAL(displayAttributeChanged()), this, SLOT(forceRepaint()) ); + // This connect doesn't really belong here, but it save a lot of code + connect( probe, SIGNAL(displayAttributeChanged()), Oscilloscope::self()->oscilloscopeView, SLOT(updateView()) ); + forceRepaint(); + Oscilloscope::self()->oscilloscopeView->updateView(); +} + + +void ProbePositioner::slotProbeDataUnregistered( int id ) +{ + m_probeDataMap.erase(id); + // We "set" the position of each probe to force it into proper bounds + + const ProbeDataMap::const_iterator end = m_probeDataMap.end(); + for ( ProbeDataMap::const_iterator it = m_probeDataMap.begin(); it != end; ++it ) + setProbePosition( it.data(), probePosition( it.data() ) ); + + forceRepaint(); +} + + +void ProbePositioner::resizeEvent( QResizeEvent *e ) +{ + delete m_pixmap; + m_pixmap = new QPixmap( e->size() ); + QWidget::resizeEvent(e); + forceRepaint(); +} + + +void ProbePositioner::mousePressEvent( QMouseEvent * e ) +{ + p_draggedProbe = probeAtPosition(e->pos()); + if (p_draggedProbe) + e->accept(); + else + e->ignore(); +} + + +void ProbePositioner::mouseReleaseEvent( QMouseEvent * e ) +{ + if (p_draggedProbe) + e->accept(); + else + e->ignore(); +} + + +void ProbePositioner::mouseMoveEvent( QMouseEvent * e ) +{ + if (!p_draggedProbe) + { + e->ignore(); + return; + } + e->accept(); + + setProbePosition( p_draggedProbe, e->pos().y() - m_probePosOffset ); + forceRepaint(); +} + + +void ProbePositioner::paintEvent( QPaintEvent *e ) +{ + QRect r = e->rect(); + + if (b_needRedraw) + { + QPainter p; + m_pixmap->fill( paletteBackgroundColor() ); + p.begin(m_pixmap); + p.setClipRegion(e->region()); + + const ProbeDataMap::const_iterator end = m_probeDataMap.end(); + for ( ProbeDataMap::const_iterator it = m_probeDataMap.begin(); it != end; ++it ) + { + ProbeData *probeData = it.data(); + p.setBrush( probeData->color() ); + int currentPos = probePosition(probeData); + + QPointArray pa(3); + pa[0] = QPoint( 0, int(currentPos-(probeArrowHeight/2)) ); + pa[1] = QPoint( int(probeArrowWidth), currentPos ); + pa[2] = QPoint( 0, int(currentPos+(probeArrowHeight/2)) ); + + p.drawPolygon(pa); + } + b_needRedraw = false; + } + + bitBlt( this, r.x(), r.y(), m_pixmap, r.x(), r.y(), r.width(), r.height() ); +} + + +#include "probepositioner.moc" diff --git a/src/gui/probepositioner.h b/src/gui/probepositioner.h new file mode 100644 index 0000000..d106b40 --- /dev/null +++ b/src/gui/probepositioner.h @@ -0,0 +1,77 @@ +/*************************************************************************** + * Copyright (C) 2005 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#ifndef PROBEPOSITIONER_H +#define PROBEPOSITIONER_H + +#include + +class ProbeData; +typedef QMap< int, ProbeData* > ProbeDataMap; + +const float probeArrowWidth = 9; +const float probeArrowHeight = 12; + +/** +Widget for positioning the output of Probes in the OscilloscopeView +@author David Saxton +*/ +class ProbePositioner : public QWidget +{ + Q_OBJECT + public: + ProbePositioner(QWidget *parent = 0, const char *name = 0); + ~ProbePositioner(); + /** + * Returns the amount of space (height in pixels) that a probe output + * takes up + */ + int probeOutputHeight() const; + /** + * Returns the probe position (from the top) in pixels that the probe + * with the given id should be displayed at, or -1 if probe with the + * given id couldn't be found + */ + int probePosition( ProbeData *probeData ) const; + /** + * Sets the probe position relative to the top of this widget (and hence + * relative to the top of the oscilloscope view) in pixels + */ + void setProbePosition( ProbeData *probeData, int position ); + /** + * Returns the probe at the given position (plus or minus an an arrow), + * or NULL if none. Records the offset of the position from the mouse + * in m_probePosOffset. + */ + ProbeData* probeAtPosition( const QPoint &pos ); + + public slots: + void forceRepaint(); + + protected slots: + void slotProbeDataRegistered( int id, ProbeData *probe ); + void slotProbeDataUnregistered( int id ); + + protected: + virtual void mousePressEvent( QMouseEvent * e ); + virtual void mouseReleaseEvent( QMouseEvent * e ); + virtual void mouseMoveEvent( QMouseEvent * e ); + virtual void paintEvent( QPaintEvent *e ); + virtual void resizeEvent( QResizeEvent *event ); + + ProbeDataMap m_probeDataMap; + ProbeData *p_draggedProbe; + int m_probePosOffset; + + bool b_needRedraw; + QPixmap *m_pixmap; +}; + +#endif diff --git a/src/gui/processingoptionswidget.ui b/src/gui/processingoptionswidget.ui new file mode 100644 index 0000000..683092a --- /dev/null +++ b/src/gui/processingoptionswidget.ui @@ -0,0 +1,98 @@ + +ProcessingOptionsWidget + + + ProcessingOptionsWidget + + + + 0 + 0 + 458 + 40 + + + + Processing Options + + + + unnamed + + + 0 + + + + m_pMicroSelect + + + + 0 + 0 + + + + + + spacer2 + + + Vertical + + + Expanding + + + + 20 + 16 + + + + + + textLabel1 + + + Output File: + + + + + m_pOutputURL + + + + + + + MicroSelectWidget +
microselectwidget.h
+ + -1 + -1 + + 0 + + 5 + 5 + 0 + 0 + + image0 +
+
+ + + 89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000042949444154388db5954d6c545514c77ff7de37eff1a6a550da994e5ba798868f948fc847a2a2911816c436b0a02ed0083161a1981877ee10d90aa94656063491882c5cd4c4b8103f20cd806909a98604da8482341de80cb69de9bcd799799d79efba980f1da3a80b4f727273939bdff99f9b93f3175a6b6a21849080020c4002a29a8f0a5dcd002803bed63a1035f0d0d0504b6f6fef51d7758fa4d3e98d8ee3fc03af128ee3303939399548242eb8aefb09300f78464de9f0f0f0d148cc7caf3d5424de97a7ec17104220242805520a44557bbd4b21f083801d33e63a6d1bc7bf19c6064e0319a35a58b9ae7ba43d54e4d7c54b64dc097c7f09d30ef04b36736983cc7c11b4456b9b492c5e20dc54a6540e00896a8268a7017010f8bcae1830d2e9f4c69ebe3c197782b2ce60d94ddc9b30f9feeb45ae5d7181c5ead35636ef08d3ffe26a76ee3208b4031a56d80aa00768fda362e9380e25bf80ef3b587613d7afc099533380a4b5dda46fcb5aa42998b9eb7173dce5e6788e434763ec7fc942532008ea436003660d2caa7f8d69c3bd8910674e4d033e83877ad8d36fb0aa4d6058658ac5358c5df6383bf480f31fdda5a3632bbbfb6da4ccd5c00a10b2012cc12fd97cfb5516f0187c25cee0619396480ec3ca909d0f3372d1e5f9fe66de3ad605587c712ec55256a2540d5519d19ae24a29057329839f7ecc138944d833102290f3184ae1e6d6f0e98739c61229e6d21eafbed1c9c8c5558c8f3ee4ceed76946a1c43d97091828585223e2eebfbc295f60d45de89707628cb58224577bc85a79e5d4d786581cddb9b0148259711b20145836221400416e0232d1f6595c9ce4538773ac7b54406f0b15784e8e80aa1ac2594190220d021e49f2437960156b70ba095e95f96f18acd8c263cc6122962b1167a7ba34cdd7ec8c977a699bed546722a8fc2a02b6e2185fff78ab586ce78894ddb9ab9f5738ed14b1e030756929d8ff2e4ae5544632b38f96e89a99b298ebd6950cc2d12ed0eb3618b26f520788462ad09877df60db600f0f1fb49c646f21c7ebd836dcf94e9d9b4c0db27d6d3bd36c6426a96bce731703046d7da129a4670836284a054869d4f1b1c7e2dca67676ef3c1898091ef5ad8bc358c3205c93bf7c9a40ad4c660f4728edd7bbb3142ea2fc1da711cfc200011e08b45f6bd1c261adbce9717928c5f9d63fc6a19f0014567773303073790f8214bd6f5282dfbb8b9fa1f6b40d7c1939393533b92e63ad9240990484aec7e41b27d579cbb531e0f67023492d86316ebb768ba1e0f786e6f37e56550c62237aee7011e54abd7c1412291b8a06de378b4d3c0b215da9708e5a3a442192085404a83d4accfecac067c0c43e13a70e3fa12e96409e0325000966bbb354465339d04a6f9dd15fe6dde07ce030780278088d05ad72cc9a6b2f2daaaa74d75a1f0e8d0d5f60b40868a8364ead6248430000b0857a126ffcdf396abf03ce089ffcb4c7f033046c6b4a995e7a00000000049454e44ae426082 + + + + + microselectwidget.h + kurlrequester.h + klineedit.h + kpushbutton.h + +
diff --git a/src/gui/programmerdlg.cpp b/src/gui/programmerdlg.cpp new file mode 100644 index 0000000..a2186b4 --- /dev/null +++ b/src/gui/programmerdlg.cpp @@ -0,0 +1,90 @@ +/*************************************************************************** + * Copyright (C) 2005 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#include "language.h" +#include "microselectwidget.h" +#include "picprogrammer.h" +#include "port.h" +#include "programmerdlg.h" +#include "programmerwidget.h" +#include "src/core/ktlconfig.h" + +#include +#include +#include +#include + +ProgrammerDlg::ProgrammerDlg( const QString & picID, QWidget *parent, const char *name ) + : KDialogBase( parent, name, true, i18n("PIC Programmer"), Ok|Cancel ) +{ + // Change the "Ok" button to a "Burn" button + KGuiItem burnItem = KStdGuiItem::ok(); + burnItem.setText( i18n("Burn") ); + setButtonOK( burnItem ); + + m_bAccepted = false; + m_pProgrammerWidget = new ProgrammerWidget( this ); + m_pProgrammerSettings = new PicProgrammerSettings; + + // Setup the list of programmers + KComboBox * programmerCombo = m_pProgrammerWidget->m_pProgrammerProgram; + QStringList programmerNames = m_pProgrammerSettings->configNames( false ); + programmerCombo->insertStringList( programmerNames ); + programmerCombo->setSizeLimit( programmerNames.size() ); + programmerCombo->setCurrentText( KTLConfig::picProgrammerProgram() ); + + // Sets up the list of ports + m_pProgrammerWidget->m_pPicProgrammerPort->insertStringList( Port::ports( Port::ExistsAndRW ) ); + m_pProgrammerWidget->m_pPicProgrammerPort->setCurrentText( KTLConfig::picProgrammerPort() ); + + // Set the pic type to the one requested + if ( !picID.isEmpty() ) + m_pProgrammerWidget->m_pMicroSelect->setMicro( picID ); + + setMainWidget( m_pProgrammerWidget ); +} + + +ProgrammerDlg::~ProgrammerDlg() +{ +} + + +void ProgrammerDlg::initOptions( ProcessOptions * options ) +{ + if ( !options ) + return; + + options->m_picID = m_pProgrammerWidget->m_pMicroSelect->micro(); + options->m_port = m_pProgrammerWidget->m_pPicProgrammerPort->currentText(); + options->m_program = m_pProgrammerWidget->m_pProgrammerProgram->currentText(); +} + + +void ProgrammerDlg::accept() +{ + m_bAccepted = true; + hide(); +} + + +void ProgrammerDlg::reject() +{ + m_bAccepted = false; +} + + +MicroSelectWidget * ProgrammerDlg::microSelect( ) const +{ + return m_pProgrammerWidget->m_pMicroSelect; +} + + +#include "programmerdlg.moc" diff --git a/src/gui/programmerdlg.h b/src/gui/programmerdlg.h new file mode 100644 index 0000000..ab64e5a --- /dev/null +++ b/src/gui/programmerdlg.h @@ -0,0 +1,54 @@ +/*************************************************************************** + * Copyright (C) 2005 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#ifndef PROGRAMMERDLG_H +#define PROGRAMMERDLG_H + +#include + +class MicroSelectWidget; +class PicProgrammerSettings; +class ProcessOptions; +class ProgrammerWidget; + + +/** +@author David Saxton +*/ +class ProgrammerDlg : public KDialogBase +{ + Q_OBJECT + public: + /** + * Create a new ProgrammerDlg with the PIC type set to picID. Other + * options (such as the program to use) will be read in from the + * settings. + */ + ProgrammerDlg( const QString & picID, QWidget * parent = 0, const char * name = 0 ); + ~ProgrammerDlg(); + + virtual void reject(); + virtual void accept(); + bool isAccepted() const { return m_bAccepted; } + /** + * Initialises options with the values that the user has entered into + * the widgets. + */ + void initOptions( ProcessOptions * options ); + + MicroSelectWidget * microSelect() const; + + protected: + bool m_bAccepted; + ProgrammerWidget * m_pProgrammerWidget; + PicProgrammerSettings * m_pProgrammerSettings; +}; + +#endif diff --git a/src/gui/programmerwidget.ui b/src/gui/programmerwidget.ui new file mode 100644 index 0000000..3436ac1 --- /dev/null +++ b/src/gui/programmerwidget.ui @@ -0,0 +1,123 @@ + +ProgrammerWidget + + + ProgrammerWidget + + + + 0 + 0 + 320 + 96 + + + + Programmer + + + + unnamed + + + 0 + + + + textLabel1_3 + + + Program: + + + + + m_pProgrammerProgram + + + + 1 + 0 + 1 + 0 + + + + false + + + + + m_pMicroSelect + + + + 0 + 0 + + + + + + textLabel1 + + + Port + + + + + m_pPicProgrammerPort + + + true + + + + + spacer4 + + + Vertical + + + Expanding + + + + 20 + 0 + + + + + + + + MicroSelectWidget +
microselectwidget.h
+ + -1 + -1 + + 0 + + 5 + 5 + 0 + 0 + + image0 +
+
+ + + 89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000042949444154388db5954d6c545514c77ff7de37eff1a6a550da994e5ba798868f948fc847a2a2911816c436b0a02ed0083161a1981877ee10d90aa94656063491882c5cd4c4b8103f20cd806909a98604da8482341de80cb69de9bcd799799d79efba980f1da3a80b4f727273939bdff99f9b93f3175a6b6a21849080020c4002a29a8f0a5dcd002803bed63a1035f0d0d0504b6f6fef51d7758fa4d3e98d8ee3fc03af128ee3303939399548242eb8aefb09300f78464de9f0f0f0d148cc7caf3d5424de97a7ec17104220242805520a44557bbd4b21f083801d33e63a6d1bc7bf19c6064e0319a35a58b9ae7ba43d54e4d7c54b64dc097c7f09d30ef04b36736983cc7c11b4456b9b492c5e20dc54a6540e00896a8268a7017010f8bcae1830d2e9f4c69ebe3c197782b2ce60d94ddc9b30f9feeb45ae5d7181c5ead35636ef08d3ffe26a76ee3208b4031a56d80aa00768fda362e9380e25bf80ef3b587613d7afc099533380a4b5dda46fcb5aa42998b9eb7173dce5e6788e434763ec7fc942532008ea436003660d2caa7f8d69c3bd8910674e4d033e83877ad8d36fb0aa4d6058658ac5358c5df6383bf480f31fdda5a3632bbbfb6da4ccd5c00a10b2012cc12fd97cfb5516f0187c25cee0619396480ec3ca909d0f3372d1e5f9fe66de3ad605587c712ec55256a2540d5519d19ae24a29057329839f7ecc138944d833102290f3184ae1e6d6f0e98739c61229e6d21eafbed1c9c8c5558c8f3ee4ceed76946a1c43d97091828585223e2eebfbc295f60d45de89707628cb58224577bc85a79e5d4d786581cddb9b0148259711b20145836221400416e0232d1f6595c9ce4538773ac7b54406f0b15784e8e80aa1ac2594190220d021e49f2437960156b70ba095e95f96f18acd8c263cc6122962b1167a7ba34cdd7ec8c977a699bed546722a8fc2a02b6e2185fff78ab586ce78894ddb9ab9f5738ed14b1e030756929d8ff2e4ae5544632b38f96e89a99b298ebd6950cc2d12ed0eb3618b26f520788462ad09877df60db600f0f1fb49c646f21c7ebd836dcf94e9d9b4c0db27d6d3bd36c6426a96bce731703046d7da129a4670836284a054869d4f1b1c7e2dca67676ef3c1898091ef5ad8bc358c3205c93bf7c9a40ad4c660f4728edd7bbb3142ea2fc1da711cfc200011e08b45f6bd1c261adbce9717928c5f9d63fc6a19f0014567773303073790f8214bd6f5282dfbb8b9fa1f6b40d7c1939393533b92e63ad9240990484aec7e41b27d579cbb531e0f67023492d86316ebb768ba1e0f786e6f37e56550c62237aee7011e54abd7c1412291b8a06de378b4d3c0b215da9708e5a3a442192085404a83d4accfecac067c0c43e13a70e3fa12e96409e0325000966bbb354465339d04a6f9dd15fe6dde07ce030780278088d05ad72cc9a6b2f2daaaa74d75a1f0e8d0d5f60b40868a8364ead6248430000b0857a126ffcdf396abf03ce089ffcb4c7f033046c6b4a995e7a00000000049454e44ae426082 + + + + + kcombobox.h + microselectwidget.h + +
diff --git a/src/gui/projectdlgs.cpp b/src/gui/projectdlgs.cpp new file mode 100644 index 0000000..4ea18c0 --- /dev/null +++ b/src/gui/projectdlgs.cpp @@ -0,0 +1,275 @@ +/*************************************************************************** + * Copyright (C) 2005 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#include "createsubprojectwidget.h" +#include "linkeroptionswidget.h" +#include "microlibrary.h" +#include "microselectwidget.h" +#include "newprojectwidget.h" +#include "processingoptionswidget.h" +#include "projectdlgs.h" +#include "projectmanager.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//BEGIN class NewProjectDlg +NewProjectDlg::NewProjectDlg( QWidget * parent ) + : KDialogBase( parent, "newprojectdlg", true, "New Project", KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Ok, true ) +{ + m_pWidget = new NewProjectWidget(this); + connect( m_pWidget->projectNameEdit, SIGNAL(textChanged(const QString & )), this, SLOT(locationChanged(const QString& )) ); + connect( m_pWidget->projectLocationURL, SIGNAL(textChanged(const QString & )), this, SLOT(locationChanged(const QString& )) ); + + // Check if already valid dir + locationChanged( QString::null ); + + m_pWidget->projectLocationURL->setURL( QDir::homeDirPath() ); + m_pWidget->projectLocationURL->setMode( KFile::Directory ); + + setMainWidget( m_pWidget ); + setInitialSize( m_pWidget->rect().size() ); +} + +void NewProjectDlg::accept() +{ + hide(); + + m_bAccepted = true; + + m_projectName = m_pWidget->projectNameEdit->text(); + m_projectLocation = m_pWidget->projectLocationURL->url(); +} + +void NewProjectDlg::reject() +{ + m_bAccepted = false; +} + +void NewProjectDlg::locationChanged( const QString & ) +{ + m_location = m_pWidget->projectLocationURL->url(); + QDir subDir(m_location); + + if ( !m_location.endsWith("/") ) + m_location.append("/"); + + if ( !m_pWidget->projectNameEdit->text().isEmpty() ) + m_location.append( m_pWidget->projectNameEdit->text().lower() + "/" ); + + m_pWidget->locationLabel->setText( m_location ); + + QDir dir(m_location); + + if ( dir.exists() || !subDir.exists() ) + enableButtonOK(false); + + else + enableButtonOK(true); +} +//END class NewProjectDlg + + + +//BEGIN class CreateSubprojectDlg +CreateSubprojectDlg::CreateSubprojectDlg( QWidget * parent ) + : KDialogBase( parent, "Create Subproject Dialog", true, "Create Subproject", KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Ok, true ) +{ + m_pWidget = new CreateSubprojectWidget(this); + + if ( ProjectManager::self()->currentProject() ) + m_pWidget->m_targetFile->setURL( ProjectManager::self()->currentProject()->directory() ); + + m_type = ProgramType; + + setMainWidget( m_pWidget ); + setInitialSize( m_pWidget->rect().size() ); +} + + +CreateSubprojectDlg::~CreateSubprojectDlg() +{ +} + + +void CreateSubprojectDlg::accept() +{ + hide(); + + m_bAccepted = true; + + m_targetFile = m_pWidget->m_targetFile->url(); + m_type = (Type)m_pWidget->m_typeCombo->currentItem(); +} + + +void CreateSubprojectDlg::reject() +{ + m_bAccepted = false; +} +//END class CreateSubprojectDlg + + + +//BEGIN class LinkerOptionsDlg +LinkerOptionsDlg::LinkerOptionsDlg( LinkerOptions * linkingOptions, QWidget *parent ) + : KDialogBase( parent, "Linker Options Dialog", true, "Linker Options", KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Ok, true ) +{ + m_pLinkerOptions = linkingOptions; + m_pWidget = new LinkerOptionsWidget(this); + + ProjectInfo * pi = ProjectManager::self()->currentProject(); + assert(pi); + + + //BEGIN Update gplink options + m_pWidget->m_pHexFormat->setCurrentItem( m_pLinkerOptions->hexFormat() ); + m_pWidget->m_pOutputMap->setChecked( m_pLinkerOptions->outputMapFile() ); + m_pWidget->m_pLibraryDir->setText( m_pLinkerOptions->libraryDir() ); + m_pWidget->m_pLinkerScript->setText( m_pLinkerOptions->linkerScript() ); + m_pWidget->m_pOther->setText( m_pLinkerOptions->linkerOther() ); + //END Update gplink options + + + + //BEGIN Update library widgets + const KURL::List availableInternal = pi->childOutputURLs( ProjectItem::LibraryType ); + const QStringList linkedInternal = m_pLinkerOptions->linkedInternal(); + + KURL::List::const_iterator end = availableInternal.end(); + for ( KURL::List::const_iterator it = availableInternal.begin(); it != end; ++it ) + { + QString relativeURL = KURL::relativeURL( pi->url(), *it ); + QCheckListItem * item = new QCheckListItem( m_pWidget->m_pInternalLibraries, relativeURL, QCheckListItem::CheckBox ); + item->setOn( linkedInternal.contains(relativeURL) ); + } + + m_pExternalLibraryRequester = new KURLRequester( 0l ); + m_pExternalLibraryRequester->fileDialog()->setURL( "/usr/share/sdcc/lib" ); + + delete m_pWidget->m_pExternalLibraries; + m_pWidget->m_pExternalLibraries = new KEditListBox( i18n("Link libraries outside project"), m_pExternalLibraryRequester->customEditor(), m_pWidget ); + m_pWidget->m_pExternalLibraries->layout()->setMargin(11); + (dynamic_cast(m_pWidget->layout()))->addMultiCellWidget( m_pWidget->m_pExternalLibraries, 7, 7, 0, 1 ); + +#if defined(KDE_MAKE_VERSION) +# if KDE_VERSION >= KDE_MAKE_VERSION(3,4,0) + m_pWidget->m_pExternalLibraries->setButtons( KEditListBox::Add | KEditListBox::Remove ); +# endif +#endif + m_pWidget->m_pExternalLibraries->insertStringList( m_pLinkerOptions->linkedExternal() ); + //END Update library widgets + + + setMainWidget( m_pWidget ); + setInitialSize( m_pWidget->rect().size() ); +} + + +LinkerOptionsDlg::~LinkerOptionsDlg() +{ + delete m_pExternalLibraryRequester; +} + + +void LinkerOptionsDlg::accept() +{ + hide(); + + QStringList linkedInternal; + for ( QListViewItemIterator internalIt( m_pWidget->m_pInternalLibraries ); internalIt.current(); ++internalIt ) + { + QCheckListItem * item = static_cast(internalIt.current()); + if ( item->isOn() ) + linkedInternal << item->text(); + } + m_pLinkerOptions->setLinkedInternal( linkedInternal ); + + m_pLinkerOptions->setLinkedExternal( m_pWidget->m_pExternalLibraries->items() ); + m_pLinkerOptions->setHexFormat( (LinkerOptions::HexFormat::type) m_pWidget->m_pHexFormat->currentItem() ); + m_pLinkerOptions->setOutputMapFile( m_pWidget->m_pOutputMap->isChecked() ); + m_pLinkerOptions->setLibraryDir( m_pWidget->m_pLibraryDir->text() ); + m_pLinkerOptions->setLinkerScript( m_pWidget->m_pLinkerScript->text() ); + m_pLinkerOptions->setLinkerOther( m_pWidget->m_pOther->text() ); +} + + +void LinkerOptionsDlg::reject() +{ +} +//END class LinkerOptionsDlg + + + +//BEGIN class ProcessingOptionsDlg +ProcessingOptionsDlg::ProcessingOptionsDlg( ProjectItem * projectItem, QWidget *parent ) + : KDialogBase( parent, "Processing Options Dialog", true, "Processing Options", KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Ok, true ) +{ + m_pProjectItem = projectItem; + m_pWidget = new ProcessingOptionsWidget(this); + + m_pWidget->m_pMicroSelect->setEnabled( !projectItem->useParentMicroID() ); + + switch ( projectItem->type() ) + { + case ProjectItem::ProjectType: + m_pWidget->m_pOutputURL->setEnabled(false); + break; + + case ProjectItem::FileType: + m_pWidget->m_pOutputURL->setEnabled(true); + break; + + case ProjectItem::ProgramType: + case ProjectItem::LibraryType: + m_pWidget->m_pOutputURL->setEnabled(false); + break; + } + + m_pWidget->m_pOutputURL->setURL( projectItem->outputURL().path() ); + m_pWidget->m_pMicroSelect->setMicro( projectItem->microID() ); + + setMainWidget( m_pWidget ); + setInitialSize( m_pWidget->rect().size() ); +} + + +ProcessingOptionsDlg::~ProcessingOptionsDlg() +{ +} + + +void ProcessingOptionsDlg::accept() +{ + hide(); + + if ( m_pWidget->m_pOutputURL->isEnabled() ) + m_pProjectItem->setOutputURL( m_pWidget->m_pOutputURL->url() ); + + if ( m_pWidget->m_pMicroSelect->isEnabled() ) + m_pProjectItem->setMicroID( m_pWidget->m_pMicroSelect->micro() ); +} + + +void ProcessingOptionsDlg::reject() +{ +} +//END class ProcessingOptionsDlg + + diff --git a/src/gui/projectdlgs.h b/src/gui/projectdlgs.h new file mode 100644 index 0000000..fe50361 --- /dev/null +++ b/src/gui/projectdlgs.h @@ -0,0 +1,159 @@ +/*************************************************************************** + * Copyright (C) 2005 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#ifndef PROJECTDLGS_H +#define PROJECTDLGS_H + +#include + +class CreateSubprojectWidget; +class LinkerOptions; +class LinkerOptionsWidget; +class KURLRequester; +class NewProjectWidget; +class ProcessingOptions; +class ProcessingOptionsWidget; +class ProjectItem; + +/** +A standard dialog for getting project details from the user for a new project +@short Dialog for new project details +@author David Saxton +*/ +class NewProjectDlg : public KDialogBase +{ + Q_OBJECT + public: + NewProjectDlg( QWidget * parent ); + + /** + * Called when the 'Cancel' button is pressed. + */ + void reject(); + + /** + * Called when the 'OK' button is pressed. + * User entered values are read in + */ + void accept(); + + bool accepted() const { return m_bAccepted; } + QString projectName() const { return m_projectName; } + QString projectLocation() const { return m_projectLocation; } + QString location() const { return m_location; } + + public slots: + /** + * Called when the projectName or projectLocation edit boxes are edited. + * Checks whether the resultant location combination is a valid path - + * if so, enabels the OK button; otherwise disables it. + */ + void locationChanged( const QString & ); + + protected: + NewProjectWidget * m_pWidget; + bool m_bAccepted; + QString m_projectName; + QString m_projectLocation; + QString m_location; +}; + + +/** +@author David Saxton +*/ +class CreateSubprojectDlg : public KDialogBase +{ + Q_OBJECT + public: + CreateSubprojectDlg( QWidget *parent = 0 ); + ~CreateSubprojectDlg(); + + // The following values should agree with the positions in the combo box + enum Type + { + ProgramType = 0, + LibraryType = 1 + }; + + /** + * Called when the 'Cancel' button is pressed. + */ + void reject(); + /** + * Called when the 'OK' button is pressed. User entered values are read + * in. + */ + void accept(); + + bool accepted() const { return m_bAccepted; } + Type type() const { return m_type; } + QString targetFile() const { return m_targetFile; } + + protected: + CreateSubprojectWidget * m_pWidget; + bool m_bAccepted; + Type m_type; + QString m_targetFile; +}; + + +/** +@author David Saxton +*/ +class LinkerOptionsDlg : public KDialogBase +{ + Q_OBJECT + public: + LinkerOptionsDlg( LinkerOptions * linkingOptions, QWidget *parent = 0 ); + virtual ~LinkerOptionsDlg(); + + /** + * Called when the 'Cancel' button is pressed. + */ + void reject(); + /** + * Called when the 'OK' button is pressed. User entered values are read + * in. + */ + void accept(); + + protected: + LinkerOptions * m_pLinkerOptions; + LinkerOptionsWidget * m_pWidget; + KURLRequester * m_pExternalLibraryRequester; +}; + + +/** +@author David Saxton +*/ +class ProcessingOptionsDlg : public KDialogBase +{ + public: + ProcessingOptionsDlg( ProjectItem * projectItem, QWidget *parent = 0 ); + virtual ~ProcessingOptionsDlg(); + + /** + * Called when the 'Cancel' button is pressed. + */ + void reject(); + /** + * Called when the 'OK' button is pressed. User entered values are read + * in. + */ + void accept(); + + protected: + ProjectItem * m_pProjectItem; + ProcessingOptionsWidget * m_pWidget; +}; + +#endif diff --git a/src/gui/propertieslistview.cpp b/src/gui/propertieslistview.cpp new file mode 100644 index 0000000..5f57aa3 --- /dev/null +++ b/src/gui/propertieslistview.cpp @@ -0,0 +1,328 @@ +/*************************************************************************** + * Copyright (C) 2003-2004 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#include "item.h" +#include "cnitemgroup.h" +#include "itemgroup.h" +#include "iteminterface.h" +#include "pieditor.h" +#include "plvitem.h" +#include "propertieslistview.h" +#include "variant.h" + + +#include +#include +#include +#include +#include +#include + +PropertiesListView::PropertiesListView(QWidget *parent, const char *name) + : KListView(parent, name) +{ + addColumn(i18n("Property")); + addColumn(i18n("Data")); + setFullWidth(true); + setColumnAlignment(1,Qt::AlignRight); + + p_lastItem = 0l; + m_diffBt = 0L; + + connect(this,SIGNAL(selectionChanged(QListViewItem*)),this,SLOT(slotSelectionChanged(QListViewItem*))); + m_editor = 0L; + connect(header(),SIGNAL(sizeChange(int,int,int)),this,SLOT(headerSizeChanged(int,int,int))); +} + +PropertiesListView::~PropertiesListView() +{ +} + +void PropertiesListView::slotClear() +{ + destroyEditor(); + delete m_diffBt; + m_diffBt = 0L; + clear(); + m_plvItemMap.clear(); +} + +void PropertiesListView::slotCreate( ItemGroup * itemGroup ) +{ + if ( !itemGroup || !itemGroup->activeItem() ) + { + slotClear(); + return; + } + + Item *item = itemGroup->activeItem(); + + VariantDataMap *vmap = item->variantMap(); + // Build the list + for( VariantDataMap::iterator vait = vmap->begin(); vait != vmap->end(); ++vait ) + { + if ( vait.data()->isHidden() ) + continue; + + switch( vait.data()->type() ) + { + case Variant::Type::Int: + case Variant::Type::Double: + case Variant::Type::String: + case Variant::Type::FileName: + case Variant::Type::Port: + case Variant::Type::Pin: + case Variant::Type::VarName: + case Variant::Type::Combo: + case Variant::Type::Select: + case Variant::Type::Bool: + case Variant::Type::PenStyle: + case Variant::Type::PenCapStyle: + case Variant::Type::SevenSegment: + case Variant::Type::KeyPad: + { + m_plvItemMap[vait.key()] = new PLVItem( this, vait.key(), vait.data() ); + break; + } + case Variant::Type::Color: + { + m_plvItemMap[vait.key()] = new PLVColorItem( this, vait.key(), vait.data() ); + break; + } + case Variant::Type::Raw: + case Variant::Type::Multiline: + case Variant::Type::None: + { + break; + } + } + } + + slotUpdate(itemGroup); +} + + +void PropertiesListView::slotUpdate( ItemGroup * itemGroup ) +{ + if ( !itemGroup ) + { + slotClear(); + return; + } + + const PLVItemMap::iterator end = m_plvItemMap.end(); + for ( PLVItemMap::iterator it = m_plvItemMap.begin(); it != end; ++it ) + { + it.data()->setEnabled( itemGroup->itemsHaveSameDataValue( it.key() ) ); + } +} + +void PropertiesListView::slotSelectionChanged(QListViewItem *item) +{ + if (!item) return; + destroyEditor(); + p_lastItem = dynamic_cast(item); + if ( !p_lastItem->data() ) return; + + const Variant::Type::Value type = p_lastItem->data()->type(); + switch(type) + { + case Variant::Type::String: + { + m_editor = new PILineEdit(p_lastItem->id(),p_lastItem->data(),this); + break; + } + case Variant::Type::Port: + case Variant::Type::Pin: + case Variant::Type::Combo: + case Variant::Type::VarName: + case Variant::Type::Select: + case Variant::Type::PenStyle: + case Variant::Type::PenCapStyle: + case Variant::Type::SevenSegment: + case Variant::Type::KeyPad: + { + m_editor = new PIStringCombo(p_lastItem->id(),p_lastItem->data(),this); + break; + } + case Variant::Type::FileName: + { + m_editor = new PIFilename(p_lastItem->id(),p_lastItem->data(),this); + break; + } + case Variant::Type::Int: + { + m_editor = new PIInt(p_lastItem->id(),p_lastItem->data(),this); + break; + } + case Variant::Type::Double: + { + m_editor = new PIDouble(p_lastItem->id(),p_lastItem->data(),this); + break; + } + case Variant::Type::Color: + { + m_editor = new PIColor(p_lastItem->id(),p_lastItem->data(),this); + break; + } + case Variant::Type::Bool: + { + m_editor = new PIBool(p_lastItem->id(),p_lastItem->data(),this); + break; + } + case Variant::Type::Raw: + case Variant::Type::Multiline: + case Variant::Type::None: + { + break; + } + } + + connect(p_lastItem->data(),SIGNAL(destroyed()),this,SLOT(destroyEditor())); + // Connect so that changes in the editor change the canvas item data. + connect(m_editor,SIGNAL(editorDataChanged(const QString&,QVariant)),ItemInterface::self(),SLOT(slotSetData(const QString&,QVariant))); + connect(m_editor,SIGNAL(editorDataChanged(const QString&,QVariant)),this,SLOT(slotDataChanged(const QString&,QVariant))); + + int x = columnWidth(0); + int y = viewportToContents(QPoint(0,itemRect(p_lastItem).y())).y(); + addChild(m_editor,x,y); + m_editor->setFocus(); + m_editor->show(); + m_editor->setGeometry(QRect(x,y,columnWidth(1),itemRect(p_lastItem).height())); + + if(p_lastItem->data()->type() == Variant::Type::FileName) + { + // The folder button in the KURLComboBox has a minimum size taller than + // the height of the ListViewItems so this is a temporary kludge to + // make it look slightly acceptable. + m_editor->setGeometry(QRect(x,y,columnWidth(1),itemRect(p_lastItem).height()+7)); + } + + // Active the editor as appropriate + switch(type) + { + case Variant::Type::Port: + case Variant::Type::Pin: + case Variant::Type::Combo: + case Variant::Type::VarName: + case Variant::Type::Select: + case Variant::Type::PenStyle: + case Variant::Type::PenCapStyle: + case Variant::Type::SevenSegment: + case Variant::Type::KeyPad: + { + (static_cast(m_editor))->popup(); + break; + } + case Variant::Type::Color: + { + (static_cast(m_editor))->popup(); + break; + } + case Variant::Type::Bool: + { + (static_cast(m_editor))->popup(); + break; + } + case Variant::Type::FileName: + { + break; + } + case Variant::Type::Int: + { + break; + } + case Variant::Type::Double: + { + break; + } + case Variant::Type::String: + { + break; + } + case Variant::Type::Raw: + case Variant::Type::Multiline: + case Variant::Type::None: + { + break; + } + } +} + +void PropertiesListView::destroyEditor() +{ + if( !m_editor ) return; + + removeChild( m_editor ); + delete m_editor; + m_editor = 0L; +} + +void PropertiesListView::headerSizeChanged(int section, int /*oldSize*/, int newSize) +{ + if( !m_editor || section != 1 ) return; + + // Resize the editor to the new column width + // and move it to the right place. + QRect rect = m_editor->geometry(); + rect.setWidth(newSize); + rect.setX( columnWidth(0) ); + m_editor->setGeometry(rect); +} + +void PropertiesListView::slotDataChanged(const QString &/*id*/, QVariant data) +{ + PLVItem *pItem = static_cast(currentItem()); + pItem->updateData(data); +} + +void PropertiesListView::slotMergeProperties() +{ + for( QListViewItemIterator it( this ); it.current(); ++it ) + { + PLVItem * pItem = static_cast(it.current()); + if (pItem->isEnabled()) + continue; + + pItem->setEnabled(true); + // manually call the updates on the canvas + // and in the list + pItem->updateData(pItem->data()->defaultValue()); + ItemInterface::self()->slotSetData(pItem->id(),pItem->data()->defaultValue()); + } +} + + +void PropertiesListView::slotSetDefaults() +{ + for( QListViewItemIterator it( this ); it.current(); ++it ) + { + PLVItem *pItem = static_cast(it.current()); + ItemInterface::self()->slotSetData(pItem->id(),pItem->data()->defaultValue()); + } +} + + +void PropertiesListView::wheelEvent( QWheelEvent *e ) +{ + QPoint _pos = contentsToViewport(e->pos()); + _pos -= pos(); + _pos.setY( _pos.y()+header()->height() ); + QListViewItem *item = itemAt(_pos); + if ( item && item != dynamic_cast(p_lastItem) ) + { + e->accept(); + if(!item->isSelected()) slotSelectionChanged(item); + } + else KListView::wheelEvent(e); +} + +#include "propertieslistview.moc" + diff --git a/src/gui/propertieslistview.h b/src/gui/propertieslistview.h new file mode 100644 index 0000000..c6ad8f7 --- /dev/null +++ b/src/gui/propertieslistview.h @@ -0,0 +1,75 @@ +/*************************************************************************** + * Copyright (C) 2003-2004 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#ifndef PROPERTIESLISTVIEW_H +#define PROPERTIESLISTVIEW_H + +#include +#include + +class CNItemGroup; +class ItemGroup; +class PIEditor; +class PLVItem; +class QPushButton; + +typedef QMap< QString, PLVItem * > PLVItemMap; + +/** +@author Daniel Clarke +@author David Saxton +*/ +class PropertiesListView : public KListView +{ +Q_OBJECT +public: + PropertiesListView( QWidget *parent = 0l, const char *name = 0l ); + ~PropertiesListView(); + +public slots: + /** + * Creates a new set of property items and inserts them into the widget. + */ + void slotCreate( ItemGroup * itemGroup ); + /** + * Updates the set of property items (enables/disables according to whether + * the items have differing values, etc). This will be called by slotCreate, + * and any time new items are selected / unselected. + */ + void slotUpdate( ItemGroup * itemGroup ); + /** + * Removes all property items from the widget. + */ + void slotClear(); + void slotSelectionChanged(QListViewItem *item); + /** + * Whenthe selected items have different values, then the property editor + * for the disagreeing property will have a value taken from one of the + * items, but will also be disabled. This will enable all disabled property + * editors and set the items to the value contained. + */ + void slotMergeProperties(); + void slotSetDefaults(); + +protected slots: + void headerSizeChanged(int section, int oldSize, int newSize); + void slotDataChanged(const QString &id, QVariant data); + void destroyEditor(); + +protected: + virtual void wheelEvent( QWheelEvent *e ); + + PIEditor *m_editor; + QPushButton *m_diffBt; + PLVItem *p_lastItem; + PLVItemMap m_plvItemMap; +}; + +#endif diff --git a/src/gui/sdccoptionswidget.ui b/src/gui/sdccoptionswidget.ui new file mode 100644 index 0000000..218f796 --- /dev/null +++ b/src/gui/sdccoptionswidget.ui @@ -0,0 +1,586 @@ + +SDCCOptionsWidget + + + SDCCOptionsWidget + + + + 0 + 0 + 441 + 377 + + + + SDCC Options + + + + unnamed + + + 0 + + + + tabWidget12 + + + + general + + + Ge&neral + + + + unnamed + + + + kcfg_SDCC_nostdlib + + + Don't search in the standard librar&y directory (--nostdlib) + + + Alt+Y + + + + + kcfg_SDCC_nostdinc + + + Don't search in the standard include directory (--nostdinc) + + + + + + + + kcfg_SDCC_less_pedantic + + + Disa&ble pedantic warnings (--less-pedantic) + + + Alt+B + + + + + kcfg_SDCC_std_c89 + + + Use C&89 standard only (--std-c89) + + + Alt+8 + + + Follow the C89 standard and disable SDCC features that conflict with the standard. + + + + + kcfg_SDCC_std_c99 + + + Use C&99 standard only (--std-c99) + + + Alt+9 + + + + + + Follow the C99 standard and disable SDCC features that conflict with the standard (incomplete support). + + + + + spacer32 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + + code_generation + + + Code Gener&ation + + + + unnamed + + + + kcfg_SDCC_stack_auto + + + Stack auto&matic variables (--stack-auto) + + + Alt+M + + + + + + All functions in the source file will be compiled as reentrant, i.e. the parameters and local variables will be allocated on the stack. If this option is used all source files in the project should be compiled with this option. It automatically implies -int-long-reent and -float-reent. + + + + + kcfg_SDCC_int_long_reent + + + Integer li&braries were compiled as reentrant (--int-long-reent) + + + Alt+B + + + + + + Integer (16 bit) and long (32 bit) libraries have been compiled as reentrant. Note by default these libraries are compiled as non-reentrant. + + + + + kcfg_SDCC_float_reent + + + Floating point librar&y was compiled as reentrant (--float-reent) + + + Alt+Y + + + Floating point library is compiled as reentrant. + + + + + kcfg_SDCC_fommit_frame_pointer + + + Leave out the frame pointer (--fommit-frame-pointer) + + + + + + + + kcfg_SDCC_no_xinit_opt + + + Don't memcpy initialized &xram from code (--no-xinit-opt) + + + Alt+X + + + Will not memcpy initialized data from code space into xdata space. This saves a few bytes in code space if you don't have initialized data. + + + + + kcfg_SDCC_all_callee_saves + + + Callee will &always save registers used (--all-callee-saves) + + + Alt+A + + + + + spacer31 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + + optimization + + + &Optimization + + + + unnamed + + + + kcfg_SDCC_nooverlay + + + Disable overlaying leaf function &auto variables (--nooverlay) + + + Alt+A + + + The compiler will not overlay parameters and local variables of any function, see section Parameters and local variables for more details. + + + + + kcfg_SDCC_nogcse + + + Disable the GCSE optimization (--nogcse) + + + + + + + + kcfg_SDCC_nolabelopt + + + Disable label optimi&zation (--nolabelopt) + + + Alt+Z + + + Will not optimize labels (makes the dumpfiles more readable). + + + + + kcfg_SDCC_noinvariant + + + Disable optimization of invariants (--noinvariant) + + + + + + + + kcfg_SDCC_noinduction + + + Disable loop variable induction (--noinduction) + + + + + + + + kcfg_SDCC_no_peep + + + Disable peep-hole optimization (--&no-peep) + + + Alt+N + + + Disable peep-hole optimization. + + + + + kcfg_SDCC_noloopreverse + + + Disable loop reverse optimization (--noloopreverse) + + + + + + Will not do loop reversal optimization. + + + + + kcfg_SDCC_opt_code_size + + + Opti&mize for compact code (--opt-code-size) + + + Alt+M + + + The compiler will optimize code generation towards compact code, possibly at the expense of code speed. + + + + + kcfg_SDCC_opt_code_speed + + + &Optimize for fast code (--opt-code-speed) + + + Alt+O + + + The compiler will optimize code generation towards fast code, possibly at the expense of code size. + + + + + kcfg_SDCC_peep_asm + + + Ena&ble inline assembly peephole optimization (--peep-asm) + + + Alt+B + + + Pass the inline assembler code through the peep hole optimizer. This can cause unexpected changes to inline assembler code, please go through the peephole optimizer rules defined in the source file tree '<target>/peeph.def' before using this option. + + + + + kcfg_SDCC_nojtbound + + + Don't generate boundary check for &jump tables (--nojtbound) + + + Alt+J + + + + + spacer33 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + + pic16_specific + + + PIC&16 Specific + + + + unnamed + + + + kcfg_SDCC_nodefaultlibs + + + Don't use default libraries (--nodefaultlibs) + + + + + + + + kcfg_SDCC_pno_banksel + + + Don't generate BANKSEL directives (--pno-banksel) + + + + + + + + kcfg_SDCC_pstack_model_large + + + Use large stac&k model (--pstack-model=large) + + + Alt+K + + + + + kcfg_SDCC_debug_xtra + + + Show more debug info in assembl&y output (--debug-xtra) + + + Alt+Y + + + + + kcfg_SDCC_denable_peeps + + + E&xplicit enable of peepholes (--denable-peeps) + + + Alt+X + + + + + kcfg_SDCC_calltree + + + Du&mp call tree in .calltree file (--calltree) + + + Alt+M + + + + + kcfg_SDCC_fstack + + + Ena&ble stack optimizations (--fstack) + + + Alt+B + + + + + kcfg_SDCC_optimize_goto + + + Try to use conditional BRA instead of GOTO (--optimi&ze-goto) + + + Alt+Z + + + + + kcfg_SDCC_optimize_cmp + + + Try to optimize some compares (--optimize-cmp) + + + + + + + + kcfg_SDCC_optimize_df + + + Thorough data flow analyis (resource intensive) (--optimize-df) + + + + + + + + spacer34 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + + + kcfg_MiscSDCCOptions + + + + + textLabel2 + + + Other options: + + + + + spacer4 + + + Vertical + + + Expanding + + + + 20 + 16 + + + + + + + + klineedit.h + + diff --git a/src/gui/settingsdlg.cpp b/src/gui/settingsdlg.cpp new file mode 100644 index 0000000..3b42027 --- /dev/null +++ b/src/gui/settingsdlg.cpp @@ -0,0 +1,386 @@ +/*************************************************************************** + * Copyright (C) 2005 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#include "asmformattingwidget.h" +#include "generaloptionswidget.h" +#include "gpasmsettingswidget.h" +#include "logicwidget.h" +#include "picprogrammerconfigwidget.h" +#include "picprogrammer.h" +#include "port.h" +#include "sdccoptionswidget.h" +#include "settingsdlg.h" +#include "src/core/ktlconfig.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Make sure that this value is the same as that in ktechlab.kcfg +const int defaultRefreshRate = 50; + +SettingsDlg::SettingsDlg( QWidget *parent, const char *name, KConfigSkeleton *config ) + : KConfigDialog( parent, name, config ) +{ + m_generalOptionsWidget = new GeneralOptionsWidget( this, "generalOptionsWidget" ); + m_gpasmSettingsWidget = new GpasmSettingsWidget( this, "gpasmSettingsWidget" ); + m_sdccOptionsWidget = new SDCCOptionsWidget( this, "sdccOptionsWidget" ); + m_asmFormattingWidget = new AsmFormattingWidget( this, "asmFormattingWidget" ); + m_logicWidget = new LogicWidget( this, "logicWidget" ); + m_picProgrammerConfigWidget = new PicProgrammerConfigWidget( this, "picProgrammerConfigWidget" ); + + m_pPicProgrammerSettings = new PicProgrammerSettings; + + m_logicWidget->kcfg_LogicOutputHighImpedance->setSuffix( QString(" ") + QChar(0x3a9) ); + m_logicWidget->kcfg_LogicOutputLowImpedance->setSuffix( QString(" ") + QChar(0x3a9) ); + + addPage( m_generalOptionsWidget, i18n("General"), "misc", i18n("General Options") ); + addPage( m_picProgrammerConfigWidget, i18n("Programmer"), "memory", i18n("PIC Programmer") ); + addPage( m_asmFormattingWidget, i18n("Formatter"), "indent_asm", i18n("Assembly Formatter") ); + addPage( m_logicWidget, i18n("Logic"), "logic_or", i18n("Electronic Logic Values") ); + addPage( m_gpasmSettingsWidget, "Gpasm", "convert_to_hex", "gpasm" ); + addPage( m_sdccOptionsWidget, "SDCC", "source_c", "SDCC" ); + + connect( m_generalOptionsWidget->refreshRateSlider, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateRefreshRateLabel(int)) ); + connect( m_picProgrammerConfigWidget->kcfg_PicProgrammerProgram, SIGNAL(activated(const QString &)), this, SLOT(slotUpdatePicProgrammerDescription()) ); + connect( m_picProgrammerConfigWidget->removeButton, SIGNAL(clicked()), this, SLOT(slotRemoveProgrammerConfig()) ); + connect( m_picProgrammerConfigWidget->addButton, SIGNAL(clicked()), this, SLOT(slotAddProgrammerConfig()) ); + + + connect( m_picProgrammerConfigWidget->initCommand, SIGNAL(textChanged(const QString &)), this, SLOT(slotSaveCurrentProgrammerConfig()) ); + connect( m_picProgrammerConfigWidget->readCommand, SIGNAL(textChanged(const QString &)), this, SLOT(slotSaveCurrentProgrammerConfig()) ); + connect( m_picProgrammerConfigWidget->writeCommand, SIGNAL(textChanged(const QString &)), this, SLOT(slotSaveCurrentProgrammerConfig()) ); + connect( m_picProgrammerConfigWidget->verifyCommand, SIGNAL(textChanged(const QString &)), this, SLOT(slotSaveCurrentProgrammerConfig()) ); + connect( m_picProgrammerConfigWidget->blankCheckCommand, SIGNAL(textChanged(const QString &)), this, SLOT(slotSaveCurrentProgrammerConfig()) ); + connect( m_picProgrammerConfigWidget->eraseCommand, SIGNAL(textChanged(const QString &)), this, SLOT(slotSaveCurrentProgrammerConfig()) ); + + + m_generalOptionsWidget->kcfg_GridColor->setEnabled( KTLConfig::showGrid() ); + + m_picProgrammerConfigWidget->kcfg_PicProgrammerPort->insertStringList( Port::ports( Port::ExistsAndRW ) ); + slotUpdatePicProgrammerDescription(); +} + + +SettingsDlg::~SettingsDlg() +{ + delete m_pPicProgrammerSettings; +} + + +void SettingsDlg::show() +{ + KComboBox * combo = m_picProgrammerConfigWidget->kcfg_PicProgrammerProgram; + combo->setEditable( true ); + KConfigDialog::show(); + combo->setEditable( false ); +} + + +void SettingsDlg::slotUpdateRefreshRateLabel( int sliderValue ) +{ + const QString number = QString::number( sliderValueToRefreshRate(sliderValue) ); + switch(sliderValue) + { + case 0: + m_generalOptionsWidget->refreshRateLabel->setText( i18n("Lowest (%1 FPS)").arg(number) ); + break; + case 1: + m_generalOptionsWidget->refreshRateLabel->setText( i18n("Low (%1 FPS)").arg(number) ); + break; + case 2: + m_generalOptionsWidget->refreshRateLabel->setText( i18n("Medium (%1 FPS)").arg(number) ); + break; + case 3: + m_generalOptionsWidget->refreshRateLabel->setText( i18n("High (%1 FPS)").arg(number) ); + break; + case 4: + m_generalOptionsWidget->refreshRateLabel->setText( i18n("Highest (%1 FPS)").arg(number) ); + break; + default: + m_generalOptionsWidget->refreshRateLabel->setText( i18n("Unknown value") ); + break; + } + updateButtons(); +} + + +void SettingsDlg::slotUpdatePicProgrammerDescription() +{ + QString program = m_picProgrammerConfigWidget->kcfg_PicProgrammerProgram->currentText(); + + ProgrammerConfig config = m_pPicProgrammerSettings->config( program ); + QString description = config.description; + + bool customProgrammer = ! m_pPicProgrammerSettings->isPredefined( program ); + + QString executable = config.executable; + if ( executable.isEmpty() ) + executable = program.lower(); + + QString programLocation = KStandardDirs::findExe( executable ); + if ( programLocation.isNull() ) + description.prepend( i18n("%1 cannot be found.
").arg( executable ) ); + else + description.prepend( i18n("%1 found: %2
").arg( executable ).arg(programLocation) ); + + m_picProgrammerConfigWidget->m_pProgrammerDescription->setText( description ); + m_picProgrammerConfigWidget->removeButton->setEnabled( customProgrammer ); + + KLineEdit * edit; + +#define SETUP_COMMAND( name ) \ + edit = m_picProgrammerConfigWidget->name; \ + edit->setText( config.name ); \ + edit->setEnabled(customProgrammer); \ + QToolTip::add( edit, customProgrammer ? 0 : config.name ) + + SETUP_COMMAND( initCommand ); + SETUP_COMMAND( readCommand ); + SETUP_COMMAND( writeCommand ); + SETUP_COMMAND( verifyCommand ); + SETUP_COMMAND( blankCheckCommand ); + SETUP_COMMAND( eraseCommand ); + +#undef SETUP_COMMAND +} + + +void SettingsDlg::slotSaveCurrentProgrammerConfig() +{ + QString program = m_picProgrammerConfigWidget->kcfg_PicProgrammerProgram->currentText(); + + if ( m_pPicProgrammerSettings->isPredefined( program ) ) + return; + + ProgrammerConfig config; + + config.initCommand = m_picProgrammerConfigWidget->initCommand->text(); + config.readCommand = m_picProgrammerConfigWidget->readCommand->text(); + config.writeCommand = m_picProgrammerConfigWidget->writeCommand->text(); + config.verifyCommand = m_picProgrammerConfigWidget->verifyCommand->text(); + config.blankCheckCommand = m_picProgrammerConfigWidget->blankCheckCommand->text(); + config.eraseCommand = m_picProgrammerConfigWidget->eraseCommand->text(); + + m_pPicProgrammerSettings->saveConfig( program, config ); +} + + +void SettingsDlg::slotRemoveProgrammerConfig() +{ + KComboBox * combo = m_picProgrammerConfigWidget->kcfg_PicProgrammerProgram; + + QString program = combo->currentText(); + + KMessageBox::ButtonCode confirm = (KMessageBox::ButtonCode)KMessageBox::warningContinueCancel( this, i18n("Remove programmer configuration \"%1\"?").arg(program), i18n("Remove \"%1\"").arg(program), i18n("Remove") ); + if ( confirm == KMessageBox::Cancel ) + return; + + m_pPicProgrammerSettings->removeConfig( program ); + combo->removeItem( combo->currentItem() ); + slotUpdatePicProgrammerDescription(); +} + + +class NameValidator : public QValidator +{ + public: + NameValidator( QStringList unallowed ) + : QValidator(0) { + m_unallowed = unallowed; + } + + virtual State validate( QString & input, int & ) const { + return (input.isEmpty() || m_unallowed.contains( input.lower() )) ? Intermediate : Acceptable; + } + + protected: + QStringList m_unallowed; +}; + + +void SettingsDlg::slotAddProgrammerConfig() +{ + KComboBox * combo = m_picProgrammerConfigWidget->kcfg_PicProgrammerProgram; + + QStringList takenNames; + int count = combo->count(); + for ( int i = 0; i < count; ++i ) + takenNames << combo->text(i).lower(); + + NameValidator * nv = new NameValidator( takenNames ); + + bool ok = false; + QString name = KInputDialog::getText( i18n("Configuration Name"), i18n("Name"), 0, &ok, this, 0, nv ); + + delete nv; + + if (!ok) + return; + + ProgrammerConfig config; + config.executable = name.lower(); + + m_pPicProgrammerSettings->saveConfig( name, config ); + + combo->insertItem( name ); + combo->setCurrentItem( count ); + slotUpdatePicProgrammerDescription(); +} + + +int SettingsDlg::refreshRateToSliderValue( int refreshRate ) +{ + switch (refreshRate) + { + case 10: return 0; + case 25: return 1; + case 50: return 2; + case 75: return 3; + case 100: return 4; + default: return -1; + } +} + + +int SettingsDlg::sliderValueToRefreshRate( int sliderValue ) +{ + switch (sliderValue) + { + case 0: return 10; + case 1: return 25; + case 2: return 50; + case 3: return 75; + case 4: return 100; + default: return -1; + } +} + + +void SettingsDlg::updateSettings() +{ + KConfig * config = kapp->config(); + + KConfigSkeleton::ItemInt *item = dynamic_cast(KTLConfig::self()->findItem( "RefreshRate" )); + if ( !item ) + return; + + int newRefreshRate = sliderValueToRefreshRate(m_generalOptionsWidget->refreshRateSlider->value()); + + if ( newRefreshRate != KTLConfig::refreshRate() ) + { + item->setValue(newRefreshRate); + config->setGroup("WorkArea"); + if ( newRefreshRate != defaultRefreshRate ) + config->writeEntry("RefreshRate",newRefreshRate); + else + config->deleteEntry("RefreshRate"); + + emit settingsChanged(); + } + + QTimer::singleShot( 0, this, SLOT(slotUpdateSettings()) ); +} + + +void SettingsDlg::slotUpdateSettings() +{ + KConfig * config = kapp->config(); + + KConfigSkeleton::ItemString * item = dynamic_cast(KTLConfig::self()->findItem( "PicProgrammerProgram" )); + if ( !item ) + return; + + KComboBox * combo = m_picProgrammerConfigWidget->kcfg_PicProgrammerProgram; + QString newProgram = combo->currentText(); + + if ( newProgram != KTLConfig::picProgrammerProgram() ) + { + item->setValue( newProgram ); + config->setGroup( "PicProgramming" ); + if ( newProgram != "picp" ) + config->writeEntry( "PicProgrammerProgram", newProgram ); + else + config->deleteEntry( "PicProgrammerProgram" ); + + emit settingsChanged(); + } + + m_pPicProgrammerSettings->save( config ); + + config->sync(); +} + + +void SettingsDlg::updateWidgets() +{ + m_generalOptionsWidget->refreshRateSlider->setValue( refreshRateToSliderValue( KTLConfig::refreshRate() ) ); + + m_pPicProgrammerSettings->load( kapp->config() ); + + QStringList programmerNames = m_pPicProgrammerSettings->configNames( false ); + + KComboBox * combo = m_picProgrammerConfigWidget->kcfg_PicProgrammerProgram; + combo->clear(); + combo->insertStringList( programmerNames ); + combo->setSizeLimit( programmerNames.size() ); + + QTimer::singleShot( 0, this, SLOT(slotUpdateWidgets()) ); +} + + +void SettingsDlg::slotUpdateWidgets() +{ + KComboBox * combo = m_picProgrammerConfigWidget->kcfg_PicProgrammerProgram; + + combo->setCurrentText( KTLConfig::picProgrammerProgram() ); + slotUpdatePicProgrammerDescription(); +} + + +void SettingsDlg::updateWidgetsDefault() +{ + m_generalOptionsWidget->refreshRateSlider->setValue( refreshRateToSliderValue( defaultRefreshRate ) ); + slotUpdatePicProgrammerDescription(); +} + + +bool SettingsDlg::hasChanged() +{ + if ( sliderValueToRefreshRate( m_generalOptionsWidget->refreshRateSlider->value() ) == KTLConfig::refreshRate() ) + return KConfigDialog::hasChanged(); + return true; +} + + +bool SettingsDlg::isDefault() +{ + if ( sliderValueToRefreshRate( m_generalOptionsWidget->refreshRateSlider->value() ) == defaultRefreshRate ) + return KConfigDialog::isDefault(); + + return false; +} + + +#include "settingsdlg.moc" diff --git a/src/gui/settingsdlg.h b/src/gui/settingsdlg.h new file mode 100644 index 0000000..1fbf966 --- /dev/null +++ b/src/gui/settingsdlg.h @@ -0,0 +1,69 @@ +/*************************************************************************** + * Copyright (C) 2005 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#ifndef SETTINGSDLG_H +#define SETTINGSDLG_H + +#include +#include + +class AsmFormattingWidget; +class GeneralOptionsWidget; +class GpasmSettingsWidget; +class LogicWidget; +class PicProgrammerConfigWidget; +class PicProgrammerSettings; +class SDCCOptionsWidget; + + +/** +@author David Saxton +*/ +class SettingsDlg : public KConfigDialog +{ + Q_OBJECT + public: + SettingsDlg( QWidget *parent, const char *name, KConfigSkeleton *config ); + ~SettingsDlg(); + + static int refreshRateToSliderValue( int refreshRate ); + static int sliderValueToRefreshRate( int sliderValue ); + + virtual void show(); + + public slots: + void slotUpdateRefreshRateLabel( int sliderValue ); + void slotUpdatePicProgrammerDescription(); + void slotAddProgrammerConfig(); + void slotRemoveProgrammerConfig(); + void slotSaveCurrentProgrammerConfig(); + + protected slots: + void slotUpdateSettings(); + void slotUpdateWidgets(); + + protected: + virtual void updateSettings(); + virtual void updateWidgets(); + virtual void updateWidgetsDefault(); + virtual bool hasChanged(); + virtual bool isDefault(); + + PicProgrammerSettings * m_pPicProgrammerSettings; + + GeneralOptionsWidget * m_generalOptionsWidget; + GpasmSettingsWidget * m_gpasmSettingsWidget; + SDCCOptionsWidget * m_sdccOptionsWidget; + AsmFormattingWidget * m_asmFormattingWidget; + LogicWidget * m_logicWidget; + PicProgrammerConfigWidget * m_picProgrammerConfigWidget; +}; + +#endif diff --git a/src/gui/symbolviewer.cpp b/src/gui/symbolviewer.cpp new file mode 100644 index 0000000..74d54e1 --- /dev/null +++ b/src/gui/symbolviewer.cpp @@ -0,0 +1,218 @@ +/*************************************************************************** + * Copyright (C) 2005 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#include "config.h" +#ifndef NO_GPSIM + +#include "gpsimprocessor.h" +#include "symbolviewer.h" + +#include +#include +#include +#include +#include +#include + +#include + +static const int NAME_COLUMN = 0; +static const int VALUE_COLUMN = 1; + + +//BEGIN class SymbolViewerItem +SymbolViewerItem::SymbolViewerItem( SymbolViewer * symbolViewer, RegisterInfo * registerInfo ) + : KListViewItem( symbolViewer->symbolList() ) +{ + assert(registerInfo); + m_pRegisterInfo = registerInfo; + m_pSymbolViewer = symbolViewer; + + setText( NAME_COLUMN, m_pRegisterInfo->name() ); +// setText( TYPE_COLUMN, RegisterInfo::toString( m_pRegisterInfo->type() ) ); + radixChanged(); // force update of displayed string + + connect( m_pRegisterInfo, SIGNAL(valueChanged(unsigned)), this, SLOT(valueChanged(unsigned)) ); + connect( m_pSymbolViewer, SIGNAL(valueRadixChanged(SymbolViewer::Radix)), this, SLOT(radixChanged()) ); + +} + + +void SymbolViewerItem::valueChanged( unsigned newValue ) +{ + setText( VALUE_COLUMN, m_pSymbolViewer->toDisplayString( newValue ) ); +} + + +void SymbolViewerItem::radixChanged() +{ + valueChanged( m_pRegisterInfo->value() ); +} +//END class SymbolViewerItem + + + +//BEGIN class SymbolView +SymbolViewer * SymbolViewer::m_pSelf = 0l; +SymbolViewer * SymbolViewer::self( KateMDI::ToolView * parent ) +{ + if (!m_pSelf) + { + assert (parent); + m_pSelf = new SymbolViewer(parent); + } + return m_pSelf; +} + +SymbolViewer::SymbolViewer( KateMDI::ToolView * parent ) + : QWidget( (QWidget*)parent ) +{ + QGridLayout * grid = new QGridLayout( this, 1, 1, 0, 6 ); + + m_pSymbolList = new KListView(this); + grid->addMultiCellWidget( m_pSymbolList, 0, 0, 0, 1 ); + + grid->addWidget( new QLabel( i18n("Value radix:"), this ), 1, 0 ); + + m_pRadixCombo = new KComboBox( false, this ); + grid->addWidget( m_pRadixCombo, 1, 1 ); + m_pRadixCombo->insertItem( i18n("Binary") ); + m_pRadixCombo->insertItem( i18n("Octal") ); + m_pRadixCombo->insertItem( i18n("Decimal") ); + m_pRadixCombo->insertItem( i18n("Hexadecimal") ); + m_valueRadix = Decimal; + m_pRadixCombo->setCurrentItem(2); + connect( m_pRadixCombo, SIGNAL(activated(int)), this, SLOT(selectRadix(int)) ); + + m_pGpsim = 0l; + m_pCurrentContext = 0l; + + m_pSymbolList->addColumn( i18n("Name") ); + m_pSymbolList->addColumn( i18n("Value") ); + m_pSymbolList->setFullWidth(true); + m_pSymbolList->setAllColumnsShowFocus( true ); +} + + +SymbolViewer::~SymbolViewer() +{ +} + + +void SymbolViewer::saveProperties( KConfig * config ) +{ + QString oldGroup = config->group(); + + config->setGroup( "SymbolEditor" ); + config->writeEntry( "Radix", m_valueRadix ); + + config->setGroup( oldGroup ); +} + + +void SymbolViewer::readProperties( KConfig * config ) +{ + QString oldGroup = config->group(); + + config->setGroup( "SymbolEditor" ); + m_valueRadix = (SymbolViewer::Radix)config->readNumEntry( "Radix", Decimal ); + + int pos = 4; + switch ( m_valueRadix ) + { + case Binary: + pos--; + case Octal: + pos--; + case Decimal: + pos--; + case Hexadecimal: + pos--; + } + m_pRadixCombo->setCurrentItem( pos ); + + config->setGroup( oldGroup ); +} + + +void SymbolViewer::setContext( GpsimProcessor * gpsim ) +{ + RegisterSet * registerSet = gpsim ? gpsim->registerMemory() : 0l; + + if ( registerSet == m_pCurrentContext ) + return; + + m_pSymbolList->clear(); + m_pGpsim = gpsim; + m_pCurrentContext = registerSet; + + if (!m_pCurrentContext) + return; + + connect( gpsim, SIGNAL(destroyed()), m_pSymbolList, SLOT(clear()) ); + + unsigned count = m_pCurrentContext->size(); + for ( unsigned i = 0; i < count; ++i ) + { + RegisterInfo * reg = m_pCurrentContext->fromAddress(i); + + if ( (reg->type() == RegisterInfo::Generic) || + (reg->type() == RegisterInfo::Invalid) ) + continue; + + new SymbolViewerItem( this, reg ); + } +} + + +void SymbolViewer::selectRadix( int selectIndex ) +{ + if ( (selectIndex<0) || (selectIndex>3) ) + { + kdWarning() << k_funcinfo << "Invalid select position for radix: " << selectIndex << endl; + return; + } + + Radix radii[] = { Binary, Octal, Decimal, Hexadecimal }; + Radix newRadix = radii[selectIndex]; + + if ( newRadix == m_valueRadix ) + return; + + m_valueRadix = newRadix; + + emit valueRadixChanged(m_valueRadix); +} + + +QString SymbolViewer::toDisplayString( unsigned value ) const +{ + switch ( m_valueRadix ) + { + case Binary: + return QString::number( value, 2 ).rightJustify( 8, '0', false ); + + case Octal: + return "0" + QString::number( value, 8 ); + + case Decimal: + return QString::number( value, 10 ); + + case Hexadecimal: + return "0x" + QString::number( value, 16 ); + } + + return "?"; +} +//END class SymbolView + +#include "symbolviewer.moc" + +#endif diff --git a/src/gui/symbolviewer.h b/src/gui/symbolviewer.h new file mode 100644 index 0000000..9a09cb6 --- /dev/null +++ b/src/gui/symbolviewer.h @@ -0,0 +1,103 @@ +/*************************************************************************** + * Copyright (C) 2005 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#include "config.h" +#ifndef NO_GPSIM + +#ifndef SYMBOLVIEWER_H +#define SYMBOLVIEWER_H + +#include +#include + +class KComboBox; +class RegisterInfo; +class RegisterSet; +class SymbolViewer; +namespace KateMDI { class ToolView; } + + +/** +@author David Saxton +*/ +class SymbolViewer : public QWidget +{ + Q_OBJECT + public: + static SymbolViewer * self( KateMDI::ToolView * parent = 0l ); + static QString toolViewIdentifier() { return "SymbolViewer"; } + ~SymbolViewer(); + + enum Radix + { + Binary = 2, + Octal = 8, + Decimal = 10, + Hexadecimal = 16 + }; + + Radix valueRadix() const { return m_valueRadix; } + + KListView * symbolList() const { return m_pSymbolList; } + /** + * Write the current properties (such as currently selected radix) to + * the config. + */ + void saveProperties( KConfig * config ); + /** + * Reads the properties (such as the last selected radix) from the + * config file. + */ + void readProperties( KConfig * config ); + + void setContext( GpsimProcessor * gpsim ); + /** + * Converts the value to a string for display according to the currently + * selected radix. + */ + QString toDisplayString( unsigned value ) const; + + signals: + void valueRadixChanged( SymbolViewer::Radix newRadix ); + + public slots: + void selectRadix( int selectIndex ); + + protected: + QGuardedPtr m_pGpsim; + RegisterSet * m_pCurrentContext; + KListView * m_pSymbolList; + Radix m_valueRadix; + + private: + SymbolViewer( KateMDI::ToolView * parent ); + static SymbolViewer * m_pSelf; + KComboBox * m_pRadixCombo; +}; + + +class SymbolViewerItem : public QObject, public KListViewItem +{ + Q_OBJECT + public: + SymbolViewerItem( SymbolViewer * symbolViewer, RegisterInfo * registerInfo ); + + public slots: + void valueChanged( unsigned newValue ); + void radixChanged(); + + protected: + RegisterInfo * m_pRegisterInfo; + SymbolViewer * m_pSymbolViewer; +}; + +#endif + +#endif -- cgit v1.2.1