microsettingsdlg.cpp

00001 /***************************************************************************
00002  *   Copyright (C) 2003-2005 by David Saxton                               *
00003  *   david@bluehaze.org                                                    *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  ***************************************************************************/
00010 
00011 #include "microinfo.h"
00012 #include "microsettings.h"
00013 #include "microsettingsdlg.h"
00014 #include "microsettingswidget.h"
00015 #include "micropackage.h"
00016 #include "newpinmappingwidget.h"
00017 #include "pinmapping.h"
00018 
00019 #include <kcombobox.h>
00020 #include <kdebug.h>
00021 #include <kinputdialog.h>
00022 #include <klineedit.h>
00023 #include <klocale.h>
00024 #include <kmessagebox.h>
00025 #include <kpushbutton.h>
00026 
00027 #include <qgroupbox.h>
00028 #include <qlabel.h>
00029 #include <qlayout.h>
00030 #include <qregexp.h>
00031 #include <qtable.h>
00032 #include <qwhatsthis.h>
00033 
00034 MicroSettingsDlg::MicroSettingsDlg( MicroSettings * microSettings, QWidget *parent, const char *name )
00035         : KDialogBase( parent, name, true, i18n("PIC Settings"), KDialogBase::Ok|KDialogBase::Apply|KDialogBase::Cancel, KDialogBase::Ok, true )
00036 {
00037         m_pMicroSettings = microSettings;
00038         m_pNewPinMappingWidget = 0;
00039         m_pNewPinMappingDlg = 0;
00040         m_pWidget = new MicroSettingsWidget(this);
00041         
00042         QWhatsThis::add( this, i18n("This dialog allows editing of the initial properties of the PIC") );
00043         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.<br><br>The \"Type (TRIS)\" edit shows the initial input/output state of the ports; 1 represents an input, and 0 an output.<br><br>The \"State (PORT)\" edit shows the initial high/low state of the ports; 1 represents a high, and 0 a low.") );
00044         QWhatsThis::add( m_pWidget->variables, i18n("Edit the initial value of the variables here.<br><br>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.") );
00045         
00046         
00047         //BEGIN Initialize initial port settings
00048         m_portNames = microSettings->microInfo()->package()->portNames();
00049         
00050         m_portTypeEdit.resize( m_portNames.size(), 0 );
00051         m_portStateEdit.resize( m_portNames.size(), 0 );
00052         
00053         uint row = 0;
00054         QStringList::iterator end = m_portNames.end();
00055         for ( QStringList::iterator it = m_portNames.begin(); it != end; ++it, ++row )
00056         {
00057                 //BEGIN Get current Type / State text
00058                 QString portType = QString::number( microSettings->portType(*it), 2 );
00059                 QString portState = QString::number( microSettings->portState(*it), 2 );
00060 
00061                 QString fill;
00062                 fill.fill( '0', 8-portType.length() );
00063                 portType.prepend(fill);
00064                 fill.fill( '0', 8-portState.length() );
00065                 portState.prepend(fill);
00066                 //END Get current Type / State text
00067                 
00068                 
00069                 QGroupBox * groupBox = new QGroupBox( *it, m_pWidget->portsGroupBox );
00070                 
00071                 groupBox->setColumnLayout(0, Qt::Vertical );
00072                 groupBox->layout()->setSpacing( 6 );
00073                 groupBox->layout()->setMargin( 11 );
00074                 QGridLayout * groupBoxLayout = new QGridLayout( groupBox->layout() );
00075                 groupBoxLayout->setAlignment( Qt::AlignTop );
00076                 
00077                 // TODO: replace this with i18n( "the type", "Type (TRIS register):" );
00078                 groupBoxLayout->addWidget( new QLabel( i18n("Type (TRIS register):"), groupBox ), 0, 0 ); 
00079                 groupBoxLayout->addWidget( new QLabel( i18n("State (PORT register):"), groupBox ), 1, 0 );
00080 
00081                 m_portTypeEdit[row] = new KLineEdit( portType, groupBox );
00082                 groupBoxLayout->addWidget( m_portTypeEdit[row], 0, 1 );
00083 
00084                 m_portStateEdit[row] = new KLineEdit( portState, groupBox );
00085                 groupBoxLayout->addWidget( m_portStateEdit[row], 1, 1 );
00086 
00087 //              (dynamic_cast<QVBoxLayout*>(m_pWidget->portsGroupBox->layout()))->insertWidget( row, groupBox );
00088                 (dynamic_cast<QVBoxLayout*>(m_pWidget->portsGroupBox->layout()))->addWidget( groupBox );
00089         }
00090         //END Initialize initial port settings
00091         
00092         
00093         
00094         //BEGIN Initialize initial variable settings
00095         // Hide row headers
00096         m_pWidget->variables->setLeftMargin(0);
00097         
00098         // Make columns as thin as possible
00099         m_pWidget->variables->setColumnStretchable( 0, true );
00100         m_pWidget->variables->setColumnStretchable( 1, true );
00101         
00102         QStringList variables = microSettings->variableNames();
00103         row = 0;
00104         end = variables.end();
00105         for ( QStringList::iterator it = variables.begin(); it != end; ++it )
00106         {
00107                 VariableInfo *info = microSettings->variableInfo(*it);
00108                 if (info)
00109                 {
00110                         m_pWidget->variables->insertRows( row, 1 );
00111                         m_pWidget->variables->setText( row, 0,  *it );
00112                         m_pWidget->variables->setText( row, 1, info->valueAsString() );
00113                         ++row;
00114                 }
00115         }
00116         m_pWidget->variables->insertRows( row, 1 );
00117         
00118         connect( m_pWidget->variables, SIGNAL(valueChanged(int,int)), this, SLOT(checkAddVariableRow()) );
00119         //END Initialize initial variable settings
00120         
00121         
00122         
00123         //BEGIN Initialize pin maps
00124         connect( m_pWidget->pinMapAdd, SIGNAL(clicked()), this, SLOT(slotCreatePinMap()) );
00125         connect( m_pWidget->pinMapModify, SIGNAL(clicked()), this, SLOT(slotModifyPinMap()) );
00126         connect( m_pWidget->pinMapRename, SIGNAL(clicked()), this, SLOT(slotRenamePinMap()) );
00127         connect( m_pWidget->pinMapRemove, SIGNAL(clicked()), this, SLOT(slotRemovePinMap()) );
00128         
00129         m_pinMappings = microSettings->pinMappings();
00130         m_pWidget->pinMapCombo->insertStringList( m_pinMappings.keys() );
00131         
00132         updatePinMapButtons();
00133         //END Initialize pin maps
00134         
00135         
00136         enableButtonSeparator( false );
00137         setMainWidget(m_pWidget);
00138         m_pWidget->adjustSize();
00139         adjustSize();
00140         
00141         connect( this, SIGNAL(applyClicked()), this, SLOT(slotSaveStuff()) );
00142 }
00143 
00144 
00145 MicroSettingsDlg::~MicroSettingsDlg()
00146 {
00147 }
00148 
00149 
00150 void MicroSettingsDlg::accept()
00151 {
00152         hide();
00153         slotSaveStuff();
00154         deleteLater();
00155 }
00156 
00157 
00158 void MicroSettingsDlg::slotSaveStuff()
00159 {
00160         for ( unsigned i = 0; i < m_portNames.size(); i++ )
00161                 savePort(i);
00162         
00163         m_pMicroSettings->removeAllVariables();
00164         for ( int i=0; i< m_pWidget->variables->numRows(); i++ )
00165                 saveVariable(i);
00166         
00167         m_pMicroSettings->setPinMappings( m_pinMappings );
00168 }
00169 
00170 
00171 void MicroSettingsDlg::reject()
00172 {
00173         deleteLater();
00174 }
00175 
00176 
00177 QValidator::State MicroSettingsDlg::validatePinMapName( QString & name ) const
00178 {
00179         name.replace( ' ', '_' );
00180         
00181         if ( name.isEmpty() )
00182                 return QValidator::Intermediate;
00183         
00184         for ( unsigned i = 0; i < name.length(); ++i )
00185         {
00186                 if ( !name[i].isLetterOrNumber() && name[i] != '_' )
00187                         return QValidator::Invalid;
00188         }
00189         
00190         if ( name[0].isNumber() )
00191                 return QValidator::Intermediate;
00192         
00193         if ( m_pWidget->pinMapCombo->contains( name ) )
00194                 return QValidator::Intermediate;
00195         
00196         return QValidator::Acceptable;
00197 }
00198 
00199 
00200 class PinMappingNameValidator : public QValidator
00201 {
00202         public:
00207                 PinMappingNameValidator( MicroSettingsDlg * dlg, const QString & oldName = 0 )
00208                         : QValidator(0)
00209                 {
00210                         m_pDlg = dlg;
00211                         m_oldName = oldName;
00212                 }
00213                 
00214                 virtual State validate( QString & input, int & ) const
00215                 {
00216                         if ( (!m_oldName.isEmpty()) && (input == m_oldName) )
00217                                 return QValidator::Acceptable;
00218                         
00219                         return m_pDlg->validatePinMapName( input );
00220                 }
00221                 
00222         protected:
00223                 MicroSettingsDlg * m_pDlg;
00224                 QString m_oldName;
00225 };
00226 
00227 
00228 void MicroSettingsDlg::slotCheckNewPinMappingName( const QString & name )
00229 {
00230         // Validate name might change the name so that it is valid
00231         QString newName = name;
00232         
00233         if ( m_pNewPinMappingWidget )
00234                 m_pNewPinMappingDlg->enableButtonOK( validatePinMapName( newName ) == QValidator::Acceptable );
00235         
00236         if ( newName != name )
00237                 m_pNewPinMappingWidget->nameEdit->setText( newName );
00238 }
00239 
00240 
00241 void MicroSettingsDlg::slotCreatePinMap()
00242 {
00243         m_pNewPinMappingDlg = new KDialogBase( this, "New Pin Mapping Dlg", true, i18n("New Pin Mapping"), Ok | Cancel );
00244         m_pNewPinMappingDlg->setButtonText( Ok, i18n("Create") );
00245         m_pNewPinMappingWidget = new NewPinMappingWidget( m_pNewPinMappingDlg );
00246         m_pNewPinMappingDlg->setMainWidget( m_pNewPinMappingWidget );
00247         
00248         PinMappingNameValidator * validator = new PinMappingNameValidator( this );
00249         m_pNewPinMappingWidget->nameEdit->setValidator( validator );
00250         
00251         connect( m_pNewPinMappingWidget->nameEdit, SIGNAL(textChanged(const QString &)), this, SLOT(slotCheckNewPinMappingName(const QString &)) );
00252         slotCheckNewPinMappingName( 0 );
00253         
00254         int accepted = m_pNewPinMappingDlg->exec();
00255         unsigned selectedType = m_pNewPinMappingWidget->typeCombo->currentItem();
00256         QString name = m_pNewPinMappingWidget->nameEdit->text();
00257         
00258         delete m_pNewPinMappingDlg;
00259         delete validator;
00260         m_pNewPinMappingDlg = 0;
00261         m_pNewPinMappingWidget = 0;
00262         if ( accepted != QDialog::Accepted )
00263                 return;
00264         
00265         PinMapping::Type type = PinMapping::Invalid;
00266                 
00267         switch ( selectedType )
00268         {
00269                 case 0:
00270                         type = PinMapping::SevenSegment;
00271                         break;
00272                                 
00273                 case 1:
00274                         type = PinMapping::Keypad_4x3;
00275                         break;
00276                                 
00277                 case 2:
00278                         type = PinMapping::Keypad_4x4;
00279                         break;
00280                                 
00281                 default:
00282                         kdError() << k_funcinfo << "Unknown selected type " << type << endl;
00283                         break;
00284         }
00285         
00286         m_pinMappings[name] = PinMapping( type );
00287         m_pWidget->pinMapCombo->insertItem( name );
00288         m_pWidget->pinMapCombo->setCurrentItem( m_pWidget->pinMapCombo->count() - 1 );
00289         
00290         updatePinMapButtons();
00291         slotModifyPinMap();
00292 }
00293 
00294 
00295 void MicroSettingsDlg::slotRenamePinMap()
00296 {
00297         KComboBox * combo = m_pWidget->pinMapCombo;
00298         
00299         QString oldName = combo->currentText();
00300         if ( oldName.isEmpty() )
00301                 return;
00302         
00303         PinMappingNameValidator * validator = new PinMappingNameValidator( this, oldName );
00304         
00305         bool ok = false;
00306         QString newName = KInputDialog::getText( i18n("New Pin Map Name"), i18n("Name"), oldName, & ok, this, 0, validator );
00307         
00308         delete validator;
00309         
00310         if ( !ok )
00311                 return;
00312         
00313         if ( newName == oldName )
00314                 return;
00315         
00316         m_pinMappings[ newName ] = m_pinMappings[ oldName ];
00317         m_pinMappings.remove( oldName );
00318         
00319         combo->setCurrentText( newName );
00320 }
00321 
00322 
00323 void MicroSettingsDlg::slotModifyPinMap()
00324 {
00325         QString name = m_pWidget->pinMapCombo->currentText();
00326         PinMapping pinMapping = m_pinMappings[ name ];
00327 
00328         PinMapEditor *pinMapEditor = new PinMapEditor( & pinMapping, m_pMicroSettings->microInfo(), this, "PinMapEditor" );
00329         int accepted = pinMapEditor->exec();
00330 
00331         delete pinMapEditor;
00332 
00333         if ( accepted != QDialog::Accepted ) return;
00334 
00335         m_pinMappings[ name ] = pinMapping;
00336 }
00337 
00338 
00339 void MicroSettingsDlg::slotRemovePinMap()
00340 {
00341         KComboBox * combo = m_pWidget->pinMapCombo;
00342         
00343         QString pinMapID = combo->currentText();
00344         if ( pinMapID.isEmpty() )
00345                 return;
00346         
00347         m_pinMappings.remove( pinMapID );
00348         combo->removeItem( combo->currentItem() );
00349         
00350         updatePinMapButtons();
00351 }
00352 
00353 
00354 void MicroSettingsDlg::updatePinMapButtons()
00355 {
00356         bool havePinMaps = (m_pWidget->pinMapCombo->count() != 0);
00357         
00358         m_pWidget->pinMapModify->setEnabled( havePinMaps );
00359         m_pWidget->pinMapRename->setEnabled( havePinMaps );
00360         m_pWidget->pinMapRemove->setEnabled( havePinMaps );
00361 }
00362 
00363 
00364 void MicroSettingsDlg::savePort( int row )
00365 {
00366         QString port = m_portNames[row];
00367         
00368         int type, state;
00369         
00370         QString typeText = m_portTypeEdit[row]->text();
00371         bool typeOk = true;
00372         if              ( typeText.startsWith( "0x", false ) ) type = typeText.remove(0,2).toInt( &typeOk, 16 );
00373         else if ( typeText.contains( QRegExp("[^01]") ) ) type = typeText.toInt( &typeOk, 10 );
00374         else type = typeText.toInt( &typeOk, 2 );
00375         
00376         if ( !typeOk )
00377         {
00378 //              KMessageBox::sorry( this, i18n("Unregnised Port Type: %1").arg(typeText) );
00379                 return;
00380         }
00381         
00382         
00383         QString stateText = m_portStateEdit[row]->text();
00384         bool stateOk = true;
00385         if              ( stateText.startsWith( "0x", false ) ) state = stateText.remove(0,2).toInt( &stateOk, 16 );
00386         else if ( stateText.contains( QRegExp("[^01]") ) ) state = stateText.toInt( &stateOk, 10 );
00387         else state = stateText.toInt( &stateOk, 2 );
00388         
00389         if ( !stateOk )
00390         {
00391 //              KMessageBox::sorry( this, i18n("Unregnised Port State: %1").arg(stateText) );
00392                 return;
00393         }
00394         
00395         m_pMicroSettings->setPortState( port, state );
00396         m_pMicroSettings->setPortType( port, type );
00397 }
00398 
00399 
00400 void MicroSettingsDlg::saveVariable( int row )
00401 {
00402         QString name = m_pWidget->variables->text( row, 0 );
00403         if ( name.isEmpty() ) return;
00404         
00405         QString valueText = m_pWidget->variables->text( row, 1 );
00406         int value;
00407         bool ok = true;
00408         if ( valueText.startsWith( "0x", false ) ) value = valueText.remove(0,2).toInt( &ok, 16 );
00409         else value = valueText.toInt( &ok, 10 );
00410 
00411         if (!ok)
00412         {
00413                 KMessageBox::sorry( this, i18n("Invalid variable value: %1").arg(valueText) );
00414                 return;
00415         }
00416         
00417         m_pMicroSettings->setVariable( name, value, true );
00418         VariableInfo *info = m_pMicroSettings->variableInfo(name);
00419         if ( info && info->valueAsString().toInt() != value )
00420         {
00421 //              info->setValue(value);
00422 //              info->permanent = true;
00423                 info->initAtStart = true;
00424         }
00425 }
00426 
00427 
00428 void MicroSettingsDlg::checkAddVariableRow()
00429 {
00430         int lastRow = m_pWidget->variables->numRows()-1;
00431         if ( !m_pWidget->variables->text( lastRow, 0 ).isEmpty() ) m_pWidget->variables->insertRows( lastRow+1, 1 );
00432 }
00433 
00434 
00435 
00436 #include "microsettingsdlg.moc"

Generated on Tue May 8 17:05:31 2007 for KTechLab by  doxygen 1.5.1