~arcachofo/simulide/1.1.0

« back to all changes in this revision

Viewing changes to src/gui/circuitwidget/connector.cpp

  • Committer: arcachofo
  • Date: 2021-01-01 14:23:42 UTC
  • Revision ID: arcachofo@simulide.com-20210101142342-ozfljnll44g5lbl3
Initial Commit 0.5.15-RC3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
 *   Copyright (C) 2012 by santiago González                               *
 
3
 *   santigoro@gmail.com                                                   *
 
4
 *                                                                         *
 
5
 *   This program is free software; you can redistribute it and/or modify  *
 
6
 *   it under the terms of the GNU General Public License as published by  *
 
7
 *   the Free Software Foundation; either version 3 of the License, or     *
 
8
 *   (at your option) any later version.                                   *
 
9
 *                                                                         *
 
10
 *   This program is distributed in the hope that it will be useful,       *
 
11
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 
12
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 
13
 *   GNU General Public License for more details.                          *
 
14
 *                                                                         *
 
15
 *   You should have received a copy of the GNU General Public License     *
 
16
 *   along with this program; if not, see <http://www.gnu.org/licenses/>.  *
 
17
 *                                                                         *
 
18
 ***************************************************************************/
 
19
 
 
20
#include "connector.h"
 
21
#include "connectorline.h"
 
22
#include "circuitwidget.h"
 
23
#include "simulator.h"
 
24
#include "circuit.h"
 
25
#include "pin.h"
 
26
#include "e-node.h"
 
27
#include "utils.h"
 
28
 
 
29
 
 
30
Connector::Connector( QObject* parent, QString type, QString id, Pin* startpin, Pin* endpin )
 
31
         : Component( parent, type, id )
 
32
{
 
33
    //m_eNode = 0l;
 
34
    m_actLine   = 0;
 
35
    m_lastindex = 0;
 
36
    
 
37
    m_isBus = false;
 
38
    m_freeLine = false;
 
39
 
 
40
    if( startpin )
 
41
    {
 
42
        m_startPin   =  startpin;
 
43
        m_startpinid = startpin->objectName();
 
44
        setPos( startpin->scenePos() );
 
45
        if( m_startPin->isBus() ) setIsBus( true );
 
46
    }
 
47
 
 
48
    if( endpin )
 
49
    {
 
50
        m_endPin   = endpin;
 
51
        m_endpinid = endpin->objectName();
 
52
        m_startPin->setConnector( this );
 
53
        m_endPin->setConnector( this );
 
54
        m_startPin->setConPin( m_endPin );
 
55
        m_endPin->setConPin( m_startPin );
 
56
        if( m_isBus ) m_endPin->setIsBus( true );
 
57
    }
 
58
    else
 
59
    {
 
60
        m_endPin   = 0l;
 
61
        m_endpinid = "";
 
62
    }
 
63
    m_idLabel->setVisible( false );
 
64
}
 
65
Connector::~Connector() { }
 
66
 
 
67
void Connector::remNullLines()      // Remove lines with leght = 0 or aligned
 
68
{
 
69
    if( m_conLineList.length() < 2 ) 
 
70
    {
 
71
        refreshPointList();
 
72
        return;
 
73
    }
 
74
 
 
75
    for( ConnectorLine* line : m_conLineList )
 
76
    {
 
77
        if( line->isDiagonal() ) continue;
 
78
        
 
79
        int index = m_conLineList.indexOf( line );
 
80
        if( index < m_conLineList.length()-1 )      //
 
81
        {
 
82
            ConnectorLine* line2 = m_conLineList.at( index+1 );
 
83
            
 
84
            if( line2->isDiagonal() ) continue;
 
85
 
 
86
            if( line->dx() == line2->dx() || line->dy() == line2->dy() ) // Lines aligned or null line
 
87
            {
 
88
                line2->sSetP1( line->p1() );
 
89
                remConLine( line  );
 
90
            }
 
91
        }
 
92
    }
 
93
    //
 
94
    if( m_conLineList.length() < 2 )
 
95
    {
 
96
        m_lastindex = 0;
 
97
        m_actLine   = 0;
 
98
    }
 
99
    refreshPointList();
 
100
}
 
101
 
 
102
void Connector::remConLine( ConnectorLine* line  )
 
103
{
 
104
    int index = m_conLineList.indexOf( line );
 
105
 
 
106
    connectLines( index-1, index+1 );
 
107
    Circuit::self()->removeItem( line );
 
108
    m_conLineList.removeOne( line );
 
109
    if( m_actLine > 0 )  m_actLine -= 1;
 
110
}
 
111
 
 
112
void Connector::refreshPointList()
 
113
{
 
114
    if( m_conLineList.isEmpty() ) return;
 
115
 
 
116
    QStringList list;
 
117
    QString     data;
 
118
 
 
119
    data.setNum( m_conLineList.at(0)->p1().x() );
 
120
    list.append( data );
 
121
    data.setNum( m_conLineList.at(0)->p1().y() );
 
122
    list.append( data );
 
123
    int count = m_conLineList.size();
 
124
    for( int i=0; i<count; i++ )
 
125
    {
 
126
        data.setNum( m_conLineList.at(i)->p2().x() );
 
127
        list.append( data );
 
128
        data.setNum( m_conLineList.at(i)->p2().y() );
 
129
        list.append( data );
 
130
    }
 
131
    setPos( m_conLineList.first()->scenePos() );
 
132
 
 
133
    setPointList( list );
 
134
    //qDebug() << "lines " << count << "connector poinlist" << m_conLineList;
 
135
}
 
136
 
 
137
void Connector::addConLine( ConnectorLine* line, int index )
 
138
{
 
139
    if( index > 0  && index < m_conLineList.size() ) disconnectLines( index-1, index );
 
140
 
 
141
    m_conLineList.insert( index, line );
 
142
 
 
143
    Circuit::self()->addItem(line);
 
144
 
 
145
    if( index > 0 )
 
146
    {
 
147
        connectLines( index-1, index );
 
148
        m_conLineList.at( index-1 )->sSetP2( line->p1() );
 
149
    }
 
150
 
 
151
    if( index < m_conLineList.size()-1 )
 
152
    {
 
153
        if( m_conLineList.size() < 2 ) return;
 
154
 
 
155
        connectLines( index, index+1 );
 
156
        m_conLineList.at( index+1 )->sSetP1( line->p2() );
 
157
    }
 
158
    line->setIsBus( m_isBus );
 
159
    if( Circuit::self()->is_constarted() ) line->setCursor( Qt::ArrowCursor );
 
160
}
 
161
 
 
162
ConnectorLine* Connector::addConLine( int x1, int y1, int x2, int y2, int index )
 
163
{
 
164
    ConnectorLine* line = new ConnectorLine( x1, y1, x2, y2, this );
 
165
 
 
166
    addConLine( line, index );
 
167
 
 
168
    return line;
 
169
}
 
170
 
 
171
void Connector::connectLines( int index1, int index2 )
 
172
{
 
173
    if( index1 < 0 || index2 < 0 || index2 > m_conLineList.length()-1 )
 
174
        return;
 
175
 
 
176
    ConnectorLine* line1 = m_conLineList.at( index1 );
 
177
    ConnectorLine* line2 = m_conLineList.at( index2 );
 
178
 
 
179
    line1->setNextLine( line2 );
 
180
    line2->setPrevLine( line1 );
 
181
}
 
182
 
 
183
void Connector::disconnectLines( int index1, int index2 )
 
184
{
 
185
    if( index1 < 0 || index2 < 0 || index2 > m_conLineList.length()-1 )
 
186
        return;
 
187
 
 
188
    ConnectorLine* line1 = m_conLineList.at( index1 );
 
189
    ConnectorLine* line2 = m_conLineList.at( index2 );
 
190
 
 
191
    line1->setNextLine( 0l );
 
192
    line2->setPrevLine( 0l );
 
193
}
 
194
 
 
195
void Connector::updateConRoute( Pin* pin, QPointF thisPoint )
 
196
{
 
197
    if( !this->isVisible() ) return;
 
198
    if( Circuit::self()->pasting() ) 
 
199
    {
 
200
        remNullLines();
 
201
        return;
 
202
    }
 
203
 
 
204
    bool diagonal = false;
 
205
    int length = m_conLineList.length();
 
206
    ConnectorLine* line;
 
207
    ConnectorLine* preline = 0l;
 
208
 
 
209
    if( pin == m_startPin )
 
210
    {
 
211
        line = m_conLineList.first();
 
212
        diagonal = line->isDiagonal();
 
213
        //qDebug() << "Connector::updateConRoute StartPin";
 
214
        
 
215
        line->sSetP1( thisPoint.toPoint() );
 
216
 
 
217
        m_lastindex = 0;
 
218
 
 
219
        if( length > 1 )
 
220
        {
 
221
            preline = m_conLineList.at(1);
 
222
            m_actLine = 1;
 
223
        }
 
224
        else m_actLine = 0;
 
225
        
 
226
        if( diagonal ) 
 
227
        {
 
228
            remNullLines();
 
229
            return;
 
230
        }
 
231
    }
 
232
    else
 
233
    {
 
234
        line = m_conLineList.last();
 
235
        
 
236
        diagonal = line->isDiagonal();
 
237
        //qDebug() << "Connector::updateConRoute EndPin";
 
238
        
 
239
        line->sSetP2( togrid( thisPoint ).toPoint() );
 
240
        
 
241
        m_lastindex = length-1;
 
242
 
 
243
        if( length > 1 )
 
244
        {
 
245
            preline = m_conLineList.at( m_lastindex-1 );
 
246
            if( pin != 0l ) m_actLine = m_lastindex-1;
 
247
        }
 
248
        if( diagonal || m_freeLine ) 
 
249
        {
 
250
            m_freeLine = false;
 
251
            if( m_lastindex == m_actLine )          // Add new corner
 
252
            {
 
253
                QPoint point = line->p2();
 
254
 
 
255
                ConnectorLine* newLine = addConLine( point.x(), point.y(), point.x()+4, point.y()+4, m_lastindex + 1 );
 
256
 
 
257
                if( line->isSelected() ) newLine->setSelected( true );
 
258
            }
 
259
            remNullLines();
 
260
            return;
 
261
        }
 
262
    }
 
263
    
 
264
    if( (line->dx() == 0) && (line->dy() == 0) && (length > 1) ) // Null Line
 
265
    {
 
266
        //if( preline && preline->isDiagonal() ) return;
 
267
        
 
268
        Circuit::self()->removeItem( line );
 
269
        m_conLineList.removeOne( line );
 
270
 
 
271
        if( m_actLine > 0 )  m_actLine -= 1;
 
272
    }
 
273
    else if( line->dx() != 0 && line->dy() != 0 )
 
274
    {
 
275
        QPoint point;
 
276
 
 
277
        if( m_lastindex == m_actLine )          // Add new corner
 
278
        {
 
279
            point = line->p2();
 
280
 
 
281
            if( abs(line->dx()) > abs(line->dy()) ) point.setY( line->p1().y() );
 
282
            else                                    point.setX( line->p1().x() );
 
283
 
 
284
            ConnectorLine* newLine = addConLine( point.x(), point.y(), line->p2().x(), line->p2().y(), m_lastindex + 1 );
 
285
 
 
286
            if( line->isSelected() ) newLine->setSelected( true );
 
287
 
 
288
            line->setP2( point );
 
289
 
 
290
        }
 
291
        else if( m_lastindex < m_actLine )        // Update first corner
 
292
        {
 
293
            point = line->p2();
 
294
 
 
295
            if     ( preline->dx() == 0 ) point.setY( line->p1().y() );
 
296
            else /*if( preline->dy() == 0 )*/ point.setX( line->p1().x() );
 
297
 
 
298
            line->setP2( point );
 
299
 
 
300
            if( line->dx() == preline->dx() || line->dy() == preline->dy() ) // Lines aligned or null line
 
301
            {
 
302
                if( line->isSelected() || preline->isSelected())
 
303
                {
 
304
                    preline->sSetP1( line->p1() );
 
305
                    remConLine( line  );
 
306
                }
 
307
            }
 
308
        }
 
309
        else                                       // Update last corner
 
310
        {
 
311
            point = line->p1();
 
312
 
 
313
            if     ( preline->dx() == 0 ) point.setY( line->p2().y() );
 
314
            else /*if( preline->dy() == 0 )*/ point.setX( line->p2().x() );
 
315
 
 
316
            line->setP1( point );
 
317
 
 
318
            if( line->dx() == preline->dx() || line->dy() == preline->dy() ) // Lines aligned or null line
 
319
            {
 
320
                if( line->isSelected() || preline->isSelected())
 
321
                {
 
322
                    preline->sSetP2( line->p2() );
 
323
                    remConLine( line  );
 
324
                }
 
325
            }
 
326
        }
 
327
    }
 
328
    //qDebug() << "Connector::updateConRoute"<<line->p1()<<line->p2();
 
329
    //if( preline ) qDebug() << "Connector::updateConRoute"<<preline->p1()<<preline->p2();
 
330
    remNullLines();
 
331
}
 
332
 
 
333
void Connector::remLines()
 
334
{
 
335
    while( !m_conLineList.isEmpty() )
 
336
    {
 
337
        ConnectorLine* line = m_conLineList.takeLast();
 
338
        Circuit::self()->removeItem( line );
 
339
        delete line;
 
340
    }
 
341
}
 
342
 
 
343
void Connector::move( QPointF delta )
 
344
{
 
345
    //qDebug() << "Connector::move ..........................";
 
346
    if( Circuit::self()->pasting() )
 
347
    {
 
348
        for( ConnectorLine* line : m_conLineList )
 
349
            line->move( delta );
 
350
 
 
351
        //return;
 
352
    }
 
353
    //else
 
354
    //remNullLines();
 
355
    //Component::move( delta );
 
356
}
 
357
 
 
358
void Connector::setSelected(  bool selected )
 
359
{
 
360
    //qDebug() <<"\nConnector::setSelected"<<selected;
 
361
    for( ConnectorLine* line : m_conLineList )
 
362
    {
 
363
        line->setSelected( selected );
 
364
        //qDebug() << line->isSelected();
 
365
    }
 
366
 
 
367
    Component::setSelected( selected );
 
368
}
 
369
 
 
370
void Connector::setVisib(  bool vis )
 
371
{
 
372
    //qDebug() <<"\nConnector::setSelected"<<selected;
 
373
    for( ConnectorLine* line : m_conLineList )
 
374
    {
 
375
        line->setVisible( vis );
 
376
        //qDebug() << line->isSelected();
 
377
    }
 
378
 
 
379
    this->setVisible( vis );
 
380
}
 
381
 
 
382
void Connector::remove()
 
383
{
 
384
    //qDebug() << "Connector::remove simulator running: " << Simulator::self()->isRunning();
 
385
    //qDebug()<<"Connector::remove" << this->objectName();
 
386
    if( Simulator::self()->isRunning() )  CircuitWidget::self()->powerCircOff();
 
387
 
 
388
    if( m_startPin ) m_startPin->reset();
 
389
    if( m_endPin )   m_endPin->reset();
 
390
 
 
391
    Circuit::self()->conList()->removeOne( this );
 
392
    Circuit::self()->removeItem( this );
 
393
    remLines();
 
394
}
 
395
 
 
396
void Connector::closeCon( Pin* endpin, bool connect  )
 
397
{
 
398
    if( Simulator::self()->isRunning() )  CircuitWidget::self()->powerCircOff();
 
399
 
 
400
    m_endPin   = endpin;
 
401
    m_endpinid = endpin->objectName();
 
402
 
 
403
    if( connect )
 
404
    {
 
405
        QString enodid = "enode";
 
406
        enodid.append( m_id );
 
407
        enodid.remove( "Connector" );
 
408
        eNode* newEnode = new eNode( enodid );
 
409
        if( m_isBus ) newEnode->setIsBus( true );
 
410
 
 
411
        // We will get all ePins from stratPin and endPin nets an add to new eNode
 
412
        m_startPin->setConPin( 0l );
 
413
        m_endPin->setConPin( 0l );
 
414
 
 
415
        m_startPin->registerPins( newEnode );
 
416
        m_endPin->registerPins( newEnode );
 
417
    }
 
418
    m_startPin->setConnector( this );
 
419
    m_endPin->setConnector( this );
 
420
    
 
421
    if( m_isBus )
 
422
    {
 
423
        m_startPin->setIsBus( true );
 
424
        m_endPin->setIsBus( true );
 
425
    }
 
426
    m_startPin->setConPin( m_endPin );
 
427
    m_endPin->setConPin( m_startPin );
 
428
 
 
429
    updateConRoute( m_endPin, m_endPin->scenePos() );
 
430
 
 
431
    remNullLines();
 
432
    for( ConnectorLine* line : m_conLineList ) line->setCursor( Qt::CrossCursor );
 
433
}
 
434
 
 
435
void Connector::splitCon( int index, Pin* pin1, Pin* pin2 )
 
436
{
 
437
    if( !m_endPin ) return;
 
438
 
 
439
    pin2->setEnode( enode() );
 
440
    pin1->setEnode( enode() );
 
441
 
 
442
    disconnectLines( index-1, index );
 
443
 
 
444
    QString type = QString("Connector");
 
445
    QString id = type;
 
446
    id.append( "-" );
 
447
    id.append( Circuit::self()->newSceneId() );
 
448
 
 
449
    Connector* new_connector = new Connector( Circuit::self(), type, id, pin2 );
 
450
    Circuit::self()->addItem(new_connector);
 
451
 
 
452
    int newindex = 0;
 
453
    int size = m_conLineList.size();
 
454
    for( int i = index; i < size; ++i)
 
455
    {
 
456
        ConnectorLine* lline = m_conLineList.takeAt( index );
 
457
        new_connector->lineList()->insert( newindex, lline );
 
458
 
 
459
        lline->setParent( new_connector );
 
460
        lline->setConnector( new_connector );
 
461
 
 
462
        if( newindex > 1 ) new_connector->incActLine();
 
463
        ++newindex;
 
464
    }
 
465
 
 
466
    if( index > 1 )  m_actLine = index-2;
 
467
    else             m_actLine = 0;
 
468
    
 
469
    new_connector->closeCon( m_endPin );    // Close new_connector first please
 
470
    closeCon( pin1 );                       // Close this
 
471
}
 
472
 
 
473
void Connector::updateLines()
 
474
{
 
475
    eNode* enode = startPin()->getEnode();
 
476
    if( enode && enode->voltchanged() )
 
477
    {
 
478
        for( ConnectorLine*  line : m_conLineList ) line->update();
 
479
    }
 
480
}
 
481
 
 
482
QStringList Connector::pointList()             { refreshPointList(); return m_pointList; }
 
483
void Connector::setPointList( QStringList pl ) { /*m_pointList.clear(); */m_pointList = pl;}
 
484
 
 
485
QString Connector::startPinId()               { return m_startpinid;}
 
486
void Connector::setStartPinId( QString pinid) { m_startpinid = pinid; }
 
487
QString Connector::endPinId()                 { return m_endpinid; }
 
488
void Connector::setEndPinId( QString pinid)   { m_endpinid = pinid; }
 
489
 
 
490
QString Connector::enodId() 
 
491
{
 
492
    eNode *node = m_startPin->getEnode();
 
493
 
 
494
    if( node ) return node->itemId();
 
495
    return "";
 
496
}
 
497
//void Connector::setEnodId( QString enodid ) { m_enodid = enodid; }
 
498
 
 
499
Pin* Connector::startPin()             { return m_startPin;}
 
500
void Connector::setStartPin( Pin* pin) { m_startPin = pin; }
 
501
Pin* Connector::endPin()               { return m_endPin; }
 
502
void Connector::setEndPin( Pin* pin)   { m_endPin = pin; }
 
503
 
 
504
eNode* Connector::enode() { return m_startPin->getEnode(); }
 
505
 
 
506
void   Connector::setEnode( eNode* enode )
 
507
 
508
    if( m_startPin ) m_startPin->setEnode( enode );
 
509
    if( m_endPin )   m_endPin->setEnode( enode );
 
510
    if( m_isBus )    enode->setIsBus( true );
 
511
}
 
512
 
 
513
double Connector::getVolt()
 
514
{
 
515
    //if( !m_eNode ) return 0;
 
516
    return m_startPin->getVolt();
 
517
}
 
518
 
 
519
QList<ConnectorLine*>* Connector::lineList() { return &m_conLineList; }
 
520
 
 
521
void Connector::incActLine() 
 
522
 
523
    //qDebug() << "Connector::incActLine"<<  m_actLine << m_conLineList.size()-1;
 
524
 
 
525
    if( m_actLine < m_conLineList.size()-1 ) m_actLine += 1;
 
526
}
 
527
 
 
528
void Connector::setIsBus( bool bus )
 
529
{
 
530
    if( m_isBus == bus ) return;
 
531
    if( !bus ) return;
 
532
    
 
533
    for( ConnectorLine* line : m_conLineList ) line->setIsBus( bus );
 
534
    
 
535
    m_isBus = bus;
 
536
}
 
537
 
 
538
bool Connector::isBus()
 
539
{
 
540
    return m_isBus;
 
541
}
 
542
 
 
543
#include "moc_connector.cpp"
 
544