1 /****************************************************************************
2 **
3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the examples of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** Commercial Usage
11 ** Licensees holding valid Qt Commercial licenses may use this file in
12 ** accordance with the Qt Commercial License Agreement provided with the
13 ** Software or, alternatively, in accordance with the terms contained in
14 ** a written agreement between you and Nokia.
15 **
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file.  Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23 **
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27 **
28 ** GNU General Public License Usage
29 ** Alternatively, this file may be used under the terms of the GNU
30 ** General Public License version 3.0 as published by the Free Software
31 ** Foundation and appearing in the file LICENSE.GPL included in the
32 ** packaging of this file.  Please review the following information to
33 ** ensure the GNU General Public License version 3.0 requirements will be
34 ** met: http://www.gnu.org/copyleft/gpl.html.
35 **
36 ** If you have questions regarding the use of this file, please contact
37 ** Nokia at qt-info@nokia.com.
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include <QtGui>
43 
44 #include "codeeditor.h"
45 #include "shx_helper.h"
46 #include "window.h"
47 #include "dsrgui.h"
48 #include "deprecation.h"
49 #include "partcolor.h"
50 //#include "chgl.h"
51 
CodeEditor(QWidget * parent)52 CodeEditor::CodeEditor(QWidget *parent) : QPlainTextEdit(parent), c(0){
53   lineNumberArea = new LineNumberArea(this);
54   lineNumberArea->setObjectName("lineNumberArea");
55   lineNumberArea->setMouseTracking(true);
56   afixHighlightArea = new AfixHighlightArea(this);
57   afixHighlightArea->setObjectName("afixHighlightArea");
58   afixHighlightArea->setMouseTracking(true);
59   setMouseTracking(true);
60   midCursorpos=0;
61   dark=false;
62   //setTabChangesFocus(true);
63   highlighter = new Highlighter(document());
64   connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth(int)));
65   connect(this, SIGNAL(updateRequest(QRect,int)), this, SLOT(updateLineNumberArea(QRect,int)));
66 //  connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(highlightCurrentLine()));
67   connect(this, SIGNAL(textChanged()),this,SLOT(updateAfix()));
68 //  updateLineNumberAreaWidth(0);
69   //highlightCurrentLine();
70 
71   updateAfix();
72 
73     suchbox =  new QGroupBox("Search and Replace",this);
74     searchLE = new QLineEdit(suchbox);
75     searchLE->setMinimumSize(QSize(150, 0));
76     suchbox->setFlat(true);
77     slt=new QGridLayout(suchbox);
78     hidesearch = new QToolButton(suchbox);
79     hidesearch->setIcon(QIcon(":/xle-icons/cancel.png"));
80     hidesearch->setAutoRaise(true);
81     prev = new QToolButton(suchbox);
82     prev->setIcon(QIcon(":/xle-icons/moveleft.png"));
83     prev->setText("Previous");
84     prev->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
85     prev->setAutoRaise(true);
86     next = new QToolButton(suchbox);
87     next->setIcon(QIcon(":/xle-icons/moveright.png"));
88     next->setText("Next");
89     next->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
90     next->setAutoRaise(true);
91     wholeLine = new QCheckBox("Select whole lines",suchbox);
92     wholeLine->setChecked(false);
93 
94     slt->setSpacing(5);
95     slt->setMargin(0);
96     slt->addWidget(hidesearch,0,0);
97     slt->addWidget(searchLE,0,1);
98     slt->addWidget(prev,0,2);
99     slt->addWidget(next,0,3);
100     slt->setVerticalSpacing (0);
101     slt->addWidget(wholeLine,0,4);
102    // slt->setColumnStretch(6,10);
103     replace = new QLineEdit(suchbox);
104     replace->setMinimumSize(QSize(150, 0));
105 
106     replaceButton = new QToolButton(suchbox);
107     replaceButton->setIcon(QIcon(":/xle-icons/moveright.png"));
108     replaceButton->setText("Replace");
109     replaceButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
110     replaceButton->setAutoRaise(true);
111 
112     replacePButton = new QToolButton(suchbox);
113     replacePButton->setIcon(QIcon(":/xle-icons/moveleft.png"));
114     replacePButton->setText("Replace");
115     replacePButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
116     replacePButton->setAutoRaise(true);
117     replaceAButton= new QToolButton(suchbox);
118     //ediVis=oupVis=false;
119     replaceAButton->setIcon(QIcon(":/xle-icons/all.png"));
120 //
121 
122     replaceAButton->setText("Replace All!");
123     replaceAButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
124     replaceAButton->setAutoRaise(true);
125     slt->addWidget(replace,1,1);
126     slt->addWidget(replacePButton,1,2);
127     slt->addWidget(replaceButton,1,3);
128     slt->addWidget(replaceAButton,1,4);
129     suchbox->setLayout(slt);
130     suchbox->hide();
131     connect(searchLE, SIGNAL(textChanged(const QString&)),this,SLOT(findText()));
132     connect(searchLE, SIGNAL(textChanged(const QString&)),highlighter,SLOT(highlightSearch(const QString &)));
133     connect(next, SIGNAL(clicked() ), this, SLOT(findNext()));
134     connect(prev, SIGNAL(clicked() ), this, SLOT(findPrev()));
135     connect(searchLE, SIGNAL(returnPressed()), this, SLOT(findNext()));
136     connect(replaceButton, SIGNAL(clicked() ), this, SLOT(replaceNext()));
137     connect(replacePButton, SIGNAL(clicked() ), this, SLOT(replacePrev()));
138     connect(replaceAButton, SIGNAL(clicked() ), this, SLOT(replaceAll()));
139     connect(hidesearch, SIGNAL(clicked() ), this, SLOT(hideSearch()));
140 
141   //
142     resiFinder = new QComboBox();
143     resiFinder->setSizeAdjustPolicy(QComboBox::AdjustToContents);
144     connect(resiFinder, SIGNAL(activated(QString)), this, SLOT(findResi(QString)));
145     connect(resiFinder, SIGNAL(destroyed(QObject*)), this, SLOT(resiFinderDestroyed()));
146 }
147 
~CodeEditor()148 CodeEditor::~CodeEditor(){
149   //printf("CodeEditor will close%d\n",__LINE__);
150   disconnect(this);
151   //printf("ce%d\n",__LINE__);
152   delete lineNumberArea;
153   //printf("ce%d\n",__LINE__);
154   delete afixHighlightArea;
155   //printf("ce%d\n",__LINE__);
156   delete highlighter;
157   //printf("CodeEditor closed. %d %p\n",__LINE__,chgl);
158 
159 }
160 
lineNumberAreaWidth()161 int CodeEditor::lineNumberAreaWidth(){
162   int digits = 4;//2;
163   //int max = qMax(1, blockCount());
164   //while (max >= 10) {
165   //  max /= 10;
166   //  ++digits;
167   //}
168 
169   int space = 5 + fontMetrics().width(QLatin1Char('9')) * digits;
170   return space;
171 }
172 
updateLineNumberAreaWidth(int)173 void CodeEditor::updateLineNumberAreaWidth(int /* newBlockCount */){
174     setViewportMargins(lineNumberAreaWidth()+15, 0, 0, 0);
175 }
176 
updateLineNumberArea(const QRect & rect,int dy)177 void CodeEditor::updateLineNumberArea(const QRect &rect, int dy){
178   Q_UNUSED ( rect );
179 //  printf("updateLineNumberArea\n");
180     if (dy){
181         lineNumberArea->scroll(0, dy);
182         afixHighlightArea->scroll(0,dy);
183     }
184    /*
185     else{
186       printf("Area->update1 %d %d\n",rect.x(),rect.y());
187     //lineNumberArea->update(0, rect.y(), lineNumberArea->width(), rect.height());
188       printf("Area->update2\n");
189     //afixHighlightArea->update(0,rect.y(),10,rect.height());
190       printf("Area->update3\n");
191 }*/
192   if (rect.contains(viewport()->rect()))
193     updateLineNumberAreaWidth(0);
194     //*/
195 }
196 
resizeEvent(QResizeEvent * e)197 void CodeEditor::resizeEvent(QResizeEvent *e){
198   QPlainTextEdit::resizeEvent(e);
199   QRect cr = contentsRect();
200   lineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height()));
201   afixHighlightArea->setGeometry(QRect(
202       cr.left()+lineNumberAreaWidth()+1,
203       cr.top(),
204       10,cr.height()
205       ));
206   e->accept();
207 }
208 
expandGreaterThan()209 void CodeEditor::expandGreaterThan(){//!< some SHELXL re- or constrainst use > to specify a range of atoms this is a problem for sorting atoms
210     QTextDocument *document = this->document();
211     printf("expandGreaterThan\n");
212     for (int i=0; i<blocks.size(); i++){
213         if (blocks.at(i).startsWith("REM",Qt::CaseInsensitive)) continue;
214         if (blocks.at(i).contains('>')){
215             int comRN=-1,comPart=9999;
216             QString comRL="";
217             QString orig=blocks.at(i);
218             QStringList tokens=orig.split(QRegExp("\\s+"));
219             int da=tokens.indexOf(">");
220             QRegExp toReplace=QRegExp(QString("%1\\s+>\\s+%2").arg(tokens.at(da-1)).arg(tokens.at(da+1)));
221             QString with="";
222             if (tokens.at(0).contains("_")){
223                 QString spec = tokens.at(0).section('_',1,1);
224                 if (spec.contains(QRegExp("^[0-9]+$"))) comRN=spec.toInt();
225                 else if (spec.contains(QRegExp("^[A-Z]"))) comRL=spec;
226                 else if (spec.contains(QRegExp("^[a-z]$"))) comPart=spec.toInt(0,36)-9;
227             }
228             bool on=false;
229             //printf("%d %d \n",comRN,comPart);
230             for (int j=0; j< chgl->mol->asymm.size(); j++){
231                 if (chgl->mol->asymm.at(j).an<1)continue;
232                 QString s=chgl->mol->asymm.at(j).Label.section(QString::fromUtf8("_"),0,0);
233                 if ((comRN>0)&&(chgl->mol->asymm.at(j).resiNr!=comRN))continue;
234                 if ((comPart!=9999)&&((chgl->mol->asymm.at(j).part!=comPart)||(chgl->mol->asymm.at(j).part!=(25-comPart)))) continue;
235                 if ((!comRL.isEmpty())&&(chgl->mol->asymm.at(j).ResiClass!=comRL))continue;
236                 if (s==tokens.at(da-1)) on=true;
237                 if (on) if (!with.contains(s+" ")){
238                     with.append(QString("%1 ").arg(s));
239                     if (with.section('=',-1,-1).length()>60) with.append(" = \n ");
240                 }
241                 if (s==tokens.at(da+1)) on=false;
242             }
243             //DSRGui::textWrap(buffer)
244             //qDebug()<<orig<<toReplace.pattern()<<with;
245             QTextCursor cursor = textCursor();
246             cursor.movePosition(QTextCursor::Start);
247             cursor = document->find(orig,cursor);
248             cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
249             cursor =document->find(toReplace);
250             cursor.insertText(with);
251         }
252         if (blocks.at(i).contains('<')){
253             int comRN=-1,comPart=9999;
254             QString comRL="";
255             QString orig=blocks.at(i);
256             QStringList tokens=orig.split(QRegExp("\\s+"));
257             int da=tokens.indexOf("<");
258             QRegExp toReplace=QRegExp(QString("%1\\s+<\\s+%2").arg(tokens.at(da-1)).arg(tokens.at(da+1)));
259             QString with="";
260             if (tokens.at(0).contains("_")){
261                 QString spec = tokens.at(0).section('_',1,1);
262                 if (spec.contains(QRegExp("^[0-9]+$"))) comRN=spec.toInt();
263                 else if (spec.contains(QRegExp("^[A-Z]"))) comRL=spec;
264                 else if (spec.contains(QRegExp("^[a-z]$"))) comPart=spec.toInt(0,36)-9;
265             }
266             bool on=false;
267             for (int j=chgl->mol->asymm.size()-1; j>=0; j--){
268                 if (chgl->mol->asymm.at(j).an<1)continue;
269                 QString s=chgl->mol->asymm.at(j).Label.section(QString::fromUtf8("_"),0,0);
270                 if ((comRN>0)&&(chgl->mol->asymm.at(j).resiNr!=comRN))continue;
271                 if ((comPart!=9999)&&((chgl->mol->asymm.at(j).part!=comPart)||(chgl->mol->asymm.at(j).part!=(25-comPart)))) continue;
272                 if ((!comRL.isEmpty())&&(chgl->mol->asymm.at(j).ResiClass!=comRL))continue;
273                 if (s==tokens.at(da-1)) on=true;
274                 if (on) if (!with.contains(s+" ")) {
275                     with.append(QString("%1 ").arg(s));
276                     if (with.section('=',-1,-1).length()>60) with.append(" = \n ");
277                 }
278                 if (s==tokens.at(da+1)) on=false;
279             }
280             //DSRGui::textWrap(buffer)
281             //qDebug()<<orig<<toReplace.pattern()<<with;
282             QTextCursor cursor = textCursor();
283             cursor.movePosition(QTextCursor::Start);
284             cursor = document->find(orig,cursor);
285             cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
286             cursor =document->find(toReplace);
287             cursor.insertText(with);
288         }
289     }
290 }
291 
selectedRestraintsAtoms(QString buffer,QList<MyAtom> selected,QString resiSpec,bool exclude_H)292 QString CodeEditor::selectedRestraintsAtoms(QString buffer, QList<MyAtom> selected, QString resiSpec, bool exclude_H){
293   //! Assembles the selected atom names to parameters for the specific restraint.
294   for (QList<MyAtom>::iterator atom = selected.begin(); atom != selected.end(); atom++) {
295     if((atom->an==0) && (exclude_H)) {//Hydrogen have an == 0 !
296       // excludes hydrogen atoms
297       continue;
298     }
299     if (atom->an < 0) {//non atoms have an < 0
300       // excludes q-peaks, even if exclude_H is false
301       continue;
302     }
303     // Do not add atoms outside of the asymmetric unit to the restraints:
304     if (atom->symmGroup!=0) {
305       continue;
306     }
307     if ((resiSpec.isEmpty()) && (atom->resiNr > 0)) {//I think 'and' is confusing and I prefere &&
308       buffer += (atom->Label.section("_", 0, 0) + QString("_%1").arg(atom->resiNr) + " ");
309     } else {
310       buffer += (atom->Label.section("_", 0, 0) + " ");
311     }
312   }
313   return buffer + "\n";
314 }
315 
updateWght()316 void CodeEditor::updateWght(){
317   if (chgl->mol->asymm.isEmpty()) return;
318   QTextDocument *document = this->document();
319   QTextCursor cursor = textCursor();
320   cursor.beginEditBlock ();
321   cursor.movePosition(QTextCursor::End);
322   cursor = document->find("WGHT",cursor,QTextDocument::FindBackward);
323   if (cursor.isNull()) {
324     cursor = textCursor();
325     cursor.endEditBlock ();
326     return;
327   }
328   cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
329   cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
330   QString newWeight= cursor.selectedText();
331   cursor.clearSelection();
332 
333   cursor.movePosition(QTextCursor::Up);
334 
335   cursor = document->find("WGHT",cursor,QTextDocument::FindBackward);
336 
337   cursor.movePosition(QTextCursor::StartOfLine);
338   cursor.clearSelection();
339   cursor.insertText(" ");
340   cursor.movePosition(QTextCursor::Down);
341   cursor.insertText(newWeight);
342   cursor.insertText("\n");
343 
344   cursor.endEditBlock ();
345   setTextCursor(cursor);
346   centerCursor () ;
347   cursor.clearSelection ();
348   setFocus () ;
349   update();
350 }
351 
insertList4()352 void CodeEditor::insertList4(){
353     //we have a active LIST already in the file let's replace it
354     replace->setText("REM LIST ");
355     searchLE->setText("^LIST ");
356     replaceAll();
357     replace->setText("");
358     searchLE->setText("");
359   if (!toPlainText().contains(QRegExp("\nLIST",Qt::CaseInsensitive))){
360     QTextDocument *document = this->document();
361     QTextCursor cursor = textCursor();
362     cursor.movePosition(QTextCursor::Start,QTextCursor::MoveAnchor);
363     cursor = document->find(QRegExp("^UNIT",Qt::CaseInsensitive),cursor);
364     cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
365     cursor.movePosition(QTextCursor::Down,QTextCursor::MoveAnchor);
366     cursor.insertText("LIST 4\n");
367     emit saveMe(true,false);
368   }
369 
370 }
371 
insertList6()372 void CodeEditor::insertList6(){
373   if (!toPlainText().contains(QRegExp("\nLIST",Qt::CaseInsensitive))){
374     QTextDocument *document = this->document();
375     QTextCursor cursor = textCursor();
376     cursor.movePosition(QTextCursor::Start,QTextCursor::MoveAnchor);
377     cursor = document->find(QRegExp("^UNIT",Qt::CaseInsensitive),cursor);
378     cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
379     cursor.movePosition(QTextCursor::Down,QTextCursor::MoveAnchor);
380     cursor.insertText("LIST 6 ! automatically inserted. Change 6 to 4 for CHECKCIF!!\n");
381     emit saveMe(true,false);
382   }
383 }
384 
insertAnis()385 void CodeEditor::insertAnis(){
386   QTextDocument *document = this->document();
387   QTextCursor cursor = textCursor();
388   cursor.movePosition(QTextCursor::Start,QTextCursor::MoveAnchor);
389   cursor = document->find(QRegExp("^UNIT",Qt::CaseInsensitive),cursor);
390   cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
391   cursor.movePosition(QTextCursor::Down,QTextCursor::MoveAnchor);
392   cursor.insertText("ANIS ! automatically inserted\n");
393 }
394 
insertActa()395 void CodeEditor::insertActa(){
396     insertList4();
397   QTextDocument *document = this->document();
398   QTextCursor cc,cursor = textCursor();
399   cursor.movePosition(QTextCursor::Start,QTextCursor::MoveAnchor);
400 
401   cc = document->find(QRegExp("^ACTA",Qt::CaseInsensitive),cursor);
402   if (cc.isNull()) {
403     cursor = textCursor();
404     cursor.movePosition(QTextCursor::Start,QTextCursor::MoveAnchor);
405   }else return;
406   cursor = document->find(QRegExp("^UNIT",Qt::CaseInsensitive),cursor);
407   cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
408   cursor.movePosition(QTextCursor::Down,QTextCursor::MoveAnchor);
409   cursor.insertText("ACTA \n");
410 }
411 
dispFromWave()412 void CodeEditor::dispFromWave(){
413   if (chgl->mol->asymm.isEmpty()) return;
414   QFile kis(":kisselwave");
415   kis.open(QIODevice::ReadOnly|QIODevice::Text);
416   QByteArray ba=kis.readAll();
417   QStringList all= QString(ba).split('\n');
418   kis.close();
419   QTextDocument *document = this->document();
420   QTextCursor cursor = textCursor();
421   cursor.beginEditBlock();
422   replace->setText("REM DISP ");
423   searchLE->setText("^DISP ");
424   replaceAll();
425   replace->setText("");
426   searchLE->setText("");
427   cursor.movePosition(QTextCursor::Start,QTextCursor::MoveAnchor);
428   cursor = document->find("UNIT",cursor);
429   cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
430   QStringList nn,an;
431   QString disp;
432   for (int i=0; i<sfac.size();i++){
433     double aw=0,w;
434     w=aw;
435 
436     int x=all.indexOf(QString("#S %1 %2").arg(sfac.at(i)+1,2,10,QChar('0')).arg(chgl->mol->pse(sfac.at(i))));
437     int y=all.indexOf(QString("#S %1 %2").arg(sfac.at(i)+2,2,10,QChar('0')).arg(chgl->mol->pse(sfac.at(i)+1)));
438     //printf("SFAC <<%d>> %s\n",x,QString("#S %1 %2").arg(sfac.at(i)+1,2,10,QChar('0')).arg(chgl->mol->pse(sfac.at(i))).toStdString().c_str());
439     //printf("SFAC <<%d>> %s\n",y,QString("#S %1 %2").arg(sfac.at(i)+2,2,10,QChar('0')).arg(chgl->mol->pse(sfac.at(i)+1)).toStdString().c_str());
440     for (int j=x+1; j<y; j++){
441       an=nn;
442       nn=all.at(j).split(" ",skipEmptyParts);
443       aw=w;
444       w=nn.at(0).toDouble();
445       if ((w!=aw)&&(chgl->mol->cell.wave>w)) {
446         double f= (chgl->mol->cell.wave-aw)/(w-aw);
447             //printf("DISP $%s %f %f\n",chgl->mol->pse(sfac.at(i)).toStdString().c_str(),f*nn.at(1).toDouble()+(1-f)*an.at(1).toDouble(),f*nn.at(2).toDouble()+(1-f)*an.at(2).toDouble());
448             if (nn.size()>3){
449                 disp=QString("DISP $%1 %2 %3 %4!source kissel\n")//REM %5\nREM %6\n")
450                   .arg(chgl->mol->pse(sfac.at(i)))
451                   .arg(f*nn.at(1).toDouble()+(1-f)*an.at(1).toDouble(),8,'f',5)
452                   .arg(f*nn.at(2).toDouble()+(1-f)*an.at(2).toDouble(),8,'f',5)
453                   .arg(f*nn.at(3).toDouble()+(1-f)*an.at(3).toDouble(),8,'f',5)
454                   ;}else{
455                 disp=QString("DISP $%1 %2 %3!source kissel\n")//REM %5\nREM %6\n")
456                   .arg(chgl->mol->pse(sfac.at(i)))
457                   .arg(f*nn.at(1).toDouble()+(1-f)*an.at(1).toDouble(),8,'f',5)
458                   .arg(f*nn.at(2).toDouble()+(1-f)*an.at(2).toDouble(),8,'f',5)
459                   ;
460             }
461         cursor.insertText(disp);
462         j=5000+x;
463       }
464     }
465 
466   }
467 
468   cursor.endEditBlock();
469 }
470 
updateUnit()471 void CodeEditor::updateUnit(){
472   if (chgl->mol->asymm.isEmpty()) return;
473   QTextDocument *document = this->document();
474   QTextCursor cursor = textCursor();
475   cursor.beginEditBlock ();
476   cursor.movePosition(QTextCursor::Start);
477   cursor = document->find(unitAlt,cursor);
478   if (cursor.isNull()) {
479     cursor = textCursor();
480     cursor.endEditBlock ();
481     printf("can't find unit\n");
482     update();
483     return;
484   }
485   cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
486   cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
487   cursor.deleteChar();
488   cursor.insertText(unitNeu);
489   cursor.endEditBlock ();
490   setTextCursor(cursor);
491   centerCursor () ;
492   cursor.clearSelection ();
493   setTextCursor(cursor);
494   setFocus () ;
495   update();
496 }
497 
weedEmptySfacs()498 void CodeEditor::weedEmptySfacs(){
499   if (chgl->mol->asymm.isEmpty()) return;
500   emit saveMe(true,true);
501   if (1){//(maybeSave()){
502     QMap<int,double> unit;
503     for (int i=0; i<chgl->mol->asymm.size(); i++){
504       if (chgl->mol->asymm.at(i).an>=0) unit[chgl->mol->asymm.at(i).an]+= chgl->mol->asymm.at(i).sof * chgl->mol->cell.symmops.size();
505     }
506     unitNeu="UNIT";
507     for (int i = 0; i < sfac.size() ; i++){
508       if (unit.value(sfac.at(i))) {
509         if (unit.value(sfac.at(i))>9999)
510           unitNeu.append(QString(" %1").arg((int)unit.value(sfac.at(i)))); else
511             unitNeu.append(QString(" %1").arg(unit.value(sfac.at(i)),0,'g'));
512       }
513       if (unitNeu.split('\n').last().size()>76) unitNeu.append("=\n    ");
514     }
515     updateUnit();
516     QTextDocument *document = this->document();
517     QTextCursor cursor = textCursor();
518     QTextCursor c=cursor;
519     cursor.movePosition(QTextCursor::Start);
520     int apos=0,pos=0;
521     QList<int> mussweg,newSfac=sfac;
522     for (int i = 0; i < sfac.size() ; i++){
523       if (unit.value(sfac.at(i))==0) {
524         mussweg.append(i);
525         newSfac.removeOne(sfac.at(i));
526       }
527     }
528     if (mussweg.isEmpty()) return;
529     cursor = document->find(QRegExp("^SFAC"),cursor);
530     if (cursor.isNull()){setTextCursor(c);return;}
531     cursor.movePosition(QTextCursor::Start);
532     while ((!cursor.isNull())&&(pos<sfac.size())){
533       cursor = document->find(QRegExp("^SFAC"),cursor);
534       cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
535       if (cursor.selectedText().contains(QRegExp("[.0-9]+"))){
536         bool hatgleich=cursor.selectedText().contains(QRegExp("=\\s*$"));
537         cursor.clearSelection();
538         cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
539         if (mussweg.contains(pos)) {
540           cursor.insertText("REM ");
541           if (hatgleich) {
542             cursor.movePosition(QTextCursor::Down,QTextCursor::MoveAnchor);
543             cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
544             cursor.insertText("REM ");
545           }
546         }else if (hatgleich) cursor.movePosition(QTextCursor::Down,QTextCursor::MoveAnchor);
547         pos++;
548       }
549       else {
550         pos+=cursor.selectedText().split(" ",skipEmptyParts).size()-1;
551         cursor.deleteChar();
552         QString ac;
553         for (int i =apos; i<newSfac.size() && i<pos+apos;i++) ac.append(QString("%1 ").arg(chgl->mol->pse(newSfac.at(i))));
554         apos=pos;
555         cursor.insertText(QString("SFAC %1\n").arg(ac));
556       }
557     }
558     for (int i=0; i<chgl->mol->asymm.size();i++){
559       if ((sfac.indexOf(chgl->mol->asymm.at(i).an)>-1)&&
560           (newSfac.indexOf(chgl->mol->asymm.at(i).an)>-1)&&
561           (sfac.indexOf(chgl->mol->asymm.at(i).an)!=newSfac.indexOf(chgl->mol->asymm.at(i).an))){
562         jumpToAtom(i);
563         cursor = textCursor();
564         cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
565         QString repla=cursor.selectedText();
566         cursor.deleteChar();
567         repla.replace(QString(" %1 ").arg(1+sfac.indexOf(chgl->mol->asymm.at(i).an)), QString(" %1 ").arg(1+newSfac.indexOf(chgl->mol->asymm.at(i).an)));
568         cursor.insertText(repla);
569         chgl->mol->asymm[i].orginalLine=repla;
570       }
571     }
572     emit saveMe(true,true);
573     document = this->document();
574     if(document->toPlainText().contains("DISP"))
575       dispFromWave();
576   }
577 }
578 
jumpToAtom(int index)579 void CodeEditor::jumpToAtom(int index){
580   QString label = chgl->mol->showatoms.at(index).orginalLine.left(80).trimmed();
581   //  qDebug()<<index<<chgl->mol->showatoms.at(index).Label<<label;
582   QTextDocument *document = this->document();
583   QTextCursor cursor = textCursor();
584   cursor.movePosition(QTextCursor::Start);
585   cursor = document->find(label,cursor);
586   if (cursor.isNull()){
587     cursor = textCursor();
588     cursor.movePosition(QTextCursor::Start);
589     label.chop(10);
590     cursor = document->find(label,cursor);
591     if (cursor.isNull()) cursor = textCursor();
592     cursor.movePosition(QTextCursor::Start);
593     label = chgl->mol->showatoms.at(index).orginalLine.left(80).simplified();
594     cursor = document->find(label,cursor);
595     if (cursor.isNull()) cursor = textCursor();
596   }
597   cursor.movePosition(QTextCursor::StartOfLine);
598   setTextCursor(cursor);
599   centerCursor();
600   cursor.clearSelection();
601   setTextCursor(cursor);
602   setFocus();
603 }
604 
insertANIS(QList<MyAtom> selected)605 void CodeEditor::insertANIS(QList<MyAtom> selected){
606   QTextDocument *document = this->document();
607   QTextCursor cursor = textCursor();
608   cursor.movePosition(QTextCursor::Start,QTextCursor::MoveAnchor);
609   cursor = document->find(QRegExp("^UNIT",Qt::CaseInsensitive),cursor);
610   cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
611   cursor.movePosition(QTextCursor::Down,QTextCursor::MoveAnchor);
612   QString buffer("ANIS ");
613   buffer = selectedRestraintsAtoms(buffer, selected, "", true);
614   cursor.insertText(DSRGui::textWrap(buffer));
615 }
616 
insertDFIX(double value,double esd,QList<MyAtom> selected,QString resiSpec)617 void CodeEditor::insertDFIX(double value, double esd, QList<MyAtom> selected, QString resiSpec){
618 
619   QTextDocument *document = this->document();
620   QTextCursor cursor = textCursor();
621   cursor.movePosition(QTextCursor::Start,QTextCursor::MoveAnchor);
622   cursor = document->find(QRegExp("^UNIT",Qt::CaseInsensitive),cursor);
623   cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
624   cursor.movePosition(QTextCursor::Down,QTextCursor::MoveAnchor);
625   QString buffer = QString("DFIX%1 %2 %3 ").arg((resiSpec.isEmpty())?"":"_"+resiSpec).arg(value).arg(esd);
626   buffer = selectedRestraintsAtoms(buffer, selected, resiSpec);
627   cursor.insertText(DSRGui::textWrap(buffer));
628 }
629 
insertDANG(double value,double esd,QList<MyAtom> selected,QString resiSpec)630 void CodeEditor::insertDANG(double value, double esd, QList<MyAtom> selected, QString resiSpec){
631 
632   QTextDocument *document = this->document();
633   QTextCursor cursor = textCursor();
634   cursor.movePosition(QTextCursor::Start,QTextCursor::MoveAnchor);
635   cursor = document->find(QRegExp("^UNIT",Qt::CaseInsensitive),cursor);
636   cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
637   cursor.movePosition(QTextCursor::Down,QTextCursor::MoveAnchor);
638   QString buffer =QString("DANG%1 %2 %3 ").arg((resiSpec.isEmpty())?"":"_"+resiSpec).arg(value).arg(esd);
639   buffer = selectedRestraintsAtoms(buffer, selected, resiSpec);
640   cursor.insertText(DSRGui::textWrap(buffer));
641 }
642 
insertFLAT(double esd,QList<MyAtom> selected,QString resiSpec)643 void CodeEditor::insertFLAT(double esd, QList<MyAtom> selected, QString resiSpec){
644   QTextDocument *document = this->document();
645   QTextCursor cursor = textCursor();
646   cursor.movePosition(QTextCursor::Start,QTextCursor::MoveAnchor);
647   cursor = document->find(QRegExp("^UNIT",Qt::CaseInsensitive),cursor);
648   cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
649   cursor.movePosition(QTextCursor::Down,QTextCursor::MoveAnchor);
650   QString buffer =QString("FLAT%1 %2 ").arg((resiSpec.isEmpty())?"":"_"+resiSpec).arg(esd);
651   buffer = selectedRestraintsAtoms(buffer, selected, resiSpec);
652   cursor.insertText(DSRGui::textWrap(buffer));
653 }
654 
insertEXYZ(QList<MyAtom> selected,QString resiSpec)655 void CodeEditor::insertEXYZ(QList<MyAtom> selected, QString resiSpec){
656   QTextDocument *document = this->document();
657   QTextCursor cursor = textCursor();
658   cursor.movePosition(QTextCursor::Start,QTextCursor::MoveAnchor);
659   cursor = document->find(QRegExp("^UNIT",Qt::CaseInsensitive),cursor);
660   cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
661   cursor.movePosition(QTextCursor::Down,QTextCursor::MoveAnchor);
662   QString buffer =QString("EXYZ%1 ").arg((resiSpec.isEmpty())?"":"_"+resiSpec);
663   buffer = selectedRestraintsAtoms(buffer, selected, resiSpec);
664   cursor.insertText(DSRGui::textWrap(buffer));
665 }
666 
jumpToError()667 void CodeEditor::jumpToError(){
668   QTextCursor c = textCursor();
669   if (!errorInLine.isEmpty()){
670     c.movePosition(QTextCursor::Start,QTextCursor::MoveAnchor);
671     c.movePosition(QTextCursor::Down,QTextCursor::MoveAnchor,errorInLine.first());
672     setTextCursor(c);
673     ensureCursorVisible ();
674   }
675 }
676 
findResi(QString index)677 void CodeEditor::findResi(QString index){
678   if (!index.isEmpty()) {
679     QTextCursor c=this->document()->find(index);
680     if (!c.isNull()) {
681       c.movePosition(QTextCursor::StartOfLine);
682       setTextCursor(c);
683       centerCursor();
684       c.clearSelection ();
685       //QTextBlock b =c.block();
686       QStringList tt=index.split(QRegExp("\\s+"),skipEmptyParts);
687 
688       int nr=0;
689       if ((tt.size()>1)&&(tt.at(1).indexOf(QRegExp("^[0-9]+"))!=-1))
690         nr=tt.at(1).toInt();
691       else if (tt.size()>2) nr=tt.at(2).toInt();
692       //QString tt = index.section(QRegExp("\\s+"),1,1).toInt();
693       chgl->selectResiByNr(nr);
694       setTextCursor(c);
695       setFocus () ;
696     }
697   }
698 }
699 
increaseEdtiorFont()700 void CodeEditor::increaseEdtiorFont(){
701   QFont f =font();
702   f.setPointSize(qMin(f.pointSize()+1,24));
703   setFont(f);
704   update();
705 }
706 
decreaseEdtiorFont()707 void CodeEditor::decreaseEdtiorFont(){
708   QFont f =font();
709   f.setPointSize(qMax(f.pointSize()-1,6));
710   setFont(f);
711   update();
712 }
713 
hideSearch()714 void CodeEditor::hideSearch(){
715   searchLE->clear();
716   suchbox->hide();
717 }
718 
showSearch()719 void CodeEditor::showSearch(){
720   suchbox->show();
721   if (isReadOnly()){
722     replace->hide();
723     replaceButton->hide();
724     replacePButton->hide();
725     replaceAButton->hide();
726   }else{
727     replace->show();
728     replaceButton->show();
729     replacePButton->show();
730     replaceAButton->show();
731   }
732   suchbox->setTitle(QString("Search and Replace:"));
733   searchLE->setFocus();
734 }
735 
findNext()736 void CodeEditor::findNext(){
737   suchbox->show();
738   if (isReadOnly()){
739     replace->hide();
740     replaceButton->hide();
741     replacePButton->hide();
742     replaceAButton->hide();
743   }else{
744     replace->show();
745     replaceButton->show();
746     replacePButton->show();
747     replaceAButton->show();
748   }
749   suchbox->setTitle(QString("Search and Replace:"));
750   searchchanged(false,false);
751 }
752 
findPrev()753 void CodeEditor::findPrev(){
754   suchbox->show();
755   if (isReadOnly()){
756     replace->hide();
757     replaceButton->hide();
758     replacePButton->hide();
759     replaceAButton->hide();
760   }else{
761     replace->show();
762     replaceButton->show();
763     replacePButton->show();
764     replaceAButton->show();
765   }
766   suchbox->setTitle(QString("Search and Replace:"));
767   searchchanged(false,true);
768 }
769 
findText()770 void CodeEditor::findText(){
771   searchchanged(true,false);
772 }
773 
searchchanged(bool current,bool back)774 void CodeEditor::searchchanged(bool current,bool back){
775   QRegExp searchString = QRegExp(searchLE->text(),Qt::CaseInsensitive);
776   QPalette p = searchLE->palette();
777   p.setBrush(QPalette::Active,QPalette::Base,Qt::white);
778   QTextDocument *document;
779   QTextCursor cursor;
780 
781   document = this->document();
782   cursor = textCursor();
783 
784   if (!searchString.isEmpty()){
785     if (cursor.hasSelection())
786       cursor.setPosition((current|back)?cursor.anchor():cursor.position(), QTextCursor::MoveAnchor);
787     QTextDocument::FindFlags options;
788     if (back) options|=QTextDocument::FindBackward;
789     cursor=document->find(searchString,cursor,options);
790     if (cursor.isNull()){
791       QTextCursor ac(document);
792       ac.movePosition(options & QTextDocument::FindBackward
793           ? QTextCursor::End : QTextCursor::Start);
794       cursor = document->find(searchString, ac,options);
795       if (cursor.isNull()){
796         p.setBrush(QPalette::Active,QPalette::Base,QColor(205,100,100));
797         cursor = textCursor();
798         cursor.movePosition(QTextCursor::Start);
799       }
800     }
801     if ((!cursor.isNull())&&(wholeLine->isChecked())){
802       cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
803       cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
804     }
805   }
806   else cursor.movePosition(QTextCursor::Start);
807 
808   setTextCursor(cursor);
809   searchLE->setPalette(p);
810 }
811 
replaceNext()812 void CodeEditor::replaceNext(){
813   suchbox->setTitle(QString("Search and Replace:"));
814   QRegExp searchString = QRegExp(searchLE->text(),Qt::CaseInsensitive);
815   QPalette p = searchLE->palette();
816   p.setBrush(QPalette::Active,QPalette::Base,Qt::white);
817   QTextDocument *document;
818   QTextCursor cursor;
819 
820   document = this->document();
821   cursor = textCursor();
822 
823   if (!searchString.isEmpty()){
824     if (cursor.hasSelection()){
825       cursor.beginEditBlock();
826       if (wholeLine->isChecked()){
827         cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
828         cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
829       }
830       cursor.deleteChar();
831       if (replace->text().isEmpty())cursor.deleteChar();
832       else cursor.insertText(replace->text());
833       cursor.endEditBlock();
834       cursor.setPosition(cursor.position(), QTextCursor::MoveAnchor);
835     }
836     cursor=document->find(searchString,cursor);
837     if (cursor.isNull()){
838       QTextCursor ac(document);
839       ac.movePosition(QTextCursor::Start);
840       cursor = document->find(searchString, ac);
841       if (cursor.isNull()){
842         p.setBrush(QPalette::Active,QPalette::Base,QColor(205,100,100));
843       }
844     }
845     if ((!cursor.isNull())&&(wholeLine->isChecked())){
846       cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
847       cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
848     }
849   }
850   else cursor.movePosition(QTextCursor::Start);
851   setTextCursor(cursor);
852   searchLE->setPalette(p);
853   centerCursor();
854   return;
855 }
856 
replaceAll()857 void CodeEditor::replaceAll(){
858   suchbox->setTitle(QString("Search and Replace:"));
859   QRegExp searchString = QRegExp(searchLE->text(),Qt::CaseInsensitive);
860   QPalette p = searchLE->palette();
861   p.setBrush(QPalette::Active,QPalette::Base,Qt::white);
862   QTextDocument *document;
863   QTextCursor cursor;
864 
865   document = this->document();
866   cursor = textCursor();
867   int occurrence=0;
868   cursor.beginEditBlock();
869   cursor.movePosition(QTextCursor::Start);
870   if (!searchString.isEmpty()){
871     do {
872       cursor=document->find(searchString,cursor);
873       if (cursor.hasSelection()){
874         cursor.beginEditBlock();
875         if (wholeLine->isChecked()){
876           cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
877           cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
878         }
879         cursor.deleteChar();
880         if (replace->text().isEmpty())cursor.deleteChar();
881         else cursor.insertText(replace->text());
882         cursor.endEditBlock();
883         cursor.setPosition(cursor.position(), QTextCursor::MoveAnchor);
884         occurrence++;
885       }
886     }
887     while (!cursor.isNull());
888   }
889 
890   cursor = textCursor();
891   cursor.endEditBlock();
892   setTextCursor(cursor);
893   searchLE->setPalette(p);
894   centerCursor();
895   if (occurrence){
896     suchbox->setTitle(QString("Search and Replace: Replaced %1 occurrencies of '%2' by '%3'.").arg(occurrence).arg(searchString.pattern()).arg(replace->text()));
897   }
898   return;
899 }
900 
replacePrev()901 void CodeEditor::replacePrev(){
902   suchbox->setTitle(QString("Search and Replace:"));
903   QRegExp searchString = QRegExp(searchLE->text(),Qt::CaseInsensitive);
904 
905   QPalette p = searchLE->palette();
906   p.setBrush(QPalette::Active,QPalette::Base,Qt::white);
907   QTextDocument *document;
908   QTextCursor cursor;
909 
910   document = this->document();
911   cursor = textCursor();
912 
913   if (!searchString.isEmpty()){
914     if (cursor.hasSelection()){
915       cursor.beginEditBlock();
916       if (wholeLine->isChecked()){
917         cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
918         cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
919       }
920       cursor.deleteChar();
921       if (replace->text().isEmpty())cursor.deleteChar();
922       else cursor.insertText(replace->text());
923       cursor.endEditBlock();
924       cursor.setPosition(cursor.anchor(), QTextCursor::MoveAnchor);
925     }
926     cursor=document->find(searchString,cursor,QTextDocument::FindBackward);
927     if (cursor.isNull()){
928       QTextCursor ac(document);
929       ac.movePosition(QTextCursor::End);
930       cursor = document->find(searchString, ac,QTextDocument::FindBackward);
931       if (cursor.isNull()){
932         p.setBrush(QPalette::Active,QPalette::Base,QColor(205,100,100));
933       }
934     }
935   }
936   else cursor.movePosition(QTextCursor::Start);
937   setTextCursor(cursor);
938   searchLE->setPalette(p);
939   centerCursor();
940   searchchanged(false,true);
941   return;
942 }
943 
resiFinderDestroyed()944 void CodeEditor::resiFinderDestroyed(){
945   resiFinder = nullptr;
946 }
947 
changeSortierWeise(QAction * action)948 void CodeEditor::changeSortierWeise(QAction* action){
949   int index = action->data().toInt();
950   sortierWeise = index;
951   chgl->mol->einstellung->beginGroup("Sorting");
952   chgl->mol->einstellung->setValue("SortingOption",sortierWeise);
953   chgl->mol->einstellung->endGroup();
954 }
955 
sortLabelList(CEnvironment & asymm,MyAtom & tatze)956 QString CodeEditor::sortLabelList(CEnvironment &asymm, MyAtom &tatze){
957     if (asymm.isEmpty()) return "HKLF";
958     QMultiMap<long double,MyAtom> atomSortMap;
959     long double lodo=0.0l;
960     int amax = asymm.size();
961 
962     int t1=0,t2=0;
963     for (int i=0; i < asymm.size(); i++){
964       if (asymm.at(i).an<0) continue;
965       t1++;
966       QString s1 = asymm.at(i).Label.section('_',0,0);
967       s1.remove(0,chgl->mol->pse(asymm.at(i).an).size());
968       int n1 = s1.section(QRegExp("\\D"),0,0).toInt();
969       int r1 = 0 ;
970       char cc[10];
971       strncpy(cc,s1.section(QRegExp("\\d+"),1,-1).toStdString().c_str(),4);
972       for (size_t k=0; k<strlen(cc);k++) {r1*=256;r1+=(size_t)cc[k];}
973       switch (sortierWeise){
974         case 1:
975           lodo=asymm.at(i).resiNr*99*amax+
976                   asymm.at(i).part*amax+
977                   n1+
978                   ((110-asymm.at(i).an)/220.0l)+
979                   (r1 / 50000.0l);//46656
980           //atomSortMap.insertMulti(lodo,asymm.at(i));
981           atomSortMap.insert(lodo,asymm.at(i));
982           break;
983         case 2:
984           lodo=asymm.at(i).resiNr*99*amax+
985                   asymm.at(i).part*amax+
986                   n1/999.0l+
987                   ((110-asymm.at(i).an))+
988                   (r1 / 50000.0l);//46656
989 
990           atomSortMap.insert(lodo,asymm.at(i));
991           //printf("##= %Lf %d %d %d %d %d\n",lodo,asymm.at(i).resiNr,asymm.at(i).part,n1,(110-asymm.at(i).an),r1);
992           break;
993         case 3:
994           lodo=  asymm.at(i).resiNr*99*amax+
995                   asymm.at(i).part*amax+
996                   n1/999.0l+
997                   sfac.indexOf(asymm.at(i).an)*10+
998                   (r1 / 50000.0l);//46656
999           atomSortMap.insert(lodo,asymm.at(i));
1000           break;
1001         case 4:
1002           lodo=
1003           asymm.at(i).resiNr*99*amax+
1004           asymm.at(i).part*amax+
1005           n1/50000.0l+
1006           ((110-asymm.at(i).an)/220)+
1007           (r1 );//46656
1008           atomSortMap.insert(lodo,asymm.at(i));
1009           t2++;
1010           break;
1011         case 5:
1012           lodo=
1013           asymm.at(i).molindex*9999*amax+
1014           asymm.at(i).resiNr*99*amax+
1015           asymm.at(i).part*amax+
1016           n1/999.0l+
1017           ((110-asymm.at(i).an))+
1018           (r1 / 50000.0l);//46656
1019           atomSortMap.insert(lodo,asymm.at(i));
1020           /*printf("%s %g\n", asymm.at(i).Label.toStdString().c_str(),asymm.at(i).molindex*9999*amax+
1021               asymm.at(i).resiNr*99*amax+
1022               asymm.at(i).part*amax+
1023               n1/999.0+
1024               ((110-asymm.at(i).an))+
1025               (r1 / 50000.0));*/
1026           break;
1027         case 6:
1028             lodo=  asymm.at(i).resiNr*99*amax+
1029                     asymm.at(i).part*amax+
1030                     chgl->mol->ueq(asymm.at(i).uf);
1031 
1032         atomSortMap.insert(lodo,asymm.at(i));
1033         break;
1034         default:
1035           atomSortMap.insert(i, asymm.at(i));
1036           break;
1037       }
1038     }
1039     {
1040         QString s1 = tatze.Label.section('_',0,0);
1041         s1.remove(0,chgl->mol->pse(tatze.an).size());
1042         int n1 = s1.section(QRegExp("\\D"),0,0).toInt();
1043         int r1 = 0 ;
1044         char cc[10];
1045         strncpy(cc,s1.section(QRegExp("\\d+"),1,-1).toStdString().c_str(),4);
1046         for (size_t k=0; k<strlen(cc);k++) {r1*=256;r1+=(size_t)cc[k];}
1047         //printf("VV= %Lf %d %d %d %d %d\n",lodo,tatze.resiNr,tatze.part,n1,(110-tatze.an),r1);
1048     switch (sortierWeise){
1049       case 1:
1050         lodo=tatze.resiNr*99*amax+
1051                 tatze.part*amax+
1052                 n1+
1053                 ((110-tatze.an)/220.0l)+
1054                 (r1 / 50000.0l);//46656
1055         break;
1056       case 2:
1057         lodo=tatze.resiNr*99*amax+
1058                 tatze.part*amax+
1059                 n1/999.0l+
1060                 ((110-tatze.an))+
1061                 (r1 / 50000.0l);//46656
1062         break;
1063       case 3:
1064         lodo=  tatze.resiNr*99*amax+
1065                 tatze.part*amax+
1066                 n1/999.0l+
1067                 sfac.indexOf(tatze.an)*10+
1068                 (r1 / 50000.0l);//46656
1069         break;
1070       case 4:
1071         lodo=
1072         tatze.resiNr*99*amax+
1073         tatze.part*amax+
1074         n1/50000.0l+
1075         ((110-tatze.an)/220)+
1076         (r1 );//46656
1077         break;
1078       case 5:
1079         lodo=
1080         tatze.molindex*9999*amax+
1081         tatze.resiNr*99*amax+
1082         tatze.part*amax+
1083         n1/999.0l+
1084         ((110-tatze.an))+
1085         (r1 / 50000.0l);//46656
1086         break;
1087     case 6:
1088         lodo=  tatze.resiNr*99*amax+
1089                tatze.part*amax+
1090                chgl->mol->ueq(tatze.uf);
1091         break;
1092     }
1093     }
1094     QList<long double> kys = atomSortMap.keys();
1095     long double fi = kys.first();//, la = kys.last();
1096     QString l="HKLF";
1097     //printf("value = %Lf first = %Lf last = %Lf\n", lodo, fi, la);
1098     if ((lodo>=fi)) {//
1099         CEnvironment asymm2    =  atomSortMap.values();
1100         int idx=0;
1101         for (; (idx<kys.size())&& (lodo>kys.at(idx)); idx++){}
1102         if (idx>0) idx--;
1103       //  printf("idx %d\n",idx);
1104         l = asymm2.at(idx).orginalLine.left(80).trimmed();
1105         asymm2.clear();
1106     }else{
1107         QTextDocument *doc = this->document();
1108         QTextCursor cursor = textCursor();
1109         cursor.movePosition(QTextCursor::Start);
1110         l=asymm.first().orginalLine.left(80).trimmed();
1111         cursor=doc->find(l, cursor);
1112         cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
1113         cursor.movePosition(QTextCursor::Up,QTextCursor::MoveAnchor);
1114         cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
1115         l=cursor.selectedText();
1116         cursor.clearSelection();
1117         cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
1118     }
1119     kys.clear();
1120     atomSortMap.clear();
1121     return l;
1122 }
sortAtoms(CEnvironment & as)1123 void CodeEditor::sortAtoms(CEnvironment &as){
1124     if (as.isEmpty()) return;
1125     if (toPlainText().contains(QRegExp("[<>]"))){
1126       expandGreaterThan();
1127     }
1128     QMap<long double,MyAtom> atomSortMap;
1129 
1130     int amax = as.size();
1131     int t1=0,t2=0;
1132     for (int i=0; i < as.size(); i++){
1133       if (as.at(i).an<0) continue;
1134       t1++;
1135       QString s1 = as.at(i).Label;
1136       s1.remove(0,chgl->mol->pse(as.at(i).an).size());
1137       int n1 = s1.section(QRegExp("\\D"),0,0).toInt();
1138       int r1 = 0 ;
1139       char cc[10];
1140       strncpy(cc,s1.section(QRegExp("\\d+"),1,-1).toStdString().c_str(),4);
1141       for (size_t k=0; k<strlen(cc);k++) {r1*=256;r1+=(size_t)cc[k];}
1142       switch (sortierWeise){
1143         case 1:
1144           atomSortMap.insert(
1145               as.at(i).resiNr*99*amax+
1146               as.at(i).part*amax+
1147               n1+
1148               ((110-as.at(i).an)/220.0)+
1149               (r1 / 50000.0)//46656
1150               ,as.at(i));
1151           break;
1152         case 2:
1153           atomSortMap.insert(
1154               as.at(i).resiNr*99*amax+
1155               as.at(i).part*amax+
1156               n1/999.0+
1157               ((110-as.at(i).an))+
1158               (r1 / 50000.0)//46656
1159               ,as.at(i));
1160           break;
1161         case 3:
1162           atomSortMap.insert(
1163               as.at(i).resiNr*99*amax+
1164               as.at(i).part*amax+
1165               n1/999.0+
1166               sfac.indexOf(as.at(i).an)*10+
1167               (r1 / 50000.0)//46656
1168               ,as.at(i));
1169           break;
1170         case 4:
1171           atomSortMap.insert(
1172               as.at(i).resiNr*99*amax+
1173               as.at(i).part*amax+
1174               n1/50000.0+
1175               ((110-as.at(i).an)/220)+
1176               (r1 )//46656
1177               ,as.at(i));
1178           t2++;
1179           break;
1180         case 5:
1181           atomSortMap.insert(
1182               as.at(i).molindex*9999*amax+
1183               as.at(i).resiNr*99*amax+
1184               as.at(i).part*amax+
1185               n1/999.0+
1186               ((110-as.at(i).an))+
1187               (r1 / 50000.0)//46656
1188               ,as.at(i));
1189           printf("%s %g\n", as.at(i).Label.toStdString().c_str(),as.at(i).molindex*9999*amax+
1190               as.at(i).resiNr*99*amax+
1191               as.at(i).part*amax+
1192               n1/999.0+
1193               ((110-as.at(i).an))+
1194               (r1 / 50000.0));
1195           break;
1196 
1197       case 6:{
1198           long double lodo=0.0l;
1199           lodo=  as.at(i).resiNr*99*amax+
1200                   as.at(i).part*amax+
1201                   chgl->mol->ueq(as.at(i).uf);
1202           atomSortMap.insert(lodo,as.at(i));
1203       }
1204       break;
1205         default:
1206           atomSortMap.insert(i
1207               ,as.at(i));
1208           break;
1209       }
1210     }
1211     as=  atomSortMap.values();
1212 }
1213 
sortAtoms()1214 void CodeEditor::sortAtoms(){
1215   if (chgl->mol->asymm.isEmpty()) return;
1216 
1217   const QString sicher = toPlainText();
1218   //find atomranges
1219   if (sicher.contains(QRegExp("[<>]"))){
1220     //QStringList ranges;
1221     /*QStringList lines = sicher.split('\n');
1222     for (int i=0; (i<lines.size()); i++){
1223       if (lines.at(i).startsWith(' ')) continue;
1224       if (lines.at(i).startsWith("REM",Qt::CaseInsensitive)) continue;
1225       if (lines.at(i).startsWith("HKLF",Qt::CaseInsensitive)) break;
1226       if (lines.at(i).contains(QRegExp("[<>]"))) ranges.append(QString("LINE %1: %2")
1227           .arg(i+1)
1228           .arg(lines.at(i)));
1229     }*/
1230     expandGreaterThan();
1231     /*if (!ranges.isEmpty()){
1232       QMessageBox::information(0,"information",QString("<h3>Atom ranges detected! %1 "
1233             " can not sort here without destroying functionality of the file.</h3 <pre>%2 </pre>").arg(PROGRAM_NAME).arg(ranges.join("\n")));
1234       return;
1235     }*/
1236   }
1237   QMap<long double,MyAtom> atomSortMap;
1238 
1239   int amax = chgl->mol->asymm.size();
1240   int t1=0,t2=0;
1241   for (int i=0; i < chgl->mol->asymm.size(); i++){
1242     if (chgl->mol->asymm.at(i).an<0) continue;
1243     t1++;
1244     QString s1 = chgl->mol->asymm.at(i).Label;
1245     s1.remove(0,chgl->mol->pse(chgl->mol->asymm.at(i).an).size());
1246     int n1 = s1.section(QRegExp("\\D"),0,0).toInt();
1247     int r1 = 0 ;
1248     char cc[10];
1249     strncpy(cc,s1.section(QRegExp("\\d+"),1,-1).toStdString().c_str(),4);
1250     for (size_t k=0; k<strlen(cc);k++) {r1*=256;r1+=(size_t)cc[k];}
1251     switch (sortierWeise){
1252       case 1:
1253         atomSortMap.insert(
1254             chgl->mol->asymm.at(i).resiNr*99*amax+
1255             chgl->mol->asymm.at(i).part*amax+
1256             n1+
1257             ((110-chgl->mol->asymm.at(i).an)/220.0)+
1258             (r1 / 50000.0)//46656
1259             ,chgl->mol->asymm.at(i));
1260         break;
1261       case 2:
1262         atomSortMap.insert(
1263             chgl->mol->asymm.at(i).resiNr*99*amax+
1264             chgl->mol->asymm.at(i).part*amax+
1265             n1/999.0+
1266             ((110-chgl->mol->asymm.at(i).an))+
1267             (r1 / 50000.0)//46656
1268             ,chgl->mol->asymm.at(i));
1269         break;
1270       case 3:
1271         atomSortMap.insert(
1272             chgl->mol->asymm.at(i).resiNr*99*amax+
1273             chgl->mol->asymm.at(i).part*amax+
1274             n1/999.0+
1275             sfac.indexOf(chgl->mol->asymm.at(i).an)*10+
1276             (r1 / 50000.0)//46656
1277             ,chgl->mol->asymm.at(i));
1278         break;
1279       case 4:
1280         atomSortMap.insert(
1281             chgl->mol->asymm.at(i).resiNr*99*amax+
1282             chgl->mol->asymm.at(i).part*amax+
1283             n1/50000.0+
1284             ((110-chgl->mol->asymm.at(i).an)/220)+
1285             (r1 )//46656
1286             ,chgl->mol->asymm.at(i));
1287         t2++;
1288         break;
1289       case 5:
1290         atomSortMap.insert(
1291             chgl->mol->asymm.at(i).molindex*9999*amax+
1292             chgl->mol->asymm.at(i).resiNr*99*amax+
1293             chgl->mol->asymm.at(i).part*amax+
1294             n1/999.0+
1295             ((110-chgl->mol->asymm.at(i).an))+
1296             (r1 / 50000.0)//46656
1297             ,chgl->mol->asymm.at(i));
1298         printf("%s %g\n", chgl->mol->asymm.at(i).Label.toStdString().c_str(),chgl->mol->asymm.at(i).molindex*9999*amax+
1299             chgl->mol->asymm.at(i).resiNr*99*amax+
1300             chgl->mol->asymm.at(i).part*amax+
1301             n1/999.0+
1302             ((110-chgl->mol->asymm.at(i).an))+
1303             (r1 / 50000.0));
1304         break;
1305 
1306     case 6:{
1307         long double lodo=0.0l;
1308         lodo=  chgl->mol->asymm.at(i).resiNr*99*amax+
1309                 chgl->mol->asymm.at(i).part*amax+
1310                 chgl->mol->ueq(chgl->mol->asymm.at(i).uf);
1311         atomSortMap.insert(lodo,chgl->mol->asymm.at(i));
1312     }
1313     break;
1314       default:
1315         atomSortMap.insert(i
1316             ,chgl->mol->asymm.at(i));
1317         break;
1318     }
1319   }
1320   CEnvironment asymm2=
1321     atomSortMap.values();
1322 
1323   QTextDocument *document = this->document();
1324   QTextCursor cursor = textCursor();
1325   wholeLine->setChecked(false);
1326   replace->setText("");
1327   searchLE->setText("^part.*$");
1328   replaceAll();
1329   replace->setText("");
1330   searchLE->setText("^resi.*$");
1331   replaceAll();
1332   cursor.beginEditBlock();
1333   cursor.movePosition(QTextCursor::Start);
1334   cursor = document->find("HKLF",cursor);
1335   cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
1336   cursor.movePosition(QTextCursor::Up,QTextCursor::KeepAnchor);
1337   if (parenthesis.at(cursor.blockNumber())){
1338     cursor.select(QTextCursor::WordUnderCursor);
1339     if ((cursor.selectedText().contains("RESI",Qt::CaseInsensitive))||(cursor.selectedText().contains("PART",Qt::CaseInsensitive)))
1340       cursor.movePosition(QTextCursor::Up,QTextCursor::KeepAnchor);
1341     cursor.select(QTextCursor::WordUnderCursor);
1342     if ((cursor.selectedText().contains("RESI",Qt::CaseInsensitive))||(cursor.selectedText().contains("PART",Qt::CaseInsensitive)))
1343       cursor.movePosition(QTextCursor::Up,QTextCursor::KeepAnchor);
1344     cursor.movePosition(QTextCursor::Down,QTextCursor::MoveAnchor);
1345     cursor.clearSelection();
1346     cursor.insertText("AFIX 0 \n");
1347   }
1348 
1349   /*QProgressDialog progress("Sorting atoms in Editor", QString(), 0, asymm2.size(), this);
1350   progress.setWindowModality(Qt::WindowModal);*/
1351   int ares=0, apart=0;
1352   for (int i=0; i < asymm2.size(); i++){
1353     //progress.setValue(i);
1354     QString  label = asymm2.at(i).orginalLine.left(80).trimmed();
1355     cursor.movePosition(QTextCursor::Start);
1356     cursor = document->find(label,cursor);
1357     //printf("find=>>%s {%d}\n",label.toStdString().c_str(),cursor.blockNumber());
1358     if (cursor.isNull()){
1359       cursor = textCursor();
1360       cursor.movePosition(QTextCursor::Start);
1361       label.chop(10);
1362       cursor = document->find(label,cursor);
1363       if (cursor.isNull()) {
1364         cursor = textCursor();
1365         printf("hab was nicht %d %s\n",i,label.toStdString().c_str());
1366         continue;
1367       }
1368     }
1369 
1370     if (parenthesis.at(cursor.blockNumber()))continue;//Afix not sorted here
1371     QString vorherig,neues;
1372     cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
1373     cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
1374     while (cursor.selectedText().endsWith("=")) {
1375       cursor.movePosition(QTextCursor::Down,QTextCursor::KeepAnchor);
1376       cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
1377     }
1378     while (parenthesis.at(cursor.blockNumber()+1)){
1379       cursor.movePosition(QTextCursor::Down,QTextCursor::KeepAnchor);
1380       cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
1381     }
1382     neues = vorherig= cursor.selectedText();
1383     cursor.deleteChar();
1384     cursor.deleteChar();
1385     cursor = textCursor();
1386     cursor.movePosition(QTextCursor::Start);
1387     cursor = document->find(QRegExp("^HKLF",Qt::CaseInsensitive),cursor);
1388     cursor.clearSelection();
1389     cursor.movePosition(QTextCursor::StartOfLine);
1390     if ((asymm2.at(i).resiNr!=ares))
1391       cursor.insertText(QString("RESI %1 %2\n")
1392           .arg(asymm2.at(i).resiNr)
1393           .arg(asymm2.at(i).ResiClass));
1394     if ((asymm2.at(i).part!=apart))
1395       cursor.insertText(QString("PART %1\n")
1396           .arg(asymm2.at(i).part));
1397     //printf("=>%d\n",cursor.blockNumber());
1398     cursor.insertText(neues);
1399     cursor.insertText("\n");
1400     ares = asymm2.at(i).resiNr;
1401     apart = asymm2.at(i).part;
1402     updateAfix();
1403   }
1404   cursor = document->find("HKLF",cursor);
1405   cursor.clearSelection();
1406   cursor.movePosition(QTextCursor::StartOfLine);
1407   if ((0!=apart)) cursor.insertText(QString("PART 0\n"));
1408   if ((0!=ares)) cursor.insertText(QString("RESI 0\n"));
1409   cursor.endEditBlock ();
1410   emit updateLabel();
1411 
1412   chgl->disSelection();
1413   if (chgl->fuse->isVisible())chgl->mol->grow();
1414   else  chgl->mol->fuse();
1415   chgl->murx=__LINE__;
1416   setUndoRedoEnabled ( true );
1417   chgl->updateGL();
1418   searchLE->setText("");
1419   replace->setText("");
1420   wholeLine->setChecked(false);
1421   setTextCursor(cursor);
1422 
1423   //progress.setValue(asymm2.size());
1424 }
1425 
sortSelectedRegion()1426 void CodeEditor::sortSelectedRegion(){
1427 
1428   QTextCursor cursor = textCursor();
1429   int sta=cursor.selectionStart();
1430   int end=cursor.selectionEnd();
1431   cursor.setPosition(sta);
1432   cursor.movePosition(QTextCursor::StartOfLine);
1433   cursor.setPosition(end, QTextCursor::KeepAnchor);
1434   cursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor);
1435   if (cursor.selectedText().endsWith("=")) cursor.movePosition(QTextCursor::Down, QTextCursor::KeepAnchor);
1436   //cursor.movePosition(QTextCursor::StartOfLine);
1437   QString sel=cursor.selectedText();
1438   CEnvironment toms;
1439   for (int i=0; i<chgl->mol->asymm.size(); i++){
1440     if (chgl->mol->asymm.at(i).afix!=0) continue;
1441     if (chgl->mol->asymm.at(i).orginalLine.size()<30) continue;
1442     if (sel.contains(chgl->mol->asymm.at(i).orginalLine,Qt::CaseInsensitive)){
1443       toms.append(chgl->mol->asymm[i]);
1444     }
1445   }
1446   int amax = toms.size();
1447   //int zeilen=sel.count(QChar::ParagraphSeparator);
1448   if (amax <3) {
1449     toms.clear();
1450     cursor.clearSelection ();
1451     setTextCursor(cursor);
1452     update();
1453     qDebug()<<"not enough atoms selected!";
1454     return;
1455   }
1456   int t1=0,t2=0;
1457   QMap<long double,MyAtom> atomSortMap;
1458   QMap<long double,int> atomSortMapi;
1459   for (int i=0; i < amax; i++){
1460     if (toms.at(i).an<0) continue;
1461     t1++;
1462     QString s1 = toms.at(i).Label;
1463     s1.remove(0,chgl->mol->pse(toms.at(i).an).size());
1464     int n1 = s1.section(QRegExp("\\D"),0,0).toInt();
1465     int r1 = 0 ;
1466     char cc[10];
1467     strncpy(cc,s1.section(QRegExp("\\d+"),1,-1).toStdString().c_str(),4);
1468     for (size_t k=0; k<strlen(cc);k++) {r1*=256;r1+=(size_t)cc[k];}
1469     switch (sortierWeise){
1470       case 1:
1471         atomSortMap.insert(
1472             toms.at(i).resiNr*99*amax+
1473             toms.at(i).part*amax+
1474             n1+
1475             ((110-toms.at(i).an)/220.0)+
1476             (r1 / 50000.0)//46656
1477             ,toms.at(i));
1478         atomSortMapi.insert(
1479             toms.at(i).resiNr*99*amax+
1480             toms.at(i).part*amax+
1481             n1+
1482             ((110-toms.at(i).an)/220.0)+
1483             (r1 / 50000.0)//46656
1484             ,i);
1485         break;
1486       case 2:
1487         atomSortMap.insert(
1488             toms.at(i).resiNr*99*amax+
1489             toms.at(i).part*amax+
1490             n1/999.0+
1491             ((110-toms.at(i).an))+
1492             (r1 / 50000.0)//46656
1493             ,toms.at(i));
1494         atomSortMapi.insert(
1495             toms.at(i).resiNr*99*amax+
1496             toms.at(i).part*amax+
1497             n1/999.0+
1498             ((110-toms.at(i).an))+
1499             (r1 / 50000.0)//46656
1500             ,i);
1501         break;
1502       case 3:
1503         atomSortMap.insert(
1504             toms.at(i).resiNr*99*amax+
1505             toms.at(i).part*amax+
1506             n1/999.0+
1507             sfac.indexOf(toms.at(i).an)*10+
1508             (r1 / 50000.0)//46656
1509             ,toms.at(i));
1510         atomSortMapi.insert(
1511             toms.at(i).resiNr*99*amax+
1512             toms.at(i).part*amax+
1513             n1/999.0+
1514             sfac.indexOf(toms.at(i).an)*10+
1515             (r1 / 50000.0)//46656
1516             ,i);
1517         break;
1518       case 4:
1519         atomSortMap.insert(
1520             toms.at(i).resiNr*99*amax+
1521             toms.at(i).part*amax+
1522             n1/50000.0+
1523             ((110-toms.at(i).an)/220)+
1524             (r1 )//46656
1525             ,toms.at(i));
1526         atomSortMapi.insert(
1527             toms.at(i).resiNr*99*amax+
1528             toms.at(i).part*amax+
1529             n1/50000.0+
1530             ((110-toms.at(i).an)/220)+
1531             (r1 )//46656
1532             ,i);
1533         t2++;
1534         break;
1535       case 5:
1536         atomSortMap.insert(
1537             toms.at(i).molindex*9999*amax+
1538             toms.at(i).resiNr*99*amax+
1539             toms.at(i).part*amax+
1540             n1/999.0+
1541             ((110-toms.at(i).an))+
1542             (r1 / 50000.0)//46656
1543             ,toms.at(i));
1544         atomSortMapi.insert(
1545             toms.at(i).molindex*9999*amax+
1546             toms.at(i).resiNr*99*amax+
1547             toms.at(i).part*amax+
1548             n1/999.0+
1549             ((110-toms.at(i).an))+
1550             (r1 / 50000.0)//46656
1551             ,i);
1552         /*		printf("%s %g\n", chgl->mol->asymm.at(i).Label.toStdString().c_str(),chgl->mol->asymm.at(i).molindex*9999*amax+
1553                         chgl->mol->asymm.at(i).resiNr*99*amax+
1554                         chgl->mol->asymm.at(i).part*amax+
1555                         n1/999.0+
1556                         ((110-chgl->mol->asymm.at(i).an))+
1557                         (r1 / 50000.0));*/
1558         break;
1559       default:
1560         atomSortMap.insert(i
1561             ,toms.at(i));
1562         atomSortMapi.insert(i
1563             ,i);
1564         break;
1565     }
1566   }
1567   CEnvironment asymm2=
1568     atomSortMap.values();
1569   QList<int> kk=atomSortMapi.values();
1570   cursor.beginEditBlock ();
1571   cursor.removeSelectedText ();
1572 
1573   QStringList neu,li= sel.split(QChar::ParagraphSeparator);
1574 
1575   QRegExp sep=QRegExp("\\s+");
1576   QString neues;
1577   bool fix=false;
1578   for (int i=0; i<li.size(); i++){
1579     int cmd=Window::isacommand(li.at(i).section(sep,0,0));
1580     switch (cmd){
1581       case 1:fix=true;
1582              printf("afix\n");
1583              // intentional fall-through !
1584       case -1:
1585              if ((!fix)&&(cmd==-1)&&(!li.at(i).startsWith(" "))&&(!neues.isEmpty())){
1586                neu.append(neues);
1587                neues.clear();
1588              }
1589              neues.append('\n');
1590              neues.append(li.at(i));
1591              if (li.at(i).contains (QRegExp("AFIX\\s+0", Qt::CaseInsensitive))){
1592                neu.append(neues);
1593                neues.clear();
1594                fix=false;
1595              }
1596              break;
1597       case 51:
1598       case 58:break;
1599       default:
1600               if (!neues.isEmpty()){
1601                 neu.append(neues);
1602                 neues.clear();
1603               }
1604               cursor.insertText(li.at(i));
1605               cursor.insertText("\n");
1606     }
1607 
1608   }
1609   if (!neues.isEmpty()){
1610     neu.append(neues);
1611     neues.clear();
1612   }
1613   //qDebug()<<neu<<neu.size()<<kk;
1614   int ares=0, apart=0;
1615   for (int i=0; i < asymm2.size(); i++){
1616     if ((asymm2.at(i).resiNr!=ares))
1617       cursor.insertText(QString("RESI %1 %2\n")
1618           .arg(asymm2.at(i).resiNr)
1619           .arg(asymm2.at(i).ResiClass));
1620     if ((asymm2.at(i).part!=apart))
1621       cursor.insertText(QString("PART %1\n")
1622           .arg(asymm2.at(i).part));
1623     cursor.insertText(neu.at(kk.at(i)));
1624     ares = asymm2.at(i).resiNr;
1625     apart = asymm2.at(i).part;
1626   }
1627   cursor.endEditBlock ();
1628   updateAfix();
1629   //todo editieren!!
1630 }
1631 
insertEADP(QList<MyAtom> selected,QString resiSpec)1632 void CodeEditor::insertEADP(QList<MyAtom> selected, QString resiSpec){
1633   QTextDocument *document = this->document();
1634   QTextCursor cursor = textCursor();
1635   cursor.movePosition(QTextCursor::Start,QTextCursor::MoveAnchor);
1636   cursor = document->find(QRegExp("^UNIT",Qt::CaseInsensitive),cursor);
1637   cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
1638   cursor.movePosition(QTextCursor::Down,QTextCursor::MoveAnchor);
1639   QString buffer =QString("EADP%1 ").arg((resiSpec.isEmpty())?"":"_"+resiSpec);
1640   buffer = selectedRestraintsAtoms(buffer, selected, resiSpec);
1641   cursor.insertText(DSRGui::textWrap(buffer));
1642 }
1643 
insertDELU(double esd1,double esd2,QList<MyAtom> selected,QString resiSpec)1644 void CodeEditor::insertDELU(double esd1, double esd2, QList<MyAtom> selected, QString resiSpec){
1645   QTextDocument *document = this->document();
1646   QTextCursor cursor = textCursor();
1647   cursor.movePosition(QTextCursor::Start,QTextCursor::MoveAnchor);
1648   cursor = document->find(QRegExp("^UNIT",Qt::CaseInsensitive),cursor);
1649   cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
1650   cursor.movePosition(QTextCursor::Down,QTextCursor::MoveAnchor);
1651   QString buffer = QString("DELU%1 %2 %3 ").arg((resiSpec.isEmpty())?"":"_"+resiSpec).arg(esd1).arg(esd2);
1652   buffer = selectedRestraintsAtoms(buffer, selected, resiSpec);
1653   cursor.insertText(DSRGui::textWrap(buffer));
1654 }
1655 
insertSIMU(double esd1,double esd2,double dmax,QList<MyAtom> selected,QString resiSpec)1656 void CodeEditor::insertSIMU(double esd1, double esd2, double dmax, QList<MyAtom> selected, QString resiSpec){
1657   QTextDocument *document = this->document();
1658   QTextCursor cursor = textCursor();
1659   cursor.movePosition(QTextCursor::Start,QTextCursor::MoveAnchor);
1660   cursor = document->find(QRegExp("^UNIT",Qt::CaseInsensitive),cursor);
1661   cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
1662   cursor.movePosition(QTextCursor::Down,QTextCursor::MoveAnchor);
1663   QString buffer =QString("SIMU%1 %2 %3 %4 ").arg((resiSpec.isEmpty())?"":"_"+resiSpec).arg(esd1).arg(esd2).arg(dmax);
1664   buffer = selectedRestraintsAtoms(buffer, selected, resiSpec);
1665   cursor.insertText(DSRGui::textWrap(buffer));
1666 }
1667 
insertISOR(double esd1,double esd2,QList<MyAtom> selected,QString resiSpec)1668 void CodeEditor::insertISOR(double esd1, double esd2, QList<MyAtom> selected, QString resiSpec){
1669   QTextDocument *document = this->document();
1670   QTextCursor cursor = textCursor();
1671   cursor.movePosition(QTextCursor::Start,QTextCursor::MoveAnchor);
1672   cursor = document->find(QRegExp("^UNIT",Qt::CaseInsensitive),cursor);
1673   cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
1674   cursor.movePosition(QTextCursor::Down,QTextCursor::MoveAnchor);
1675   QString buffer =QString("ISOR%1 %2 %3 ").arg((resiSpec.isEmpty())?"":"_"+resiSpec).arg(esd1).arg(esd2);
1676   buffer = selectedRestraintsAtoms(buffer, selected, resiSpec);
1677   cursor.insertText(DSRGui::textWrap(buffer));
1678 }
1679 
insertRIGU(double esd1,double esd2,QList<MyAtom> selected,QString resiSpec)1680 void CodeEditor::insertRIGU(double esd1, double esd2, QList<MyAtom> selected, QString resiSpec){
1681   QTextDocument *document = this->document();
1682   QTextCursor cursor = textCursor();
1683   cursor.movePosition(QTextCursor::Start,QTextCursor::MoveAnchor);
1684   cursor = document->find(QRegExp("^UNIT",Qt::CaseInsensitive),cursor);
1685   cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
1686   cursor.movePosition(QTextCursor::Down,QTextCursor::MoveAnchor);
1687   QString buffer =QString("RIGU%1 %2 %3 ").arg((resiSpec.isEmpty())?"":"_"+resiSpec).arg(esd1).arg(esd2);
1688   buffer = selectedRestraintsAtoms(buffer, selected, resiSpec);
1689   cursor.insertText(DSRGui::textWrap(buffer));
1690 }
1691 
insertCHIV(double vol,double esd1,QList<MyAtom> selected,QString resiSpec)1692 void CodeEditor::insertCHIV(double vol, double esd1, QList<MyAtom> selected, QString resiSpec){
1693   QTextDocument *document = this->document();
1694   QTextCursor cursor = textCursor();
1695   cursor.movePosition(QTextCursor::Start,QTextCursor::MoveAnchor);
1696   cursor = document->find(QRegExp("^UNIT",Qt::CaseInsensitive),cursor);
1697   cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
1698   cursor.movePosition(QTextCursor::Down,QTextCursor::MoveAnchor);
1699   QString buffer =QString("CHIV%1 %2 %3 ").arg((resiSpec.isEmpty())?"":"_"+resiSpec).arg(vol).arg(esd1);
1700   buffer = selectedRestraintsAtoms(buffer, selected, resiSpec);
1701   cursor.insertText(DSRGui::textWrap(buffer));
1702 }
1703 
omitsome(const QString & s)1704 void CodeEditor::omitsome(const QString &s){
1705   //  qDebug()<<"omi->t"<<s.size()<<s;
1706   QList<Omit> schonWeg;
1707   Omit o;
1708   QTextDocument *document = this->document();
1709   QTextCursor cursor = textCursor();
1710   cursor.movePosition(QTextCursor::Start,QTextCursor::MoveAnchor);
1711   QStringList sli;
1712   while (!cursor.isNull()){
1713     cursor = document->find(QRegExp("OMIT\\s+\\d+\\s+\\d+\\s+\\d+"),cursor);
1714     if (!cursor.isNull()){
1715       sli=cursor.selectedText().split(" ",skipEmptyParts);
1716       o.h=sli.at(1).toInt();
1717       o.k=sli.at(2).toInt();
1718       o.l=sli.at(3).toInt();
1719       schonWeg.append(o);
1720     }
1721   }
1722   QString sm=s;
1723   for (int i=0; i<schonWeg.size(); i++){
1724     sm.remove(QString("OMIT %1 %2 %3\n").arg(schonWeg.at(i).h).arg(schonWeg.at(i).k).arg(schonWeg.at(i).l));
1725   }
1726   cursor = textCursor();
1727   cursor.movePosition(QTextCursor::Start,QTextCursor::MoveAnchor);
1728   if (!sm.isEmpty()){
1729     cursor = document->find("UNIT",cursor);
1730     cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
1731     cursor.movePosition(QTextCursor::Down,QTextCursor::MoveAnchor);
1732     cursor.insertText(sm);
1733     emit saveMe(true, true);
1734   }
1735 }
1736 
lineNumberAreaPaintEvent(QPaintEvent * event)1737 void CodeEditor::lineNumberAreaPaintEvent(QPaintEvent *event){
1738   QPainter painter(lineNumberArea);
1739   int current = textCursor().blockNumber();
1740   if (!dark){
1741       painter.fillRect(event->rect(), QColor("#eeeeee"));
1742         QTextBlock block = firstVisibleBlock();
1743        // printf("edidor Font: %s italic%d bold %d point %d pixel %d height %d\n",fontInfo().family().toStdString().c_str(),fontInfo().italic (),fontInfo().bold (),fontInfo().pointSize (),fontInfo().pixelSize (),fontMetrics().height());
1744       //   printf("lineNumberAreaPaintEvent\n");
1745         int blockNumber = block.blockNumber();
1746         int top = (int) blockBoundingGeometry(block).translated(contentOffset()).top();
1747         int bottom = top + (int) blockBoundingRect(block).height();
1748         // printf ("line %d %d\n",top,bottom);
1749         int minbl=8888888,maxbl=0;
1750         while (block.isValid() && top <= event->rect().bottom()) {
1751           if (block.isVisible() && bottom >= event->rect().top()) {
1752             QString number = QString::number(blockNumber + 1);
1753             bool iscurrent=(blockNumber==current);
1754             if (blockNumber%2) painter.fillRect(0, top,
1755                                             lineNumberArea->width(),
1756                                             fontMetrics().height(),QColor("#dddddd"));
1757             if (iscurrent) painter.fillRect(0, top,
1758                                             lineNumberArea->width(),
1759                                             fontMetrics().height(),QColor("#242424"));
1760             // /*
1761             QFont f=painter.font();
1762             if (errorInLine.contains(blockNumber)) {
1763           painter.fillRect(0, top,
1764                   lineNumberArea->width(),
1765                   fontMetrics().height(),QColor("#aa0000"));
1766           iscurrent=true;
1767             }
1768             if (comment.at(blockNumber)) {
1769           painter.fillRect(5, top+2,
1770                   3,//lineNumberArea->width()
1771                   fontMetrics().height()-4,(iscurrent)?QColor("#99aaff"):QColor("#0000aa"));
1772             }
1773 
1774 
1775             //printf("edidor Font: %s %d %d %d\n",f.family().toStdString().c_str(),f.pointSize(),fontMetrics().height(),fontMetrics().lineSpacing ());
1776             f.setWeight((iscurrent)?QFont::Black:QFont::Light);
1777             painter.setFont(f);
1778             // */
1779             painter.setPen((iscurrent)?Qt::white:Qt::darkGray);
1780             painter.drawText(0, top,
1781                     lineNumberArea->width(),
1782                             fontMetrics().lineSpacing () ,
1783                             Qt::AlignRight, number);
1784             minbl=qMin(minbl,blockNumber + 1);
1785             maxbl=qMax(maxbl,blockNumber + 1);
1786           }
1787           if (ListFile)
1788           midCursorpos=(minbl+maxbl)/2;
1789           block = block.next();
1790           top = bottom;
1791           bottom = top + (int) blockBoundingRect(block).height();
1792           ++blockNumber;
1793         }
1794   }else{
1795   painter.fillRect(event->rect(), QColor("#242424"));//"#eeeeee"));
1796   QTextBlock block = firstVisibleBlock();
1797  // printf("edidor Font: %s italic%d bold %d point %d pixel %d height %d\n",fontInfo().family().toStdString().c_str(),fontInfo().italic (),fontInfo().bold (),fontInfo().pointSize (),fontInfo().pixelSize (),fontMetrics().height());
1798 //   printf("lineNumberAreaPaintEvent\n");
1799   int blockNumber = block.blockNumber();
1800   int top = (int) blockBoundingGeometry(block).translated(contentOffset()).top();
1801   int bottom = top + (int) blockBoundingRect(block).height();
1802   // printf ("line %d %d\n",top,bottom);
1803   int minbl=8888888,maxbl=0;
1804   while (block.isValid() && top <= event->rect().bottom()) {
1805     if (block.isVisible() && bottom >= event->rect().top()) {
1806       QString number = QString::number(blockNumber + 1);
1807       bool iscurrent=(blockNumber==current);
1808       if (blockNumber%2) painter.fillRect(0, top,
1809                                       lineNumberArea->width(),
1810                                       fontMetrics().height(),QColor("424242"));//"#dddddd"));
1811       if (iscurrent) painter.fillRect(0, top,
1812                                       lineNumberArea->width(),
1813                                       fontMetrics().height(),QColor("#eeeeee"));
1814       // /*
1815       QFont f=painter.font();
1816       if (errorInLine.contains(blockNumber)) {
1817 	painter.fillRect(0, top,
1818 			lineNumberArea->width(),
1819 			fontMetrics().height(),QColor("#aa0000"));
1820 	iscurrent=true;
1821       }
1822       if (comment.at(blockNumber)) {
1823     painter.fillRect(5, top+2,
1824 			3,//lineNumberArea->width()
1825             fontMetrics().height()-4,(!iscurrent)?QColor("#99aaff"):QColor("#0000aa"));
1826       }
1827 
1828 
1829       //printf("edidor Font: %s %d %d %d\n",f.family().toStdString().c_str(),f.pointSize(),fontMetrics().height(),fontMetrics().lineSpacing ());
1830       f.setWeight((iscurrent)?QFont::Black:QFont::Light);
1831       painter.setFont(f);
1832       // */
1833       painter.setPen((!iscurrent)?Qt::lightGray:Qt::black);
1834       painter.drawText(0, top,
1835 		      lineNumberArea->width(),
1836                       fontMetrics().lineSpacing () ,
1837                       Qt::AlignRight, number);
1838       minbl=qMin(minbl,blockNumber + 1);
1839       maxbl=qMax(maxbl,blockNumber + 1);
1840     }
1841     if (ListFile)
1842     midCursorpos=(minbl+maxbl)/2;
1843     block = block.next();
1844     top = bottom;
1845     bottom = top + (int) blockBoundingRect(block).height();
1846     ++blockNumber;
1847   }
1848   }
1849 
1850 
1851   //updateAfix();
1852   //afixHighlightArea->update();
1853   event->accept();
1854 }
1855 
lineNumberToggled(QMouseEvent * event)1856 void CodeEditor::lineNumberToggled(QMouseEvent *event){
1857     QTextBlock block=firstVisibleBlock();
1858     int top = (int) blockBoundingGeometry(block).translated(contentOffset()).top();
1859     int bn=firstVisibleBlock().blockNumber();
1860     int idx=(int)  (event->y()-top)/ ((int) blockBoundingRect(block).height()) + bn + 1;
1861 //    printf("remark->  idx-1 %d  event.y %d top %d first %d height %g\n",idx-1,event->y(),top,bn,blockBoundingRect(block).height());
1862     remark(idx-1);
1863 }
1864 
updateAfix()1865 void CodeEditor::updateAfix(){
1866  // printf("updateAfix\n");
1867   blocks=toPlainText().split('\n');
1868 
1869   /*printf("test die Zeilenanzahl ist jetzt %d %d\n",
1870 		  blocks.size(),
1871 		  blockCount()
1872 		  );*/
1873   parenthesis.clear();
1874   parenthesis2.clear();
1875   comment.clear();
1876   int probe=0,aprobe=0,amn=0;
1877   bool kommentar=false;
1878   for (int i=0; i<blocks.size();i++){
1879     kommentar =  (blocks.at(i).contains(QRegExp("^REM",Qt::CaseInsensitive)));
1880     comment.append(kommentar);
1881       if (blocks.at(i).contains(QRegExp("^AFIX\\s+0",Qt::CaseInsensitive))) {
1882           probe=0;
1883           amn=0;
1884       }
1885     else {
1886       if (blocks.at(i).contains(QRegExp("^AFIX\\s+\\d+",Qt::CaseInsensitive))) {
1887 	probe++;
1888 	int m=blocks.at(i).section(QRegExp("\\s+"),1,1,QString::SectionSkipEmpty).toInt()/10;
1889         int n=blocks.at(i).section(QRegExp("\\s+"),1,1,QString::SectionSkipEmpty).toInt()%10;
1890         if (amn==(m*10+n)) {
1891             probe--;
1892             parenthesis.last()=2;
1893         }
1894 	if (n==5) {
1895 //	  printf("%d be---\n",probe);
1896 	  probe=(qMax(probe-2,0));
1897 //	  printf("%d----\n",probe);
1898 	}
1899         amn=m*10+n;
1900       }
1901     }
1902     if (blocks.at(i).contains(QRegExp("^HKLF",Qt::CaseInsensitive))) {probe=aprobe=0;}
1903     parenthesis.append(qMax(probe,aprobe));
1904     aprobe=probe;
1905   }
1906   probe=0;
1907   for (int i=0; i<blocks.size();i++){
1908     if (blocks.at(i).contains(QRegExp("^PART\\s+0",Qt::CaseInsensitive))) probe=0;
1909     else if (blocks.at(i).contains(QRegExp("^PART\\s+[-0-9]{1,}",Qt::CaseInsensitive)))
1910       probe=blocks.at(i).section(' ',1,1,QString::SectionSkipEmpty).toInt();
1911     if (blocks.at(i).contains(QRegExp("^HKLF",Qt::CaseInsensitive))) {probe=0;}
1912     parenthesis2.append(probe);
1913   }
1914   afixHighlightArea->update();
1915 }
1916 
remark(int line)1917 void CodeEditor::remark(int line){
1918   if (isReadOnly ())return;
1919   if (blocks.size()<=line) return;
1920   QString zeile=blocks.at(line).simplified();
1921   bool cont= blocks.at(qMax(0,line-1)).contains(QRegExp("=\\s*$"));
1922   if (zeile.contains(QRegExp("^REM",Qt::CaseInsensitive))) {
1923     zeile=zeile.remove(0,4);
1924     if (cont) zeile.prepend(' ');
1925   }
1926   else zeile.prepend("REM ");
1927   QTextCursor cu=textCursor ();
1928   cu.movePosition(QTextCursor::Start);
1929   cu.movePosition(QTextCursor::Down,QTextCursor::MoveAnchor,line);
1930   cu.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
1931   cu.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
1932   if (!cu.selectedText().isEmpty()) cu.deleteChar();
1933   cu.insertText(zeile);
1934   //qDebug()<<zeile;
1935 
1936 }
1937 
toggleRemarks()1938 void CodeEditor::toggleRemarks(){
1939 QTextCursor cu=textCursor();
1940 if (!cu.hasSelection())return;
1941 cu.beginEditBlock();
1942 int start=-1,end=-1,hilf=0;
1943 start=cu.selectionStart();
1944 end=cu.selectionEnd();
1945 cu.setPosition(start);
1946 start=cu.blockNumber();
1947 cu.setPosition(end);
1948 end=cu.blockNumber();
1949 printf("start %d end %d\n",start,end);
1950 hilf=start;
1951 start=qMin(start,end);
1952 end=qMax(hilf,end);
1953 if (end!=start) {
1954 cu.clearSelection();
1955 for (int i=start; i<=end; i++) remark(i);
1956 //qDebug()<<cu.selectedText()<<"\n"<<start<<end;
1957 }
1958 cu.endEditBlock();
1959 cu.clearSelection();
1960 cu.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
1961 
1962 if (!cu.isNull()) setTextCursor(cu);
1963 }
1964 
afixHighlightAreaPaintEvent(QPaintEvent * event)1965 void CodeEditor::afixHighlightAreaPaintEvent(QPaintEvent *event){
1966 //   printf("\nafixHighlightAreaPaintEvent\n");
1967   QPainter apainter(afixHighlightArea);
1968   apainter.fillRect(afixHighlightArea->rect(), (dark)?QColor("#242424"):QColor("#fafafa"));
1969   QTextBlock block = firstVisibleBlock();
1970   QColor color;
1971   QColor pcolor;
1972   int blockNumber = block.blockNumber();
1973 
1974 
1975   int top = (int) blockBoundingGeometry(block).translated(contentOffset()).top();
1976   int bottom = top + (int) blockBoundingRect(block).height();
1977   //printf ("afix %d %d %d %d \n",top,bottom,block.isVisible(),event->rect().top());
1978   while (block.isValid() && top <= event->rect().bottom()) {
1979       switch (parenthesis.at(blockNumber)){
1980       case 0: color=(dark)?QColor("#242424"):QColor("#fafafa");
1981           //          Qt::white;
1982               break;
1983       case 1: color=Qt::darkGreen;break;
1984       default:
1985               color=QColor("blueviolet");
1986               break;
1987       }
1988       pcolor=PartColor::color(parenthesis2.at(blockNumber),dark);
1989     if (block.isVisible() && bottom >= event->rect().top()) {
1990     //  printf("%d %d %d %d %d %d\n",0,top, 4,fontMetrics().height(),parenthesis.at(blockNumber),blockNumber);
1991       apainter.fillRect(5,top, 4,fontMetrics().lineSpacing (),color);
1992       apainter.fillRect(0,top, 4,fontMetrics().lineSpacing (),pcolor);
1993      }
1994     block = block.next();
1995     blockNumber = block.blockNumber();
1996     top = bottom;
1997     bottom = top + (int) blockBoundingRect(block).height();
1998   }
1999   event->accept();
2000 }
2001 
hoverLineNumber(QMouseEvent * event)2002 void CodeEditor::hoverLineNumber(QMouseEvent *event){
2003     if (!isVisible()) {event->ignore(); return;}
2004     //fontMetrics().lineSpacing ()
2005     QTextBlock block=firstVisibleBlock();
2006     int top = (int) blockBoundingGeometry(block).translated(contentOffset()).top();
2007     int bn=firstVisibleBlock().blockNumber();
2008     int idx=(int)  (event->y()-top)/ ((int) blockBoundingRect(block).height()) + bn;
2009     if (idx>=parenthesis.size()) {event->accept();return;}
2010     QString msg=QString("Line:%6<br>%1 PART=%2 <br>%3 Color: %4 <font color=%5>#######</font> %5")
2011             .arg((parenthesis.at(idx))?"AFIXed<br>":"")
2012             .arg(parenthesis2.at(idx))
2013             .arg((comment.at(idx))?"This line is a comment.<br>":"")
2014             .arg(PartColor::name(parenthesis2.at(idx),dark))
2015             .arg(PartColor::color(parenthesis2.at(idx),dark).name())
2016             .arg(idx+1)
2017             ;
2018     QToolTip::showText(event->globalPos(),msg);
2019     event->accept();
2020 }
viewportEvent(QEvent * event)2021 bool CodeEditor::viewportEvent(QEvent *event){
2022 //  printf("lala %d\n",event->type());
2023 if (!isVisible()) {event->ignore(); return false;}
2024 if (event->type() == QEvent::ToolTip) {
2025   QHelpEvent *helpEvent = static_cast<QHelpEvent *>(event);
2026   QTextCursor cursor = cursorForPosition( helpEvent->pos());
2027   if(cursor.block().text().isEmpty()) return true;
2028   QStringList block=shxToolTips.filter(cursor.block().text().left(4),Qt::CaseInsensitive);
2029   if (block.size())
2030     QToolTip::showText(helpEvent->globalPos(),block.first());
2031   int lnr=cursor.block().blockNumber()+1;
2032   QRegExp re=QRegExp("[-]*\\d{2,}\\.\\d+");
2033   double fvar=6666.6666;
2034   QString fvs;
2035   QString msg;
2036   int pos=0,len=0;
2037   if ((block.isEmpty())&&(!highlighter->outputStyle())&&(cursor.block().blockNumber() > fvMinLine)){
2038     while (-1 != (pos=re.indexIn(cursor.block().text(),pos+len+1))){
2039       fvs=re.cap(0);
2040       len=fvs.size();
2041       fvar=fvs.toDouble();
2042       if (fvar!=6666.6666) {
2043         double av=qAbs(fvar),res=0.0,var=1.0;
2044         int m=0;
2045         while ((-10*m+av) > 5){m++;}
2046         if ((m>1)&&(m<=fv.size())) var = fv.at(m-1);
2047         if (!m) res = fvar;
2048         else if (fvar>0) res = (av-(10*m))*var;
2049         else res = (av-(10*m))*(1.0-var);
2050         //qDebug()<<v<<res<<m;
2051         // std::cout<< av <<"abs  v"<< v <<" m ="<< m << " var =" << var <<" res = "<<res<< std::endl ;
2052         //return res;
2053         if ((m)>fv.size()){
2054           if (m>1) msg+=QString("<font color=\"red\">Error in line %2!<br>Free Variable %1 is not defined yet!</font><hr>")
2055           .arg(m).arg(lnr);}
2056         else
2057           msg+=QString("Line <b>%3</b>: Free Variable <b>%1</b> gives <b> %2</b> here.<hr>")
2058                .arg(m).arg(res).arg(lnr);
2059       }
2060     }
2061     QToolTip::showText(helpEvent->globalPos(),msg);
2062     //  printf("shxToolTips size+%d %d %f\n", shxToolTips.size(),block.size(),fvar);
2063   }
2064   event->accept();
2065   return true;
2066 }
2067 return QAbstractScrollArea::viewportEvent ( event);
2068 }
2069 
contextMenuEvent(QContextMenuEvent * event)2070 void  CodeEditor::contextMenuEvent(QContextMenuEvent *event) {
2071      //QMenu *menu = new QMenu();//createStandardContextMenu();
2072      QMenu *menu = createStandardContextMenu();
2073      QAction *a;
2074      QTextCursor cursor = cursorForPosition( event->pos());
2075      QTextBlock block=cursor.block();
2076      QString aname=block.text().section(" ",0,0);
2077      QStringList bfl=shxToolTips.filter(QRegExp(QString("^%1\\b").arg(aname)));
2078      if (bfl.isEmpty()){
2079         QString data=block.text().remove("=").trimmed();                                      // findInStructure
2080         if (data.startsWith("+")) a=menu->addAction(QString("+Open inluded file '%1'").arg(data) ,this,SLOT(openAnIncludeFile()));
2081         else a=menu->addAction(QString("locate %1 in structure").arg(aname) ,this,SLOT(searchInStructure()));
2082         a->setData(data);
2083      }//else {qDebug()<<bfl;}
2084 
2085      if (textCursor().hasSelection()){
2086          a=menu->addAction(QString("select atoms in structure found in selected text"),
2087                          this, SLOT(selectInStructure()));
2088          a->setData(textCursor().selectedText());
2089          a=menu->addAction(QString("sort atoms found in selected text"),
2090                          this, SLOT(sortSelectedRegion()));
2091          a->setData(textCursor().selectedText());
2092 	 a=menu->addAction(QString("toggle remarks states of selected text"),
2093 			 this,SLOT(toggleRemarks()));
2094      }
2095      //...
2096      menu->exec(event->globalPos());
2097      delete menu;
2098 
2099      event->accept();
2100  }
2101 
diffTo(QString org)2102 void CodeEditor::diffTo(QString org){
2103     QList<QTextEdit::ExtraSelection> extraSelections;
2104     QTextEdit::ExtraSelection selection;
2105     QStringList orgZ = org.split('\n');
2106     QColor lineColor = QColor("#ffddaa");
2107     setReadOnly(false);
2108     selection.cursor = textCursor();
2109     selection.cursor.clearSelection();
2110     selection.cursor.movePosition(QTextCursor::Start);
2111 
2112     selection.format.setBackground(lineColor);
2113     selection.format.setProperty(QTextFormat::FullWidthSelection, true);
2114 
2115     QTextBlock b = selection.cursor.block();
2116     int i=0;
2117     while (b.isValid()){
2118         if (b.text()!=orgZ.at(i)){
2119            /* printf(">>%s!\n<<%s!%d\n",
2120                    b.text().toStdString().c_str(),
2121                    orgZ.at(i).toStdString().c_str(),b.position()
2122                    );// */
2123             selection.cursor.clearSelection();
2124             selection.cursor.setPosition(b.position());
2125             selection.cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
2126             selection.cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::MoveAnchor);
2127 
2128             extraSelections.append(selection);
2129         }
2130         b=b.next();
2131         int j=orgZ.indexOf(b.text(),i);
2132         i=(j<0)?i+1:j;
2133         i=qMin(i,orgZ.size()-1);
2134     }
2135     setExtraSelections(extraSelections);
2136     setReadOnly(true);
2137     update();
2138 }
2139 
searchInStructure()2140 void CodeEditor::searchInStructure(){
2141     QAction *action = qobject_cast<QAction *>(sender());
2142     if (action)
2143         emit findInStructure(action->data().toString());
2144 
2145 }
2146 
openAnIncludeFile()2147 void CodeEditor::openAnIncludeFile(){
2148     QAction *action = qobject_cast<QAction *>(sender());
2149     if (action)
2150         emit openIncludeFile(action->data().toString());
2151 
2152 }
2153 
selectInStructure()2154 void CodeEditor::selectInStructure(){
2155     QAction *action = qobject_cast<QAction *>(sender());
2156     if (action)
2157         emit electInStructure(action->data().toString());
2158 
2159 }
2160 
setCompleter(QCompleter * completer)2161 void CodeEditor::setCompleter(QCompleter *completer){
2162     //printf("setCompleter %p %p\n",c,completer);
2163     if (c)
2164         QObject::disconnect(c, 0, this, 0);
2165 
2166     c = completer;
2167 
2168     if (!c)
2169         return;
2170 
2171     c->setWidget(this);
2172     //c->setMaxVisibleItems(13);
2173     c->setCompletionMode(QCompleter::PopupCompletion);
2174     c->setCaseSensitivity(Qt::CaseInsensitive);
2175     QObject::connect(c, SIGNAL(activated(QString)),
2176                      this, SLOT(insertCompletion(QString)));
2177 }
2178 
completer() const2179 QCompleter *CodeEditor::completer() const{
2180     return c;
2181 }
2182 
insertCompletion(const QString & completion)2183 void CodeEditor::insertCompletion(const QString& completion){
2184     if (c->widget() != this)
2185         return;
2186     QTextCursor tc = textCursor();
2187     tc.joinPreviousEditBlock ();
2188     //int extra = completion.length() - c->completionPrefix().length();
2189     //tc.movePosition(QTextCursor::Left);
2190 //    int p=tc.selectionStart()- tc.block().position();
2191     tc.movePosition(QTextCursor::EndOfWord,QTextCursor::MoveAnchor);
2192     tc.movePosition(QTextCursor::StartOfLine,QTextCursor::KeepAnchor);
2193     QString extra = tc.selectedText();
2194     //extra.remove(0,1);
2195     extra.remove(QRegExp("^[a-z]+"));
2196     if ((completion!="REM "))extra.clear();
2197     tc.deleteChar();
2198     tc.insertText(completion+" "+extra);
2199     tc.endEditBlock();
2200     setTextCursor(tc);
2201 }
2202 
textUnderCursor() const2203 QString CodeEditor::textUnderCursor() const{
2204     QTextCursor tc = textCursor();
2205     tc.select(QTextCursor::WordUnderCursor);
2206     if (tc.selectedText().contains("_")) return "";
2207     int si=tc.selectedText().size();
2208     //if (tc.selectedText().startsWith('r',Qt::CaseSensitive))
2209     //    return tc.selectedText().section(QRegExp("[A-Z]+",Qt::CaseSensitive),0,0).toUpper();
2210     //    printf("%d %d\n", (tc.selectionStart ()  - tc.block().position()) ,si);
2211     if (((tc.selectionStart () - tc.block().position())<4)&&(si>4)) return tc.selectedText().left(si-4);
2212     if ((tc.position() - tc.block().position())>2) return "";
2213     return tc.selectedText();
2214 }
2215 
focusInEvent(QFocusEvent * e)2216 void CodeEditor::focusInEvent(QFocusEvent *e){
2217 
2218 //    printf("focusInEvent %p \n",c);
2219     if (c)
2220         c->setWidget(this);
2221     QPlainTextEdit::focusInEvent(e);
2222     e->accept();
2223     //e->ignore();
2224     //setFocus(Qt::MouseFocusReason);
2225 }
2226 
insertFree()2227 void CodeEditor::insertFree(){
2228   if (chgl->mol->selectedatoms.size()!=2) return;
2229   QAction *action = qobject_cast<QAction *>(sender());
2230   if (action){
2231     int index=  action->data().toInt();
2232     QString frei=QString("FREE %1 %2 !experimental does not work with EQIV AND PART\n")
2233       .arg(chgl->mol->selectedatoms.at(0).Label.section(QString::fromUtf8("»"),0,0))
2234       .arg(chgl->mol->selectedatoms.at(1).Label.section(QString::fromUtf8("»"),0,0));
2235 
2236     QTextDocument *document = this->document();
2237     QTextCursor cursor = textCursor();
2238     cursor.beginEditBlock();
2239     cursor = document->find("HKLF",cursor);
2240     cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
2241     cursor.insertText(frei);
2242     cursor.endEditBlock();
2243     chgl->disConnectSelection(index);
2244   }
2245 }
2246 
insertBind()2247 void CodeEditor::insertBind(){
2248   if (chgl->mol->selectedatoms.size()!=2) return;
2249   QString binde=QString("BIND %1 %2 !experimental does not work with EQIV AND PART\n")
2250     .arg(chgl->mol->selectedatoms.at(0).Label.section(QString::fromUtf8("»"),0,0))
2251     .arg(chgl->mol->selectedatoms.at(1).Label.section(QString::fromUtf8("»"),0,0));
2252   QTextDocument *document = this->document();
2253   QTextCursor cursor = textCursor();
2254   cursor.beginEditBlock();
2255   cursor = document->find("HKLF",cursor);
2256   cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
2257   cursor.insertText(binde);
2258   cursor.endEditBlock();
2259   chgl->connectSelection();
2260 }
2261 
keyPressEvent(QKeyEvent * e)2262 void CodeEditor::keyPressEvent(QKeyEvent *e){
2263 //    printf("kp\n");
2264 //    if (!chgl->mol->selectedatoms.isEmpty()){
2265   // Pressing F1 when the mouse cursor is over a SHELX command will
2266   // open the SHELXL help text:
2267   if (e->key() == Qt::Key_F1) {
2268     QTextCursor tc = textCursor();
2269     //tc.select(QTextCursor::WordUnderCursor);
2270     tc.select(QTextCursor::LineUnderCursor);
2271     QString txt = tc.selectedText().toUpper().left(4).trimmed();
2272     printf("%s\n",txt.toStdString().c_str());
2273     if ( Window::isacommand(txt) >= 0 ) {
2274       QUrl help_url = QString("http://shelx.uni-goettingen.de/shelxl_html.php#%1").arg(txt);
2275       QDesktopServices::openUrl(help_url);
2276     }
2277   }
2278   if ((e->modifiers() & Qt::ControlModifier)&&(e->key()==Qt::Key_Delete)) {
2279       	e->ignore();
2280         emit deleteSelected();
2281     return;
2282     }
2283     //}
2284     if (c && c->popup()->isVisible()) {
2285         // The following keys are forwarded by the completer to the widget
2286        switch (e->key()) {
2287        case Qt::Key_Enter:
2288        case Qt::Key_Return:
2289        case Qt::Key_Escape:
2290        case Qt::Key_Tab:
2291       // case Qt::Key_Left:
2292       // case Qt::Key_Right:
2293        case Qt::Key_Backtab:
2294             e->ignore();
2295             return; // let the completer do default behavior
2296        default:
2297            break;
2298        }
2299     }
2300 
2301    // bool isShortcut = ((e->modifiers() & Qt::ControlModifier) && e->key() == Qt::Key_E); // CTRL+E
2302    // if (!c) // do not process the shortcut when we have a completer
2303         QPlainTextEdit::keyPressEvent(e);
2304 
2305     const bool ctrlOrShift = e->modifiers() & (Qt::ControlModifier | Qt::ShiftModifier);
2306     if (!c || (ctrlOrShift && e->text().isEmpty()))
2307         return;
2308 
2309     static QString eow("!"); // end of word
2310     bool hasModifier = (e->modifiers() != Qt::NoModifier) && !ctrlOrShift;
2311     QString completionPrefix = textUnderCursor();
2312     if ((hasModifier || e->text().isEmpty()|| completionPrefix.length() < 1
2313                       || eow.contains(e->text().right(1)))) {
2314         c->popup()->hide();
2315         return;
2316     }
2317 
2318     if (completionPrefix != c->completionPrefix()) {
2319         c->setCompletionPrefix(completionPrefix);
2320         c->popup()->setCurrentIndex(c->completionModel()->index(0, 0));
2321     }
2322     QRect cr = cursorRect();
2323     cr.moveRight(lineNumberAreaWidth()+11);;
2324     cr.setWidth(c->popup()->sizeHintForColumn(0)
2325                 + c->popup()->verticalScrollBar()->sizeHint().width());
2326     c->complete(cr); // popup it up!
2327 }
2328 
2329