00001
00002
00003
00004
00005
00006
00007
00008
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
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
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
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
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
00088 (dynamic_cast<QVBoxLayout*>(m_pWidget->portsGroupBox->layout()))->addWidget( groupBox );
00089 }
00090
00091
00092
00093
00094
00095
00096 m_pWidget->variables->setLeftMargin(0);
00097
00098
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
00120
00121
00122
00123
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
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
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
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
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
00422
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"