@@ -42,7 +42,12 @@ InterfaceWithPythonDialog::InterfaceWithPythonDialog(const std::string& name, Mo
4242 setWindowTitle (QString::fromStdString (name));
4343 fixSize ();
4444
45- addTextEditManager (pythonCodeTextEdit_, Parameters::PythonCode);
45+ {
46+ pythonCodePlainTextEdit_ = new CodeEditor (this );
47+ tabWidget->widget (0 )->layout ()->addWidget (pythonCodePlainTextEdit_);
48+ }
49+
50+ addPlainTextEditManager (pythonCodePlainTextEdit_, Parameters::PythonCode);
4651
4752 addSpinBoxManager (retryAttemptsSpinBox_, Parameters::NumberOfRetries);
4853 addSpinBoxManager (pollingIntervalSpinBox_, Parameters::PollingIntervalMilliseconds);
@@ -91,13 +96,12 @@ void InterfaceWithPythonDialog::setupOutputTableCells()
9196
9297void InterfaceWithPythonDialog::updateFromPortChange (int numPorts, const std::string& portId, DynamicPortChange type)
9398{
94- // qDebug() << "InterfaceWithPythonDialog::updateFromPortChange" << numPorts << portId.c_str() << type;
9599 if (type == DynamicPortChange::INITIAL_PORT_CONSTRUCTION)
96100 return ;
97101
98102 if (type == DynamicPortChange::USER_REMOVED_PORT)
99103 {
100- QMessageBox::warning (this , " Warning: possible Python code update required" , windowTitle () +
104+ QMessageBox::warning (this , " Warning: possible Python code update required" , windowTitle () +
101105 " : The connection to port " + QString::fromStdString (portId) + " was deleted. The variable name \" " +
102106 QString::fromStdString (state_->getValue (SCIRun::Core::Algorithms::Name (portId)).toString ()) + " \" is no longer valid."
103107 + " Please update your Python code or input variable table to reflect this." );
@@ -116,11 +120,103 @@ void InterfaceWithPythonDialog::updateFromPortChange(int numPorts, const std::st
116120void InterfaceWithPythonDialog::handleInputTableWidgetRowChange (const std::string& portId, const std::string& type, DynamicPortChange portChangeType)
117121{
118122 const int lineEditColumn = 2 ;
119- syncTableRowsWithDynamicPort (portId, type, inputVariableNamesTableWidget_, lineEditColumn, portChangeType,
123+ syncTableRowsWithDynamicPort (portId, type, inputVariableNamesTableWidget_, lineEditColumn, portChangeType,
120124 { { 1 , [&](){ return new QTableWidgetItem (QString::fromStdString (type)); } } });
121125}
122126
123127void InterfaceWithPythonDialog::loadAPIDocumentation ()
124128{
125129 openPythonAPIDoc ();
126130}
131+
132+ CodeEditor::CodeEditor (QWidget *parent) : QPlainTextEdit(parent)
133+ {
134+ lineNumberArea_ = new LineNumberArea (this );
135+
136+ connect (this , SIGNAL (blockCountChanged (int )), this , SLOT (updateLineNumberAreaWidth (int )));
137+ connect (this , SIGNAL (updateRequest (QRect,int )), this , SLOT (updateLineNumberArea (QRect,int )));
138+ connect (this , SIGNAL (cursorPositionChanged ()), this , SLOT (highlightCurrentLine ()));
139+
140+ updateLineNumberAreaWidth (0 );
141+ highlightCurrentLine ();
142+ }
143+
144+ int CodeEditor::lineNumberAreaWidth ()
145+ {
146+ int digits = 1 ;
147+ int max = qMax (1 , blockCount ());
148+ while (max >= 10 ) {
149+ max /= 10 ;
150+ ++digits;
151+ }
152+
153+ int space = 3 + fontMetrics ().width (QLatin1Char (' 9' )) * digits;
154+
155+ return space;
156+ }
157+
158+ void CodeEditor::updateLineNumberAreaWidth (int /* newBlockCount */ )
159+ {
160+ setViewportMargins (lineNumberAreaWidth (), 0 , 0 , 0 );
161+ }
162+
163+ void CodeEditor::updateLineNumberArea (const QRect &rect, int dy)
164+ {
165+ if (dy)
166+ lineNumberArea_->scroll (0 , dy);
167+ else
168+ lineNumberArea_->update (0 , rect.y (), lineNumberArea_->width (), rect.height ());
169+
170+ if (rect.contains (viewport ()->rect ()))
171+ updateLineNumberAreaWidth (0 );
172+ }
173+
174+ void CodeEditor::resizeEvent (QResizeEvent *e)
175+ {
176+ QPlainTextEdit::resizeEvent (e);
177+
178+ QRect cr = contentsRect ();
179+ lineNumberArea_->setGeometry (QRect (cr.left (), cr.top (), lineNumberAreaWidth (), cr.height ()));
180+ }
181+
182+ void CodeEditor::highlightCurrentLine ()
183+ {
184+ QList<QTextEdit::ExtraSelection> extraSelections;
185+
186+ if (!isReadOnly ()) {
187+ QTextEdit::ExtraSelection selection;
188+
189+ QColor lineColor = QColor (Qt::darkGray);
190+
191+ selection.format .setBackground (lineColor);
192+ selection.format .setProperty (QTextFormat::FullWidthSelection, true );
193+ selection.cursor = textCursor ();
194+ selection.cursor .clearSelection ();
195+ extraSelections.append (selection);
196+ }
197+
198+ setExtraSelections (extraSelections);
199+ }
200+
201+ void CodeEditor::lineNumberAreaPaintEvent (QPaintEvent *event)
202+ {
203+ QPainter painter (lineNumberArea_);
204+ painter.fillRect (event->rect (), Qt::lightGray);
205+ QTextBlock block = firstVisibleBlock ();
206+ int blockNumber = block.blockNumber ();
207+ int top = (int ) blockBoundingGeometry (block).translated (contentOffset ()).top ();
208+ int bottom = top + (int ) blockBoundingRect (block).height ();
209+ while (block.isValid () && top <= event->rect ().bottom ()) {
210+ if (block.isVisible () && bottom >= event->rect ().top ()) {
211+ QString number = QString::number (blockNumber + 1 );
212+ painter.setPen (Qt::black);
213+ painter.drawText (0 , top, lineNumberArea_->width (), fontMetrics ().height (),
214+ Qt::AlignRight, number);
215+ }
216+
217+ block = block.next ();
218+ top = bottom;
219+ bottom = top + (int ) blockBoundingRect (block).height ();
220+ ++blockNumber;
221+ }
222+ }
0 commit comments