/****************************************************************************
 **
 ** Copyright (C) 2011 Christian B. Huebschle & George M. Sheldrick
 ** All rights reserved.
 ** Contact: chuebsch@moliso.de
 **
 ** This file is part of the ShelXle
 **
 ** This file may be used under the terms of the GNU Lesser
 ** General Public License version 2.1 as published by the Free Software
 ** Foundation and appearing in the file COPYING included in the
 ** packaging of this file.  Please review the following information to
 ** ensure the GNU Lesser General Public License version 2.1 requirements
 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 **
 **
 ****************************************************************************/
//äöüß needed to keep this file UTF8 QString::fromUtf8("»")
int Revision=1338;
#include "window.h"
#include "scatt.h"
#include "includeeditor.h"
#include "exportccdlg.h"
#include "deprecation.h"
//QString datum=QString(__TIME__ " " __DATE__);
#ifdef __x86_64__
const int BitWidth=64;
#else
const int BitWidth=32;//                        "<p>This is a 32 bit Version.</p> "
#endif
const QFileDialog::Options noneopt = 0;
QString latestRev="no network available, or you disabled checking";
QString lstpatternfile=":lst_and_output_style.ini";
QString inspatternfile=":ins_res_style.ini";
QString lstpatternfile_dark=":lst_and_output_style_dark.ini";
QString inspatternfile_dark=":ins_res_style_dark.ini";

void Window::dragEnterEvent(QDragEnterEvent *event) {
  if (event->mimeData()->hasFormat("text/uri-list"))
    event->acceptProposedAction();
}

void Window::toggleFullScreen(){
    if (QString(PROGRAM_NAME).compare("shelXle")) return;
    fullscreen=!fullscreen;
    if (fullscreen) {
        showFullScreen();
        updateStatusBar("+++PRESS F11 to exit full screen mode.+++PRESS F11 to exit full screen mode.+++PRESS F11 to exit full screen mode.+++PRESS F11 to exit full screen mode.+++PRESS F11 to exit full screen mode.+++");
    }
    else showNormal();
}

void Window::dropEvent(QDropEvent *event) {
  QList<QUrl> drops = event->mimeData()->urls();
  QString path=drops.first().path();
#if defined Q_WS_WIN || defined Q_OS_WIN
  path.remove(QRegExp("^/"));
#endif
  if ((path.endsWith(".res",Qt::CaseInsensitive))||(path.endsWith(".ins",Qt::CaseInsensitive))){
    loadFile(path);
    event->acceptProposedAction();
  }
}

void Window::qinitres() {
  Q_INIT_RESOURCE(icons);
}

Window::Window(){
  /*! \brief the constructor of the main window rather lengthy but most widgets are created and placed here. 
   *
   */
  fullscreen=false;
  oldFileName=popel=QString("");  
  extraIndex = -1;
  printf("QT_VERSION %x \n",QT_VERSION);
  setAcceptDrops(true);
  mole.mynewnameis=QString(PROGRAM_NAME);
  if (PROGRAM_NAME[0]=='s') {
    int qtmajor=(QT_VERSION&0xff0000)>>16;
    mole.mynewnameis= QString("%1-%2-%3").arg(PROGRAM_NAME).arg(BitWidth).arg(qtmajor);//each version should get ist new ini file because qt5 seems to be
    //incompatible in windows state
    QSettings *testset = new QSettings( QSettings::IniFormat, QSettings::UserScope ,PROGRAM_NAME, mole.mynewnameis );
    QSettings *oldset = new QSettings( QSettings::IniFormat, QSettings::UserScope ,PROGRAM_NAME,  PROGRAM_NAME);
    if ((!QFile::exists(testset->fileName()))&&(QFile::exists(oldset->fileName()))){
      QFile::copy(oldset->fileName(),testset->fileName());
    }
    testset->deleteLater();
    oldset->deleteLater();
  }
  mole.einstellung = new QSettings( QSettings::IniFormat, QSettings::UserScope ,PROGRAM_NAME, mole.mynewnameis );
  QFontDatabase::addApplicationFont(":/xle-icons/droid-sans-mono.ttf");
  falschAtom=-1;
  MaxNumberOfPeaks=100;
  altExtraIconPath="";
  calcmenu=NULL;//if not needed it will be not created.
  dsr=NULL;
  qsaPNG=nullptr;
  nowaste=true;
  focusSet=true;
  doNotAnnoyMe=false;
  hhh  =  qApp->desktop()->availableGeometry(-1).height();
  shxPath=shxOptions=NULL;
  machPlatz=false;
  char *ENUS=setlocale(LC_ALL,"C");
  if (!ENUS)ENUS=setlocale(LC_ALL,"en_US.UTF-8"); 
  //printf("%s\n",ENUS);
  FFTErrorString="";
  range=3.0;
  mode=0;
  weight=1.0;
  //scroller=false;
  setDockNestingEnabled(true);
  otherOpenFiles=false;
  {//initialize Edidor
    navibox = new QGroupBox(this);

    nlt = new QHBoxLayout(navibox);  
    nlt->setMargin(0);
    selectPart = new QCheckBox("Select Part",navibox);
    selectPart->setChecked(false);
    spinSelectPart = new QSpinBox(navibox);
    spinSelectPart->setMinimum(1);
    spinSelectPart->setMaximum(2);
    spinSelectPart->setVisible(false);
    inculdePartNull = new QCheckBox("incl. Pt. 0",navibox);
    inculdePartNull->setToolTip("Include part 0 in selection");
    inculdePartNull->setChecked(true);
    inculdePartNull->setVisible(false);
    QToolButton *nothing=new QToolButton(navibox);
    nothing->setIcon(QIcon(":/xle-icons/nospell.png"));
    nothing->setText("no errors");
    nothing->setIconSize(QSize(22,22));
    nothing->setToolButtonStyle(Qt::ToolButtonIconOnly);

    spellCheckact = new QToolButton(navibox);
    spellCheckact->setIcon(QIcon(":/xle-icons/spell.png"));
    spellCheckact->setText("Jump to error");
    spellCheckact->setIconSize(QSize(22,22));
    spellCheckact->setToolTip("Jump to first error in file.");
    spellCheckact->setToolButtonStyle(Qt::ToolButtonIconOnly);
    lineColumn = new QLabel("",navibox);
    nlt->addWidget(selectPart);
    nlt->addWidget(spinSelectPart);
    nlt->addWidget(inculdePartNull);
    connect(selectPart,SIGNAL(toggled(bool)),spinSelectPart,SLOT(setVisible(bool)));
    connect(selectPart,SIGNAL(toggled(bool)),inculdePartNull,SLOT(setVisible(bool)));
    connect(selectPart,SIGNAL(stateChanged(int)),this,SLOT(selectParts()));
    connect(inculdePartNull,SIGNAL(toggled(bool)),this,SLOT(selectParts()));
    connect(spinSelectPart,SIGNAL(valueChanged(int)),this,SLOT(selectParts()));
    nlt->addStretch(10);
    nlt->addWidget(lineColumn);
    navibox->setLayout(nlt);
    editor = new CodeEditor(this);
    nlt->addWidget(editor->resiFinder);
    nlt->addWidget(spellCheckact);
    nlt->addWidget(nothing);
    connect(spellCheckact,SIGNAL(clicked()),editor,SLOT(jumpToError()));
    connect(editor,SIGNAL(saveMe(bool,bool)),this,SLOT(fileSave(bool,bool)));
    connect(editor,SIGNAL(updateLabel()),this,SLOT(updateLabel()));
    connect(editor,SIGNAL(textChanged ()),this,SLOT(spellCheck())); 
    connect(editor,SIGNAL(cursorPositionChanged ()),this,SLOT(updateLC()));
    connect(editor,SIGNAL(findInStructure(const QString&)),this,SLOT(findInStructure(const QString &)));    
    connect(editor,SIGNAL(openIncludeFile(const QString&)),this,SLOT(openIncludeFile(const QString &)));
    connect(editor,SIGNAL(electInStructure(const QString&)),this,SLOT(selectInStructure(const QString &)));
    connect(editor,SIGNAL(textChanged()),this,SLOT(updateSelectResi()));
    connect(editor,SIGNAL(cursorPositionChanged()),this,SLOT(resiSelectorCheck()));
    completer = new QCompleter(this);
    {
      QStringList keywords;
      keywords << "ACTA"<<"AFIX"<<"ANIS"<<"BASF"<<"BIND"<<"BLOC"<<"BOND"<<
        "BUMP"<<"CELL"<<"CGLS"<<"CHIV"<<"CONF"<<"CONN"<<"DAMP"<<"DANG"<<
        "DEFS"<<"DELU"<<"DFIX"<<"DISP"<<"EADP"<<"END "<<"EQIV"<<
        "EXTI"<<"EXYZ"<<"FEND"<<"FLAT"<<"FMAP"<<"FRAG"<<"FREE"<<
        "FVAR"<<"GRID"<<"HFIX"<<"HKLF"<<"HOPE"<<"HTAB"<<"ISOR"<<
        "LATT"<<"LAUE"<<"LIST"<<"L.S."<<"MERG"<<"MOLE"<<
        "MORE"<<"MOVE"<<"MPLA"<<"NCSY"<<"OMIT"<<"PART"<<"PLAN"<<
        "REM "<<"RESI"<<"RTAB"<<"SADI"<<"SAME"<<"SFAC"<<"SHEL"<<
        "SIMU"<<"SIZE"<<"SPEC"<<"STIR"<<"SUMP"<<"SWAT"<<"SYMM"<<
        "TEMP"<<"TIME"<<"TITL"<<"TWIN"<<"UNIT"<<"VECT"<<
        "WPDB"<<"WGHT"<<"ZERR"<<
        // New Shelxl commands!
        "XNPD"<<//83
        "REST"<<//84
        "CHAN"<<//85
        "RIGU"<<//86
        "FLAP"<<//87
        "RNUM"<<//88
        "SOCC"<<//89
        "PRIG"<<//90
        "WIGL"<<//91
        "RANG"<<//92
        "TANG"<<//93
        "ADDA"<<//94
        "STAG"<<//;//95
        "ABIN"<<//96
        "ANSC"<<//97
        "ANSR"<<//98
        "NOTR"<<//99
        "NEUT"<<//100
        "TWST";//<<101
      keywords.sort();

      completer->setModel(new QStringListModel(keywords, completer));
    }
    completer->setModelSorting(QCompleter::CaseInsensitivelySortedModel);
    completer->setCaseSensitivity(Qt::CaseInsensitive);
    completer->setWrapAround(false);
    editor->setCompleter(completer);
    shxEditorDock = new QDockWidget("SHELXL Editor",this,Qt::Widget);//Qt::Window//Qt::Tool
    shxEditorDock->setObjectName("Editor");
    shxEditorDock->setFeatures(
        QDockWidget::DockWidgetMovable|
        QDockWidget::DockWidgetFloatable|
        QDockWidget::DockWidgetClosable);
    connect(shxEditorDock,SIGNAL(visibilityChanged(bool)),this,SLOT(editorIsVisible(bool)));
    shxMW = new QMainWindow(this);
    shx_group = new QWidget(this);
    shxMW->setCentralWidget(shx_group);
    shx_group->setContentsMargins(0,0,0,0);
    sss = new QVBoxLayout(shx_group);
    sss->addWidget(navibox);
    sss->addWidget(editor);
    sss->addWidget(editor->suchbox);
    shx_group->setLayout(sss);
    shxEditorDock->setWidget(shxMW);
    connect(shxEditorDock,SIGNAL(visibilityChanged(bool)),this,SLOT(shxActUpdate(bool)));
    //int fid =
    //qDebug()<<QFontDatabase::applicationFontFamilies(fid);
    QFont font;
    font.setFamily("Droid Sans Mono");
    font.setPointSize(9);
#if (QT_VERSION >= 0x040700)
    font.setStyleStrategy(QFont::ForceIntegerMetrics);
#endif
    editor->setFont(font);
    editor->setLineWrapMode(QPlainTextEdit::NoWrap);

    addDockWidget(Qt::RightDockWidgetArea, shxEditorDock );
  } 
  {//init shelx output viewer
    xlPutor = new CodeEditor();
    xlPutor->setReadOnly(true);

    QFont font;
    //font.setFamily(FONTFAM);
    font.setFamily("Droid Sans Mono");
    font.setFixedPitch(true);
    font.setPointSize(9);
    xlPutor->setFont(font);
    xlPutor->setLineWrapMode(QPlainTextEdit::NoWrap);
    shxOutputDock = new QDockWidget("SHELXL output",this,Qt::Widget);
    shxOutputDock->setObjectName("Output");
    shxOutputDock->setFeatures(
        QDockWidget::DockWidgetMovable|
        QDockWidget::DockWidgetFloatable|
        QDockWidget::DockWidgetClosable);
    shxOutputDock->hide();

    connect(shxOutputDock,SIGNAL(visibilityChanged(bool)),this,SLOT(outputIsVisible(bool)));
    buttomLt = new QHBoxLayout();
    loadRes = new QPushButton(QIcon(":/xle-icons/open.png"),"Load refinement results",this);
    withdraw = new QPushButton(QIcon(":/xle-icons/cancel.png"),"Discard results",this);
    showLst = new QPushButton("Show output listing file",this);
    connect(loadRes,SIGNAL(pressed()),this,SLOT(loadrefres()));
    connect(withdraw,SIGNAL(pressed()),this,SLOT(withdrawres()));
    connect(showLst,SIGNAL(pressed()),this,SLOT(loadLst()));
    pro7 = new QPushButton("Visualize output");
    connect(pro7,SIGNAL(pressed()),this,SLOT(raiseTaff()));
    connect(pro7,SIGNAL(pressed()),this,SLOT(displayDisagreeableRestraints()));
    buttomLt->addWidget(loadRes);
    buttomLt->addWidget(withdraw);
    buttomLt->addStretch(10);    
    buttomLt->addWidget(showLst);
    stoppRefinement = new QPushButton(QIcon(":/xle-icons/cancel.png"),"STOP refinement!",this);
    stoppRefinement->hide();
    finishRefinement = new QPushButton(QIcon(":/xle-icons/cancel.png"),"Finish Gracefully.",this);
    finishRefinement->hide();
    refineButtonBox = new  QGroupBox();
    refineButtonBox->setLayout(buttomLt);

    vlt = new QVBoxLayout();
    vlt->addWidget(xlPutor);
    vlt->addWidget(xlPutor->suchbox);
    vlt->addWidget(refineButtonBox);
    vlt->addWidget(stoppRefinement);
    vlt->addWidget(finishRefinement);

    vlt->addWidget(pro7);
    refineButtonBox->hide();
    pro7->hide();
    gp = new  QGroupBox("");
    gp->setFlat(true);
    gp->setLayout(vlt);
    shxOutputDock->setWidget(gp);
    addDockWidget(Qt::RightDockWidgetArea, shxOutputDock);
    tabifyDockWidget (shxEditorDock,shxOutputDock);

    connect(shxOutputDock,SIGNAL(visibilityChanged(bool)),this,SLOT(shxOPTUpdate(bool)));
  }
  {//infotainment widget
    vis_settings = new QSettings(QSettings::IniFormat, QSettings::UserScope, PROGRAM_NAME, mole.mynewnameis);
    vis_settings->beginGroup("infotaiment");
    if (!vis_settings->contains("info_as_default")) {
      vis_settings->setValue("info_as_default", false);
    }
    vis_settings->endGroup();
    infotainmentDock = new QDockWidget("Visual Refinement output",this,Qt::Widget);
    infotainmentDock->setObjectName("Painment");
    infotainmentDock->setFeatures(
        QDockWidget::DockWidgetMovable|
        QDockWidget::DockWidgetFloatable|
        QDockWidget::DockWidgetClosable);
    infotainmentDock->hide();
    resid_label = new QTextEdit(); // shows residuals from refinement output
    resid_label->setAlignment(Qt::AlignTop);
    resid_label->setStyleSheet("QLabel { background-color : white; border: 1px solid lightgray;}");
    resid_label->setWordWrapMode(QTextOption::NoWrap);  // prevents word wrap in the table
    restr_table = new QTextEdit();
    restr_table->setAlignment(Qt::AlignBottom);
    restr_table->setReadOnly(true);
    resid_label->setReadOnly(true);
    resid_layout = new QVBoxLayout();
    resid_layout->addWidget(resid_label, 4); // residuals
    resid_layout->addWidget(restr_table, 2);  // list of most disagreeable restraints
    refineButtonBox2 = new  QGroupBox();
    loadRes2 = new QPushButton(QIcon(":/xle-icons/open.png"),"Load refinement results",this);
    withdraw2 = new QPushButton(QIcon(":/xle-icons/cancel.png"),"Discard results",this);
    connect(loadRes2,SIGNAL(pressed()),this,SLOT(loadrefres()));
    connect(withdraw2,SIGNAL(pressed()),this,SLOT(withdrawres()));
    QHBoxLayout *buttomLt2 = new QHBoxLayout();
    buttomLt2->addWidget(loadRes2);
    buttomLt2->addWidget(withdraw2);
    QPushButton *arte= new QPushButton("show text output");
    connect(arte,SIGNAL(pressed()),this,SLOT(raiseTaz()));
    refineButtonBox2->setLayout(buttomLt2);
    stoppRefinement2 = new QPushButton(QIcon(":/xle-icons/cancel.png"),"STOP refinement!",this);
    stoppRefinement2->hide();
    finishRefinement2 = new QPushButton(QIcon(":/xle-icons/cancel.png"),"Finish Gracefully",this);
    finishRefinement2->hide();
    resid_layout->addWidget(refineButtonBox2, 1);
    resid_layout->addWidget(stoppRefinement2, 1);
    resid_layout->addWidget(finishRefinement2, 1);
    resid_layout->addWidget(arte);
    refineButtonBox2->hide();
    restr_table->setMinimumSize(150, 50);

    restr_table->setToolTip("The error of a parameter should generally not be higher than 3sigma. A higher\n"
        "value means that the assumption of the target value is not met. \n"
        "The reason for this can be either, for example, a distorted molecular geometry \n"
        "or systematic errors in the data.\n"
        "\n"
        "Disagreeable restraints will be highlighted in yellow if the error is above \n"
        "2.5sigma. They will be highlighted in red if the error is above 3.5sigma.\n");

    resid_gb = new  QGroupBox("");
    resid_gb->setFlat(true);
    resid_gb->setLayout(resid_layout);
    infotainmentDock->setWidget(resid_gb);
    addDockWidget(Qt::RightDockWidgetArea, infotainmentDock);
    tabifyDockWidget (shxEditorDock,infotainmentDock);
  }

  dock = new QDockWidget("Information Window",this);
  dock->setObjectName("Info");
  dock->setAllowedAreas(Qt::AllDockWidgetAreas);
  infoKanal = new QTextBrowser(dock);
  infoKanal->setLineWrapMode(QTextEdit::NoWrap);
  dock->setFeatures(QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable|QDockWidget::DockWidgetClosable);
  dock->setWidget(infoKanal);
  dock->hide();
  addDockWidget(Qt::RightDockWidgetArea, dock);
 // resize(qApp->desktop()->screenGeometry().width(),qApp->desktop()->screenGeometry().height());

  //rename dock
  renamDock = new QDockWidget("Rename Mode");
  renamDock->setObjectName("Rename");
  enterRenameMode = renamDock->toggleViewAction ();
  enterRenameMode->setShortcut(Qt::ALT+Qt::Key_R); 
  QShortcut *altplus = new QShortcut(Qt::CTRL+Qt::ALT+Qt::Key_Plus,renamDock);
  connect(altplus, SIGNAL(activated()),this, SLOT(incResiNr()));
  QShortcut *altminus = new QShortcut(Qt::CTRL+Qt::ALT+Qt::Key_Minus,renamDock);
  connect(altminus, SIGNAL(activated()),this, SLOT(decResiNr()));
  connect(enterRenameMode,SIGNAL(triggered(bool)),this,SLOT(renamUpdate(bool)));
  renamDock->setFeatures(
      QDockWidget::DockWidgetMovable|
      QDockWidget::DockWidgetFloatable|
      QDockWidget::DockWidgetClosable);

  renameBox = new QGroupBox();
  rnla    = new QVBoxLayout();
  rnla->setObjectName("Rename Layout");
  nliL         = new QLabel("You are in 'rename mode' now.");
  nliL->setFont(QFont("Helvetica",18,QFont::Bold));
  spellCheckact2 = new QToolButton(renameBox); 
  spellCheckact2->setIcon(QIcon(":/xle-icons/spell.png"));
  spellCheckact2->setText("Oops! I made a mistake! Sorry!  Please check!");
  spellCheckact2->setIconSize(QSize(22,22));
  spellCheckact2->setToolTip("Jump to first error in file.");
  spellCheckact2->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
  connect(spellCheckact2,SIGNAL(clicked()),shxEditorDock,SLOT(raise()));
  connect(spellCheckact2,SIGNAL(clicked()),renamDock,SLOT(hide()));
  connect(spellCheckact2,SIGNAL(clicked()),editor,SLOT(jumpToError()));
  rnla->addWidget(spellCheckact2);
  rnla->addWidget(nliL);
  hintL = new QLabel("<div style=color:#0000aa; style=white-space:normal; style=background-color:"
      "#f8f5cd; style=font-size:large;><b><u>Hint:</u></b><a name=\"test\"><img width=\"23\" src=\""
      ":/xle-icons/filesave.png\"></a> It is wise to save often. Especially after renaming a couple of Q-Peaks. "
      "<br>Saving synchronizes the visualized structure and the editor content.<br> <b>Before</b> you start renaming and <b>after</b> "
      "you are finished renaming you should <b>SAVE!</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=\"#test\" style=text-align:right;>Click here to hide this hint for ever.</a></div>");
  hintL->setWordWrap(true);
  rnla->addWidget(hintL);
  connect(hintL,SIGNAL(linkActivated ( const QString)), this ,SLOT(hintLhide()));
  rufModeBox  = new QCheckBox("Automatically jump to first unused label");
  rufModeBox->setChecked(false);
  connect(rufModeBox,SIGNAL(stateChanged(int)),this,SLOT(rufmode())); 
  partSpinL = new QLabel("Part:");
  partSpin = new QSpinBox();
  partSpin->setMinimum(-99);
  partSpin->setMaximum(99);  
  partSpin->setValue(0);
  connect(partSpin,SIGNAL(valueChanged(int)),this,SLOT(updateLabel()));
  resiNrSpinL = new QLabel("Residue Nr:");
  resiNrSpin = new QSpinBox();
  resiNrSpin->setMinimum(0);
  resiNrSpin->setMaximum(9999);
  resiNrSpin->setValue(0);
  connect(resiNrSpin,SIGNAL(valueChanged(int)),this,SLOT(renameRNchanged(int)));
  resiResiClassL = new QLabel("Residue Class:");
  resiResiClass = new QLineEdit("");
  resiResiClass->setMaxLength(4);
  resiResiClass->setValidator(new QRegExpValidator(QRegExp("^[A-Za-z]\\w{0,3}"),resiResiClass)); 
  resiResiClass->setMinimumWidth(100);
  connect(resiResiClass,SIGNAL(textEdited(const QString&)),this,SLOT(grossRC(const QString&)));
  resiResiClass->setEnabled(false);
  resiResiClassCB = new QComboBox(this);
  resiResiClassCB->setLineEdit(resiResiClass);
  resiResiClassCB->setEditable(true);
  resiResiClassCB->setMinimumWidth(150);
  rhla = new QHBoxLayout();
  rhla->addWidget(partSpinL);
  rhla->addWidget(partSpin);
  rhla->addWidget(resiNrSpinL);
  rhla->addWidget(resiNrSpin);
  rhla->addWidget(resiResiClassL);
  rhla->addWidget(resiResiClassCB);
  rnla->addLayout(rhla);
  rhla2 = new QHBoxLayout();
  tieOccL = new QLabel("Tie occupancy to: ");
  tieOccL->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
  tieType = new QComboBox();
  tieType->addItem("its fixed value",0);
  tieType->addItem("fv(n)",1);
  tieType->addItem("1-fv(n)",-1);
  tieFVNrL = new QLabel("n = ");
  tieFVNrL->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
  tieFVNr = new QSpinBox();
  tieFVNr->setMinimum(1);
  tieFVNr->setMaximum(9999);
  tieFVNr->setValue(2);
  tieUsedL = new QLabel("fv(2) is 0x used");
  tieFix = new QDoubleSpinBox(this);
  tieFix->setDecimals(1);
  tieFix->setMinimum(0.0);
  tieFix->setMaximum(1.0);
  tieFix->setValue(1.0);
  tieFix->setSingleStep(0.1);
  tieFix->hide();
  connect(tieType,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTieFreeVar()));
  connect(tieFVNr,SIGNAL(valueChanged(int)),this,SLOT(updateTieFreeVar()));  
  connect(partSpin,SIGNAL(valueChanged(int)),this,SLOT(updateTieFreeVar()));
  rhla2->addWidget(tieOccL);
  rhla2->addWidget(tieType);
  rhla2->addWidget(tieFix);
  rhla2->addWidget(tieFVNrL);
  rhla2->addWidget(tieFVNr);
  rhla2->addWidget(tieUsedL);
  rhla2->setEnabled ( false );
  rnla->addLayout(rhla2);
  indexla = new QHBoxLayout();
  indexIncr = new QCheckBox("Increment Suffix "); 
  indexIncr->setChecked(false);
  indexL = new QLabel("Number");
  indexSpin = new QSpinBox();
  indexSpin->setMinimum(-1);
  indexSpin->setMaximum(999);
  indexSpin->setValue(labelIndex);
  connect(indexSpin,SIGNAL(valueChanged(int )),this,SLOT(changeIndexofLabel(int )));
  sufixBox = new QComboBox();
  sufixL =new QLabel("Suffix");
  QFont dlg2fnt=sufixL->font();
  alpha<<"'"<<""<<"A"<<"B"<<"C"<<"D"<<"E"<<"F"<<"G"<<"H"<<"I"<<"J"<<"K"
    <<"L"<<"M"<<"N"<<"O"<<"P"<<"Q"<<"R"<<"S"<<"T"<<"U"<<"V"<<"W"<<"X"<<"Y"<<"Z"
    <<"A'"<<"B'"<<"C'"<<"D'"<<"E'"<<"F'"<<"G'"<<"H'"<<"I'"<<"J'"<<"K'"<<"L'"<<"M'"
    <<"N'"<<"O'"<<"P'"<<"Q'"<<"R'"<<"S'"<<"T'"<<"U'"<<"V'"<<"W'"<<"X'"<<"Y'"<<"Z'";
  sufixBox->addItems(alpha);
  sufixBox->setCurrentIndex(1);
  sufixBox->setEditable(true);
  connect(sufixBox,SIGNAL( currentIndexChanged ( const QString &)),this,SLOT(changeSuffixofLabel( const QString & )));
  indexla->addWidget(indexL);
  indexla->addWidget(indexSpin);
  indexla->addWidget(sufixL);
  indexla->addWidget(sufixBox);
  rnla->addLayout(indexla);
  labelSuffix="";
  nextLabel="C1";
  labelIndex=1;
  labelPSE="C";
  sfacBox = new QGroupBox("Scattering factors");
  sfacBox->setFixedSize(110*52,70);
  sfacla = new QHBoxLayout();
  dsm= new QSignalMapper(this);
  sfacla->addWidget(pserbt[0] = new QRadioButton("any"));
  /*
     QString pth=QDir::homePath()+"/QRadioButtonFont.txt";
     FILE *frbf=fopen(pth.toStdString().c_str(),"wt");
     fprintf(frbf, "%d %s\n", pserbt[0]->fontInfo().pointSize(), pserbt[0]->fontInfo().family().toStdString().c_str());
     fclose(frbf);
     */
  dlg2fnt.setPointSize(10);
  pserbt[0]->setFont(dlg2fnt);
  dsm->setMapping(pserbt[0],"any");
  connect(pserbt[0], SIGNAL(clicked()), dsm, SLOT(map()));
  for (int i=1; i<109; i++){
    sfacla->addWidget(pserbt[i] = new QRadioButton(mole.pse(i-1)));
    pserbt[i]->setFont(dlg2fnt);
    dsm->setMapping(pserbt[i],mole.pse(i-1));
    connect(pserbt[i], SIGNAL(clicked()), dsm, SLOT(map()));
    pserbt[i]->hide();
  }
  connect(dsm, SIGNAL(mapped(const QString &)), this, SLOT(changeElemetofLabel(const QString &)));

  sfacBox->setLayout(sfacla);
  qsa =new QScrollArea();
  qsa->setWidget(sfacBox);
  qsa->setMaximumHeight(100);
  QHBoxLayout *rufla= new QHBoxLayout();
  rufla->addWidget(rufModeBox);
  rufla->addWidget(indexIncr);
  rnla->addLayout(rufla);
  nextNameL = new QLabel("Next Label is:<br> <font color=\"red\">C1</font>");
  nextNameL->setFont(QFont("Helvetica",16,QFont::Bold));
  rnla->addWidget(nextNameL);
  rnla->addWidget(qsa);
  psew = new PSEWidget(this);
  psew->selection=0;
  psew->setVisible(false);
  rnla->addWidget(psew);
  willpse = new QPushButton("more scattering factors");

  willpse->setStyleSheet(
      QString(
        "QPushButton {"
        "border: 1px solid #000000;"
        "border-radius: 9px;"
        "background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 %1, stop: 0.5 %3, stop: 1 %2);"
        "}"
        "QPushButton:hover {"
        "background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 %2, stop: 0.5 %1, stop: 1 %2);"
        "}"
        "QPushButton:flat {"
        "    border: none; /* no border for a flat push button */"
        "}"
        ).arg("#dedede").arg("#eeeeee").arg("#aeaeae"));

  connect(willpse,SIGNAL(clicked()),psew,SLOT(show()));
  hidwillpse=new QTimer();
  hidwillpse->setSingleShot(true);
  hidwillpse->setInterval(100);

  connect(willpse,SIGNAL(clicked()),hidwillpse,SLOT(start()));
  connect(hidwillpse,SIGNAL(timeout()),willpse,SLOT(hide()));
  connect(psew,SIGNAL(pseSelected(int)),psew,SLOT(hide()));
  connect(psew,SIGNAL(pseSelected(int)),willpse,SLOT(show()));
  connect(psew,SIGNAL(pseSelected(int)),this,SLOT(addNewScatteringFactor(int)));

  rnla->addWidget(willpse);

  buttonBoxRN = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
  buttonBoxRN->hide();
  rnla->addWidget(buttonBoxRN);
  renameBox->setLayout(rnla);

  renamDock->setWidget(renameBox);
  addDockWidget(Qt::RightDockWidgetArea, renamDock);
  renamDock->hide();
  tabifyDockWidget (shxEditorDock,renamDock);
  //rename dock
  //
  qPeakDock = new QDockWidget("Q-Peak-Legend");
  qPeakDock->setObjectName("Peak");
  qPeakDock->hide();
  qPeakDock->setFixedWidth(50);
  qPeakDock->setToolTip("Click or scroll here to reduce the number of Q-peaks shown.");
  qPeakDock->setFeatures(QDockWidget::DockWidgetClosable);
  showQPeakLegend = qPeakDock->toggleViewAction ();
  connect(showQPeakLegend, SIGNAL(toggled(bool )),this,SLOT(setMonoQ(bool )));
  showQPeakLegend->setIcon(QIcon(":/xle-icons/qlegend.svg"));
  qpv = new QPeakView();
  qPeakDock->setWidget(qpv);
  addDockWidget(Qt::LeftDockWidgetArea,qPeakDock);

  //HISTORY
  histDock = new QDockWidget("Refinement History");
  histDock->setObjectName("History");
  hw = new HistoryWidget();
  qsa2 =new QScrollArea();
  hwl = new QVBoxLayout();
  hwl->addWidget(hw);
  qsa2->setLayout(hwl);
  qsa2->setWidget(hw);
  qsa2->setAlignment(Qt::AlignBottom|Qt::AlignLeft);
  histDock->hide();
  histDock->setFeatures(QDockWidget::DockWidgetMovable|
      QDockWidget::DockWidgetFloatable|
      QDockWidget::DockWidgetClosable);
  histDock->setWidget(qsa2);
  histDock->setMinimumSize(100,150);
  addDockWidget(Qt::RightDockWidgetArea,histDock);
  connect(hw, SIGNAL(message(const QString&)), this, SLOT(updateStatusBar(const QString&)));
  connect(hw, SIGNAL(lofi(const QString&)), this, SLOT(loadFile(const QString&)));
  connect(hw, SIGNAL(saveHist()), this, SLOT(openSaveHistory()));
  //HISTORY


  scalePic=1.0;
  if ((Revision%666)==0)
    setWindowTitle(QString("%1 - A clumsy GUI for sHELLxl (Rev: %2)(easteregg) ")
        .arg(PROGRAM_NAME)
        .arg(Revision));
  else
    setWindowTitle(QString("%1 - A Qt GUI for SHELXL (Rev: %2)(%3bit)").arg(PROGRAM_NAME).arg(Revision)

        .arg(BitWidth));


  chgl =new ChGL(this);
  chgl->pause=true;
  chgl->setMolecule(&mole);
  editor->setgl(chgl);
  xlPutor->setgl(chgl);
  connect(editor,SIGNAL(deleteSelected()),this,SLOT(deleteSelectedAtoms()));
  connect(qpv,SIGNAL(cutOffChanged(double)),chgl,SLOT(hideQPeaksBelow(double)));
  connect(qpv,SIGNAL(findQP(double)),chgl,SLOT(highliteQPeak(double)));
  connect(chgl,SIGNAL(qpfoci(double)),qpv,SLOT(qpeaksInFocus(double)));
  connect(renamDock,SIGNAL(visibilityChanged(bool)),chgl,SLOT(setReNaMo(bool))); 
  connect(renamDock,SIGNAL(visibilityChanged(bool)),this,SLOT(updateLabel()));

  connect(renamDock,SIGNAL(visibilityChanged(bool)),this,SLOT(renamUpdate(bool)));
  connect(chgl,SIGNAL(message(const QString&)),this,SLOT(updateStatusBar(const QString&)));
  connect(chgl,SIGNAL(bigmessage(const QString&)),this,SLOT(infoKanalNews(const QString&)));
  connect(chgl,SIGNAL(jumpit(int)),this ,SLOT(jumpToAtom(int)));
  connect(chgl,SIGNAL(insertDFIX(double,double,QList<MyAtom>,QString)), editor,SLOT(insertDFIX(double,double,QList<MyAtom>,QString)));
  connect(chgl,SIGNAL(bindthem()),editor,SLOT(insertBind()));
  connect(chgl,SIGNAL(insertDANG(double,double,QList<MyAtom>,QString)), editor,SLOT(insertDANG(double,double,QList<MyAtom>,QString)));
  connect(chgl,SIGNAL(insertFLAT(double,QList<MyAtom>,QString)), editor,SLOT(insertFLAT(double,QList<MyAtom>,QString)));
  connect(chgl,SIGNAL(insertEXYZ(QList<MyAtom>)), editor, SLOT(insertEXYZ(QList<MyAtom>)));
  connect(chgl,SIGNAL(insertEADP(QList<MyAtom>)), editor, SLOT(insertEADP(QList<MyAtom>)));
  connect(chgl,SIGNAL(insertSADI(int)), this, SLOT(insertSADI(int)));
  connect(chgl,SIGNAL(insertDELU(double, double, QList<MyAtom>,QString)), editor,SLOT(insertDELU(double,double,QList<MyAtom>,QString)));
  connect(chgl,SIGNAL(insertSIMU(double,double,double,QList<MyAtom>,QString)), editor,SLOT(insertSIMU(double,double,double,QList<MyAtom>,QString)));
  connect(chgl,SIGNAL(insertISOR(double,double,QList<MyAtom>,QString)), editor,SLOT(insertISOR(double,double,QList<MyAtom>,QString)));
  connect(chgl,SIGNAL(insertRIGU(double, double, QList<MyAtom>,QString)), editor,SLOT(insertRIGU(double,double,QList<MyAtom>,QString)));
  connect(chgl,SIGNAL(insertCHIV(double, double, QList<MyAtom>,QString)), editor,SLOT(insertCHIV(double,double,QList<MyAtom>,QString)));
  connect(chgl,SIGNAL(insertANIS(QList<MyAtom>)), editor, SLOT(insertANIS(QList<MyAtom>)));
  QAction *sma =new QAction("Show matrices (for debugging)",this);
  sma->setShortcut(tr("Alt+F1"));
  connect(sma,SIGNAL(triggered()),chgl,SLOT(showMatrix()));
  for (int i = 0; i < MaxRecentFiles; ++i) {
    recentFileActs[i] = new QAction(this);
    recentFileActs[i]->setVisible(false);
    connect(recentFileActs[i], SIGNAL(triggered()),
        this, SLOT(openRecentFile()));
  }
  fileMenu   = new QMenu(tr("File"), this);
  chgl->sfacMenu   = new QMenu(tr("Change element to..."),chgl);
  editMenu   = new QMenu(tr("Edit"),this);
  dialogMenu = new QMenu(tr("Settings"), this);
  viewMenu   = new QMenu(tr("View"), this);
  runMenu    =  new QMenu(tr("SHELX"),this);
  runMenu->setObjectName("SHELX");
  packMenu   = new QMenu(tr("Pack"),this);
  packMenu->setEnabled(false);
  extraMenu  = new QMenu(tr("Extra"),this);
  {
    QAction *a;
    a = refineAct = runMenu->addAction(QIcon(":/xle-icons/refine.svg"),"Copy current file to instruction file and run shelxl",this,SLOT(runShelXL()));
    a->setShortcut(QKeySequence("F2"));
    a->setData(0);
    refineAct->setVisible(false);
    refineAct->setEnabled(false);

    a->setObjectName("refineAct");

    a = refineActAnis = runMenu->addAction(QIcon(":/xle-icons/refineanis.svg"),"Insert ANIS and run shelxl",this,SLOT(runShelXL()));
    a->setShortcut(QKeySequence("Alt+F2"));
    a->setData(1);
    refineActAnis->setVisible(false);
    refineActAnis->setEnabled(false);
    a->setObjectName("refineActAnis");
    a = refineActActa = runMenu->addAction(QIcon(":/xle-icons/refineacta.svg"),"Insert ACTA and run shelxl",this,SLOT(runShelXL()));
    a->setData(2);
    refineActActa->setVisible(false);
    refineActActa->setEnabled(false);
    wghtRefineAct=runMenu->addAction(QIcon(":/xle-icons/wghtref.svg"),"Try to refine until WGHT converges (max 10 runs)",this,SLOT(convergeWght()));

    QIcon icke = QIcon(":/xle-icons/autohfix.svg");
    //icke.addFile("icons/autohfix64.png");
    //icke.addFile("icons/autohfix96.png");
    a=actionHFix=runMenu->addAction(icke,
        tr("Automatic H-Fi&x"),this,SLOT(autoHFix()));
    a->setObjectName("actionHFix");
    a=runMenu->addAction("DISPersion from WAVElength", editor, SLOT(dispFromWave()));
    a=actionUniq=runMenu->addAction(QIcon(":/xle-icons/putincell.png"),tr("move centers of gravity into unit cell"),this,SLOT(uniq()));
    a->setObjectName("actionUniq");
    runMenu->addAction("Update UNIT instruction", editor, SLOT(updateUnit()));
    runMenu->addAction("Weed unused sfac numbers ", editor, SLOT(weedEmptySfacs()));
    wghtAct=runMenu->addAction("Update WGHT instruction",editor,SLOT(updateWght()));
    wghtAct->setEnabled(false);
    sinaAct = runMenu->addAction(QIcon(":/xle-icons/sina.svg"),"Make (selected or all) atoms isotropic (ISOT)",this,SLOT(sina()));
    sinaAct->setObjectName("sinaAct");
    sinaAct->setData(-1);
    soact=runMenu->addAction("Sort atoms in file.",editor ,SLOT(sortAtoms()));
    editor->sortierWeise=1;
    runMenu->addAction("Create Q-Peaks from Fo-Fc map",this, SLOT(addMoreQPeaks()));
    actionQPeakLimit = runMenu->addAction(QString("Change maximum number of created Q-peaks (%1)").arg(MaxNumberOfPeaks),this,SLOT(changeQPeakLimit()));
    runMenu->addAction("Invert structure", this, SLOT(invert()));
    runMenu->addAction("Fix some parameters", this, SLOT(fixIt()));
    runMenu->addAction("Most Disagreeable Reflections",this,SLOT(worstReflections()));
    runMenu->addAction("UNIQue ", this, SLOT(unique()));
    a=runMenu->addAction("test for merohedral twinning");
    twinDlg=nullptr;
    connect(a,SIGNAL(triggered() ),this,SLOT(testMerohedral()));
    runMenu->addAction(QIcon(":/xle-icons/aula.svg"),"Automatic Labeling", this, SLOT(aula()));
    runMenu->addSeparator();
    runMenu->addAction("Specify SHELXL runtime options",this , SLOT(setShelxlOptions()));
  }
  {
    QToolBar *tb =fito= new QToolBar(this);
    tb->setWindowTitle(tr("File Tools"));
    tb->setObjectName("FileTB");
    addToolBar(tb);
    QAction *a;
    openAct=a=fileMenu->addAction(QIcon(":/xle-icons/open.png"),
        tr("&Open..."), this, SLOT(openFile() ),
        QKeySequence(tr("Ctrl+O", "File|Open")));
    tb->addAction(a);
    screenshotAct=a=fileMenu->addAction(QIcon(":/xle-icons/diskette.png"),
        tr("&ScreenShot"),this,SLOT(saveScene()),
        QKeySequence(tr("F7","File|ScreenShot")));
    //tb->addAction(a);
    a=fileMenu->addAction(QIcon(":/xle-icons/POV-Ray.ico"),"Export Scene to Pov-Ray",this, SLOT(savePovRay()));
    tb->addAction(a);
    objExport=a=fileMenu->addAction(QIcon(":/xle-icons/obj.svg"),"Export Wafefront .obj file",this,SLOT(obj()));
    tb->addAction(a);
    actionSave = new QAction(QIcon(":/xle-icons/filesave.png"),tr("&Save"), this);
    actionSave->setShortcut(QKeySequence::Save);
    connect(actionSave, SIGNAL(triggered()), this, SLOT(fileSave()));
    actionSave->setEnabled(false);
    tb->addAction(actionSave);
    fileMenu->addAction(actionSave);
    actionSaveAs = new QAction(QIcon(":/xle-icons/filesave.png"),tr("&Save as ..."), this);
    actionSaveAs->setShortcut(tr("Shift+Alt+S"));
    connect(actionSaveAs, SIGNAL(triggered()), this, SLOT(fileSaveAs()));
    actionSaveAs->setEnabled(true);
    fileMenu->addAction(actionSaveAs);
    fileMenu->addAction("Export visible atoms ...",this,SLOT(exportCoordinates()));
    fileMenu->addAction("Export for computational chemistry programs",this, SLOT(exportCC()));
    fileMenu->addSeparator();
    fileMenu->addAction("Shred a CIF and load its res",this,SLOT(shredCIF()));
    fileMenu->addSeparator();
    fileMenu->addAction(tr("Open save history"),this,SLOT(openSaveHistory()));
    fileMenu->addAction("Export Fourier Maps",this,SLOT(exportFMaps()));
    fileMenu->addSeparator();
    for (int i = 0; i < MaxRecentFiles; ++i)
      fileMenu->addAction(recentFileActs[i]);
    fileMenu->addSeparator();
    fileMenu->addAction("Set default path",this,SLOT(setDefaultPath()));
    fileMenu->addSeparator();
    a=fileMenu->addAction(QIcon(":/xle-icons/cancel.png"), tr("&Quit"),
        this, SLOT(close()),
        QKeySequence(tr("Ctrl+Q", "File|Quit")) );
    tb->addAction(a);
  }
  backColor       = new QAction(tr("Change background color"), this);
  labelColor      = new QAction(tr("Change label color"), this);
  backColor->setShortcut (tr("Shift+Alt+B"));
  labelColor->setShortcut(tr("Shift+Alt+T"));
  connect(backColor, SIGNAL (triggered ()), chgl, SLOT(changeBColor()));
  connect(labelColor, SIGNAL (triggered ()), chgl, SLOT(changeTColor()));
  dialogMenu->addAction("Change tool bar icon size",this,SLOT(changeIconSize()));
  QAction *adoptAct=
    dialogMenu->addAction("Edit tool bar is attached to Editor",this,SLOT(adoptEditToolBar(bool)));
  adoptAct->setCheckable(true);
  adoptAct->setChecked(false);
  dialogMenu->addAction("Change screen shot resolution",this,SLOT(changeScalefactor()));
  dialogMenu->addAction("Number of atoms in asymmetric unit to skip automatic distance calculation on loading",this, SLOT(setSDMLimit()));
  separateLabelFile= dialogMenu->addAction("Render labels in a separate file");
  separateLabelFile->setCheckable(true);
  separateLabelFile->setChecked(false);
  dialogMenu->addAction(backColor);
  dialogMenu->addAction(labelColor);
  dialogMenu->addAction(tr("Change label font"), this, SLOT(changeLabelFont()));
  dialogMenu->addAction(tr("Change editor font"), this, SLOT(changeEditorFont()));
  astdlg = dialogMenu->addAction(QIcon(":/xle-icons/eac.svg"),"Atom Styles", this,SLOT(styleDialog()),QKeySequence("Alt+Shift+A"));
  dialogMenu->addAction("Save current orientation matrix",chgl,SLOT(saveOrientation()));
  dialogMenu->addAction("Load orientation matrix",chgl,SLOT(loadOrientation()));
  editMenu->addAction(enterRenameMode);
  {
    QToolBar *tb = editToolBar = new QToolBar(this);
    tb->setObjectName("EditTB");
    tb->setWindowTitle(tr("Editor Tools"));
    QAction *a;
    actionEP=a=viewMenu->addAction(QIcon(":/xle-icons/efplus.png"), "Increase editor fontsize", editor, SLOT(increaseEdtiorFont()), QKeySequence(QKeySequence::ZoomIn));
    connect(actionEP,SIGNAL(triggered()),xlPutor,SLOT(increaseEdtiorFont()));
    tb->addAction(a);
    actionEM=a=viewMenu->addAction(QIcon(":/xle-icons/efminus.png"), "Decrease editor fontsize",editor,SLOT(decreaseEdtiorFont()), QKeySequence(QKeySequence::ZoomOut));
    connect(actionEM,SIGNAL(triggered()),xlPutor,SLOT(decreaseEdtiorFont()));
    tb->addAction(a);
    a = actionUndo = new QAction(QIcon( ":/xle-icons/editundo.png"),tr("&Undo"), this);
    a->setShortcut(QKeySequence::Undo);
    a->setEnabled(false);
    tb->addAction(a);
    editMenu->addAction(a);
    a = actionRedo = new QAction(QIcon( ":/xle-icons/editredo.png"),tr("&Redo"), this);
    a->setShortcut(QKeySequence::Redo);
    a->setEnabled(false);
    tb->addAction(a);
    editMenu->addAction(a);
    editMenu->addSeparator();
    a = actionCut = new QAction(QIcon(":/xle-icons/editcut.png"),tr("Cu&t"), this);
    a->setShortcut(QKeySequence::Cut);
    a->setEnabled(false);
    tb->addAction(a);
    editMenu->addAction(a);
    a = actionCopy = new QAction(QIcon(":/xle-icons/editcopy.png"),tr("&Copy"), this);
    a->setShortcut(QKeySequence::Copy);
    a->setEnabled(false);
    tb->addAction(a);
    editMenu->addAction(a);
    a = actionPaste = new QAction(QIcon(":/xle-icons/editpaste.png"),tr("&Paste"), this);
    a->setShortcut(QKeySequence::Paste);
    a->setEnabled(false);
    tb->addAction(a);
    editMenu->addAction(a);
#ifndef QT_NO_CLIPBOARD
    actionPaste->setEnabled(!QApplication::clipboard()->text().isEmpty());
    connect(QApplication::clipboard(), SIGNAL(dataChanged()), this, SLOT(clipboardDataChanged()));
#endif
    a=actionSearch=editMenu->addAction(QIcon(":/xle-icons/search.png"),
        "&Find in Text",this,SLOT(showSearch()),
        QKeySequence(tr("Ctrl+F", "Edit|Find")));
    tb->addAction(a);
    a->setEnabled(false);
    a=actionNext=editMenu->addAction(QIcon(":/xle-icons/moveright.png"),
        tr("Find &Next"),this ,SLOT(findNext()),
        QKeySequence(tr("F3","Edit|Next")));
    a->setEnabled(false);
    a=actionPrev=editMenu->addAction(QIcon(":/xle-icons/moveleft.png"),
        tr("Find &Previous"),this, SLOT(findPrev()),
        QKeySequence(tr("Shift+F3", "Edit|Previous")));
    a->setEnabled(false);
    editToolBar->hide();
  }
  {
    QToolBar *tb = refineToolBar = new QToolBar(this);
    tb->setObjectName("RefineTB");
    tb->setWindowTitle(tr("Refinement Tools"));
    addToolBar(tb);
    tb->addAction(actionHFix);
    QIcon icke=QIcon(":/xle-icons/killqs.svg");
    //icke.addFile(":/xle-icons/killqs96.png");
    QAction *a;
    a=killQs=editMenu->addAction(icke,
        tr("Delete all Q-peaks"),this,SLOT(deleteAllQ()),
        QKeySequence(tr("Meta+Shift+Q")));
    tb->addAction(a);
    icke=QIcon(":/xle-icons/killhs.svg");
    //icke.addFile(":/xle-icons/killhs96.png");
    a=killHs=editMenu->addAction(icke,
        tr("Delete all Hydrogen atoms"),this,SLOT(deleteAllH()),
        QKeySequence(tr("Meta+Shift+H")));
    tb->addAction(a);
    tb->addAction(refineAct);
    tb->addAction(refineActAnis);
    tb->addAction(wghtRefineAct);
    refineToolBar->hide();
  }
  {
    QToolBar *tb = vito = new QToolBar(this);
    tb->setWindowTitle(tr("View Tools"));
    tb->setObjectName("ViewTB");
    addToolBar(tb);
    QAction *a;
    stereoMenu = new  QMenu("&3D Stereo Options");
    zm_stereo = stereoMenu->addAction("&Zalman Monitor 3D");
    pe_stereo = stereoMenu->addAction("&Parallel Eye Side by Side Stereo");
    xe_stereo = stereoMenu->addAction("&Crossed Eye Side by Side Stereo");
    an_stereo = stereoMenu->addAction("&Anaglyph Stereo red left blue right(testing)");
    hw_stereo = stereoMenu->addAction("&Hardware Stereo (testing)");
    hw_stereo->setEnabled(chgl->context()->format().stereo());
    no_stereo = stereoMenu->addAction("Stereo &Mode off");
    connect(zm_stereo,SIGNAL(triggered()),chgl,SLOT(zalman()));
    connect(pe_stereo,SIGNAL(triggered()),chgl,SLOT(parallel()));
    connect(xe_stereo,SIGNAL(triggered()),chgl,SLOT(crosseye()));
    connect(an_stereo,SIGNAL(triggered()),chgl,SLOT(anaglyphRedCyan()));
    connect(hw_stereo,SIGNAL(triggered()),chgl,SLOT(hardwareStereo()));
    connect(no_stereo,SIGNAL(triggered()),chgl,SLOT(nostereo()));
    stereoGroup = new QActionGroup(this);
    stereoGroup->addAction(zm_stereo);
    stereoGroup->addAction(pe_stereo);
    stereoGroup->addAction(xe_stereo);
    stereoGroup->addAction(an_stereo);
    stereoGroup->addAction(hw_stereo);
    stereoGroup->addAction(no_stereo);
    zm_stereo->setCheckable(true);
    pe_stereo->setCheckable(true);
    xe_stereo->setCheckable(true);
    an_stereo->setCheckable(true);
    hw_stereo->setCheckable(true);
    no_stereo->setCheckable(true);
    no_stereo->setChecked(true);
    viewMenu->insertMenu(actionEP,stereoMenu);
    viewMenu->insertSeparator(actionEP);
    moveMenu = new QMenu("Move Menu");
    a=moveMenu->addAction(tr("Zoom in"),          this,SLOT(zoomin ()),QKeySequence(Qt::ALT + Qt::Key_PageUp));
    a=moveMenu->addAction(tr("Zoom out"),         this,SLOT(zoomout()),QKeySequence(Qt::ALT + Qt::Key_PageDown));
    a=moveMenu->addAction(tr("Rotate left"),      this,SLOT(rotl   ()),QKeySequence(Qt::ALT + Qt::Key_Left));
    a=moveMenu->addAction(tr("Rotate right"),     this,SLOT(rotr   ()),QKeySequence(Qt::ALT + Qt::Key_Right));
    a=moveMenu->addAction(tr("Rotate upwards"),   this,SLOT(rotu   ()),QKeySequence(Qt::ALT + Qt::Key_Up));
    a=moveMenu->addAction(tr("Rotate downwards"), this,SLOT(rotd   ()),QKeySequence(Qt::ALT + Qt::Key_Down));
    moveMenu->addAction(sma);
    a=moveMenu->addAction("Zoom out",chgl,SLOT(zoomOut()),QKeySequence(Qt::ALT + Qt::CTRL + Qt::Key_Z));
    a=moveMenu->addAction("View along z direction",chgl,SLOT(along001()));
    viewMenu->insertMenu(actionEP,moveMenu);
    QIcon icke=QIcon(":/xle-icons/ideal.svg");
    //icke.addFile("icons/ideal23.png");
    chgl->hideBeLo=viewMenu->addAction(icke,"Toggle BEDE and LONE objects (IDEAL)",chgl,SLOT(wuff()));
    chgl->hideBeLo->setCheckable(true);
    chgl->hideBeLo->setChecked(true);
    chgl->hideBeLo->setVisible(false);
    belocube = viewMenu->addAction("Compute and visualize BODD in direct space (IDEAL)" ,this,SLOT(beloWriteCube()));
    belocube->setVisible(false);
    belocube->setObjectName("BeLoCube");
    belocube->setShortcut(Qt::CTRL+Qt::Key_I);
    a=dialogMenu->addAction("HFIX only on suitable atoms", this, SLOT(toggleHFSAO(bool)));
    a->setCheckable(true);
    a->setChecked(mole.HFixSuitableAtomsOnly);

    dialogMenu->addAction("Style BEDE and LONE objects (IDEAL)",this,SLOT(configBeLos()));

    chgl->useTextureLabels=viewMenu->addAction("Use texture Labels",chgl,SLOT(updateGL()));
    chgl->useTextureLabels->setCheckable(true);
    chgl->useTextureLabels->setChecked(true);
    chgl->shortLabels=viewMenu->addAction("Short Labels",chgl,SLOT(updateLabelTextures()));
    chgl->shortLabels->setCheckable(true);
    chgl->shortLabels->setChecked(true);
    chgl->shortLabels->setShortcut(Qt::SHIFT+ Qt::ALT + Qt::Key_L);

    tb->addAction(astdlg);
    a=togAtom =viewMenu->addAction(QIcon(":/xle-icons/atoms.svg"),
        tr("Toggle atoms"),chgl,SLOT(setAtom(bool)),
        QKeySequence("Alt+A"));
    a->setCheckable(true);
    a->setChecked(true);
    tb->addAction(a);
    a=tubeStyle = tb->addAction(QIcon(":/xle-icons/tubes.svg"),"Tubes",chgl,SLOT(setTube(bool)));
    a=ballStyle = tb->addAction(QIcon(":/xle-icons/ballstick.svg"),"Ball-Stick",chgl,SLOT(unsetTube(bool)));
    tubeGroup = new QActionGroup(this);
    tubeGroup->addAction(tubeStyle);
    tubeGroup->addAction(ballStyle);
    ballStyle->setCheckable(true);
    ballStyle->setChecked(true);
    tubeStyle->setCheckable(true);
    tubeStyle->setChecked(false);
    chgl->setTube(false);
    {
    QIcon icke=QIcon(":/xle-icons/adp.svg");
    //icke.addFile(":/xle-icons/adp23.svg");
    a=togElli =viewMenu->addAction(icke,
        tr("Toggle ADPs"),chgl,SLOT(setADP(bool)),
        QKeySequence("Alt+E"));
    }
    a->setCheckable(true);
    a->setChecked(true);
    tb->addAction(a);
    a=togBond =viewMenu->addAction(QIcon(":/xle-icons/bonds.svg"),
        tr("Toggle bonds"),chgl,SLOT(setBond(bool)),
        QKeySequence("Alt+B"));
    a->setCheckable(true);
    a->setChecked(true);
    tb->addAction(a);
    a=togLabel=viewMenu->addAction(QIcon(":/xle-icons/labels.svg"),
        tr("Toggle labels"),chgl,SLOT(setLabel(bool)),
        QKeySequence("Alt+L"));
    a->setCheckable(true);
    a->setChecked(true);
    tb->addAction(a);
    a=viewMenu->addAction(QIcon(":/xle-icons/laplus.png"),
        tr("Increase label fontsize"),chgl,SLOT(incFontSize()),
        QKeySequence("Alt++"));
    a=viewMenu->addAction(QIcon(":/xle-icons/laminus.png"),
        tr("Decrease label fontsize"),chgl,SLOT(decFontSize()),
        QKeySequence("Alt+-"));
    a=togUnit =viewMenu->addAction(QIcon(":/xle-icons/unitcell.svg"),
        tr("Toggle unit cell"),chgl,SLOT(setUnit(bool)),
        QKeySequence("Alt+C"));
    a->setCheckable(true);
    a->setChecked(false);
    tb->addAction(a);
    a=togHBond=viewMenu->addAction(QIcon(":/xle-icons/hbrs.svg"),
        tr("Toggle H-bonds"),chgl,SLOT(setHBond(bool)),
        QKeySequence("Alt+H"));
    a->setCheckable(true);
    a->setChecked(true);
    tb->addAction(a);
    a=chgl->atomLegend=viewMenu->addAction(QIcon(":/xle-icons/legend.svg"),
        tr("Toggle Atom Legend"),chgl,SLOT(updateGL()),
        QKeySequence("Alt+K"));
    a->setCheckable(true);
    a->setChecked(true);
    tb->addAction(a);
    fxle= new FourXle(&mole, chgl,tb);
    fxle->mapcontrol=dialogMenu->addAction(QIcon(":/xle-icons/mapcontrol.svg"),tr("Open map control"), fxle, SLOT(openMapControl()));
    tb->addAction(fxle->mapcontrol);
    fxle->mapcontrol->setVisible(false);
    connect(chgl,SIGNAL(destroyed()),fxle ,SLOT(killFourXleFirst()));//maybe tidy up before die
    connect(fxle,SIGNAL(reloadRes()),this ,SLOT(loadAFile()));
    connect(fxle->jnkButton,SIGNAL(pressed()),this,SLOT(jnk()));
    fxle->keepiso = dialogMenu->addAction("Keep map iso values fixed", fxle, SLOT(keepIsoValues(bool )));
    fxle->keepiso->setCheckable(true);
    fxle->keepiso->setChecked(fxle->keepIso->isChecked());//diffent CaSe !
    a=viewMenu->addAction(tr("Toggle MSAA"),chgl,SLOT(setMSAA(bool)),QKeySequence("F4"));
    a->setCheckable(true);
    a->setChecked(true);
    a=equivHighlighting=viewMenu->addAction("Highlight symmetry equivalents",this,SLOT(toggleEQHighlighting(bool)));
    equivHighlighting->setCheckable(true);
    equivHighlighting->setChecked(true);
    a=togBackGr=viewMenu->addAction(tr("Toggle background gradient"),chgl,SLOT(setBGGradient(bool)),QKeySequence("F6"));
    a->setCheckable(true);
    a->setChecked(true);
    viewMenu->addAction(dock->toggleViewAction());
    viewMenu->addAction(shxEditorDock->toggleViewAction());
    viewMenu->addAction(chgl->wireButt);
    viewMenu->addAction(chgl->rainbowPlot);
    a=togDepthCueing=viewMenu->addAction(tr("toggle DepthCueing (mist)"),chgl,SLOT(setDepthCueing(bool)),QKeySequence(Qt::ALT+Qt::Key_M));//=togDepthCueing
    a->setCheckable(true);
    a->setChecked(false);

    viewMenu->addSeparator();
    ydleStart=viewMenu->addAction("Start rotation",this, SLOT(idleRotStart()),QKeySequence(Qt::ALT + Qt::Key_Y));
    ydleStop=viewMenu->addAction("Stop rotation",this, SLOT(idleRotStop()),QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_Space));
    ydleStop->setVisible(false);

    QAction *moviMaker = viewMenu->addAction("Create a rotation movie", this,SLOT(makeRotMovi()));
    moviMaker->setShortcut(Qt::CTRL+Qt::Key_M);

    viewMenu->addSeparator();
    viewMenu->addAction("Redraw structure",this,SLOT(effuenf()),QKeySequence("F5"));
    viewMenu->addAction("Reload structure from current file",this,SLOT(loadAFile()),QKeySequence("Ctrl+F5"));
    {
      QAction *a=
        viewMenu->addAction("Create voronoi polyeders of asymetric unit",this,SLOT(makeVoro()));
      a->setData(-1);
    }
    {
      QAction *a=clearVoro=
        viewMenu->addAction("Remove voronoi polyeder(s) ",this,SLOT(clearVoros()));
      a->setData(-1);
      clearVoro->setVisible(false);
    }
    if (!QString(PROGRAM_NAME).compare("shelXle"))//olny in standalone shelXle
        viewMenu->addAction("Fullscreen mode",this, SLOT(toggleFullScreen()),QKeySequence("F11"));

  }
  {
    QAction *a;
    QToolBar *tb=bottomToolBar= new QToolBar("Atom Selection Tools",this);
    tb->setObjectName("AtomTB");
    tb->setMovable(false);
    tb->setAllowedAreas(Qt::BottomToolBarArea|Qt::TopToolBarArea);
    tb->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
    QMenu *m= new QMenu("Configure selection toolbar");
    a=m->addAction("Text only",this,SLOT(configureBottomToolbar()));
    a->setData(Qt::ToolButtonTextOnly);
    a=m->addAction("Icon only",this,SLOT(configureBottomToolbar()));
    a->setData(Qt::ToolButtonIconOnly);
    a=m->addAction("Text beside icon",this,SLOT(configureBottomToolbar()));
    a->setData(Qt::ToolButtonTextBesideIcon);
    a=m->addAction("Text under icon",this,SLOT(configureBottomToolbar()));
    a->setData(Qt::ToolButtonTextUnderIcon);
    m->addSeparator();
    a=m->addAction("Place on top",this,SLOT(configureBottomToolbar()));
    a->setData(Qt::TopToolBarArea+32);
    a=m->addAction("Place on bottom",this,SLOT(configureBottomToolbar()));
    a->setData(Qt::BottomToolBarArea+32);
    useNativeDlg=dialogMenu->addAction("Use native dialog for file open/save",this,SLOT(fileNative()));
    useNativeDlg->setCheckable(true);
    useNativeDlg->setChecked(true);

    darkTheme=dialogMenu->addAction("Use dark colors theme",this,SLOT(darkEdit()));
    darkTheme->setCheckable(true);
    darkTheme->setChecked(false);
    if (QString(PROGRAM_NAME).compare("shelXle")){
        darkTheme->setVisible(false);
    }

    a=dialogMenu->addAction(QIcon(":/xle-icons/configure-toolbars.svg"),"Configure selection toolbar");
    a->setToolTip("Configure selection toolbar icon/text style");
    a->setMenu(m);
    chgl->toggleDockWidgets= a = tb->addAction(QIcon(":/xle-icons/hidedockwdg.svg"), "Hide Text Windows",this,SLOT(toggDocWid(bool)));
    a->setCheckable(true);
    a->setChecked(false);
    a->setVisible(false);
    toggleOrthoView = a = tb->addAction(QIcon(":/xle-icons/ortho.svg"), "Ortho-projection",this,SLOT(toggleOrtho(bool)));
    a->setCheckable(true);
    a->setChecked(false);    
    a->setToolTip("toggle Orthographic projection / central perspective projection");
    chgl->grow=a=tb->addAction(QIcon(":/xle-icons/grow.svg"),"GROW ",this,SLOT(grow()));
    a->setShortcut(Qt::ALT+Qt::Key_G);
    packMenu->addAction(a);
    a->setToolTip("Complete the molecule(s)");
    a->setVisible(false);
    chgl->fuse=a=tb->addAction(QIcon(":/xle-icons/fuse.svg"),"FUSE ",this,SLOT(fuse()));
    a->setShortcut(Qt::ALT+Qt::Key_F);
    packMenu->addAction(a);
    a->setVisible(false);
    a->setToolTip("Show the asymmetric unit only");
    recalcSDM=a=packMenu->addAction(QIcon(":/xle-icons/grow.svg"),"recalculate distance matrices",this,SLOT(sdm()));
    recalcSDM->setShortcut(Qt::CTRL+Qt::Key_R);
    QToolBar *sptb=new QToolBar();
    sptb->addAction(recalcSDM);
    renamUpdateAct=sptb->addAction("Update RESIdue Class ComboBox",this,SLOT(renamUpdate(bool)));
    renamUpdateAct->setCheckable(true);
    renamUpdateAct->setChecked(false);
    rnla->addWidget(sptb);
    packMenu->addAction("Symmetry manager",this,SLOT(symmetryManager()));
    tb->addAction(enterRenameMode);
    enterRenameMode->setIcon(QIcon(":/xle-icons/rename.svg"));
    enterRenameMode->setVisible(false);
    tb->addAction(showQPeakLegend);
    showQPeakLegend->setVisible(false);
    a=tb->addAction(QIcon(":/xle-icons/qbond.svg"),"Q-Peak-Bonds",chgl,SLOT(updateGL()));
    a->setCheckable(true);
    a->setChecked(true);
    a->setVisible(false);
    chgl->qPeakBonds=a;
    sinaAct->setVisible(false);
    chgl->addBond=a=tb->addAction(QIcon(":/xle-icons/bind.svg"),"Bind selected atoms",editor,SLOT(insertBind()));
    a->setVisible(false);
    chgl->killBond=a=tb->addAction(QIcon(":/xle-icons/free.svg"),"Free selected atoms",editor,SLOT(insertFree()));
    a->setVisible(false);
    chgl->clearSelection=a=tb->addAction(QIcon(":/xle-icons/deselect.svg"),"Deselect",chgl,SLOT(disSelection()));
    a->setVisible(false);
    chgl->centroid=a=tb->addAction(QIcon(":/xle-icons/centroid.svg"), "Create centroid", this , SLOT(createCentroid()));
    a->setVisible(false);
    chgl->cntrPlot = a = tb->addAction(QIcon(":/xle-icons/cont.svg"),"Create Contour Plot",this, SLOT(contourPlot()));
    a->setVisible(false);
    chgl->nocntrPlot = a = tb->addAction(QIcon(":/xle-icons/nocont.svg"),"Remove Contour Plot",this, SLOT(nocontourPlot()));
    a->setVisible(false);
    chgl->centerSelection=a=tb->addAction(QIcon(":/xle-icons/center.svg"),"Center selected atoms",chgl,SLOT(homeXY()));
    a->setCheckable(true);
    a->setChecked(false);
    a->setVisible(false);
    chgl->invSelection=a=tb->addAction(QIcon(":/xle-icons/invsel.svg"),"Invert selection",chgl,SLOT(invertSelection()));
    a->setVisible(false);
    chgl->hideNotSelection=a=tb->addAction(QIcon(":/xle-icons/hide.svg"),"Hide other atoms",chgl,SLOT(hideNonSelected()));
    a->setVisible(false);
    a=chgl->hideh=tb->addAction(QIcon(":/xle-icons/hideh.svg"),"Hide Hydrogen atoms",chgl,SLOT(hideHydrogens()));
    a->setVisible(false);
    chgl->unhide=a=tb->addAction(QIcon(":/xle-icons/show.svg"),"Show all hidden",chgl,SLOT(showHidden()));
    connect(a,SIGNAL(triggered()),qpv,SLOT(unhide()));
    a->setVisible(false);
    chgl->invhide=a=tb->addAction(QIcon(":/xle-icons/invshow.svg"),"Toggle visibility ",chgl,SLOT(invertHidden()));
    a->setVisible(false);
    chgl->shpm1=a=tb->addAction(QIcon(":/xle-icons/part-1.svg"),"Hide PART -N ghost",chgl,SLOT(hidePartMinusOne(bool )));
    a->setCheckable(true);
    a->setChecked(false);
    a->setVisible(false);
    a->setToolTip("Hide PART -N symmetry equivalent as ghost atoms");
    chgl->highlightParts=a=tb->addAction(QIcon(":/xle-icons/parts.svg"),"Highlight PARTs",chgl,SLOT(updateGL()));
    a->setCheckable(true);
    a->setChecked(false);
    a->setVisible(false);
    a=chgl->delSelAt = tb->addAction(QIcon(":/xle-icons/killselected.svg"),"Delete selected atoms",this,SLOT(deleteSelectedAtoms()));
    a->setData(-1);
    a->setShortcut(Qt::CTRL+Qt::Key_Delete);
    a->setVisible(false);
    addToolBarBreak();
    addToolBar(Qt::TopToolBarArea,tb);
  }
  {
    packMenu->addAction("Pack cell",this,SLOT(fillCell()));
    packMenu->addAction("Expand all contacts",this,SLOT(expandAll()));
    packMenu->addAction("Complete" ,this,SLOT(complete()));
    packMenu->addAction("Pack inside given limits",this,SLOT(packInLimits()));
  }
  menuBar()->addMenu(fileMenu);
  menuBar()->addMenu(editMenu);
  menuBar()->addMenu(dialogMenu);
  menuBar()->addMenu(viewMenu);
  menuBar()->addMenu(packMenu);
  menuBar()->addMenu(runMenu);
  menuBar()->addMenu(extraMenu);
  QMenu *fcoMenu = new QMenu("Tools");
  fcvsfoAct=fcoMenu->addAction("Fc vs Fo",this,SLOT(foversusfc()));
  fcvsfoAct->setDisabled(true);
  calcAct=fcoMenu->addAction("Crystallographic calculator",this,SLOT(calculator()));
  calcAct->setEnabled(true);
  fcoMenu->addAction("Fractal dimension analysis (Henn-Meindl-plot)",this,SLOT(jnk()));
  dsrAct = fcoMenu->addAction("DSR plugin",this,SLOT(create_DSRGui())); 
  dsrAct->setEnabled(true);
  dsrAct->setShortcut(Qt::ALT+Qt::Key_D);
  menuBar()->addMenu(fcoMenu);

  {
    helpMenu = new QMenu(tr("Help"), this);
    menuBar()->addMenu(helpMenu);
    helpMenu->addAction("Help ", this, SLOT(linkHelp()));
    helpMenu->addAction(QWhatsThis::createAction(this));
    helpMenu->addAction(tr("About"), this, SLOT(aboutXLE()));
    helpMenu->addAction(tr("About &Qt"), qApp, SLOT(aboutQt()));
    helpMenu->addAction("Check for new versions now",this,SLOT(checkForUpdates()));
    helpMenu->addAction("Show Key Bindings", this, SLOT(hereAreMyKeys()));
  }

  chgl->rCenter = new QToolButton();
  chgl->rCenter->setText("Reset rotation center");
  connect(chgl->rCenter,SIGNAL(clicked()), chgl,SLOT( rotCenter()));
  chgl->rCenter->hide();

  chgl->invertMouseZoom = new QToolButton(this);
  chgl->invertMouseZoom->setIcon(QIcon(":/xle-icons/invzoom.svg"));
  chgl->invertMouseZoom->setCheckable(true);
  chgl->invertMouseZoom->setChecked(false);
  chgl->invertMouseZoom->setText("invert mouse zoom");
  chgl->invertMouseZoom->setToolTip("invert mouse zoom (right mouse click and drag up or down");
  quickReLoadButton = new QToolButton(this);
  QIcon qrlic =QIcon();
  qrlic.addFile(":/xle-icons/quick-re-load.png",QSize(), QIcon::Normal, QIcon::Off );
  qrlic.addFile(":/xle-icons/quick-re-load_on.png",QSize(), QIcon::Normal, QIcon::On );
  quickReLoadButton->setIcon(qrlic);
  quickReLoadButton->setCheckable(true);
  //Too many problems with this feature 11.03.2021
  quickReLoadButton->setChecked(false);
  quickReLoadButton->hide();
  quickReLoadButton->setText("Enable QuickReLoad");
  quickReLoadButton->setToolTip("QuickReLoad updates the structure instead of fresh reloading it");

  homeMe = new QToolButton(this);
  homeMe->setIcon(QIcon(":/xle-icons/home.svg"));
  homeMe->setText("home");
  homeMe->setToolTip("move molecules home");
  connect(homeMe,SIGNAL(clicked()),chgl,SLOT(homeXY()));
  qGrowPeak = new QCheckBox("grow Q-peaks");
  connect(qGrowPeak,SIGNAL(toggled(bool)),this,SLOT(growQPeaks(bool)));
  search4duplicates = new QCheckBox("search for duplicates");
  search4duplicates->setChecked(true);
  connect(search4duplicates,SIGNAL(toggled(bool)),this,SLOT(duplicates()));
  sLabel = new QLabel;
  sLabel->setFrameStyle(QFrame::Panel  );
  sLabel->setLineWidth(2);
  sLabel->setText(QString("%1").arg(PROGRAM_NAME));
  zoomIn = new QToolButton (this);
  zoomIn-> setIcon(QIcon(":/xle-icons/zoom-in.png"));
  zoomIn->setText("Zoom +");
  zoomIn->setToolTip("Zoom +");
  zoomIn->setAutoRepeat(true);
  zoomIn->setAutoRepeatDelay(150);
  zoomIn->setAutoRepeatInterval(3);
  zoomOut = new QToolButton(this);
  zoomOut->setIcon(QIcon(":/xle-icons/zoom-out.png"));
  zoomOut->setText("Zoom -");
  zoomOut->setToolTip("Zoom -");
  zoomOut->setAutoRepeat(true);
  zoomOut->setAutoRepeatDelay(150);
  zoomOut->setAutoRepeatInterval(3);
  connect(zoomIn,SIGNAL(pressed ()),this,SLOT(zoomin()));
  connect(zoomOut,SIGNAL(pressed ()),this,SLOT(zoomout()));
  connect(chgl,SIGNAL(no_hw_st()),no_stereo,SLOT(toggle()));
  fvused = new QLabel("");
  statusBar();
  statusBar()->addPermanentWidget(fvused);
  statusBar()->addPermanentWidget(chgl->rCenter);
  statusBar()->addPermanentWidget(chgl->enviButt);
  statusBar()->addPermanentWidget(chgl->enviSelect);
  statusBar()->addPermanentWidget(qGrowPeak);
  statusBar()->addPermanentWidget(search4duplicates);
  statusBar()->addPermanentWidget(zoomIn);
  statusBar()->addPermanentWidget(zoomOut);
  statusBar()->addPermanentWidget(homeMe);
  statusBar()->addPermanentWidget(chgl->invertMouseZoom);
  statusBar()->addPermanentWidget(quickReLoadButton);
  statusBar()->addPermanentWidget(fxle->keepIso);
  statusBar()->addPermanentWidget(fxle->doMaps);
  statusBar()->addPermanentWidget(fxle->ownfcf6);
  QCheckBox *hideToolBars = new QCheckBox("Hide Tool Bars");
  hideToolBars->setChecked(false);
  connect(hideToolBars,SIGNAL(toggled(bool)),this,SLOT(hideToolz(bool)));
  statusBar()->addPermanentWidget(hideToolBars);
  statusBar()->addPermanentWidget(sLabel);
  connect(fxle,SIGNAL(bigmessage(const QString&)),this,SLOT(infoKanalNews(const QString&)));
  shxEditorDock->hide();
  ////////////////////////////// SETTINGS /////////////////////////////////////////////////////////////////////////

  mole.loadSettings();
  mole.einstellung->beginGroup("Window");
  useNativeDlg->setChecked(mole.einstellung->value("nativeDialogs",true).toBool());
  chgl->invertMouseZoom->setChecked( mole.einstellung->value("InvertMouseZoom").toBool());
  //Too many issues with this feature 11.03.2021
  //quickReLoadButton->setChecked( mole.einstellung->value("QuickReLoad",true).toBool());
  //connect(quickReLoadButton, SIGNAL(toggled(bool)), this, SLOT(loadAFile()));
  bool bbb=true;
  chgl->SDM_Limit=mole.einstellung->value("SDM-LIMIT", 350).toInt();
  if (mole.einstellung->contains("HighlightEquivalents")){
    bool bb;
    equivHighlighting->setChecked(bb=mole.einstellung->value("HighlightEquivalents").toBool());
    mole.highlightEquivalents=bb;
  }
  if (mole.einstellung->contains("ADPs"))
    togElli->setChecked(bbb=mole.einstellung->value("ADPs").toBool());
  chgl->setADP(togElli->isChecked());
  if (mole.einstellung->contains("Tubes"))
    tubeStyle->setChecked(bbb=mole.einstellung->value("Tubes").toBool());
  chgl->setTube(tubeStyle->isChecked());
  if (mole.einstellung->contains("Legend"))
    chgl->atomLegend->setChecked(mole.einstellung->value("Legend").toBool());
  if (mole.einstellung->contains("ShowLabels"))
    togLabel->setChecked(bbb=mole.einstellung->value("ShowLabels").toBool());
  chgl->setLabel(togLabel->isChecked());
  if (mole.einstellung->contains("BackGroundGradient"))
    togBackGr->setChecked(bbb=mole.einstellung->value("BackGroundGradient").toBool());
  chgl->setBGGradient(togBackGr->isChecked());
  if (mole.einstellung->contains("WireModelOnRotate"))
    chgl->wireButt->setChecked(mole.einstellung->value("WireModelOnRotate").toBool());
  shelxlPath="shelxl";
  if (mole.einstellung->contains("SHELXL-PATH"))
    shelxlPath=mole.einstellung->value("SHELXL-PATH").toString();
  shelxlArgs="";
  if (mole.einstellung->contains("SHELXL-OPTION"))
    shelxlArgs=mole.einstellung->value("SHELXL-Option").toString();
  useMyBArray = false;  // If true, ShelXle does not override b-array value
  if (mole.einstellung->contains("SHELXL-BARRAY")) {
    useMyBArray=mole.einstellung->value("SHELXL-BARRAY").toBool();
  }
  mole.einstellung->endGroup();
  mole.einstellung->beginGroup("TextureLabels");
  if (mole.einstellung->contains("useTextures4Labels"))
    chgl->useTextureLabels->setChecked(mole.einstellung->value("useTextures4Labels").toBool());
  mole.einstellung->endGroup();
  mole.einstellung->beginGroup("Files");
  dirName = mole.einstellung->value("lastFile").toString();

  QStringList files = mole.einstellung->value("recentFileList").toStringList();
  foreach (QWidget *widget, QApplication::topLevelWidgets()) {
    Window *mainWin = qobject_cast<Window *>(widget);
    if (mainWin)
      mainWin->updateRecentFileActions();
  }

  mole.einstellung->endGroup();
  mole.einstellung->beginGroup("Colors");
  chgl->backGroundColor=mole.einstellung->value("BackGroundColor",QColor("lightskyblue")).value<QColor>();
  chgl->labelColor=mole.einstellung->value("LabelColor").value<QColor>();
  if (QString(PROGRAM_NAME).compare("shelXle")==0){
    darkTheme->setChecked(mole.einstellung->value("darkTheme","false").toBool());
  }
  darkEdit();
  mole.einstellung->endGroup();
  int ignore=QMessageBox::Yes;
  mole.einstellung->beginGroup("Updates");
  if (mole.einstellung->contains("IgnoreUpdates"))
    ignore=mole.einstellung->value("IgnoreUpdates").toInt();
  mole.einstellung->endGroup();
  net = new QNetworkAccessManager(this);
  if (ignore!=QMessageBox::No){
    connect(net, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));
    reply = net->get(QNetworkRequest(QUrl("http://shelxle.org/shelx/revision.php")));
  }
  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////

  mole.einstellung->beginGroup("Fonts");
  if (mole.einstellung->contains("LabelFont"))
    chgl->myFont = mole.einstellung->value("LabelFont").value<QFont>();
  if (mole.einstellung->contains("EditorFont")){
    QFont fnt;
    fnt = mole.einstellung->value("EditorFont").value<QFont>();
#if (QT_VERSION >= 0x040700)
    fnt.setStyleStrategy(QFont::ForceIntegerMetrics);
#endif
    editor->setFont(fnt);
    xlPutor->setFont(fnt);
  }
  mole.einstellung->endGroup();


  extraProgramNames.clear();
  extraProgramPaths.clear();
  extraArguments.clear();
  extraExtensions.clear();
  extraResIns.clear();
  extraOpenFileDialogBefore.clear();
  extraIconOverlay.clear();
  extraOverlayPointSize.clear();
  mole.einstellung->beginGroup("Extra");
  int siz=0;
  siz=mole.einstellung->beginReadArray("ProgramNames");
  for (int i = 0; i < siz; i++) {
    mole.einstellung->setArrayIndex(i);
    extraProgramNames.append(mole.einstellung->value("Name","").toString());
  }
  mole.einstellung->endArray();
  mole.einstellung->endGroup();

  mole.einstellung->beginGroup("Extra");
  mole.einstellung->beginReadArray("ProgramPaths");
  for (int i = 0; i < siz; i++) {
    mole.einstellung->setArrayIndex(i);
    extraProgramPaths.append(mole.einstellung->value("Path","").toString());
  }
  mole.einstellung->endArray();
  mole.einstellung->endGroup();

  mole.einstellung->beginGroup("Extra");
  mole.einstellung->beginReadArray("ProgramArgs");
  for (int i = 0; i < siz; i++) {
    mole.einstellung->setArrayIndex(i);
    extraArguments.append((Qt::CheckState) mole.einstellung->value("Arg").toInt());
  }
  mole.einstellung->endArray();
  mole.einstellung->endGroup();

  mole.einstellung->beginGroup("Extra");
  mole.einstellung->beginReadArray("ProgramExtensions");
  for (int i = 0; i < siz; i++) {
    mole.einstellung->setArrayIndex(i);
    extraExtensions.append((Qt::CheckState)mole.einstellung->value("Ext",0).toInt());
  }
  mole.einstellung->endArray();
  mole.einstellung->endGroup();

  mole.einstellung->beginGroup("Extra");
  mole.einstellung->beginReadArray("ProgramResIns");
  for (int i = 0; i < siz; i++) {
    mole.einstellung->setArrayIndex(i);
    extraResIns.append((Qt::CheckState)mole.einstellung->value("Res2Ins",0).toInt());
  }
  mole.einstellung->endArray();
  mole.einstellung->endGroup();


  mole.einstellung->beginGroup("Extra");
  mole.einstellung->beginReadArray("FileDialog");
  for (int i = 0; i < siz; i++) {
    mole.einstellung->setArrayIndex(i);
    extraOpenFileDialogBefore.append((Qt::CheckState)mole.einstellung->value("fd",0).toInt());
  }
  mole.einstellung->endArray();
  mole.einstellung->endGroup();


  mole.einstellung->beginGroup("Extra");
  mole.einstellung->beginReadArray("IconOverlay");
  for (int i = 0; i < siz; i++) {
    mole.einstellung->setArrayIndex(i);
    extraIconOverlay.append((Qt::CheckState)mole.einstellung->value("icov",2).toInt());
  }
  mole.einstellung->endArray();
  mole.einstellung->endGroup();

  mole.einstellung->beginGroup("Extra");
  mole.einstellung->beginReadArray("OverlayPointSize");
  for (int i = 0; i < siz; i++) {
    mole.einstellung->setArrayIndex(i);
    extraOverlayPointSize.append(mole.einstellung->value("icov",36).toInt());
  }
  mole.einstellung->endArray();
  mole.einstellung->endGroup();

  mole.einstellung->beginGroup("Extra");
  mole.einstellung->beginReadArray("AltExtraIconPaths");
  for (int i = 0; i < siz; i++) {
    mole.einstellung->setArrayIndex(i);
    altExtraIconPaths.append(mole.einstellung->value("altIcon","").toString());
  }
  mole.einstellung->endArray();
  mole.einstellung->endGroup();

  mole.einstellung->beginGroup("Extra");
  mole.einstellung->beginReadArray("ProgramDetached");
  for (int i = 0; i < siz; i++) {
    mole.einstellung->setArrayIndex(i);
    extraDetach.append((Qt::CheckState)mole.einstellung->value("Detach",0).toInt());
  }
  mole.einstellung->endArray();
  mole.einstellung->endGroup();

  mole.einstellung->beginGroup("Extra");
  mole.einstellung->beginReadArray("AlternativeExtensions");
  for (int i = 0; i < siz; i++) {
    mole.einstellung->setArrayIndex(i);
    extraExt2.append(mole.einstellung->value("ext","").toString());
  }
  mole.einstellung->endArray();
  mole.einstellung->endGroup();

  mole.einstellung->beginGroup("Extra");
  mole.einstellung->beginReadArray("CommandLineOptions");
  for (int i = 0; i < siz; i++) {
    mole.einstellung->setArrayIndex(i);
    extraOptions.append(mole.einstellung->value("opt","").toString());
  }
  mole.einstellung->endArray();
  mole.einstellung->endGroup();

  mole.einstellung->beginGroup("SaveHint");
  if (mole.einstellung->contains("ShowRenameHint"))
    hintL->setVisible(mole.einstellung->value("ShowRenameHint").toBool());
  mole.einstellung->endGroup();
  {
    extraMenu->addAction("add or remove external programs",this,SLOT(extraSettings()));
  }
  if (extraProgramNames.size()) extraMenu->addSeparator();
  QFileIconProvider *epic = new QFileIconProvider();
  extraTB= new QToolBar("External Program Tool Bar",this);
  extraTB->setObjectName("ExtraTB");
  extraTB->setToolButtonStyle(Qt::ToolButtonIconOnly);
  for (int i=0; i<extraProgramNames.size(); i++){
    QAction *a;
    QString icopa=extraProgramPaths.at(i);
    QPixmap fmap = epic->icon(QFileInfo(icopa)).pixmap(64,64);
    if (QFile::exists(altExtraIconPaths.at(i))) fmap=QIcon(altExtraIconPaths.at(i)).pixmap(64,64);
    if (extraIconOverlay.at(i)==Qt::Checked){
      QPainter *paint = new QPainter(&fmap);
      paint->setPen(QPen(QColor("#FFFFFF")));
      QFont ifont=chgl->myFont;
      ifont.setPixelSize(extraOverlayPointSize.at(i)*fmap.height()/64);
      paint->setFont(ifont);
      paint->drawText(1,fmap.height()-5,extraProgramNames.at(i));
      paint->setPen(QPen(QColor("#000000")));
      paint->drawText(0,fmap.height()-4,extraProgramNames.at(i));
      paint->end();
    }
    extraIcon=QIcon(fmap);
    a=extraMenu->addAction(extraIcon,QString("run %1 !").arg(extraProgramNames.at(i)),this,SLOT(runExtra()));
    a->setData(i);
    extraTB->addAction(a);
  }
  delete epic;
  addToolBar(extraTB);
  extraOutput = new QDialog(this);
  lt = new QVBoxLayout();
  extraOutPut = new QTextEdit();
  QFont mospfo(FONTFAM);
  extraOutPut->setFont(mospfo);
  extraOutput->setMinimumWidth(
      QFontMetrics(extraOutPut->font())
      .width("###########################################################################################"));
  extraOutPut->setLineWrapMode(QTextEdit::NoWrap);
  lt->addWidget(extraOutPut);
  extraOutput->setLayout(lt);
  chgl->pause=false;
  //printf("%d\n",__LINE__);
  setCentralWidget(chgl);
  chgl->setMSAA(true);
  chgl->updateGL();
  mole.einstellung->beginGroup("Window");
  bool EditorHasOwnToolBar = mole.einstellung->value("EditorHasOwnToolBar",false).toBool();
  if (EditorHasOwnToolBar) shxMW->addToolBar(editToolBar);
  else addToolBar(editToolBar);
  adoptAct->setChecked(EditorHasOwnToolBar);
  QByteArray ba,ba_state=mole.einstellung->value("state").toByteArray();
  if (!ba_state.isEmpty()) restoreState(ba_state);
  QByteArray estate = mole.einstellung->value("EditorState").toByteArray();
  if (!estate.isEmpty()) shxMW->restoreState(estate);
  ba=mole.einstellung->value("geometry").toByteArray();
  //qDebug()<<ba.toHex()<<"##"<<ba_state.toHex();
  if (!ba.isEmpty()) restoreGeometry(ba);
  else {
    QSize size ;
    size=QSize(640,480);
    ediSize=QSize(640,480);
    ediPos=QPoint(0,0);
    if ((size.height())<45||(size.width()<108)) size=QSize(640,480);
    QPoint pos;
    pos=QPoint(1,1);
    move(pos);
    if(size.isNull())
      resize(640, 480);
    else
      resize(size);
  }
  mole.einstellung->endGroup();
  mole.einstellung->beginGroup("ToolBar");
  if (mole.einstellung->contains("SelectionToolBarStyle"))
    bottomToolBar->setToolButtonStyle((Qt::ToolButtonStyle) mole.einstellung->value("SelectionToolBarStyle").toInt());
  mole.einstellung->endGroup();
  mole.einstellung->beginGroup("DoNotAskFileSave");
  if (mole.einstellung->contains("DoNotAnnoyMe"))
    doNotAnnoyMe=mole.einstellung->value("DoNotAnnoyMe",false).toBool();
  mole.einstellung->endGroup();
  mole.einstellung->beginGroup("Sorting");
  if (mole.einstellung->contains("SortingOption")){
    editor->sortierWeise = mole.einstellung->value("SortingOption").toInt();
  }
  mole.einstellung->endGroup();
  {
    sortGroup = new QActionGroup(this);
    sortMenu = new QMenu("Change sort order");
    QAction *a = sortMenu->addAction("label number > atomic number > label suffix");
    sortGroup->addAction(a);
    a->setCheckable(true);
    if (editor->sortierWeise==1)a->setChecked(true);
    a->setData(1);
    a = sortMenu->addAction("atomic number > label number > label suffix");
    sortGroup->addAction(a);
    a->setCheckable(true);
    if (editor->sortierWeise==2)a->setChecked(true);
    a->setData(2);
    a = sortMenu->addAction("SFAC number > label number > label suffix");
    sortGroup->addAction(a);
    a->setCheckable(true);
    if (editor->sortierWeise==3)a->setChecked(true);
    a->setData(3);
    a = sortMenu->addAction("label suffix > atomic number > label number");
    sortGroup->addAction(a);
    a->setCheckable(true);
    if (editor->sortierWeise==4)a->setChecked(true);
    a->setData(4);
    a = sortMenu->addAction("fragment> atomic number > label number > label suffix");
    sortGroup->addAction(a);
    a->setCheckable(true);
    if (editor->sortierWeise==5)a->setChecked(true);
    a->setData(5);


    a = sortMenu->addAction("U equivalent");
    sortGroup->addAction(a);
    a->setCheckable(true);
    if (editor->sortierWeise==6)a->setChecked(true);
    a->setData(6);
    connect(sortGroup,SIGNAL(triggered(QAction*)), editor,SLOT(changeSortierWeise(QAction*)));
    runMenu->insertMenu(soact,sortMenu);
  }
  mole.einstellung->beginGroup("Labeling");
  if (mole.einstellung->contains("AutoUnused")){
    rufModeBox->setChecked(mole.einstellung->value("AutoUnused").toBool());
  }
  mole.einstellung->endGroup();
  tbiconSize=32;
  mole.einstellung->beginGroup("ToolBarIcons");
  if (mole.einstellung->contains("ToolBarIconSize")){
    tbiconSize=mole.einstellung->value("ToolBarIconSize").toInt();
  }
  mole.einstellung->endGroup();
  tbiconSize=qMin(tbiconSize,96);
  tbiconSize=qMax(tbiconSize,16);
  fito->setIconSize(QSize(tbiconSize,tbiconSize));
  editToolBar->setIconSize(QSize(tbiconSize,tbiconSize));
  refineToolBar->setIconSize(QSize(tbiconSize,tbiconSize));
  vito->setIconSize(QSize(tbiconSize,tbiconSize));
  extraTB->setIconSize(QSize(tbiconSize,tbiconSize));
  bottomToolBar->setIconSize(QSize(tbiconSize,tbiconSize));
  chgl->invertMouseZoom->setIconSize(QSize(tbiconSize,tbiconSize));
  quickReLoadButton->setIconSize(QSize(tbiconSize,tbiconSize));
  homeMe->setIconSize(QSize(tbiconSize,tbiconSize));
  zoomIn->setIconSize(QSize(tbiconSize,tbiconSize));
  zoomOut->setIconSize(QSize(tbiconSize,tbiconSize));
  ///
  {
    scalDlg  = new QDialog(this);
    scalDlg->setWindowTitle("Change screen-shot scalefactor");
    scalla = new QGridLayout();
    scalwla = new QLabel("Width: "); 
    scalhla = new QLabel("Height: "); 
    scalsla = new QLabel("Scalefactor: ");
    widthBox        = new QSpinBox();
    heightBox       = new QSpinBox();
    scalefBox = new QDoubleSpinBox();
    widthBox->setMinimum(32);
    widthBox->setMaximum(10000);
    widthBox->setSuffix(" pixels");
    widthBox->setObjectName("widthBox");
    heightBox->setMinimum(32);
    heightBox->setMaximum(10000);
    heightBox->setSuffix(" pixels");
    heightBox->setObjectName("heightBox");
    scalefBox->setMinimum(1);
    scalefBox->setMaximum(400.0);
    scalefBox->setSuffix(" %");
    scalefBox->setValue(scalePic*100.0);
    scalefBox->setObjectName("scalefBox");
    header = new QLabel("<h3>Change screen-shot scalefactor</h3>");
    scalla->addWidget(header   ,0,0,1,3);
    scalla->addWidget(scalwla      ,1,0);
    scalla->addWidget(widthBox ,1,1);
    scalla->addWidget(scalhla      ,2,0);
    scalla->addWidget(heightBox,2,1);
    scalla->addWidget(scalsla      ,3,0);
    scalla->addWidget(scalefBox,3,1);
    scalDlg->setLayout(scalla);
    scalDlg->hide();
    connect(widthBox,SIGNAL(valueChanged(int)),this,SLOT(updateScaleDlg()));
    connect(heightBox,SIGNAL(valueChanged(int)),this,SLOT(updateScaleDlg()));
    connect(scalefBox,SIGNAL(valueChanged(double)),this,SLOT(updateScaleDlg()));
  }
  /////////////
  toggDocWid(true);
  raise();
  double vang=0;

#if (QT_VERSION >= 0x040600)
  dirName = (QProcessEnvironment::systemEnvironment ().value("PWD",dirName));
#else
  {
    QStringList env = QProcess::systemEnvironment();
    int da = env.indexOf(QRegExp("^PWD=.*$"));
    if (da>-1) {
      dirName = QString(env.at(da)).remove(0,4);  
    }
  }
#endif
  QString ffna="";
  startFused=false;
  int argc=QCoreApplication::arguments().size();
  if (argc>1){
    for (int i=1;i<argc;i++){
      if ((QCoreApplication::arguments().at(i)=="-fcf6")) fxle->MYFCF=true;
      if ((QCoreApplication::arguments().at(i).contains(".ins",Qt::CaseInsensitive)) ||
          (QCoreApplication::arguments().at(i).contains(".res",Qt::CaseInsensitive)))
        ffna=QCoreApplication::arguments().at(i);
      if ((QCoreApplication::arguments().at(i)=="-fused")) startFused=true;
      if ((QCoreApplication::arguments().at(i)=="-HKLMAX")) fxle->HKLMX = QCoreApplication::arguments().at(i+1).toInt();
      if ((QCoreApplication::arguments().at(i)=="-viewangle")) vang = QCoreApplication::arguments().at(i+1).toDouble();
      if ((QCoreApplication::arguments().at(i)=="-voxel")) fxle->voxelstr = QCoreApplication::arguments().at(i+1);
      if ((QCoreApplication::arguments().at(i)=="-wt")) {
        chgl->dratpause = QCoreApplication::arguments().at(i+1).toInt();
        printf("Wire pause %f seconds\nThis is the time the wired model is shown after rotation, zoom etc.",chgl->dratpause*0.001);
      }
    }
  }
  chgl->pause=false;
  //printf("%d\n",__LINE__);
  chgl->updateGL();
  if (vang>0.0) chgl->setViewAngle(vang);

  mole.einstellung->beginGroup("ViewSettings");
  if (mole.einstellung->contains("OrthographicProjection")) {
    bool b=mole.einstellung->value("OrthographicProjection").toBool();
    toggleOrthoView->setChecked(b);
    //toggleOrtho(b);
  }
  mole.einstellung->endGroup();
  qPeakDock->setVisible(true);
  if (!ffna.isEmpty()) {
    dirName=ffna;
    QTimer::singleShot(200,this,SLOT(loadAFile()));
  }else {
    QTimer::singleShot(200,qPeakDock,SLOT(hide()));
  }
  //printf("Window constructor finished.\n");
#include "WhatsThisAndWhere.cpp"  
}

Window::~Window() {
  if (calcmenu!=NULL) delete calcmenu;//only delete it if it has bee created. (seg fault)
  if (dsr!=NULL) delete dsr;
  delete sortMenu;
  delete hidwillpse;
  delete fxle;
}

int Window::Version(){
  return Revision;
}

void Window::hereAreMyKeys(){
    actionInfo.clear();
    actionInfo.append("<table>");
    QWidgetList wl = QApplication::allWidgets();
    QStringList shorts;
    for (int i=0; i<wl.size(); i++){
         QList<QAction *> acs = wl.at(i)->actions();
         for (int j=0; j<acs.size(); j++){
             QString st=acs.at(j)->shortcut().toString();
             QIcon ic=acs.at(j)->icon();
             if (!st.isEmpty()){
                 QString kb=acs.at(j)->shortcut().toString().replace(QRegExp("\\+"),"]&nbsp;+&nbsp;[");
                 kb=kb.replace("+&nbsp;[]&nbsp;+&nbsp;[","+&nbsp;[+");
#if defined (Q_OS_MAC)
                 kb=kb.replace("Ctrl","&#8984;");//clover CMD
                 kb=kb.replace("Meta","&#8963;");//Ctrl
                 kb=kb.replace("Alt","&#8997;");//Opt
                 kb=kb.replace("Shift","&#8679;");//shift/
#endif
                 QString ac=acs.at(j)->text();
                 int und=ac.indexOf('&');
                 if (und!=-1) {
                     ac=ac.insert(und+2,"</u>");
                     ac=ac.replace('&',"<u>");
                 }
                 ac[0]=ac[0].toUpper();
                 ac=ac.replace(' ',"&nbsp;");
                 shorts.append(QString("<td><b>[%2]</b></td><td>%1</td>").arg(ac).arg(kb));
             }
        }
    }
    shorts.sort();
    shorts.removeDuplicates();
    for (int i=0; i<shorts.size();i++){
        if ((i%2)==0) actionInfo.append(QString("<tr>%1\n").arg(shorts.at(i)));
        else actionInfo.append(QString("%1</tr>\n").arg(shorts.at(i)));
    }
    actionInfo.append("</table><br>Try Whats This on empty menu parts for more.");
    QMessageBox::information(this, "ShelXle Key Bindings", actionInfo);
}

void Window::fileNative(){
    mole.einstellung->beginGroup("Window");
    mole.einstellung->setValue("nativeDialogs",useNativeDlg->isChecked());
    mole.einstellung->endGroup();
}

void Window::darkEdit(){

    bool b=darkTheme->isChecked();
    bool classic=false;
    if (QString(PROGRAM_NAME).compare("shelXle")){
        b=false;
        classic=true;
    }
    maybeSave();
    editor->dark=xlPutor->dark=b;
    qpv->dark=b;
    if (b){
        editor->highlighter->loadHighlightPatterns(inspatternfile_dark);
        xlPutor->highlighter->loadHighlightPatterns(lstpatternfile_dark);
        QFile f(":dark/dstyle.qss");

        if (!f.exists())   {
            printf("Unable to set stylesheet, file not found\n");
        }
        else   {
            f.open(QFile::ReadOnly | QFile::Text);
            QTextStream ts(&f);
            QString stle=ts.readAll();
            if (!classic){
            qApp->setStyleSheet(stle);
            printf("darkstyle dark!\n");
            }

        }
        QPalette p = editor->palette();
        p.setColor(QPalette::Base,QColor("#1e1e1e"));
        p.setColor(QPalette::WindowText,QColor("#c8c8c8"));
        p.setColor(QPalette::Text,QColor("#c8c8c8"));
        editor->setPalette (p );
        p = xlPutor->palette();
        p.setColor(QPalette::Base,QColor("#1e1e1e"));
        p.setColor(QPalette::WindowText,QColor("#c8c8c8"));
        p.setColor(QPalette::Text,QColor("#c8c8c8"));
        xlPutor->setPalette (p );
        xlPutor->setStyleSheet("QPlainTextEdit {\nbackground-color: #19232D;\ncolor: #E0E1E3;\nborder-radius: 4px;\nborder: 1px solid #455364;\n}");
    }else{
        editor->highlighter->loadHighlightPatterns(inspatternfile);
        xlPutor->highlighter->loadHighlightPatterns(lstpatternfile);
        QFile f(":light/lstyle.qss");

        if (!f.exists())   {
            printf("Unable to set stylesheet, file not found\n");
        }
        else   {
            f.open(QFile::ReadOnly | QFile::Text);
            QTextStream ts(&f);
            QString stle=ts.readAll();
            if (!classic){
            qApp->setStyleSheet(stle);
            printf("darkstyle light!\n");
            }

        }
        QPalette p = xlPutor->palette();
        p.setColor(QPalette::WindowText,QColor("#000000"));
        p.setColor(QPalette::Text,QColor("#000000"));
        p.setColor(QPalette::Base,QColor("#ffffff"));
        editor->setPalette (p );
        p.setColor(QPalette::Base,QColor("#ffffe6"));
        xlPutor->setStyleSheet("QPlainTextEdit {\nbackground-color: #FFFFE6;\ncolor: #19232D;\nborder-radius: 4px;\nborder: 1px solid #C9CDD0;\n}");
        xlPutor->setPalette (p );
    }
    mole.einstellung->beginGroup("Colors");
    mole.einstellung->setValue("darkTheme",darkTheme->isChecked());
    mole.einstellung->endGroup();
    if (editor->isVisible()){
        //printf("reload file!\n");
        loadAFile();
    }
    mole.einstellung->beginGroup("Fonts");
    if (mole.einstellung->contains("EditorFont")){
      QFont fnt;
      fnt = mole.einstellung->value("EditorFont").value<QFont>();
  #if (QT_VERSION >= 0x040700)
      fnt.setStyleStrategy(QFont::ForceIntegerMetrics);
  #endif
      editor->setFont(fnt);
      xlPutor->setFont(fnt);
    }
    mole.einstellung->endGroup();
    update();
}

void Window::updateTwinTest(){
    printf("\n\nUPDATE TWIN TEST\n");
    Matrix M[6];
    M[0] =Matrix ( 0,  1, 0,  1,  0, 0, 0, 0, -1);
    M[1] =Matrix ( 0, -1, 0, -1,  0, 0, 0, 0, -1);
    M[2] =Matrix (-1,  0, 0,  0, -1, 0, 0, 0,  1);
    M[3] =Matrix ( 1,  0, 0,  0, -1, 0, 0, 0, -1);
    M[4] =Matrix (-1,  0, 0,  0, -1, 0, 0, 0, -1);
    M[5] =Matrix ( 1,  0, 0,  0,  1, 0, 0, 0,  1);
    QString dn=dirName.section('/',0,-2);
    //QString hkl=dirName;
    //hkl=hkl.replace(QRegExp("(.ins$)|(.res$)",Qt::CaseInsensitive),".hkl");
    QString wd=QString("%1/twintest/").arg(dn);    
    bool didsomething=false;
    for (int m=0; m<6; m++){
        if (twinRedundant.at(m)) continue;
        if (twinDone.at(m)) continue;
        didsomething=true;
        //QString insnam=QString("%1test%2.ins").arg(wd).arg(m);
        //QString insnambase=QString("test%1").arg(m);

        QString resnam=QString("%1test%2.res").arg(wd).arg(m);
        QFile res(resnam);
        if (res.open(QIODevice::ReadOnly|QIODevice::Text)){
        printf("resname=%s\n",resnam.toStdString().c_str());
        QString inhalt=res.readAll();
        res.close();
        if (inhalt.isEmpty()) continue;
        QStringList basfs=inhalt.section("\nBASF ",1).section("\n",0,0).trimmed().split(" ",skipEmptyParts);
        bool maybe=true;
        if (!basfs.isEmpty()) {
           double basf=basfs.at(0).toDouble();
            printf("BASF %f\n",basf);
            maybe=((basf>0.04)&&(basf<0.96));
        }        
        inhalt = inhalt.section("\nHKLF ",1);

        QStringList sl2 = inhalt.section("REM wR2 =",1).section("\n",0,0).trimmed().split(",",skipEmptyParts);
        //REM R1 =  0.0150 for   6927 Fo > 4sig(Fo)  and  0.0160 for all   7220 data
        QStringList sl = inhalt.section("REM R1 =",1).section("\n",0,0).trimmed().split(" ",skipEmptyParts);
        if (sl.size()<11)continue;
        if (sl2.size()<1) maybe=maybe&&(sl.at(0).toDouble()*100.0<=(rvalue2beat+0.075));
        else maybe=maybe&&(sl2.at(0).toDouble()*100.0<=(wr2value2beat+0.075));
        /*printf("m=%d R1  %5.2f %d all %5.2f %d %s (%f)\n",
               m,
            sl.at(0).toDouble()*100.0,
            sl.at(2).toInt(),
            sl.at(7).toDouble()*100.0,
            sl.at(10).toInt(),
            (maybe)?"probably a twin":"not realy likely a suitabe twin law",
            rvalue2beat
            );*/
        QString Label= QString("TWIN %1 %2 %3   %4 %5 %6   %7 %8 %9 %10")
            .arg(M[m].m11).arg(M[m].m21).arg(M[m].m31)
            .arg(M[m].m12).arg(M[m].m22).arg(M[m].m32)
            .arg(M[m].m13).arg(M[m].m23).arg(M[m].m33)
                .arg((m==5)?"= no twin law for comparison":"");
        QGroupBox *gpx2 = new QGroupBox(Label,twinDlg);

        gpx2->setAlignment(Qt::AlignRight);
        gpx2->setCheckable(true);
        gpx2->setChecked(maybe);

        QVBoxLayout *v = new QVBoxLayout(gpx2);
        QHBoxLayout *hbl1 = new QHBoxLayout();
        double basfv=basfs.at(0).toDouble();
        QLabel *R1lab = new QLabel(QString("R1=%1\nafter applying\ntwin law").arg(sl.at(0).toDouble()*100.0,0,'f',2),twinDlg);
        R1lab->setStyleSheet(QString("QLabel { background-color : %1; color : white; }").arg(hw->rwert_farbverlauf(sl.at(0).toDouble()*300.0).name()));
        if (sl2.size()>0){
        QLabel *wR2lab = new QLabel(QString("wR2=%1\nafter applying\ntwin law").arg(sl2.at(0).toDouble()*100.0,0,'f',2),twinDlg);
        wR2lab->setStyleSheet(QString("QLabel { background-color : %1; color : white; }").arg(hw->rwert_farbverlauf(sl2.at(0).toDouble()*300.0).name()));
        QLabel *beatlab = new QLabel(QString("curent \nR1 =%1\nwR2= %2").arg(rvalue2beat,0,'f',2).arg(wr2value2beat,0,'f',2),twinDlg);
        beatlab->setStyleSheet(QString("QLabel { background-color : qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 %1, stop: 1 %2); color : white; }")
                               .arg(hw->rwert_farbverlauf(rvalue2beat*3.0).name())
                               .arg(hw->rwert_farbverlauf(wr2value2beat*3.0).name()));

        QLabel *BASFlab = new QLabel(QString("BASF = %1").arg(basfv,0,'f',4),twinDlg);
        BASFlab->setStyleSheet(QString("QLabel { background-color : %1; color : white; }").arg(((basfv>0.04)&&(basfv<0.96))?"#009933":"#990033"));
        hbl1->addWidget(beatlab);
        hbl1->addWidget(R1lab);
        hbl1->addWidget(wR2lab);
        hbl1->addWidget(BASFlab);
        }else{// old xl versions do not rem the wR2 value
            QLabel *beatlab = new QLabel(QString("curent \nR1 =%1").arg(rvalue2beat,0,'f',2),twinDlg);
            beatlab->setStyleSheet(QString("QLabel { background-color : %1; white; }")
                                   .arg(hw->rwert_farbverlauf(rvalue2beat*3.0).name())
                                   );

            QLabel *BASFlab = new QLabel(QString("BASF = %1").arg(basfv,0,'f',4),twinDlg);
            BASFlab->setStyleSheet(QString("QLabel { background-color : %1; color : white; }").arg(((basfv>0.04)&&(basfv<0.96))?"#009933":"#990033"));
            hbl1->addWidget(beatlab);
            hbl1->addWidget(R1lab);
            hbl1->addWidget(BASFlab);
        }
        //if (maybe){
            QAction *tryThisTwin = new QAction("insert this twin \nlaw in res file",twinDlg);
            tryThisTwin->setEnabled(maybe);
            tryThisTwin->setData(QString("%1\nBASF %2\n").arg(Label).arg(basfv,0,'f',4));
            connect(tryThisTwin,SIGNAL(triggered()),this,SLOT(insertTwin()));
            connect(tryThisTwin,SIGNAL(triggered()),twinDlg,SLOT(reject()));
            QToolButton *button =new QToolButton(twinDlg);
            button->setDefaultAction(tryThisTwin);
            connect(gpx2,SIGNAL(toggled(bool)),button,SLOT(setEnabled(bool)));
            if (m==5) {
                gpx2->setChecked(false);
                gpx2->setCheckable(false);
                button->setEnabled(false);
            }
            //button->setEnabled(maybe);
            hbl1->addWidget(button);
        //}
        v->addLayout(hbl1);

        twinvbl->addWidget(gpx2);

        twinDone[m]=true;
        twingpx->adjustSize();
        }
}// */
    if (didsomething){
        twinDlg->update();
        twinDlg->show();
    }else {twinpatlab->hide();}
}

void Window::testMerohedral(){
    Matrix M[6];
    M[0] =Matrix ( 0,  1, 0,  1,  0, 0, 0, 0, -1);
    M[1] =Matrix ( 0, -1, 0, -1,  0, 0, 0, 0, -1);
    M[2] =Matrix (-1,  0, 0,  0, -1, 0, 0, 0,  1);
    M[3] =Matrix ( 1,  0, 0,  0, -1, 0, 0, 0, -1);
    M[4] =Matrix (-1,  0, 0,  0, -1, 0, 0, 0, -1);
    M[5] =Matrix ( 1,  0, 0,  0,  1, 0, 0, 0,  1);
    twinRedundant.clear();
    twinDone.clear();
    for (int i=0; i<mole.cell.symmops.size(); i++){
        for (int m=0; m<6;m++){
            twinRedundant.append(false);
            twinDone.append(false);
            if ((m==4)&&(mole.cell.centeric)) twinRedundant[m]=true;
            Matrix tm=M[m]*mole.cell.symmops.at(i);

            if (m!=5) for (int n=0; n<m; n++){
                if ((i>0)&&(m!=n)&&(tm==M[n])) {printf("Matrix %d %d %d is redundant\n",m,i,n);
                    twinRedundant[m]=true;
                    printf("\nX%9.3f %9.3f %9.3f\nX%9.3f %9.3f %9.3f\nX%9.3f %9.3f %9.3f\n\n"
                           ,tm.m11
                           ,tm.m21
                           ,tm.m31
                           ,tm.m12
                           ,tm.m22
                           ,tm.m32
                           ,tm.m13
                           ,tm.m23
                           ,tm.m33
                           );
                }
            }
        }
    }

    QFile res(dirName);
    res.open(QIODevice::ReadOnly|QIODevice::Text);
    QString inhalt=res.readAll();
    res.close();
    inhalt = inhalt.section("\nHKLF ",1);
    //REM wR2 = 0.176801, GooF = S = 1.14341, Restrained GooF = 1.14341 for all data
    QStringList sl2 = inhalt.section("REM wR2 =",1).section("\n",0,0).trimmed().split(",",skipEmptyParts);
    //REM R1 =  0.0150 for   6927 Fo > 4sig(Fo)  and  0.0160 for all   7220 data
    QStringList sl = inhalt.section("REM R1 =",1).section("\n",0,0).trimmed().split(" ",skipEmptyParts);
    rvalue2beat=99.0;
    wr2value2beat=99.0;
    if (sl.size()>10) rvalue2beat=sl.at(0).toDouble()*100.0;
    if (sl2.size()>1) wr2value2beat=sl2.at(0).toDouble()*100.0;
    QString dn=dirName.section('/',0,-2);
    QString hkl=dirName;
    hkl=hkl.replace(QRegExp("(.ins$)|(.res$)",Qt::CaseInsensitive),".hkl");
    QString wd=QString("%1/twintest/").arg(dn);
    QDir work=QDir(wd);
    if (!work.exists()) work.mkdir(wd);
    else{
        QStringList filter;
        filter << QString("*.*");
        QStringList files;
        files=work.entryList(filter,QDir::Files);
        for (int i=0; i<files.size(); i++){
            printf("remove %s ok=%d\n",files.at(i).toStdString().c_str(),
                work.remove(files.at(i)));
        }
    }
    //shelxl->setWorkingDirectory(wd);
    //qDebug()<<shelxlPath;
    for (int m=0; m<6; m++){
        if (twinRedundant.at(m)) continue;
        QString insnam=QString("%1test%2.ins").arg(wd).arg(m);        
        QFile::copy(dirName,insnam);
        printf("COPY %s to %s.\n",dirName.toStdString().c_str(),insnam.toStdString().c_str());
        QFile::copy(hkl,QString("%1test%2.hkl").arg(wd).arg(m));
    }
    if (twinDlg) {
        twinDlg->hide();
        delete twinDlg;
    }
    twinDlg = new QDialog(this);

    twingpx =new QGroupBox("Possible twin laws for this structure:",twinDlg);
    twinvbl = new QVBoxLayout();
    QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Cancel,Qt::Horizontal,twinDlg);
    connect(bb, SIGNAL(rejected()), twinDlg, SLOT(reject()));
    twingpx->setLayout(twinvbl);
    QVBoxLayout *la = new QVBoxLayout();
    QScrollArea *qsa = new QScrollArea(twinDlg);
    twingpx->setMinimumSize(590,650);
    qsa->setWidget(twingpx);
    qsa->setMinimumSize(600,660);
    la->addWidget(qsa);
    la->addWidget(bb);
    twinDlg->setLayout(la);
    twinvbl->addWidget(twinpatlab = new QLabel("...please wait until some twin laws are checked..."));
    updateTwinTest();
    //QList<QCheckBox *> alleboxen;
    //QSignalMapper *map = new QSignalMapper(this);






    for (int m=0; m<6; m++){
        if (twinRedundant.at(m)) continue;
        QString insnam=QString("%1test%2.ins").arg(wd).arg(m);
        QString insnambase=QString("test%1").arg(m);
        QProcess *shelxl0 = new QProcess(this);
        shelxl0->setWorkingDirectory(wd);
        QFile f(insnam);
        f.open(QIODevice::ReadOnly|QIODevice::Text);
        QString all = f.readAll();
        f.close();
        all=all.replace(QRegExp("\nACTA[^\n]*\n",Qt::CaseInsensitive),"\n");//no acta!
        all=all.replace(QRegExp("\nTWIN[^\n]*\n",Qt::CaseInsensitive),"\n");//no TWIN!
        all=all.replace(QRegExp("\nBASF[^\n]*\n",Qt::CaseInsensitive),"\n");//no basf!
        all=all.replace(QRegExp("\nAFIX[^\n]*\n",Qt::CaseInsensitive),"\n");//no afix!
        all=all.replace(QRegExp("\nL.S.[^\n]*\n",Qt::CaseInsensitive),"\n");//no L.S.!

        int unitpos=all.indexOf("UNIT",0,Qt::CaseInsensitive);
        int afterunitpos=all.indexOf("\n",unitpos);
        all=all.insert(afterunitpos+1,QString("TWIN %1 %2 %3 %4 %5 %6 %7 %8 %9 2\nBASF 0.41\nL.S. 10\nAFIX 6\n")
                   .arg(M[m].m11).arg(M[m].m21).arg(M[m].m31)
                   .arg(M[m].m12).arg(M[m].m22).arg(M[m].m32)
                   .arg(M[m].m13).arg(M[m].m23).arg(M[m].m33));
        f.open(QIODevice::WriteOnly|QIODevice::Text);
        f.write(all.toLatin1());
        f.close();
        QStringList al;
        al.append(insnambase);
        connect(shelxl0,SIGNAL(finished(int,QProcess::ExitStatus)),this,SLOT(updateTwinTest()));
        connect(shelxl0,SIGNAL(error(QProcess::ProcessError)),this,SLOT(updateTwinTest()));
        shelxl0->start(shelxlPath,al);
        //shelxl0->waitForFinished();
        //fprintf(stderr,"\n!![%s]\n",shelxl0->readAllStandardOutput().data());
        //fprintf(stderr,"\n!![%s]\n",shelxl0->readAllStandardError().data());

    }
    QTimer::singleShot(5000,twinpatlab,SLOT(hide()));

}
void Window::insertTwin(){
    QAction *action = qobject_cast<QAction *>(sender());
    QString insertthis;
    if (action)
      insertthis=action->data().toString();
    else return;
    QTextDocument *document = editor->document();
    QTextCursor cursor = editor->textCursor();
    cursor.beginEditBlock();
    editor->replace->setText("");
    editor->searchLE->setText("^TWIN");
    editor->wholeLine->setChecked(true);
    editor->replaceAll();
    editor->searchLE->setText("^BASF");
    editor->replaceAll();
    editor->replace->setText("");
    editor->searchLE->setText("");
    editor->wholeLine->setChecked(false);
    cursor.movePosition(QTextCursor::Start);
    cursor = document->find(QRegExp("^UNIT",Qt::CaseInsensitive),cursor);
    cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
    cursor.movePosition(QTextCursor::Down,QTextCursor::MoveAnchor);
    cursor.insertText(insertthis);
    cursor.endEditBlock();

}
void Window::idleRotStart(){
    if ((ydleStart!=NULL)&&(ydleStop!=NULL)){
     ydleStart->setVisible(false);
     ydleStop->setVisible(true);
     ydleStart->setEnabled(false);
     ydleStop->setEnabled(true);
    }
    chgl->idl = new QTimer(this);
    chgl->idl_end = new QTimer(this);
    connect(chgl->idl, SIGNAL(timeout()), chgl, SLOT(rotateIdle( )));
    connect(this,SIGNAL(movedByUser()), this, SLOT(idleRotStop()));
    if (chgl!=NULL) connect(chgl,SIGNAL(movedByUser()), this, SLOT(idleRotStop()));//we have a signal in chgl as well
    chgl->idl->start(5);
    chgl->idl_end->singleShot(36000,this,SLOT(idleRotStop()));//stop this after ca 10 rotations 360/0.5 * 5 *10
    printf("start rotation %d\n",chgl->idl->timerId());
}

void Window::idleRotStop(){
    if ((ydleStart!=NULL)&&(ydleStop!=NULL)){
      ydleStart->setVisible(true);
      ydleStop->setVisible(false);
      ydleStart->setEnabled(true);
      ydleStop->setEnabled(false);
    }
    disconnect(this,SIGNAL(movedByUser()),this, SLOT(idleRotStop()));
    if (chgl!=NULL) {
        disconnect(chgl,SIGNAL(movedByUser()), this, SLOT(idleRotStop()));//we have a signal in chgl as well
        if (chgl->idl==NULL) return;
    }
    chgl->idl->stop();
    chgl->idl->disconnect();
    chgl->idl->deleteLater();
    printf("stop rotation\n");
}

void Window::setMonoQ(bool vis){
  mole.monoQrom=!vis;
  chgl->murx=64;
  chgl->updateGL();
}

void Window::foversusfc(){

  QString fcfname = dirName;
  fcfname.replace(QRegExp(".res$|.ins$", Qt::CaseInsensitive),".fcf");
  FcVsFo *d = new FcVsFo(fcfname,mole.cell.a, mole.cell.b, mole.cell.c, mole.cell.al, mole.cell.be, mole.cell.ga, mole.cell.wave);
  connect(d,SIGNAL(weg(const QString &)), editor,SLOT(omitsome(const QString &)));
  d->exec();
  delete d;
}

void Window::toggleHFSAO(bool on){
    mole.HFixSuitableAtomsOnly=on;
    mole.einstellung->beginGroup("HFIX");
    //HFixSuitableAtomsOnly=
    mole.einstellung->setValue("HFixSuitableAtomsOnly",on);
    mole.einstellung->endGroup();
}

void Window::togOMIT(bool b){
    QGroupBox *gpx = findChild<QGroupBox *>("worstReflectionsGPX");
    if (gpx!=nullptr){
        QList<QCheckBox *> ck = gpx->findChildren<QCheckBox *>();
        for (int i=0; i<ck.size();i++){
            ck[i]->setChecked(b);
        }
        update();
        //printf("toggled %d boxes...\n",ck.size());
    }else{
        printf("cant't find worstReflectionsGPX");
    }
}

void Window::selOmitG5(){
    QGroupBox *gpx = findChild<QGroupBox *>("worstReflectionsGPX");
    if (gpx!=nullptr){
        QList<QCheckBox *> ck = gpx->findChildren<QCheckBox *>();
        for (int i=0; i<ck.size();i++){
            ck[i]->setChecked(false);
            QString s=ck[i]->text();
            QStringList num = s.split(" ",skipEmptyParts);
            if ((num.size()==8)&&(num.at(5).toDouble()>5.0)){
                ck[i]->setChecked(true);
            }
        }
        update();
    }else{
        printf("cant't find worstReflectionsGPX");
    }
}

void Window::selOmitG10(){
    QGroupBox *gpx = findChild<QGroupBox *>("worstReflectionsGPX");
    if (gpx!=nullptr){
        QList<QCheckBox *> ck = gpx->findChildren<QCheckBox *>();
        for (int i=0; i<ck.size();i++){
            ck[i]->setChecked(false);
            QString s=ck[i]->text();
            QStringList num = s.split(" ",skipEmptyParts);
            if ((num.size()==8)&&(num.at(5).toDouble()>10.0)){
                ck[i]->setChecked(true);
            }
        }
        update();
    }else{
        printf("cant't find worstReflectionsGPX");
    }
}

void Window::omitRfl(){
    QGroupBox *gpx = findChild<QGroupBox *>("worstReflectionsGPX");
    if (gpx!=nullptr){
        QList<QCheckBox *> ck = gpx->findChildren<QCheckBox *>();
        QString omitstring;
        for (int i=0; i<ck.size();i++){
            if (ck[i]->isChecked()){
                QString s=ck[i]->text();
                QStringList num = s.split(" ",skipEmptyParts);
                omitstring.append(QString("OMIT %1 %2 %3\n").arg(num.at(0)).arg(num.at(1)).arg(num.at(2)));
            }
        }
        editor->omitsome(omitstring);
    }else{
        printf("cant't find worstReflectionsGPX");
    }
}

void Window::worstReflections(){
    QString listName=dirName;
    listName.replace(QRegExp(".ins$"),".lst");
    listName.replace(QRegExp(".res$"),".lst");
    QFile lstf(listName);
    if (lstf.open(QIODevice::ReadOnly|QIODevice::Text)){
        QDialog *mdr = new QDialog(this);
        QScrollArea *qsa = new QScrollArea(mdr);
        //mdr->set
        QGroupBox *gpx = new QGroupBox("Check Refelextions to omit.",mdr);
        gpx->setObjectName("worstReflectionsGPX");
        QVBoxLayout *lt = new QVBoxLayout(gpx);
        QVBoxLayout *la = new QVBoxLayout();
        QFont font;
        font.setFamily("Droid Sans Mono");
        la->addWidget(new QLabel("Most Disagreeable Reflections (* if suppressed or used for Rfree).\n\
Error/esd is calculated as sqrt(wD^2/<wD^2>) where w is given by the weight\n\
formula, D = Fo^2-Fc^2 and <> refers to the average over all reflections.",mdr));
        QCheckBox *allx;
        lt->addWidget(allx = new QCheckBox(QString("   h   k   l     Fo^2      Fc^2    Error/esd  Fc/Fc(max)  Resolution(A)")));
        connect(allx,SIGNAL(toggled(bool)),this, SLOT(togOMIT(bool)));
        allx->setFont(font);
      QStringList liste=QString(lstf.readAll()).split('\n');
      int moststart=liste.indexOf("     h   k   l          Fo^2          Fc^2    Error/esd  Fc/Fc(max)  Resolution(A)");
      if (moststart>0)for (int i=moststart+2; i<liste.size();i++){
          QStringList num=liste.at(i).split(" ",skipEmptyParts);
          if (num.size()==8){
              QCheckBox *bx;
              lt->addWidget(bx = new QCheckBox(QString("%1%2%3 %4 %5 %6 %7 %8")
                        .arg(num.at(0).toInt(),4)
                        .arg(num.at(1).toInt(),4)
                        .arg(num.at(2).toInt(),4)
                        .arg(num.at(3).toDouble(),10,'f',3)
                        .arg(num.at(4).toDouble(),10,'f',3)
                        .arg(num.at(5).toDouble(),10,'f',3)
                        .arg(num.at(6).toDouble(),10,'f',3)
                        .arg(num.at(7).toDouble(),10,'f',3)));
              bx->setFont(font);
              /*
              printf("%4d%4d%4d %10.3f %10.3f %10.3f %10.3f %10.3f\n"
                     ,num.at(0).toInt()
                     ,num.at(1).toInt()
                     ,num.at(2).toInt()
                     ,num.at(3).toDouble()
                     ,num.at(4).toDouble()
                     ,num.at(5).toDouble()
                     ,num.at(6).toDouble()
                     ,num.at(7).toDouble());*/
          }else break;
      }
      printf("Most Disagreeable Reflections %d %d\n", moststart,liste.size());
      gpx->setLayout(lt);
      qsa->setWidget(gpx);
      la->addWidget(qsa);
      QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Cancel,Qt::Horizontal,mdr);
      QPushButton *omit = bb->addButton("OMIT selected Refelections",QDialogButtonBox::AcceptRole);
      QPushButton *g5 = bb->addButton("select Refelections Error/esd > 5",QDialogButtonBox::ApplyRole);
      QPushButton *g10 = bb->addButton("select Refelections Error/esd > 10",QDialogButtonBox::ApplyRole);
      connect(omit,SIGNAL(clicked()),this,SLOT(omitRfl()));
      connect(g10,SIGNAL(clicked()),this,SLOT(selOmitG10()));
      connect(g5,SIGNAL(clicked()),this,SLOT(selOmitG5()));
      connect(bb, SIGNAL(accepted()), mdr, SLOT(accept()));
      connect(bb, SIGNAL(rejected()), mdr, SLOT(reject()));
      la->addWidget(bb);
      mdr->setLayout(la);
      mdr->exec();
      mdr->deleteLater();
    }
}

void Window::loadAFile(){
  mole.einstellung->beginGroup("Window");
  mole.einstellung->setValue("QuickReLoad",quickReLoadButton->isChecked());
  mole.einstellung->endGroup();
  loadFile(dirName);
}

void Window::openSaveHistory(){
  if ((dirName.isEmpty())||(!QFile::exists(dirName))) return;
  SaveHistoryWidget *shw = new SaveHistoryWidget(dirName,(QString(PROGRAM_NAME).compare("shelXle")==0)?darkTheme->isChecked():false);
  if (QDialog::Accepted==shw->exec()) {
    if ((quickReLoadButton->isChecked())) sdm();
    loadFile(dirName);
    if ((quickReLoadButton->isChecked())) sdm();
  }
  delete shw;
}

void Window::adoptEditToolBar(bool b){
  if (b) shxMW->addToolBar(editToolBar);
  else addToolBar(editToolBar);
  mole.einstellung->beginGroup("Window");
  mole.einstellung->setValue("EditorHasOwnToolBar",b);
  mole.einstellung->endGroup();
  update();
}

void Window::toggleEQHighlighting(bool b){
  mole.highlightEquivalents = b;
  chgl->updateGL();
}

void Window::toggleOrtho(bool ov){
  bool werdi=chgl->pause;
  chgl->pause=false;
  //printf("toggleOrtho %d\n",__LINE__);
  chgl->updateGL();
  if ((ov)&&(togDepthCueing->isChecked())){
      togDepthCueing->setChecked(false);
      chgl->setDepthCueing(false);
      //printf("toggleOrtho %d\n",__LINE__);
  }
  togDepthCueing->setDisabled(ov);
  chgl->setViewAngle((ov)?0.1:29.0);
  chgl->pause=werdi;
  mole.einstellung->beginGroup("ViewSettings");
  mole.einstellung->setValue("OrthographicProjection",ov);
  mole.einstellung->endGroup();
}

int Window::getFvarCntr(int fvar){
  return fvarCntr.value(fvar);
}

void Window::growQPeaks(bool qpg){
  mole.growQPeak=qpg;
  chgl->murx=__LINE__;
  bool growYes=chgl->fuse->isVisible ();
  chgl->mol->fuse();
  if (growYes) chgl->mol->grow();
  chgl->updateGL();
}

void Window::spellCheck(){
  QString t=editor->toPlainText();
  if (t==altText) return;
  altText=t;
  QRegExp rx=QRegExp("\\s|_");
  QRegExp nch=QRegExp("[^\"\\-~#%&$'`Â§()+\\*\\./@\\[\\]^\\\\{}\\|<>A-Za-z0-9]+");
  QString s,s0;
  QString meld;
  editor->errorInLine.clear();
  bool cont=false;
  QStringList sl;
  for (int i= 0;i< editor->blocks.size(); i++){  
    sl = editor->blocks.at(i).split(" ",skipEmptyParts);
    if (sl.isEmpty())continue;
    if ((cont)&&(editor->blocks.at(i).contains(QRegExp("^\\S+")))){
      editor->errorInLine.append(i-1);
      editor->errorInLine.append(i);
      meld+=QString("ERROR in line %1: Bad continuation line!<br>").arg(i);
    }
    cont=false;
    if (sl.isEmpty())continue;
    cont= (!(sl.at(0).contains(QRegExp("(^REM)|(^TITL)",Qt::CaseInsensitive)))&&(editor->blocks.at(i).contains(QRegExp("=\\s*$"))));
    if((editor->blocks.at(i).size()>SX_LINE_LENGTH)&&(!editor->blocks.at(i).contains(QRegExp("^\\s+")))){
      editor->errorInLine.append(i);
      meld+=QString("ERROR in line %1: Line is too long for SHELXL!<br>").arg(i+1);
    }
    if (editor->blocks.at(i).startsWith(" ")) continue;
    if (isacommand(sl.at(0))==-1){
      s0=sl.at(0).section(rx,0,0);
      if (s0.size()>4) {
        meld+=QString("ERROR in line %1: Atom label too long %2!<br>").arg(i+1).arg(sl.at(0));
        editor->errorInLine.append(i);
      }
      if (sl.at(0).contains(nch)) {
        meld+=QString("ERROR in line %1: Not allowed characters in atom label %2!<br>").arg(i+1).arg(sl.at(0));
        editor->errorInLine.append(i);
      }
      bool bb=true;
      if (sl.size()>1) {
        s=sl.at(1);
        int ii = s.toInt(&bb);
        if ((sl.size()>3)&&((ii<1)||(!bb))) {
          meld+=QString("ERROR in line %1: Scatering-factor number is missing or out of range!<br>").arg(i+1);
          editor->errorInLine.append(i);
        }
      }
    }
  }
  FehlerTeufel= !meld.isEmpty();
  if (FehlerTeufel) infoKanalNews("<font color=red size=+1>"+meld+"</font>");
  else infoKanalNews("");
  spellCheckact->setVisible(FehlerTeufel);
  spellCheckact2->setVisible(FehlerTeufel);
  editor->update();
}

void Window::exportCoordinates(){
  QString exportName = dirName;
  exportName.replace(QRegExp("(.ins)|(.res)",Qt::CaseInsensitive),"_EXPORTED.res");
  QString fn=QFileDialog::getSaveFileName(this, tr("Export all visible atoms"), exportName, tr("SHELX-files (*.res *.ins)"));
  if (fn.isEmpty()) return;
  QFile f(fn);
  QString body;
  body.append(QString("TITL %1\nCELL  %2 %3 %4 %5 %6 %7 %8\n%9\n")
      .arg(title) 
      .arg(mole.cell.wave  )
      .arg(mole.cell.a  )
      .arg(mole.cell.b  )
      .arg(mole.cell.c  )
      .arg(mole.cell.al )
      .arg(mole.cell.be )
      .arg(mole.cell.ga )
      .arg(mole.cell.Z )
      );
  body.append(QString("LATT -1\n"));
  for (int i=1; i<mole.cell.symmops.size();i++){
    body.append(QString("SYMM %1\n").arg(mole.symmcode2human(i)));
  }
  body.append(QString("SFAC "));
  for (int i=0; i<editor->sfac.size(); i++){
    body.append(QString("%1 ").arg(mole.pse(editor->sfac.at(i))));  
  }
  body.append("\n");
  body.append(editor->unitNeu);
  body.append(
      "\n\nREM ######################################################\n"
      "REM This file exported by ShelXle is for information or \n"
      "REM visualiztion purposes only. You may run into trouble \n"
      "REM if you try to refine it against data.\n"
      "REM DISABLE_REFINE\n"
      "REM ######################################################\n\n");
  body.append("FVAR 1.00 ");
  for (int i=0; i<fvar.size();i++){
    body.append(QString("%1 ").arg(fvar.at(i)));
  }
  body.append("\n\n");
  int part=0,resi=0;
  chgl->rehide();
  for (int i=0; i< mole.showatoms.size(); i++){
    if (mole.showatoms.at(i).hidden) continue;
    if ((mole.nopm1)&&(mole.showatoms.at(i).symmGroup)&&(mole.showatoms.at(i).part<-0)) continue; // ignore hidden parts (-1) 
    if ((mole.showatoms.at(i).an!=-42)&&(mole.showatoms.at(i).resiNr!=resi))
      body.append(QString("RESI %1 %2\n").arg(mole.showatoms.at(i).resiNr).arg(mole.showatoms.at(i).ResiClass));
    if ((mole.showatoms.at(i).an!=-42)&&(mole.showatoms.at(i).part!=part))
      body.append(QString("PART %1\n").arg(mole.showatoms.at(i).part));
    if (mole.showatoms.at(i).an==-1) 
      body.append(QString("%1 %2 %3 %4 %5 %6 %7 %8\n")
          .arg(mole.showatoms.at(i).Label.section('_',0,0).section(QString::fromUtf8("»"),0,0),-5)
          .arg(qMax(1,editor->sfac.indexOf(mole.showatoms.at(i).an)+1))
          .arg(mole.showatoms.at(i).frac.x,10,'f',6)
          .arg(mole.showatoms.at(i).frac.y,10,'f',6)
          .arg(mole.showatoms.at(i).frac.z,10,'f',6)
          .arg(mole.showatoms.at(i).sof_org,9,'f',5)
          .arg(mole.showatoms.at(i).uf.m33,9,'f',5)
          .arg(mole.showatoms.at(i).peakHeight,9,'f',2)
          );
    else if (mole.showatoms.at(i).an==-42){
      Matrix uf = mole.b2u(mole.showatoms.at(i).uf);
      body.append(QString("%1 %2 %3 %4 %5 %6 %7 %8 =\n    %9 %10 %11 %12\n")
          .arg(mole.showatoms.at(i).Label.section('_',0,0).section(QString::fromUtf8("»"),0,0),-5)
          .arg(2)
          .arg(mole.showatoms.at(i).frac.x,10,'f',6)
          .arg(mole.showatoms.at(i).frac.y,10,'f',6)
          .arg(mole.showatoms.at(i).frac.z,10,'f',6)
          .arg(mole.showatoms.at(i).sof_org,9,'f',5)
          .arg(uf.m11,9,'f',5)
          .arg(uf.m22,9,'f',5)
          .arg(uf.m33,9,'f',5)
          .arg(uf.m23,9,'f',5)
          .arg(uf.m13,9,'f',5)
          .arg(uf.m12,9,'f',5)
          );
    }
    else {if (mole.showatoms.at(i).isIso){
      body.append(QString("%1 %2 %3 %4 %5 %6 %7!x\n")
          .arg(mole.showatoms.at(i).Label.section('_',0,0).section(QString::fromUtf8("»"),0,0),-5)
          .arg(qMax(1,editor->sfac.indexOf(mole.showatoms.at(i).an)+1))
          .arg(mole.showatoms.at(i).frac.x,10,'f',6)
          .arg(mole.showatoms.at(i).frac.y,10,'f',6)
          .arg(mole.showatoms.at(i).frac.z,10,'f',6)
          .arg(mole.showatoms.at(i).sof_org,9,'f',5)
          .arg(mole.showatoms.at(i).ufiso_org)
          );
    }else{
      body.append(QString("%1 %2 %3 %4 %5 %6 %7 %8 =\n    %9 %10 %11 %12\n")
          .arg(mole.showatoms.at(i).Label.section('_',0,0).section(QString::fromUtf8("»"),0,0),-5)
          .arg(qMax(1,editor->sfac.indexOf(mole.showatoms.at(i).an)+1))
          .arg(mole.showatoms.at(i).frac.x,10,'f',6)
          .arg(mole.showatoms.at(i).frac.y,10,'f',6)
          .arg(mole.showatoms.at(i).frac.z,10,'f',6)
          .arg(mole.showatoms.at(i).sof_org,9,'f',5)
          .arg(mole.showatoms.at(i).uf.m11,9,'f',5)
          .arg(mole.showatoms.at(i).uf.m22,9,'f',5)
          .arg(mole.showatoms.at(i).uf.m33,9,'f',5)
          .arg(mole.showatoms.at(i).uf.m23,9,'f',5)
          .arg(mole.showatoms.at(i).uf.m13,9,'f',5)
          .arg(mole.showatoms.at(i).uf.m12,9,'f',5)
          );
    }}
    part=mole.showatoms.at(i).part;
    resi=mole.showatoms.at(i).resiNr;
  }

  body.append("\n\n"); 
  QString eqi=mole.symmcode2human(mole.usedSymmetry);
  eqi.replace("&raquo;","EQIV $");
  eqi.replace(":","");
  eqi.replace("<b>","");
  eqi.replace("</b>","");
  eqi.replace("<br>","\n");
  body.append(eqi);
  body.append("\n\n");
  for (int i =0; i<mole.showbonds.size();i++){
    if (mole.showbonds.at(i).ato1->hidden) continue; 
    if (mole.showbonds.at(i).ato2->hidden) continue;
    if ((mole.nopm1)&&(mole.showbonds.at(i).ato1->symmGroup)&&(mole.showbonds.at(i).ato1->part<0))continue; // 
    if ((mole.nopm1)&&(mole.showbonds.at(i).ato2->symmGroup)&&(mole.showbonds.at(i).ato2->part<0))continue; // ignore hidden parts (-1) 
    QString s1="",s2="",s3="";
    s1=mole.showbonds.at(i).ato1->Label;
    s2=mole.showbonds.at(i).ato2->Label;
    s1=s1.section(QString::fromUtf8("»"),0,0);
    s2=s2.section(QString::fromUtf8("»"),0,0);
    if ((mole.showbonds.at(i).ato2->symmGroup)||(mole.showbonds.at(i).ato1->symmGroup))
      s3.append(QString("_$%1").arg(qMax(mole.showbonds.at(i).ato1->symmGroup,mole.showbonds.at(i).ato2->symmGroup)));
    body.append(QString("BIND%3 %1 %2\n")
        .arg(s1)
        .arg(s2)
        .arg(s3));
  }
  body.append("\nHKLF 0 !don't refine this\nEND\n");
  bool success = f.open(QIODevice::WriteOnly|QIODevice::Text);
  if (success){
    f.write(body.toLatin1());
    f.close();
  }
}

void Window::changeIconSize(){
  bool ok;
  int tbs=tbiconSize;

#if (QT_VERSION >= 0x040500)
  tbs=QInputDialog::getInt(this,"Change tool bar icon size...","Tool bar icon size:",tbiconSize,16,96,1,&ok); 
#else
  tbs=QInputDialog::getInteger(this,"Change tool bar icon size...","Tool bar icon size:",tbiconSize,16,32,1,&ok);
#endif  
  if (ok) tbiconSize=tbs;
  mole.einstellung->beginGroup("ToolBarIcons");
  mole.einstellung->setValue("ToolBarIconSize",tbiconSize);
  mole.einstellung->endGroup();
  fito->setIconSize(QSize(tbiconSize,tbiconSize));
  editToolBar->setIconSize(QSize(tbiconSize,tbiconSize));
  refineToolBar->setIconSize(QSize(tbiconSize,tbiconSize));
  vito->setIconSize(QSize(tbiconSize,tbiconSize));
  extraTB->setIconSize(QSize(tbiconSize,tbiconSize));
  bottomToolBar->setIconSize(QSize(tbiconSize,tbiconSize));
  chgl->invertMouseZoom->setIconSize(QSize(tbiconSize,tbiconSize));
  homeMe->setIconSize(QSize(tbiconSize,tbiconSize));
  zoomIn->setIconSize(QSize(tbiconSize,tbiconSize));
  zoomOut->setIconSize(QSize(tbiconSize,tbiconSize));
  update();
}

void Window::changeQPeakLimit(){
  bool ok;
  int limit=MaxNumberOfPeaks;

#if (QT_VERSION >= 0x040500)
  limit=QInputDialog::getInt(this,"Change maximum number of created Q-peaks","maximum number of created Q-peaks:",MaxNumberOfPeaks,1,600,1,&ok);
#else
  limit=QInputDialog::getInteger(this,"Change maximum number of created Q-peaks","maximum number of created Q-peaks:",MaxNumberOfPeaks,1,600,1,&ok);
#endif
  if (ok) MaxNumberOfPeaks=limit;
  actionQPeakLimit->setText(QString("change maximum number of created Q-peaks (%1)").arg(MaxNumberOfPeaks));
  update();
}

void Window::jnk(){
  if (!fxle->doMaps->isChecked())fxle->doMaps->setChecked(true);
  fxle->maptrunc=fxle->mapSchnitt->currentIndex (); 
  if ((fxle->rw!=fxle->weak->value())||(fxle->rr!=fxle->mapprec->value())){
    fxle->rr = fxle->mapprec->value();  
    fxle->rw = fxle->weak->value();
    if (!fxle->loadFouAndPerform(fxle->fouName.toLocal8Bit(),false)){
      infoKanalNews(QString("<font color=red>Error while loading %1!</font><br>").arg(fxle->fouName));
      //printf("%d\n",__LINE__);
      fxle->killmaps();
      //printf("%d\n",__LINE__);
    }
  }    
  chgl->lintrans = fxle->lineTrans->value();
  chgl->linwidth = fxle->lineWidth->value();
  fxle->map_radius = fxle->maprad->value();
  fxle->iso[0] = fxle->fomaps->value();
  fxle->iso[1] = -fxle->difmaps->value();
  fxle->jnk();
}

void Window::deleteAllQ(){

  if (editor->sfac.isEmpty()) return;
  bool isQ = false;
  for (int o = 0; o < mole.asymm.size();o++){
    if (mole.asymm.at(o).an == -1){
      isQ = true;
      break;
    }
  }
  if (!isQ) return;
  QTextCursor cursor = editor->textCursor();
  editor->wholeLine->setChecked(false);
  editor->replace->setText("");
  editor->searchLE->setText("^Q\\S+\\s+1\\s+\\S+\\s+\\S+\\s+\\S+\\s+\\S+\\s+\\S+\\s+\\S+\\s*");
  for (int i = mole.asymm.size()-1; i>=0; i-- ){
    if (mole.asymm.at(i).an==-1){
      QString s =
        QString("<font color=magenta>Deleted atom: %1 part:%2 residue:%3 %4 </font> Please save to update structure view.")
        .arg(mole.asymm.at(i).Label)
        .arg(mole.asymm.at(i).part)
        .arg(mole.asymm.at(i).resiNr)
        .arg(mole.asymm.at(i).ResiClass);
      infoKanalNews(s);
      deletedAtom.append(mole.asymm.at(i));
      mole.asymm.removeAt(i);
    }
  }
  editor->replaceAll();
  editor->searchLE->setText("");
  chgl->pause=true;
  mole.showatoms.clear();
  mole.showbonds.clear();
  chgl->mol->showatoms.clear();
  chgl->mol->showbonds.clear();
  chgl->mol->selectedatoms.clear();

  for (int o=0; o<mole.asymm.size();o++)
    mole.showatoms.append(mole.asymm[o]);
  mole.packer(mole.sdmcompleter());
  mole.showbonds =
    mole.connecting(mole.showatoms);
  bool growYes=chgl->fuse->isVisible ();
  if (growYes) chgl->mol->grow();
  else chgl->mol->fuse();
  if ((chgl->rotze!=-1)&&(!chgl->enviPositions.isEmpty())){
    chgl->envi();
  }
  chgl->mol->selectedatoms.clear();
  chgl->showHidden();
  chgl->murx=__LINE__;
  chgl->pause=false;
//  printf("%d\n",__LINE__);
  chgl->updateBondActions();
  chgl->updateGL();
  update();
  chgl->updateGL();
}

void Window::sdm(){
  if (!(chgl->fuse->isVisible()||chgl->grow->isVisible ())){
    chgl->fuse->setVisible(true);
    chgl->grow->setVisible(false);
  }
  mole.showatoms.clear();
  mole.showbonds.clear();
  chgl->mol->showatoms.clear();
  chgl->mol->showbonds.clear();
  chgl->mol->selectedatoms.clear();
  for (int o=0; o<mole.asymm.size();o++)
    mole.showatoms.append(mole.asymm[o]);    
  mole.packer(mole.sdmcompleter());    
  mole.showbonds =
    mole.connecting(mole.showatoms);    
  chgl->mol->selectedatoms.clear();
  chgl->murx=__LINE__;
  bool growYes=chgl->fuse->isVisible ();
  chgl->mol->fuse();    
  if (growYes) chgl->mol->grow();
  chgl->pause=false;
//  printf("%d\n",__LINE__);
  chgl->updateBondActions();
  infoKanalNews(mole.Fragments);
  chgl->updateGL();
  update();
  chgl->updateGL();
}

void Window::makeVoro(){
  int ind=-1;
  QAction *action = qobject_cast<QAction *>(sender());
  if (action!=NULL){
      ind=action->data().toInt();
      ind=qMax(ind,-1);
      ind=qMin(ind,mole.asymm.size()-1);
  }
  clearVoro->setVisible(true);
  mole.voronoij(mole.asymm,ind); 
  infoKanalNews(mole.voroMsg); 
  chgl->updateGL();
}

void Window::clearVoros(){
  mole.vtriangles.clear();
  mole.vorobas=0;
  clearVoro->setVisible(false);
  chgl->updateGL();
}

void Window::deleteAllH(){
  if (editor->sfac.isEmpty()) return;
  bool isH = false;
  for (int o = 0; o < mole.asymm.size(); o++){
    if (mole.asymm.at(o).an == 0){
      isH = true;
      break;
    }
  }
  if (!isH) return;
 /* maybeSave2();
  printf("deleteallh %d %d\n",mole.asymm.size(),chgl->mol->showatoms.size());*/
  chgl->mol->selectedatoms.clear();
  for (int o = 0; o < mole.asymm.size(); o++){
    if (mole.asymm.at(o).an == 0){
        chgl->mol->selectedatoms.append(chgl->mol->showatoms[o]);
        chgl->mol->selectedatoms.last().style=o;
    }
  }
  deleteSelectedAtoms();
}

void Window::deleteSelectedAtoms(){
  if (chgl->mol->selectedatoms.isEmpty()){
    QAction *action = qobject_cast<QAction *>(sender());
    int index=-1;
    if (action)
      index=action->data().toInt();
    else index=-1;
    if (index>mole.asymm.size()) index=-1;
    if (index!=-1) {
      chgl->mol->selectedatoms.clear();
      chgl->mol->selectedatoms.append(chgl->mol->showatoms[index]);
      chgl->mol->selectedatoms.last().style=index;
    }
  }
  if (chgl->mol->selectedatoms.isEmpty()) return;
  chgl->pause=true;
  bool donotsymm=false;
  QTextCursor cursor = editor->textCursor();
  QTextDocument *document = editor->document();
  cursor.beginEditBlock();
  int ende=chgl->mol->selectedatoms.size();
  for (int i = 0; i < ende; i++ ){
    if (chgl->mol->selectedatoms.at(i).symmGroup) continue;
    if (chgl->mol->selectedatoms.at(i).Label.contains(QString::fromUtf8("»")))continue;
    if ((chgl->mol->selectedatoms.at(i).afix>0)&&(chgl->mol->selectedatoms.at(i).an>0)) continue;
    int wg=chgl->mol->selectedatoms.at(i).style;
    QString  label = mole.asymm.at(wg).orginalLine.left(80).trimmed();
    cursor.movePosition(QTextCursor::Start);
    cursor = document->find(label,cursor);
    if (cursor.isNull()){
      cursor = editor->textCursor();
      cursor.movePosition(QTextCursor::Start);
      label.chop(10);
      cursor = document->find(label,cursor);
      if (cursor.isNull()) {
        cursor = editor->textCursor();
        printf("hab was nicht %d/%d %d [%s]\n",i,ende,chgl->mol->selectedatoms.size(),label.toStdString().c_str());
        continue;
      }
    }
    cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
    //printf("wg2160->%d %s\n",wg,label.toStdString().c_str());
    bool afx=false;
    if (editor->parenthesis.at(cursor.blockNumber())){
      afx=true;
      do {
        if (!cursor.block().text().contains("afix",Qt::CaseInsensitive)) wg--;
        cursor.movePosition(QTextCursor::Up,QTextCursor::MoveAnchor);
      }while(!cursor.block().text().contains("afix",Qt::CaseInsensitive));
      cursor.movePosition(QTextCursor::Down,QTextCursor::KeepAnchor);
    }
    //printf("wg2168->%d [%s] {%s}\n",wg,cursor.selectedText().toStdString().c_str(),cursor.block().text().toStdString().c_str());
    cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
    while (cursor.selectedText().endsWith("=")) {
      cursor.movePosition(QTextCursor::Down,QTextCursor::KeepAnchor);
      cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
    }
    int haa=1;
    if (afx)
    while (!cursor.block().text().contains("afix",Qt::CaseInsensitive)){
      cursor.movePosition(QTextCursor::Down,QTextCursor::KeepAnchor);
      cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
      if ((!cursor.block().text().contains("afix",Qt::CaseInsensitive))&&(wg+haa)<chgl->mol->showatoms.size()){
        chgl->mol->selectedatoms.append(chgl->mol->showatoms.at(wg+haa));
        chgl->mol->selectedatoms.last().style=wg+haa;
        haa++;
      }
    /*  printf("wg+ =%d %d/%d %d\n",wg+haa,cursor.blockNumber()+2,(editor->parenthesis.size()),editor->blockCount());
      printf("[[%s]]\n", cursor.selectedText().toStdString().c_str());
      printf("%d %d!\n",editor->parenthesis.at(cursor.blockNumber()+1),editor->parenthesis.at(cursor.blockNumber()+2));
    */
    }
    //printf("wg2191->[%s]\n",cursor.selectedText().toStdString().c_str());
    cursor.deleteChar();
    cursor.deleteChar();
    editor->updateAfix();    
  }

  for (int i = chgl->mol->selectedatoms.size()-1; i>=0; i-- ){
    if (chgl->mol->selectedatoms.at(i).Label.contains(QString::fromUtf8("»"))){donotsymm=true;continue;}
    if (chgl->mol->selectedatoms.at(i).symmGroup){donotsymm=true;continue;}
    QString s =
      QString("<font color=magenta>Deleted atom: %1 part:%2 residue:%3 %4 </font> Please save to update structure view.")
      .arg(chgl->mol->selectedatoms.at(i).Label)
      .arg(chgl->mol->selectedatoms.at(i).part)
      .arg(chgl->mol->selectedatoms.at(i).resiNr)
      .arg(chgl->mol->selectedatoms.at(i).ResiClass);
    infoKanalNews(s);
    int wg=mole.asymm.indexOf(chgl->mol->selectedatoms.at(i));
    if (wg<0) continue;
    deletedAtom.append(mole.asymm.at(wg));
    mole.asymm.removeAt(wg);
  }

  cursor.endEditBlock();

  mole.showatoms.clear();
  mole.showbonds.clear();
  chgl->mol->showatoms.clear();
  chgl->mol->showbonds.clear();
  chgl->mol->selectedatoms.clear();
  for (int o=0; o<mole.asymm.size();o++)
    mole.showatoms.append(mole.asymm[o]);
  mole.packer(mole.sdmcompleter());
  mole.showbonds =
    mole.connecting(mole.showatoms);

  chgl->setMolecule(&mole);

  chgl->mol->selectedatoms.clear();
  chgl->murx=__LINE__;

  bool growYes=chgl->fuse->isVisible ();
  chgl->mol->fuse();
  if (growYes) chgl->mol->grow();

  switch (duplicates()){
    case 1:infoKanalNews("<font color=orange >Some hydrogen atoms have identical names please check.</font>");break;
    case 2:infoKanalNews("<font color=red >Some non-hydrogen atoms have identical names. YOU HAVE TO CHECK BEFORE REFINING!</font>");break;
    case 3:infoKanalNews("<font color=red >Some atoms have identical names. YOU HAVE TO CHECK BEFORE REFINING!</font>");break;
  }
  if (donotsymm) QMessageBox::information(0,"information","Only unique atoms can be deleted!");
  chgl->pause=false;
//  printf("%d\n",__LINE__);
  chgl->updateBondActions();
  chgl->updateGL();
  update();
  chgl->updateGL();
  /*
     }
     else {chgl->disSelection();}*/
  }

void Window::createCentroid(){
  if (chgl->mol->selectedatoms.isEmpty()) return;
  chgl->pause=true;
  QTextCursor cursor = editor->textCursor();
  QTextDocument *document = editor->document();
  cursor.beginEditBlock();
  int ctrcnt=1;
  for (int i=0; i<mole.asymm.size();i++){
    if ((mole.asymm.at(i).an==-66)&&(mole.asymm.at(i).Label.startsWith("Cnt",Qt::CaseInsensitive)))
      ctrcnt++;
  }
  int ende=chgl->mol->selectedatoms.size();
  V3 posc = V3(0,0,0), posf = V3(0,0,0);
  QString creatorS;
  for (int i = 0; i < ende; i++ ){
    posc+=chgl->mol->selectedatoms.at(i).pos;
    creatorS.append(chgl->mol->selectedatoms.at(i).Label+", ");
    if (creatorS.section('\n',-1).size()>50) creatorS.append("\nREM  ");
  }
  posc*=1.0/ende;
  mole.kart2frac(posc,posf);
  MyAtom ctr ;
  ctr.an=-66;
  ctr.part=0;
  ctr.peakHeight=9999.99;
  ctr.resiNr=0;
  ctr.hidden=0;
  ctr.symmGroup=0;
  ctr.sg=0;
  ctr.scod=555;//the identity
  ctr.auidx=-1;
  ctr.uc.m12=ctr.uc.m23=ctr.uc.m13=0.0;
  ctr.uc.m21=ctr.uc.m32=ctr.uc.m31=0.0;
  ctr.uf.m12=ctr.uf.m23=ctr.uf.m13=0.0;
  ctr.uf.m21=ctr.uf.m32=ctr.uf.m31=0.0;
  ctr.pos=posc;
  ctr.frac=posf;
  if (!editor->sfac.contains(-66)){
    editor->sfac.append(-66);
    editor->unitNeu.append(" 0");
    cursor.movePosition(QTextCursor::Start);
    cursor = document->find(editor->unitAlt,cursor);
    if (cursor.isNull()) {
      cursor = editor->textCursor();
      cursor.endEditBlock ();
      printf("can't find unit\n");
      update();
      return;
    }
    cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
    cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
    cursor.deleteChar();
    cursor.insertText(editor->unitNeu);

    cursor.movePosition(QTextCursor::Start);
    cursor = document->find(editor->unitNeu,cursor);
    cursor.clearSelection ();
    cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
    cursor.insertText("SFAC cnt 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 ! centroid dummy\n");
  }
  cursor.movePosition(QTextCursor::Start);
  cursor = document->find("HKLF",cursor);
  cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
  cursor.insertText(ctr.orginalLine=QString("Cnt%5 %1 %2 %3 %4 10.000 0.001 ! centroid\n")
      .arg(editor->sfac.indexOf(-66)+1)
      .arg(posf.x,10,'f',6)
      .arg(posf.y,10,'f',6)
      .arg(posf.z,10,'f',6)
      .arg(ctrcnt,0,36));
  cursor.insertText(QString("REM Cnt%1 was created from: %2\n").arg(ctrcnt,0,36).arg(creatorS)); 

  for (int i = 0; i < ende; i++ ){
    cursor.insertText(QString("FREE Cnt%1 %2 ! this might be needed for AFIX\n").arg(ctrcnt,0,36).arg(chgl->mol->selectedatoms.at(i).Label.section('_',0,0).section(QString::fromUtf8("»"),0,0)));
  }
  ctr.orginalLine= QString("Cnt%5 %1 %2 %3 %4 10.000 0.001\n")
    .arg(editor->sfac.indexOf(-66)+1)
    .arg(posf.x,10,'f',6)
    .arg(posf.y,10,'f',6)
    .arg(posf.z,10,'f',6)
    .arg(ctrcnt,0,36);
  ctr.Label=QString("Cnt%1").arg(ctrcnt,0,36);
  cursor.endEditBlock ();
  editor->setTextCursor(cursor);
  editor->centerCursor () ;
  cursor.clearSelection ();
  editor->setTextCursor(cursor);
  editor->setFocus () ;
  mole.asymm.append(ctr);
  chgl->pause=true;
  mole.showatoms.clear();
  mole.showbonds.clear();
  chgl->mol->showatoms.clear();
  chgl->mol->showbonds.clear();
  chgl->mol->selectedatoms.clear();
  for (int o=0; o<mole.asymm.size();o++){
    mole.showatoms.append(mole.asymm[o]);
  }
  mole.sdmcompleter();
  mole.showbonds =
    mole.connecting(mole.showatoms);
  chgl->setMolecule(&mole);
  chgl->mol->selectedatoms.clear();
  chgl->murx=__LINE__;
  bool growYes=chgl->fuse->isVisible ();
  chgl->mol->fuse();
  if (growYes) chgl->mol->grow();
  chgl->pause=false;
//  printf("%d\n",__LINE__);
  chgl->updateGL();
  update();
}

void Window::moveSymmMateSel(){

  QString kep,nextli;
  QTextCursor cursor = editor->textCursor();
  QTextDocument *document = editor->document();
  cursor.beginEditBlock();
  for (int si=0; si<mole.selectedatoms.size();si++){
    QString source,target;
    source=mole.selectedatoms.at(si).Label;
    target=source.section(QString::fromUtf8("»"),0,0);
    MyAtom ato=mole.selectedatoms.at(si);
    ato.Label=target;
    ato.symmGroup=0;
    ato.sg=0;
    ato.scod=555;//the identity
    int that=mole.asymm.indexOf(ato);
    ato.auidx=that;
    if ((that>=mole.asymm.size())||(that<0)) return;
    QString susu=mole.asymm.at(that).orginalLine;
    cursor.movePosition(QTextCursor::Start);
    cursor = document->find(susu,cursor);
    if (mole.asymm.at(that).isIso){
        ato.ufiso_org = mole.asymm.at(that).ufiso_org;
      kep=QString("%1 %2 %3 %4 %5 %6 %7")
        .arg(ato.Label.section('_',0,0),-5)
        .arg(qMax(1,editor->sfac.indexOf(ato.an)+1))
        .arg(ato.frac.x,10,'f',6)
        .arg(ato.frac.y,10,'f',6)
        .arg(ato.frac.z,10,'f',6)
        .arg(mole.asymm.at(that).sof_org,9,'f',5)
        .arg(ato.ufiso_org)
        ;
      ato.uf.m11=ato.uc.m11=ato.uc.m22=ato.uc.m33= mole.asymm.at(that).uf.m11;
      ato.isIso=true;
      ato.uc.m12=ato.uc.m13=ato.uc.m23=ato.uc.m21=ato.uc.m31=ato.uc.m32=0;
      cursor.deleteChar();
      cursor.insertText(kep);
      cursor.setPosition(cursor.position(), QTextCursor::MoveAnchor);
      editor->wholeLine->setChecked(false);
      editor->replaceNext();
    }else{
      kep=QString("%1 %2 %3 %4 %5 %6 %7 %8 ")
        .arg(ato.Label.section('_',0,0),-5)
        .arg(qMax(1,editor->sfac.indexOf(ato.an)+1))
        .arg(ato.frac.x,10,'f',6)
        .arg(ato.frac.y,10,'f',6)
        .arg(ato.frac.z,10,'f',6)
        .arg(mole.asymm.at(that).sof_org,9,'f',5)
        .arg(ato.uf.m11,9,'f',5)
        .arg(ato.uf.m22,9,'f',5);
      ato.sof_org=mole.asymm.at(that).sof_org;
      cursor.deleteChar();
      cursor.insertText(kep);
      cursor.setPosition(cursor.position(), QTextCursor::MoveAnchor);
      cursor.movePosition(QTextCursor::Down);
      cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
      cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
      nextli=cursor.selectedText();
      cursor = document->find(nextli,cursor);

      cursor.deleteChar();
      cursor.insertText(QString("     %1 %2 %3 %4")
          .arg(ato.uf.m33,9,'f',5)
          .arg(ato.uf.m23,9,'f',5)
          .arg(ato.uf.m13,9,'f',5)
          .arg(ato.uf.m12,9,'f',5));
      cursor.setPosition(cursor.position(), QTextCursor::MoveAnchor);
    }
    ato.orginalLine=kep.section("=",0,0);
    mole.asymm[that]=ato;
  }

  cursor = editor->textCursor();
  cursor.endEditBlock();
  chgl->pause=true;
  mole.showatoms.clear();
  mole.showbonds.clear();
  chgl->mol->showatoms.clear();
  chgl->mol->showbonds.clear();
  chgl->mol->selectedatoms.clear();
  for (int o=0; o<mole.asymm.size();o++)
    mole.showatoms.append(mole.asymm[o]);
  mole.sdmcompleter();
  mole.showbonds =
    mole.connecting(mole.showatoms);
  chgl->setMolecule(&mole);
  chgl->mol->selectedatoms.clear();
  chgl->murx=__LINE__;
  bool growYes=chgl->fuse->isVisible ();
  chgl->mol->fuse();
  if (growYes) chgl->mol->grow();
  editor->searchLE->setText("");
  editor->hideSearch();
  chgl->pause=false;
//  printf("%d\n",__LINE__);
  chgl->updateGL();
  update();
}

void Window::moveSymmMate(){
  QAction *action = qobject_cast<QAction *>(sender());
  int index=0;
  if (action)
    index=action->data().toInt();
  else return;
  QString source,target;
  source=chgl->mol->showatoms.at(index).Label;
  target=source.section(QString::fromUtf8("»"),0,0);
  MyAtom ato=chgl->mol->showatoms.at(index);
  ato.Label=target;
  ato.symmGroup=0;
  ato.sg=0;
  ato.scod=555;//the identity
  int that=mole.asymm.indexOf(ato);
  ato.auidx=that;
  if ((that>=mole.asymm.size())||(that<0)) return;
  QString susu=mole.asymm.at(that).orginalLine;
  editor->searchLE->setText(susu);
  if (mole.asymm.at(that).isIso){
    ato.ufiso_org = mole.asymm.at(that).ufiso_org;
    editor->replace->setText(QString("%1 %2 %3 %4 %5 %6 %7")
        .arg(ato.Label.section('_',0,0),-5)
        .arg(qMax(1, editor->sfac.indexOf(ato.an)+1))
        .arg(ato.frac.x,10,'f',6)
        .arg(ato.frac.y,10,'f',6)
        .arg(ato.frac.z,10,'f',6)
        .arg(mole.asymm.at(that).sof_org,9,'f',5)
        .arg(ato.ufiso_org)
        );
    ato.uf.m11=ato.uc.m11=ato.uc.m22=ato.uc.m33= mole.asymm.at(that).uf.m11;
    ato.isIso=true;
    ato.uc.m12=ato.uc.m13=ato.uc.m23=ato.uc.m21=ato.uc.m31=ato.uc.m32=0;
    editor->wholeLine->setChecked(false);
    editor->replaceNext();
  }else{
    QString kep=QString("%1 %2 %3 %4 %5 %6 %7 %8 ")
      .arg(ato.Label.section('_',0,0),-5)
      .arg(qMax(1,editor->sfac.indexOf(ato.an)+1))
      .arg(ato.frac.x,10,'f',6)
      .arg(ato.frac.y,10,'f',6)
      .arg(ato.frac.z,10,'f',6)
      .arg(mole.asymm.at(that).sof_org,9,'f',5)
      .arg(ato.uf.m11,9,'f',5)
      .arg(ato.uf.m22,9,'f',5);

    editor->replace->setText(kep);
    editor->wholeLine->setChecked(false);
    editor->replaceNext();
    editor->searchLE->setText(editor->replace->text());
    editor->replace->setText("");
    editor->findNext();  
    QTextCursor cursor = editor->textCursor();
    cursor.movePosition(QTextCursor::Down);
    cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
    cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
    editor->searchLE->setText(cursor.selectedText());
    editor->replace->setText(QString("     %1 %2 %3 %4")
        .arg(ato.uf.m33,9,'f',5)
        .arg(ato.uf.m23,9,'f',5)
        .arg(ato.uf.m13,9,'f',5)
        .arg(ato.uf.m12,9,'f',5)
        );

    editor->replaceNext();
    editor->replace->setText(kep);
  }
  editor->searchLE->setText(editor->replace->text());
  editor->replace->setText("");
  editor->findNext();  
  QTextCursor cursor = editor->textCursor();
  ato.orginalLine=cursor.selectedText().section("=",0,0);
  mole.asymm[that]=ato;

  chgl->pause=true;
  mole.showatoms.clear();
  mole.showbonds.clear();
  chgl->mol->showatoms.clear();
  chgl->mol->showbonds.clear();
  chgl->mol->selectedatoms.clear();
  for (int o=0; o<mole.asymm.size();o++)
    mole.showatoms.append(mole.asymm[o]);
  mole.sdmcompleter();
  mole.showbonds =
    mole.connecting(mole.showatoms);
  chgl->setMolecule(&mole);
  chgl->mol->selectedatoms.clear();
  chgl->murx=__LINE__;
  bool growYes=chgl->fuse->isVisible ();
  chgl->mol->fuse();
  if (growYes) chgl->mol->grow();
  editor->searchLE->setText("");
  editor->hideSearch();
  chgl->pause=false;
//  printf("%d\n",__LINE__);
  chgl->updateGL();
  update();
}

void Window::copySymmMate(){
  QAction *action = qobject_cast<QAction *>(sender());
  int index=0;
  if (action)
    index=action->data().toInt();
  else return;
  QString source,target;
  source=chgl->mol->showatoms.at(index).Label;
  target=source.section(QString::fromUtf8("»"),0,0);
  MyAtom ato=chgl->mol->showatoms.at(index);
  ato.Label=target;
  ato.symmGroup=0;
  ato.sg=0;
  ato.scod=555;//the identity
  int that=mole.asymm.indexOf(ato);
  ato.auidx=that;
  if ((that>=mole.asymm.size())||(that<0)) return;
  QString susu=mole.asymm.at(that).orginalLine;
  QTextCursor cursor = editor->textCursor();
  cursor.movePosition(QTextCursor::Start);
  QTextDocument *document = editor->document();
  if (document->find(susu, cursor).isNull()) {
    QMessageBox::information(0,"information","The File is out of sync with the model. Please save and try again!");
    return;
  }
  cursor.beginEditBlock();
  cursor.movePosition(QTextCursor::Start);
  cursor = document->find("HKLF",cursor);
  cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
  cursor.movePosition(QTextCursor::Up,QTextCursor::KeepAnchor);
  if (editor->parenthesis.at(cursor.blockNumber())){
    cursor.select(QTextCursor::WordUnderCursor);
    if ((cursor.selectedText().contains("RESI",Qt::CaseInsensitive))||(cursor.selectedText().contains("PART",Qt::CaseInsensitive)))
      cursor.movePosition(QTextCursor::Up,QTextCursor::KeepAnchor);
    cursor.select(QTextCursor::WordUnderCursor);
    if ((cursor.selectedText().contains("RESI",Qt::CaseInsensitive))||(cursor.selectedText().contains("PART",Qt::CaseInsensitive)))
      cursor.movePosition(QTextCursor::Up,QTextCursor::KeepAnchor);
    cursor.movePosition(QTextCursor::Down,QTextCursor::MoveAnchor);
    cursor.clearSelection();
    cursor.insertText("AFIX 0 \n");
  }
  /////////////////////////////
  cursor.movePosition(QTextCursor::Start);
  cursor = document->find(susu, cursor); 
  cursor.movePosition(QTextCursor::Down);
  cursor.movePosition(QTextCursor::StartOfLine);
  QRegExp num=QRegExp("\\d+");
  if (mole.asymm.at(that).Label.contains(num)) {
    int p=mole.asymm.at(that).an;
    labelPSE=mole.pse(p);

    labelIndex=mole.asymm.at(that).Label.section(QRegExp("\\D+"),0,0,QString::SectionSkipEmpty).toInt();
    labelSuffix=mole.asymm.at(that).Label.section(num,1,1);
    labelSuffix.remove(QRegExp("[^A-Za-z']+"));
  }
  else{
    int p=mole.asymm.at(that).an;
    labelPSE=mole.pse(p);
    labelIndex=-1;
    labelSuffix=mole.asymm.at(that).Label;
    labelSuffix.remove(0,labelPSE.size());
    labelSuffix.remove(QRegExp("[^A-Za-z']+"));
  }

  partSpin->setValue(mole.asymm.at(that).part);
  resiNrSpin->setValue(mole.asymm.at(that).resiNr);
  resiResiClass->setText(mole.asymm.at(that).ResiClass);
  pserbt[mole.asymm.at(that).an+1]->setChecked(true);

  renamUpdate(false);
  updateLabel();
  QString neues=nextLabel;
  if (mole.asymm.at(that).isIso){
    cursor.insertText(QString("%1 %2 %3 %4 %5 %6 %7 !copy\n")
        .arg(neues,-5)//1
        .arg(qMax(1,editor->sfac.indexOf(ato.an)+1))//2
        .arg(ato.frac.x,10,'f',6)//3
        .arg(ato.frac.y,10,'f',6)//4
        .arg(ato.frac.z,10,'f',6)//5
        .arg(mole.asymm.at(that).sof_org,9,'f',5)//6
        .arg(ato.uf.m33=mole.asymm.at(that).uf.m33,9,'f',5)//7
        );

  }else{
    cursor.movePosition(QTextCursor::Down);
    cursor.movePosition(QTextCursor::StartOfLine);
    while(editor->parenthesis.at(cursor.blockNumber()+1)){
      cursor.movePosition(QTextCursor::Down);
      cursor.movePosition(QTextCursor::StartOfLine);
    }
    cursor.insertText(QString("%1 %2 %3 %4 %5 %6 %7 %8 =\n %9 %10 %11 %12 !copy\n")
        .arg(neues,-5)//1
        .arg(qMax(1,editor->sfac.indexOf(ato.an)+1))//2
        .arg(ato.frac.x,10,'f',6)//3
        .arg(ato.frac.y,10,'f',6)//4
        .arg(ato.frac.z,10,'f',6)//5
        .arg(mole.asymm.at(that).sof_org,9,'f',5)//6
        .arg(ato.uf.m11,9,'f',5)//7
        .arg(ato.uf.m22,9,'f',5)//8
        .arg(ato.uf.m33,9,'f',5)//9
        .arg(ato.uf.m23,9,'f',5)//10
        .arg(ato.uf.m13,9,'f',5)//11
        .arg(ato.uf.m12,9,'f',5)//12
        );

  }
  QString nn=QString("%1_%3%4")
    .arg(nextLabel)
    .arg((resiNrSpin->value())?QString::number(resiNrSpin->value()):"")
    .arg((partSpin->value())?QString::number((partSpin->value()<0)?
          36+partSpin->value():
          partSpin->value()+9,36):"");
  ato.Label=nn;
  mole.asymm.append(ato);  
  cursor.endEditBlock();
  renamUpdate(false);
  updateLabel();
  chgl->pause=true;
  mole.showatoms.clear();
  mole.showbonds.clear();
  chgl->mol->showatoms.clear();
  chgl->mol->showbonds.clear();
  chgl->mol->selectedatoms.clear();
  for (int o=0; o<mole.asymm.size();o++)
    mole.showatoms.append(mole.asymm[o]);
  mole.sdmcompleter();
  mole.showbonds =
    mole.connecting(mole.showatoms);
  chgl->setMolecule(&mole);
  chgl->mol->selectedatoms.clear();
  chgl->murx=__LINE__;
  bool growYes=chgl->fuse->isVisible ();
  chgl->mol->fuse();
  if (growYes) chgl->mol->grow();
  chgl->pause=false;
//  printf("%d\n",__LINE__);
  chgl->updateGL();
  update();
}

void Window::updateTieFreeVar(){
  int part = partSpin->value();
  if (!part) {
    tieOccL->hide();
    tieType->hide();
    tieType->setCurrentIndex(0);
    tieFVNrL->hide();
    tieFVNr->hide();
    tieUsedL->hide();
    tieFix->hide();
    update();
    return;
  }
  tieOccL->show();
  tieType->show();

  if (tieType->itemData(tieType->currentIndex()).toInt()){
    tieFVNrL->show();
    tieFVNr->show();
    tieUsedL->hide();
    tieFix->hide();
    int j=tieFVNr->value();
    tieUsedL->setText(QString("fv(%1)=%3 [%2x used]")
        .arg(j)
        .arg(fvarCntr.value(j))
        .arg((fvar.size()>(j-1))?fvar.at(j-1):0.666) );
    tieFVNr->setMaximum(fvar.size()+1);
    if (j!=1) tieUsedL->show();
    else {
      tieFix->show();
      tieType->hide();
    }
  }else{
    tieFVNrL->hide();
    tieFVNr->hide();
    tieUsedL->hide();
    tieFix->hide();
  }
  update();
}

void Window::clipboardDataChanged(){
#ifndef QT_NO_CLIPBOARD
  actionPaste->setEnabled(!QApplication::clipboard()->text().isEmpty());
#endif
}

void Window::shxActUpdate(bool vis){
  bool v = shxOutputDock->isVisible();
  editToolBar->setVisible(vis|v);
  refineToolBar->setVisible(vis|v);
  actionSearch->setVisible(vis|v);
  actionNext->setVisible(vis|v);
  actionPrev->setVisible(vis|v);
  actionUndo->setVisible(vis);
  actionRedo->setVisible(vis);
  actionCut->setVisible(vis);
  actionCopy->setVisible(vis);
  actionPaste->setVisible(vis);
  actionEP->setVisible(vis|v);
  actionEM->setVisible(vis|v);
}

void Window::shxOPTUpdate(bool vis){

  bool v = shxEditorDock->isVisible();

  xlPutor->hideSearch();
  editToolBar->setVisible(vis|v);
  refineToolBar->setVisible(vis|v);
  actionSearch->setVisible(vis|v);
  actionNext->setVisible(vis|v);
  actionPrev->setVisible(vis|v);
  actionEP->setVisible(vis|v);
  actionEM->setVisible(vis|v);
  update();
}

void Window::renamUpdate(bool vis){
  enterRenameMode->setChecked(vis);
  enterRenameMode->setText((vis)?"Exit Rename Mode":"Rename Mode");
  renamUpdateAct->setChecked(false);
  updateTieFreeVar();
  labelSuffix = "";
  sufixBox->clearEditText();
  psew->hide();
  willpse->show();
  QStringList RCL;//ResiClassList
  RCL.append("");
  QString curcls=resiResiClass->text();
  if (!curcls.isEmpty()) RCL.append(curcls);
  for (int i=0; i<mole.asymm.size(); i++){
    if (mole.asymm.at(i).an<0) continue;
    if (!RCL.contains(mole.asymm.at(i).ResiClass))RCL.append(mole.asymm.at(i).ResiClass);
  }
  resiResiClassCB->clear();
  resiResiClassCB->addItems(RCL);
  if (!curcls.isEmpty()) resiResiClassCB->setCurrentIndex(resiResiClassCB->findText(curcls));
  renameRNchanged(resiNrSpin->value());  
  resiResiClass->setText(curcls);
  if (vis) {
    renamDock->show();
    renamDock->raise();
    editToolBar->setVisible(vis);
    refineToolBar->setVisible(vis);
    actionSearch->setVisible(vis);
    actionNext->setVisible(vis);
    actionPrev->setVisible(vis);
    actionUndo->setVisible(vis);
    actionRedo->setVisible(vis);
    actionCut->setVisible(vis);
    actionCopy->setVisible(vis);
    actionPaste->setVisible(vis);
    actionEP->setVisible(vis);
    actionEM->setVisible(vis);

    if (dock->isVisible()) dock->hide();
    if (histDock->isVisible()) histDock->hide();
    machPlatz=true;
    renamDock->show();
    renamDock->raise();
  }
  else if (enterRenameMode->text()=="Rename Mode"){
    if ((machPlatz)&&(!dock->isVisible())&&(!histDock->isVisible())) {
      dock->show();
      histDock->show();
      shxEditorDock->show();
      shxEditorDock->raise();
      machPlatz=false;

    }
  }
  if ((vis)&&(height()>hhh)) {
#if defined(linux)
    showMaximized ();
    showNormal ();
#endif
    showMaximized ();
  }
  chgl->updateLabelTextures();
}

void Window::addNewScatteringFactor(int oz){
  changeElemetofLabel(mole.pse(oz));
  if (editor->sfac.contains(oz)) {
    pserbt[oz+1]->setChecked(true);
    return;
  }
  editor->sfac.append(oz);
  pserbt[editor->sfac.last()+1]->show();
  pserbt[editor->sfac.last()+1]->setChecked(true);
  sfacBox->setFixedSize((editor->sfac.size()+1)*52,70);

  QTextDocument *document = editor->document();
  QTextCursor cursor = editor->textCursor();
  cursor.beginEditBlock();
  cursor.movePosition(QTextCursor::End);
  cursor = document->find("sfac", cursor, QTextDocument::FindBackward);
  if (!cursor.isNull()){
    cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
    cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
    QString sf = cursor.selectedText().trimmed();
    if (sf.size()<77) sf.append(QString(" %1").arg(mole.pse(oz)));
    cursor.deleteChar();
    cursor.insertText(sf);
  }
  cursor.movePosition(QTextCursor::End);
  cursor = document->find("unit", cursor, QTextDocument::FindBackward);
  if (!cursor.isNull()){
    cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
    cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
    QString sf = cursor.selectedText().trimmed();
    if (sf.size()<77) sf.append(" 1");
    cursor.deleteChar();
    cursor.insertText(sf);
  }
  cursor.endEditBlock();
}

void Window::setDefaultPath(){ //!<when the first recent file does not exists then open dialog starts here
    QString dfpa="";
    mole.einstellung->beginGroup("Files");
    if (mole.einstellung->contains("defaultPath"))
      dfpa= mole.einstellung->value("defaultPath").toString();
    else
      dfpa= QDir::homePath();
    mole.einstellung->endGroup();
    dfpa=QFileDialog::getOpenFileName(this,
                                              "set default file directory",
                                              dfpa,
                                              "SHELX-Files (*.res *.ins);;",
                                              nullptr);
    if (!dfpa.isEmpty()){
    mole.einstellung->beginGroup("Files");
    mole.einstellung->setValue("defaultPath",dfpa);
    mole.einstellung->endGroup();
    }
}

void Window::openFile(){
  QString location=dirName;
  if (!QFile::exists(dirName)) {
      mole.einstellung->beginGroup("Files");
      if (mole.einstellung->contains("defaultPath"))
        location = mole.einstellung->value("defaultPath").toString();
      else
        location = QDir::homePath();
      mole.einstellung->endGroup();
  }

  QString fileName = QFileDialog::getOpenFileName(this, tr("Open shelX file "), location,
      "SHELX-Files (*.res *.ins);;",nullptr,(useNativeDlg->isChecked())?noneopt:QFileDialog::DontUseNativeDialog);
  if (!fileName.isEmpty()) {

    loadFile(fileName);
  }
  update();
}

void Window::setShelxlOptions(){
  QDialog *shxOptDLG =  new QDialog(this);
  shxOptDLG->setWindowTitle("SHELXL runtime options");
  QGridLayout *lt = new QGridLayout(shxOptDLG);
  QLabel *PathL = new QLabel("Full path to executable",shxOptDLG);
  shxPath = new QLineEdit(shxOptDLG);
  QLabel *argumentsL =  new QLabel("Commandline options",shxOptDLG);
  QCheckBox *barray = new QCheckBox(tr("I want to set the B-array size myself"));
  shxOptions = new QLineEdit(shxOptDLG);
  shxPath->setText(shelxlPath); 
  shxOptions->setText(shelxlArgs);
  if (useMyBArray == true) {
    barray->setChecked(true);
  } else {
    barray->setChecked(false);
  }
  QPushButton *browsePath = new QPushButton("Browse",shxOptDLG);
  connect(browsePath,SIGNAL(pressed ()),this, SLOT(setShelxlPath()));
  QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel,Qt::Horizontal,shxOptDLG);
  connect(buttonBox, SIGNAL(accepted()), shxOptDLG, SLOT(accept()));
  connect(buttonBox, SIGNAL(rejected()), shxOptDLG, SLOT(reject()));
  lt->addWidget(PathL,      1, 0);
  lt->addWidget(shxPath,    1, 1);
  lt->addWidget(argumentsL, 2, 0);
  lt->addWidget(shxOptions, 2, 1);
  lt->addWidget(browsePath, 1, 2);
  lt->addWidget(barray,     3, 1, 1, 2);
  lt->addWidget(buttonBox,  8, 1, 1, 3);
  shxOptDLG->setLayout(lt);
  if (shxOptDLG->exec()==QDialog::Accepted) {
    shelxlArgs=shxOptions->text();
    shelxlPath=shxPath->text();
    mole.einstellung->beginGroup("Window");
    mole.einstellung->setValue("SHELXL-PATH", shelxlPath);
    mole.einstellung->setValue("SHELXL-OPTION", shelxlArgs);
    mole.einstellung->setValue("SHELXL-BARRAY", barray->isChecked());
    useMyBArray = barray->isChecked();
    mole.einstellung->endGroup();
  }
  shxOptDLG->deleteLater ();
  delete shxPath;
  delete shxOptions;
  shxPath=shxOptions=NULL;
}

void Window::extraSettings(){
  QDialog *extDLG = new QDialog(this);
  extDLG->setWindowTitle("External programs"); 
  QGridLayout *lt = new QGridLayout(extDLG);
  pgms = new QComboBox(extDLG);
  pgms->addItems(extraProgramNames);
  connect(pgms,SIGNAL(currentIndexChanged(int)), this, SLOT(updateExtraSettings(int)));
  QLabel *extraNameL = new QLabel("Name of external program for menu entry:",extDLG);
  extraName = new QLineEdit(extDLG);
  extraName->setMinimumSize(150,15);
  QLabel *extraPathL = new QLabel("Full path to executable",extDLG);
  extraPath = new QLineEdit(extDLG);
  QLabel *argumentsL =  new QLabel("Commandline options",extDLG);
  extraArgumentsEdit = new QLineEdit(extDLG);
  QLabel *altExtL =  new QLabel("Alternative file Extension",extDLG);
  extraAltExtEdit = new QLineEdit(extDLG);
  QPushButton *browsePath = new QPushButton("Browse",extDLG);
  extraFakeButton = new QToolButton(extDLG);
  extraFakeButton->setIconSize(QSize(tbiconSize,tbiconSize));
  connect(browsePath,SIGNAL(pressed ()),this, SLOT(setExtraPath()));
  connect(extraFakeButton,SIGNAL(pressed()),this,SLOT(brwsIcon()));
  useArgument = new QCheckBox("Give file name as argument",extDLG);
  omitExtension = new QCheckBox("Omit '*.res' extension in argument",extDLG);
  copyResIns = new QCheckBox("Copy .res file to ins file before execution",extDLG);
  openFileDialogBefore = new QCheckBox("Open file dialog before execution",extDLG);
  iconOverlay = new QCheckBox("Text overlay",extDLG);
  iovlPointSize = new QSpinBox(extDLG);
  iovlPointSize->setRange(4,96);
  iovlPointSize->setValue(36);
  iovlPointSize->setPrefix("PointSize ");
  connect(iconOverlay,SIGNAL(stateChanged(int)),this,SLOT(updateExtraIcon())); 
  connect(iovlPointSize,SIGNAL(valueChanged(int)),this,SLOT(updateExtraIcon())); 
  detach = new QCheckBox("start detached",extDLG);
  detach->setChecked(true);
  QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::No| QDialogButtonBox::Ok | QDialogButtonBox::Cancel,Qt::Horizontal,extDLG);
  QPushButton *ok = buttonBox->button(QDialogButtonBox::Ok);
  ok->setText("Add program");
  QPushButton *no =buttonBox->button(QDialogButtonBox::No);
  no->setText("Remove program");
  connect(buttonBox, SIGNAL(clicked(QAbstractButton*)),this,SLOT(removeExtra(QAbstractButton*)));
  connect(buttonBox, SIGNAL(accepted()), extDLG, SLOT(accept()));
  connect(buttonBox, SIGNAL(rejected()), extDLG, SLOT(reject()));
  lt->addWidget(pgms,0,0);
  lt->addWidget(extraNameL,1,0);
  lt->addWidget(extraName, 1,1);
  lt->addWidget(extraPathL,2,0);
  lt->addWidget(extraPath, 2,1);
  lt->addWidget(browsePath,2,2);
  lt->addWidget(extraFakeButton,0,1);
  lt->addWidget(iconOverlay,0,2);
  lt->addWidget(iovlPointSize,0,3);
  lt->addWidget(argumentsL,4,0);
  lt->addWidget(extraArgumentsEdit,4,1);
  lt->addWidget(altExtL,5,0);
  lt->addWidget(extraAltExtEdit,5,1);
  lt->addWidget(useArgument,          1, 9);
  lt->addWidget(omitExtension,        2, 9);
  lt->addWidget(detach,               3, 9);
  lt->addWidget(copyResIns,           4, 9);
  lt->addWidget(openFileDialogBefore, 5, 9);
  lt->addWidget(buttonBox,14,0,1,11);
  extDLG->setLayout(lt);
  altExtraIconPath="";
  updateExtraSettings(0);

  while (extraOptions.size()>extraProgramNames.size()){extraOptions.removeLast();}
  while (extraExt2.size()>extraProgramNames.size()){extraExt2.removeLast();}

  if (extDLG->exec()==QDialog::Accepted) {
    int wegmuss=extraProgramNames.indexOf(extraName->text());
    if (wegmuss!=-1) {
      extraProgramNames.removeAt(wegmuss);
      extraProgramPaths.removeAt(wegmuss);
      extraArguments.removeAt(wegmuss);
      extraExtensions.removeAt(wegmuss);
      if (wegmuss<extraResIns.size()) extraResIns.removeAt(wegmuss);
      if (wegmuss<extraOpenFileDialogBefore.size()) extraOpenFileDialogBefore.removeAt(wegmuss);
      if (wegmuss<extraIconOverlay.size()) extraIconOverlay.removeAt(wegmuss);
      if (wegmuss<extraOverlayPointSize.size())  extraOverlayPointSize.removeAt(wegmuss);
      if (wegmuss<altExtraIconPaths.size())  altExtraIconPaths.removeAt(wegmuss);
      extraDetach.removeAt(wegmuss);
      extraOptions.removeAt(wegmuss);
      extraExt2.removeAt(wegmuss);
    }
    altExtraIconPaths.append(altExtraIconPath);
    extraProgramNames.append(extraName->text().trimmed());
    extraProgramPaths.append(extraPath->text().trimmed());
    extraArguments.append(useArgument->checkState());
    extraOptions.append(extraArgumentsEdit->text().trimmed());
    extraExt2.append(extraAltExtEdit->text().trimmed());
    extraExtensions.append(omitExtension->checkState());
    extraResIns.append(copyResIns->checkState());
    extraOpenFileDialogBefore.append(openFileDialogBefore->checkState());
    extraIconOverlay.append(iconOverlay->checkState());
    extraOverlayPointSize.append(iovlPointSize->value());
    extraDetach.append(detach->checkState());
    mole.einstellung->beginGroup("Extra");
    mole.einstellung->beginWriteArray("ProgramNames",extraProgramNames.size());
    for (int i = 0; i < extraProgramNames.size(); i++) {
      mole.einstellung->setArrayIndex(i);
      mole.einstellung->setValue("Name", extraProgramNames.at(i));
    }
    mole.einstellung->endArray();
    mole.einstellung->endGroup();

    mole.einstellung->beginGroup("Extra");
    mole.einstellung->beginWriteArray("ProgramPaths",extraProgramPaths.size());
    for (int i = 0; i < extraProgramPaths.size(); i++) {
      mole.einstellung->setArrayIndex(i);
      mole.einstellung->setValue("Path", extraProgramPaths.at(i));
    }
    mole.einstellung->endArray();
    mole.einstellung->endGroup();

    mole.einstellung->beginGroup("Extra");
    mole.einstellung->beginWriteArray("AlternativeExtensions",extraExt2.size());
    for (int i = 0; i < extraExt2.size(); i++) {
      mole.einstellung->setArrayIndex(i);
      mole.einstellung->setValue("ext", extraExt2.at(i));
    }
    mole.einstellung->endArray();
    mole.einstellung->endGroup();

    mole.einstellung->beginGroup("Extra");
    mole.einstellung->beginWriteArray("CommandLineOptions",extraOptions.size());
    for (int i = 0; i < extraOptions.size(); i++) {
      mole.einstellung->setArrayIndex(i);
      mole.einstellung->setValue("opt", extraOptions.at(i));
    }
    mole.einstellung->endArray();
    mole.einstellung->endGroup();



    mole.einstellung->beginGroup("Extra");
    mole.einstellung->beginWriteArray("ProgramArgs",extraArguments.size());
    for (int i = 0; i < extraArguments.size(); i++) {
      mole.einstellung->setArrayIndex(i);
      mole.einstellung->setValue("Arg", extraArguments.at(i));
    }
    mole.einstellung->endArray();
    mole.einstellung->endGroup();

    mole.einstellung->beginGroup("Extra");
    mole.einstellung->beginWriteArray("ProgramExtensions",extraExtensions.size());
    for (int i = 0; i < extraExtensions.size(); i++) {
      mole.einstellung->setArrayIndex(i);
      mole.einstellung->setValue("Ext", extraExtensions.at(i));
    }
    mole.einstellung->endArray();
    mole.einstellung->endGroup();

    mole.einstellung->beginGroup("Extra");
    mole.einstellung->beginWriteArray("ProgramResIns",extraResIns.size());
    for (int i = 0; i < extraResIns.size(); i++) {
      mole.einstellung->setArrayIndex(i);
      mole.einstellung->setValue("Res2Ins", extraResIns.at(i));
    }
    mole.einstellung->endArray();
    mole.einstellung->endGroup();

    mole.einstellung->beginGroup("Extra");
    mole.einstellung->beginWriteArray("FileDialog",extraOpenFileDialogBefore.size());
    for (int i = 0; i < extraOpenFileDialogBefore.size(); i++) {
      mole.einstellung->setArrayIndex(i);
      mole.einstellung->setValue("fd", extraOpenFileDialogBefore.at(i));
    }
    mole.einstellung->endArray();
    mole.einstellung->endGroup();

    mole.einstellung->beginGroup("Extra");
    mole.einstellung->beginWriteArray("IconOverlay",extraIconOverlay.size());
    for (int i = 0; i < extraIconOverlay.size(); i++) {
      mole.einstellung->setArrayIndex(i);
      mole.einstellung->setValue("icov", extraIconOverlay.at(i));
    }
    mole.einstellung->endArray();
    mole.einstellung->endGroup();

    mole.einstellung->beginGroup("Extra");
    mole.einstellung->beginWriteArray("OverlayPointSize",extraOverlayPointSize.size());
    for (int i = 0; i < extraOverlayPointSize.size(); i++) {
      mole.einstellung->setArrayIndex(i);
      mole.einstellung->setValue("icov", extraOverlayPointSize.at(i));
    }
    mole.einstellung->endArray();
    mole.einstellung->endGroup();

    mole.einstellung->beginGroup("Extra");
    mole.einstellung->beginWriteArray("AltExtraIconPaths",altExtraIconPaths.size());
    for (int i = 0; i < altExtraIconPaths.size(); i++) {
      mole.einstellung->setArrayIndex(i);
      mole.einstellung->setValue("altIcon", altExtraIconPaths.at(i));
    }
    mole.einstellung->endArray();
    mole.einstellung->endGroup();

    mole.einstellung->beginGroup("Extra");
    mole.einstellung->beginWriteArray("ProgramDetached",extraDetach.size());
    for (int i = 0; i < extraDetach.size(); i++) {
      mole.einstellung->setArrayIndex(i);
      mole.einstellung->setValue("Detach", extraDetach.at(i));
    }
    mole.einstellung->endArray();
    mole.einstellung->endGroup();
    extraMenu->clear();
    extraTB->clear();
    extraMenu->addAction("add/remove external program",this,SLOT(extraSettings()));
    QFileIconProvider *p = new QFileIconProvider();
    if (extraProgramNames.size()) extraMenu->addSeparator();
    for (int i=0; i<extraProgramNames.size(); i++){
      QAction *a;
      QString icopa=extraProgramPaths.at(i);
      QFileIconProvider *epic = new QFileIconProvider();
      QPixmap fmap = epic->icon(QFileInfo(icopa)).pixmap(64,64);
      if (QFile::exists(altExtraIconPaths.at(i))) fmap=QIcon(altExtraIconPaths.at(i)).pixmap(64,64);
      delete epic;

      if (extraIconOverlay.at(i)==Qt::Checked){
        QPainter *paint = new QPainter(&fmap);
        paint->setPen(QPen(QColor("#FFFFFF")));
        QFont ifont=chgl->myFont;
        ifont.setPixelSize(extraOverlayPointSize.at(i)*fmap.height()/64);
        paint->setFont(ifont);
        paint->drawText(1,fmap.height()-5,extraProgramNames.at(i));
        paint->setPen(QPen(QColor("#000000")));
        paint->drawText(0,fmap.height()-4,extraProgramNames.at(i));
        paint->end();
      }
      extraIcon=QIcon(fmap);
      a=extraMenu->addAction(extraIcon,QString("run %1 !").arg(extraProgramNames.at(i)),this,SLOT(runExtra()));
      a->setData(i);  
      extraTB->addAction(a);
    }
    delete p;

  }
  extDLG->deleteLater ();
  if (strcmp(PROGRAM_NAME,"shelXle")){
      QMessageBox::information(0,"information","Restart of APEX is required to make your changes to external programs active. ",QMessageBox::Ok);

  }
}

void Window::extraSettingsLast(){
  QDialog *extDLG = new QDialog(this);
  extDLG->setWindowTitle("External programs");
  QGridLayout *lt = new QGridLayout(extDLG);
  pgms = new QComboBox(extDLG);
  pgms->addItems(extraProgramNames);
  connect(pgms,SIGNAL(currentIndexChanged(int)), this, SLOT(updateExtraSettings(int)));
  QLabel *extraNameL = new QLabel("Name of external program for menu entry:",extDLG);
  extraName = new QLineEdit(extDLG);
  extraName->setMinimumSize(150,15);
  QLabel *extraPathL = new QLabel("Full path to executable",extDLG);
  extraPath = new QLineEdit(extDLG);
  QLabel *argumentsL =  new QLabel("Commandline options",extDLG);
  extraArgumentsEdit = new QLineEdit(extDLG);
  QLabel *altExtL =  new QLabel("Alternative file Extension",extDLG);
  extraAltExtEdit = new QLineEdit(extDLG);
  QPushButton *browsePath = new QPushButton("Browse",extDLG);
  extraFakeButton = new QToolButton(extDLG);
  extraFakeButton->setIconSize(QSize(tbiconSize,tbiconSize));
  connect(browsePath,SIGNAL(pressed ()),this, SLOT(setExtraPath()));
  connect(extraFakeButton,SIGNAL(pressed()),this,SLOT(brwsIcon()));
  useArgument = new QCheckBox("Give file name as argument",extDLG);
  omitExtension = new QCheckBox("Omit '*.res' extension in argument",extDLG);
  copyResIns = new QCheckBox("Copy .res file to ins file before execution",extDLG);
  openFileDialogBefore = new QCheckBox("Open file dialog before execution",extDLG);
  iconOverlay = new QCheckBox("Text overlay",extDLG);
  iovlPointSize = new QSpinBox(extDLG);
  iovlPointSize->setRange(4,96);
  iovlPointSize->setValue(36);
  iovlPointSize->setPrefix("PointSize ");
  connect(iconOverlay,SIGNAL(stateChanged(int)),this,SLOT(updateExtraIcon()));
  connect(iovlPointSize,SIGNAL(valueChanged(int)),this,SLOT(updateExtraIcon()));
  detach = new QCheckBox("start detached",extDLG);
  detach->setChecked(true);
  QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::No| QDialogButtonBox::Ok | QDialogButtonBox::Cancel,Qt::Horizontal,extDLG);
  QPushButton *ok = buttonBox->button(QDialogButtonBox::Ok);
  ok->setText("Add program");
  QPushButton *no =buttonBox->button(QDialogButtonBox::No);
  no->setText("Remove program");
  connect(buttonBox, SIGNAL(clicked(QAbstractButton*)),this,SLOT(removeExtra(QAbstractButton*)));
  connect(buttonBox, SIGNAL(accepted()), extDLG, SLOT(accept()));
  connect(buttonBox, SIGNAL(rejected()), extDLG, SLOT(reject()));
  lt->addWidget(pgms,0,0);
  lt->addWidget(extraNameL,1,0);
  lt->addWidget(extraName, 1,1);
  lt->addWidget(extraPathL,2,0);
  lt->addWidget(extraPath, 2,1);
  lt->addWidget(browsePath,2,2);
  lt->addWidget(extraFakeButton,0,1);
  lt->addWidget(iconOverlay,0,2);
  lt->addWidget(iovlPointSize,0,3);
  lt->addWidget(argumentsL,4,0);
  lt->addWidget(extraArgumentsEdit,4,1);
  lt->addWidget(altExtL,5,0);
  lt->addWidget(extraAltExtEdit,5,1);
  lt->addWidget(useArgument,          1, 9);
  lt->addWidget(omitExtension,        2, 9);
  lt->addWidget(detach,               3, 9);
  lt->addWidget(copyResIns,           4, 9);
  lt->addWidget(openFileDialogBefore, 5, 9);
  lt->addWidget(buttonBox,14,0,1,11);
  extDLG->setLayout(lt);
  altExtraIconPath="";
  pgms->setCurrentIndex(extraProgramNames.size()-1);
  updateExtraSettings(extraProgramNames.size()-1);

  while (extraOptions.size()>extraProgramNames.size()){extraOptions.removeLast();}
  while (extraExt2.size()>extraProgramNames.size()){extraExt2.removeLast();}

  if (extDLG->exec()==QDialog::Accepted) {
    int wegmuss=extraProgramNames.indexOf(extraName->text());
    if (wegmuss!=-1) {
      extraProgramNames.removeAt(wegmuss);
      extraProgramPaths.removeAt(wegmuss);
      extraArguments.removeAt(wegmuss);
      extraExtensions.removeAt(wegmuss);
      if (wegmuss<extraResIns.size()) extraResIns.removeAt(wegmuss);
      if (wegmuss<extraOpenFileDialogBefore.size()) extraOpenFileDialogBefore.removeAt(wegmuss);
      if (wegmuss<extraIconOverlay.size()) extraIconOverlay.removeAt(wegmuss);
      if (wegmuss<extraOverlayPointSize.size())  extraOverlayPointSize.removeAt(wegmuss);
      if (wegmuss<altExtraIconPaths.size())  altExtraIconPaths.removeAt(wegmuss);
      extraDetach.removeAt(wegmuss);
      extraOptions.removeAt(wegmuss);
      extraExt2.removeAt(wegmuss);
    }
    altExtraIconPaths.append(altExtraIconPath);
    extraProgramNames.append(extraName->text().trimmed());
    extraProgramPaths.append(extraPath->text().trimmed());
    extraArguments.append(useArgument->checkState());
    extraOptions.append(extraArgumentsEdit->text().trimmed());
    extraExt2.append(extraAltExtEdit->text().trimmed());
    extraExtensions.append(omitExtension->checkState());
    extraResIns.append(copyResIns->checkState());
    extraOpenFileDialogBefore.append(openFileDialogBefore->checkState());
    extraIconOverlay.append(iconOverlay->checkState());
    extraOverlayPointSize.append(iovlPointSize->value());
    extraDetach.append(detach->checkState());
    mole.einstellung->beginGroup("Extra");
    mole.einstellung->beginWriteArray("ProgramNames",extraProgramNames.size());
    for (int i = 0; i < extraProgramNames.size(); i++) {
      mole.einstellung->setArrayIndex(i);
      mole.einstellung->setValue("Name", extraProgramNames.at(i));
    }
    mole.einstellung->endArray();
    mole.einstellung->endGroup();

    mole.einstellung->beginGroup("Extra");
    mole.einstellung->beginWriteArray("ProgramPaths",extraProgramPaths.size());
    for (int i = 0; i < extraProgramPaths.size(); i++) {
      mole.einstellung->setArrayIndex(i);
      mole.einstellung->setValue("Path", extraProgramPaths.at(i));
    }
    mole.einstellung->endArray();
    mole.einstellung->endGroup();

    mole.einstellung->beginGroup("Extra");
    mole.einstellung->beginWriteArray("AlternativeExtensions",extraExt2.size());
    for (int i = 0; i < extraExt2.size(); i++) {
      mole.einstellung->setArrayIndex(i);
      mole.einstellung->setValue("ext", extraExt2.at(i));
    }
    mole.einstellung->endArray();
    mole.einstellung->endGroup();

    mole.einstellung->beginGroup("Extra");
    mole.einstellung->beginWriteArray("CommandLineOptions",extraOptions.size());
    for (int i = 0; i < extraOptions.size(); i++) {
      mole.einstellung->setArrayIndex(i);
      mole.einstellung->setValue("opt", extraOptions.at(i));
    }
    mole.einstellung->endArray();
    mole.einstellung->endGroup();



    mole.einstellung->beginGroup("Extra");
    mole.einstellung->beginWriteArray("ProgramArgs",extraArguments.size());
    for (int i = 0; i < extraArguments.size(); i++) {
      mole.einstellung->setArrayIndex(i);
      mole.einstellung->setValue("Arg", extraArguments.at(i));
    }
    mole.einstellung->endArray();
    mole.einstellung->endGroup();

    mole.einstellung->beginGroup("Extra");
    mole.einstellung->beginWriteArray("ProgramExtensions",extraExtensions.size());
    for (int i = 0; i < extraExtensions.size(); i++) {
      mole.einstellung->setArrayIndex(i);
      mole.einstellung->setValue("Ext", extraExtensions.at(i));
    }
    mole.einstellung->endArray();
    mole.einstellung->endGroup();

    mole.einstellung->beginGroup("Extra");
    mole.einstellung->beginWriteArray("ProgramResIns",extraResIns.size());
    for (int i = 0; i < extraResIns.size(); i++) {
      mole.einstellung->setArrayIndex(i);
      mole.einstellung->setValue("Res2Ins", extraResIns.at(i));
    }
    mole.einstellung->endArray();
    mole.einstellung->endGroup();

    mole.einstellung->beginGroup("Extra");
    mole.einstellung->beginWriteArray("FileDialog",extraOpenFileDialogBefore.size());
    for (int i = 0; i < extraOpenFileDialogBefore.size(); i++) {
      mole.einstellung->setArrayIndex(i);
      mole.einstellung->setValue("fd", extraOpenFileDialogBefore.at(i));
    }
    mole.einstellung->endArray();
    mole.einstellung->endGroup();

    mole.einstellung->beginGroup("Extra");
    mole.einstellung->beginWriteArray("IconOverlay",extraIconOverlay.size());
    for (int i = 0; i < extraIconOverlay.size(); i++) {
      mole.einstellung->setArrayIndex(i);
      mole.einstellung->setValue("icov", extraIconOverlay.at(i));
    }
    mole.einstellung->endArray();
    mole.einstellung->endGroup();

    mole.einstellung->beginGroup("Extra");
    mole.einstellung->beginWriteArray("OverlayPointSize",extraOverlayPointSize.size());
    for (int i = 0; i < extraOverlayPointSize.size(); i++) {
      mole.einstellung->setArrayIndex(i);
      mole.einstellung->setValue("icov", extraOverlayPointSize.at(i));
    }
    mole.einstellung->endArray();
    mole.einstellung->endGroup();

    mole.einstellung->beginGroup("Extra");
    mole.einstellung->beginWriteArray("AltExtraIconPaths",altExtraIconPaths.size());
    for (int i = 0; i < altExtraIconPaths.size(); i++) {
      mole.einstellung->setArrayIndex(i);
      mole.einstellung->setValue("altIcon", altExtraIconPaths.at(i));
    }
    mole.einstellung->endArray();
    mole.einstellung->endGroup();

    mole.einstellung->beginGroup("Extra");
    mole.einstellung->beginWriteArray("ProgramDetached",extraDetach.size());
    for (int i = 0; i < extraDetach.size(); i++) {
      mole.einstellung->setArrayIndex(i);
      mole.einstellung->setValue("Detach", extraDetach.at(i));
    }
    mole.einstellung->endArray();
    mole.einstellung->endGroup();
    extraMenu->clear();
    extraTB->clear();
    extraMenu->addAction("add/remove external program",this,SLOT(extraSettings()));
    QFileIconProvider *p = new QFileIconProvider();
    if (extraProgramNames.size()) extraMenu->addSeparator();
    for (int i=0; i<extraProgramNames.size(); i++){
      QAction *a;
      QString icopa=extraProgramPaths.at(i);
      QFileIconProvider *epic = new QFileIconProvider();
      QPixmap fmap = epic->icon(QFileInfo(icopa)).pixmap(64,64);
      if (QFile::exists(altExtraIconPaths.at(i))) fmap=QIcon(altExtraIconPaths.at(i)).pixmap(64,64);
      delete epic;

      if (extraIconOverlay.at(i)==Qt::Checked){
        QPainter *paint = new QPainter(&fmap);
        paint->setPen(QPen(QColor("#FFFFFF")));
        QFont ifont=chgl->myFont;
        ifont.setPixelSize(extraOverlayPointSize.at(i)*fmap.height()/64);
        paint->setFont(ifont);
        paint->drawText(1,fmap.height()-5,extraProgramNames.at(i));
        paint->setPen(QPen(QColor("#000000")));
        paint->drawText(0,fmap.height()-4,extraProgramNames.at(i));
        paint->end();
      }
      extraIcon=QIcon(fmap);
      a=extraMenu->addAction(extraIcon,QString("run %1 !").arg(extraProgramNames.at(i)),this,SLOT(runExtra()));
      a->setData(i);
      extraTB->addAction(a);
    }
    delete p;

  }
  extDLG->deleteLater ();
  if (strcmp(PROGRAM_NAME,"shelXle")){
      QMessageBox::information(0,"information","Restart of APEX is required to make your changes to external programs active. ",QMessageBox::Ok);

  }
}
void Window::removeExtra(QAbstractButton *button){
  if (button->text()=="Remove program") {
    int wegmuss=extraProgramNames.indexOf(extraName->text());
    if (wegmuss!=-1) {
      extraProgramNames.removeAt(wegmuss);
      extraProgramPaths.removeAt(wegmuss);
      extraArguments.removeAt(wegmuss);
      extraExtensions.removeAt(wegmuss);
      if (wegmuss<extraResIns.size())  extraResIns.removeAt(wegmuss);
      if (wegmuss<extraOpenFileDialogBefore.size())  extraOpenFileDialogBefore.removeAt(wegmuss);
      if (wegmuss<extraIconOverlay.size())  extraIconOverlay.removeAt(wegmuss);
      if (wegmuss<extraOverlayPointSize.size())  extraOverlayPointSize.removeAt(wegmuss);
      if (wegmuss<altExtraIconPaths.size())  altExtraIconPaths.removeAt(wegmuss);
      extraOptions.removeAt(wegmuss);
      extraExt2.removeAt(wegmuss);
      extraDetach.removeAt(wegmuss);
    }
    while (extraOptions.size()>extraProgramNames.size()){extraOptions.removeLast();}
    while (extraExt2.size()>extraProgramNames.size()){extraExt2.removeLast();}
    mole.einstellung->beginGroup("Extra");
    mole.einstellung->beginWriteArray("ProgramNames",extraProgramNames.size());
    for (int i = 0; i < extraProgramNames.size(); i++) {
      mole.einstellung->setArrayIndex(i);
      mole.einstellung->setValue("Name", extraProgramNames.at(i));
    }
    mole.einstellung->endArray();
    mole.einstellung->endGroup();

    mole.einstellung->beginGroup("Extra");
    mole.einstellung->beginWriteArray("ProgramPaths",extraProgramPaths.size());
    for (int i = 0; i < extraProgramPaths.size(); i++) {
      mole.einstellung->setArrayIndex(i);
      mole.einstellung->setValue("Path", extraProgramPaths.at(i));
    }
    mole.einstellung->endArray();
    mole.einstellung->endGroup();


    mole.einstellung->beginGroup("Extra");
    mole.einstellung->beginWriteArray("ProgramArgs",extraArguments.size());
    for (int i = 0; i < extraArguments.size(); i++) {
      mole.einstellung->setArrayIndex(i);
      mole.einstellung->setValue("Arg", extraArguments.at(i));
    }
    mole.einstellung->endArray();
    mole.einstellung->endGroup();

    mole.einstellung->beginGroup("Extra");
    mole.einstellung->beginWriteArray("ProgramExtensions",extraExtensions.size());
    for (int i = 0; i < extraExtensions.size(); i++) {
      mole.einstellung->setArrayIndex(i);
      mole.einstellung->setValue("Ext", extraExtensions.at(i));
    }
    mole.einstellung->endArray();    
    mole.einstellung->endGroup();

    mole.einstellung->beginGroup("Extra");
    mole.einstellung->beginWriteArray("ProgramResIns",extraResIns.size());
    for (int i = 0; i < extraResIns.size(); i++) {
      mole.einstellung->setArrayIndex(i);
      mole.einstellung->setValue("Res2Ins", extraResIns.at(i));
    }
    mole.einstellung->endArray();
    mole.einstellung->endGroup();

    mole.einstellung->beginGroup("Extra");
    mole.einstellung->beginWriteArray("FileDialog",extraOpenFileDialogBefore.size());
    for (int i = 0; i < extraOpenFileDialogBefore.size(); i++) {
      mole.einstellung->setArrayIndex(i);
      mole.einstellung->setValue("fd", extraOpenFileDialogBefore.at(i));
    }
    mole.einstellung->endArray();
    mole.einstellung->endGroup();


    mole.einstellung->beginGroup("Extra");
    mole.einstellung->beginWriteArray("IconOverlay",extraIconOverlay.size());
    for (int i = 0; i < extraIconOverlay.size(); i++) {
      mole.einstellung->setArrayIndex(i);
      mole.einstellung->setValue("icov", extraIconOverlay.at(i));
    }
    mole.einstellung->endArray();
    mole.einstellung->endGroup();

    mole.einstellung->beginGroup("Extra");
    mole.einstellung->beginWriteArray("OverlayPointSize",extraOverlayPointSize.size());
    for (int i = 0; i < extraOverlayPointSize.size(); i++) {
      mole.einstellung->setArrayIndex(i);
      mole.einstellung->setValue("icov", extraOverlayPointSize.at(i));
    }
    mole.einstellung->endArray();
    mole.einstellung->endGroup();

    mole.einstellung->beginGroup("Extra");
    mole.einstellung->beginWriteArray("AltExtraIconPaths",altExtraIconPaths.size());
    for (int i = 0; i < altExtraIconPaths.size(); i++) {
      mole.einstellung->setArrayIndex(i);
      mole.einstellung->setValue("altIcon", altExtraIconPaths.at(i));
    }
    mole.einstellung->endArray();
    mole.einstellung->endGroup();

    mole.einstellung->beginGroup("Extra");
    mole.einstellung->beginWriteArray("ProgramDetached",extraDetach.size());
    for (int i = 0; i < extraDetach.size(); i++) {
      mole.einstellung->setArrayIndex(i);
      mole.einstellung->setValue("Detach", extraDetach.at(i));
    }
    mole.einstellung->endArray();
    mole.einstellung->endGroup();
    extraMenu->clear();

    extraMenu->addAction("add external program",this,SLOT(extraSettings()));
    extraTB->clear();
    QFileIconProvider *epic = new QFileIconProvider();
    if (extraProgramNames.size()) extraMenu->addSeparator();
    for (int i=0; i<extraProgramNames.size(); i++){
      QAction *a;
      QString icopa=extraProgramPaths.at(i);
      QPixmap fmap = epic->icon(QFileInfo(icopa)).pixmap(64,64);
      if (QFile::exists(altExtraIconPaths.at(i))) fmap=QIcon(altExtraIconPaths.at(i)).pixmap(64,64);
      if (extraIconOverlay.at(i)==Qt::Checked){
        QPainter *paint = new QPainter(&fmap);
        paint->setPen(QPen(QColor("#FFFFFF")));
        QFont ifont=chgl->myFont;
        ifont.setPixelSize(extraOverlayPointSize.at(i)*fmap.height()/64);
        paint->setFont(ifont);
        paint->drawText(1,fmap.height()-5,extraProgramNames.at(i));
        paint->setPen(QPen(QColor("#000000")));
        paint->drawText(0,fmap.height()-4,extraProgramNames.at(i));
        paint->end();
      }
      extraIcon=QIcon(fmap);
      a=extraMenu->addAction(extraIcon,QString("run %1 !").arg(extraProgramNames.at(i)),this,SLOT(runExtra()));
      a->setData(i);
      extraTB->addAction(a);
    }
    delete epic;

  }

}

void Window::updateExtraSettings(){
  updateExtraSettings(0);
}

void Window::updateExtraSettings(int index){
  if ((index<0)||(index>=extraProgramNames.size())) return;
  extraName->setText(extraProgramNames.at(index));
  extraPath->setText(extraProgramPaths.at(index));
  altExtraIconPath=(index<altExtraIconPaths.size())?altExtraIconPaths.at(index):"";
  extraArgumentsEdit->setText(extraOptions.at(index));
  extraAltExtEdit->setText(extraExt2.at(index));
  QFileIconProvider *epic = new QFileIconProvider();
  QString icopa=extraProgramPaths.at(index);
  QPixmap fmap = epic->icon(QFileInfo(icopa)).pixmap(64,64);
  if (QFile::exists(altExtraIconPaths.at(index))) fmap=QIcon(altExtraIconPaths.at(index)).pixmap(64,64);
  if (extraIconOverlay.at(index)==Qt::Checked){
    QPainter *paint = new QPainter(&fmap);
    paint->setPen(QPen(QColor("#FFFFFF")));
    QFont ifont=chgl->myFont;
    ifont.setPixelSize(iovlPointSize->value()*fmap.height()/64);
    paint->setFont(ifont);
    paint->drawText(1,fmap.height()-5,extraProgramNames.at(index));
    paint->setPen(QPen(QColor("#000000")));
    paint->drawText(0,fmap.height()-4,extraProgramNames.at(index));
    paint->end();
  }
  extraIcon=QIcon(fmap);
  extraFakeButton->setIcon(extraIcon);
  delete epic;
  useArgument->setCheckState(extraArguments.at(index));
  omitExtension->setCheckState(extraExtensions.at(index));
  if (index<extraResIns.size()) copyResIns->setCheckState(extraResIns.at(index));
  if (index<extraOpenFileDialogBefore.size()) openFileDialogBefore->setCheckState(extraOpenFileDialogBefore.at(index));
  if (index<extraIconOverlay.size()) iconOverlay->setCheckState(extraIconOverlay.at(index));
  if (index<extraOverlayPointSize.size()) iovlPointSize->setValue(extraOverlayPointSize.at(index));
  detach->setCheckState(extraDetach.at(index));
  update();
}

void Window::updateExtraIcon(){
  QPixmap fmap; 
  if (altExtraIconPath.isEmpty()){
    QFileIconProvider *epic = new QFileIconProvider();
    fmap = epic->icon(QFileInfo(extraPath->text())).pixmap(64,64);
    delete epic;
  }
  else{
    fmap = QIcon(altExtraIconPath).pixmap(64,64);

  }
  if (iconOverlay->isChecked()){
    QPainter *paint = new QPainter(&fmap);
    paint->setPen(QPen(QColor("#FFFFFF")));
    QFont ifont=chgl->myFont;
    ifont.setPixelSize(iovlPointSize->value()*fmap.height()/64);
    paint->setFont(ifont);
    paint->drawText(1, fmap.height()-5,extraName->text());
    paint->setPen(QPen(QColor("#000000")));
    paint->drawText(0, fmap.height()-4,extraName->text());
    paint->end();
  }
  extraIcon=QIcon(fmap);
  extraFakeButton->setIcon(extraIcon);

}

void Window::setExtraPath(){
  QString s =
    QFileDialog::getOpenFileName(this, "Path to external program executable", extraPath->text(), QString(),nullptr,(useNativeDlg->isChecked())?noneopt:QFileDialog::DontUseNativeDialog);
  if (!s.isEmpty()){
    extraPath->setText(s);
    updateExtraIcon();;
  }
}

void Window::brwsIcon(){
  QString path="";
#if defined (Q_WS_X11)
  path="/usr/share/pixmaps/";
#endif
  QString *filter=NULL,s=
    QFileDialog::getOpenFileName(this,QString("Select icon source"),//caption 
        path, "Icon files (*.xpm *.png *.ico *.svg);;",filter, (useNativeDlg->isChecked())?noneopt:QFileDialog::DontUseNativeDialog);
  if (QFile::exists(s)) altExtraIconPath=s;
  updateExtraIcon();
}

void Window::runExtra(){
  QAction *action = qobject_cast<QAction *>(sender());
  int index=0;
  if (action){
    index=action->data().toInt();
  } else {
    return;
  }
  if ((index<0)||(index>=extraProgramNames.size())) return;
  extraOutput->hide();
  delete extraOutput;
  extraIndex = index;
  extraOutput = new QDialog(this);
  lt = new QVBoxLayout();
  extraOutPut = new QTextEdit();
  QFont mospfo(FONTFAM);
  extraOutPut->setFont(mospfo);
  extraOutput->setMinimumWidth(
      QFontMetrics(extraOutPut->font())
      .width("#########################################################################################################################################"));
  extraOutPut->setLineWrapMode(QTextEdit::NoWrap);
  lt->addWidget(extraOutPut);
  extraOutput->setLayout(lt);
  extraOutput->setWindowTitle(QString("Running %1 ...").arg(extraProgramNames.at(index)));
  extraOutPut->clear();
  QString path,name;
  path=extraProgramPaths.at(index);
#if defined (Q_WS_MAC)
  if ((QFileInfo(path).isDir())&&(path.endsWith(".app",Qt::CaseInsensitive))){
    path.append("/Contents/MacOS/");
    path.append(QDir(path).entryList(QDir::Executable|QDir::Files).first());
  }
#endif
  QString dn=dirName.section('/',0,-2),
          argument=dirName.section('/',-1);
  if (extraOpenFileDialogBefore.at(index)==Qt::Checked){
    QString oMyDir=
      QFileDialog::getOpenFileName(this,QString("Open a file for %1").arg(extraProgramNames.at(index)),//caption 
          dn,QString(),nullptr,(useNativeDlg->isChecked())?noneopt:QFileDialog::DontUseNativeDialog);
    dn=oMyDir.section('/',0,-2);
    argument=oMyDir.section('/',-1);
  }
  if (extraExtensions.at(index)==Qt::Checked) argument.remove(QRegExp(".res$|.ins$|.p4p$|.cif$",Qt::CaseInsensitive));
  if (extraResIns.at(index)==Qt::Checked) {
    //##@##bruce will es
    //
    //printf("bruce will es\n");
    if (maybeSave2()){
      QString dn=dirName.section('/',0,-2),
              argument=dirName.section('/',-1);
      argument.remove(QRegExp(".res$|.ins$",Qt::CaseInsensitive));
      if (dirName.contains(QRegExp(".res$",Qt::CaseInsensitive))){
        QString insname =dirName;
        insname.replace(QRegExp(".res$",Qt::CaseInsensitive),".ins");

        QString fcfname = dirName;
        fcfname.replace(QRegExp(".res$",Qt::CaseInsensitive),".fcf");
        QString fcfname2 = dirName;
        fcfname2.replace(QRegExp(".res$",Qt::CaseInsensitive),".2fcf");
        if ((QFileInfo(dirName).lastModified()>=QFileInfo(insname).lastModified())){
          QDir work=QDir(QString("%1/%2saves/").arg(dn).arg(PROGRAM_NAME));
          QStringList filter;
          filter << QString("%1_*_.ins").arg(argument);
          QStringList resfs;
          resfs=work.entryList(filter,QDir::Files,QDir::Time|QDir::Reversed);
          int vers=0;
          if (resfs.isEmpty()) vers=1;
          else { 
            bool ok=true;
            for (int i = 0; i < resfs.size(); i++)
              vers = qMax(resfs.at(i).section("_",-2,-2).toInt(&ok,36),vers);
            vers++;
          }
          if (!work.exists ( QString("%1/%2saves/").arg(dn).arg(PROGRAM_NAME))) work.mkdir (QString("%1/%2saves/").arg(dn).arg(PROGRAM_NAME));
          QFile::copy(insname,QString("%1/%4saves/%2_%3_.ins").arg(dn).arg(argument).arg(vers,2,36,QLatin1Char('0')).arg(PROGRAM_NAME));
          QFile::remove(insname);
          QFile::copy(dirName,insname);

          QFile::copy(fcfname2,QString("%1/%4saves/%2_%3_.fcf").arg(dn).arg(argument).arg(vers,2,36,QLatin1Char('0')).arg(PROGRAM_NAME));
          QFile::remove(fcfname2);
          QFile::copy(fcfname,fcfname2);
        }
        else {
          int but=QMessageBox::information(0,"information",
              QString("<h3>The <b>ins</b>truction file is newer than the <b>res</b>ult file you are working on!</h3> %1 %2 <br> %3 <br> %4<br>Maybe you edited it outside of this program.\
                <br> Now the your computer clock says: %5<br>%6 %7 (negative numbers here probably indicate asynchronous clocks on network file systems.)<br><hr><b> Click on 'Ignore' to copy your current .res to .ins file and refine.</b>")
              .arg(insname)
              .arg(dirName)
              .arg(QFileInfo(insname).lastModified().toString(Qt::TextDate))
              .arg(QFileInfo(dirName).lastModified().toString(Qt::TextDate))
              .arg(QDateTime::currentDateTime().toString(Qt::TextDate))
#if (QT_VERSION >= 0x040700)
              .arg(QFileInfo(insname).lastModified().msecsTo(QDateTime::currentDateTime()))
              .arg(QFileInfo(dirName).lastModified().msecsTo(QDateTime::currentDateTime()))
#else 
              .arg(QFileInfo(insname).lastModified().secsTo(QDateTime::currentDateTime()))
              .arg(QFileInfo(dirName).lastModified().secsTo(QDateTime::currentDateTime()))

#endif
              ,QMessageBox::Ignore|QMessageBox::Ok);
          if (but==QMessageBox::Ignore){
            QDir work=QDir(QString("%1/%2saves/").arg(dn).arg(PROGRAM_NAME));
            QStringList filter;
            filter << QString("%1_*_.ins").arg(argument);
            QStringList resfs;
            resfs=work.entryList(filter,QDir::Files,QDir::Time|QDir::Reversed);
            int vers=0;
            if (resfs.isEmpty()) vers=1;
            else {
              bool ok=true;
              for (int i = 0; i < resfs.size(); i++)
                vers = qMax(resfs.at(i).section("_",-2,-2).toInt(&ok,36),vers);
              vers++;
            }
            if (!work.exists ( QString("%1/%2saves/").arg(dn).arg(PROGRAM_NAME))) work.mkdir (QString("%1/%2saves/").arg(dn).arg(PROGRAM_NAME));
            QFile::copy(insname,QString("%1/%4saves/%2_%3_.ins").arg(dn).arg(argument).arg(vers,2,36,QLatin1Char('0')).arg(PROGRAM_NAME));
            QFile::remove(insname);
            QFile::copy(dirName,insname);

            QFile::copy(fcfname2,QString("%1/%4saves/%2_%3_.fcf").arg(dn).arg(argument).arg(vers,2,36,QLatin1Char('0')).arg(PROGRAM_NAME));
            QFile::remove(fcfname2);
            QFile::copy(fcfname,fcfname2);
          }else{
            shxOutputDock->hide();
            infotainmentDock->hide();
            refineButtonBox->hide();
            pro7->hide();
            refineButtonBox2->hide();
            stoppRefinement->hide();
            stoppRefinement2->hide();
            finishRefinement->hide();
            finishRefinement2->hide();
            shxEditorDock->show();
            dock->show();
            histDock->show();
            return;
          }
        }
      }else{
        QDir work=QDir(QString("%1/%2saves/").arg(dn).arg(PROGRAM_NAME));
        QStringList filter;
        filter << QString("%1_*_.ins").arg(argument);
        QStringList resfs;
        resfs=work.entryList(filter,QDir::Files,QDir::Time|QDir::Reversed);
        int vers=0;
        if (resfs.isEmpty()) vers=1;
        else {
          bool ok=true;
          for (int i = 0; i < resfs.size(); i++)
            vers = qMax(resfs.at(i).section("_",-2,-2).toInt(&ok,36),vers);
          vers++;
        }
        if (!work.exists ( QString("%1/%2saves/").arg(dn).arg(PROGRAM_NAME))) work.mkdir (QString("%1/%2saves/").arg(dn).arg(PROGRAM_NAME));
        QFile::copy(dirName,QString("%1/%4saves/%2_%3_.ins").arg(dn).arg(argument).arg(vers,2,36,QLatin1Char('0')).arg(PROGRAM_NAME));

      }
    }
    /// bruce will es
  }
  if ((extraExt2.size()>index)&&(!extraExt2.at(index).isEmpty())){
    argument.remove(QRegExp(".res$|.ins$",Qt::CaseInsensitive));
    argument.append(extraExt2.at(index));
  }
  extraProc = new QProcess(this);
  QStringList al;
  if ((extraOptions.size()>index)&&(!extraOptions.at(index).isEmpty())) al.append(extraOptions.at(index));
  if (extraArguments.at(index)==Qt::Checked) al.append(argument);
  extraProc->setWorkingDirectory(dn);                           // updateXLput()
  connect(extraProc,SIGNAL(readyReadStandardOutput ()),this,SLOT(updateExtraOutput()));
  connect(extraProc,SIGNAL(finished(int,QProcess::ExitStatus)),this,SLOT(updateExtraOutput()));
  connect(extraProc,SIGNAL(error(QProcess::ProcessError)),this,SLOT(updateExtraOutput())); 
#if (QT_VERSION >= 0x040600)
  QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
  extraProc->setProcessEnvironment(env);//Thanks to Dr. Pavlo Solntsev!! 
#else
  QStringList env = QProcess::systemEnvironment();
  extraProc->setEnvironment(env);
#endif
  QString dummyargument=al.join(" ");
  al=dummyargument.split(" "); 
  if (extraDetach.at(index)) {

#if (QT_VERSION >= 0x050700)
#if defined Q_WS_WIN || defined Q_OS_WIN
	extraProc->setProgram(path);
	extraProc->setArguments(al);
	extraProc->setWorkingDirectory(dn);
        extraProc->setCreateProcessArgumentsModifier([] (QProcess::CreateProcessArguments *args) {args->flags &= ~CREATE_NO_WINDOW;});
	extraProc->startDetached();
/*
//https://bugreports.qt.io/browse/QTBUG-57687?focusedCommentId=354550&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-354550
QProcess p;
p.setProgram("cmd.exe");
p.setArguments({"/k", "echo", "Hello from Qt!"});
p.setCreateProcessArgumentsModifier([] (QProcess::CreateProcessArguments *args) {
        args->flags &= ~CREATE_NO_WINDOW;
    });
p.startDetached();
*/
#else
	extraProc->startDetached(path,al,dn);
#endif
#else
	extraProc->startDetached(path,al,dn);
#endif
      
  }
  else {
    extraProc->start(path,al);
    extraOutPut->setText(QString("|--- Running %1 %2 in %3 ---|\n").arg(path).arg(al.join(" ")).arg(dn));
    extraOutput->show();
  }
}

void Window::updateExtraOutput(){
  if (extraProc->pid()) {
    extraOutPut->setReadOnly(false);
    QString s=extraOutPut->toPlainText();
    s.append(extraProc->readAllStandardOutput());
    s.append(extraProc->readAllStandardError());
    extraOutPut->setPlainText(s);
    extraOutPut->moveCursor(QTextCursor::End); 
    extraOutPut->ensureCursorVisible ();
    extraOutPut->setReadOnly(true);
    extraProc->write("\n"); // this is sent to fake a 'pause' waiting for any key so that the script continues
  }else{
    extraOutPut->setReadOnly(false);
    QString s=extraOutPut->toPlainText();
    s.append(extraProc->readAllStandardOutput());
    s.append(extraProc->readAllStandardError());
    if (s.isEmpty()) {
        s.append("|---Program is not running!---|\n");
        extraIndex = -1;
    }
    else{
      if ((s.endsWith(" ---|\n"))&&(extraIndex>-1)){
          mole.einstellung->beginGroup("Extra");
          mole.einstellung->beginWriteArray("ProgramDetached",extraDetach.size());
          mole.einstellung->setArrayIndex(extraIndex);
          mole.einstellung->setValue("Detach", Qt::Checked);
          extraDetach[extraIndex] = Qt::Checked;
          mole.einstellung->endArray();
          mole.einstellung->endGroup();
          printf("There was no output. I will start this program detached in future. I hope that is Ok.\n");

      }
      if ((extraIndex == -21)&&(QFile::exists(pngName))){
      //here should be a png output file of povray be loaded
      QLabel *preview = new QLabel("");
      int eh = extraOutput->height(), ew = extraOutput->width();
      preview->setPixmap(QPixmap(pngName));
      if (qsaPNG==nullptr) qsaPNG = new QScrollArea(extraOutput);
      qsaPNG->setWidget(preview);
      lt->addWidget(qsaPNG);
      QString s=extraOutPut->toPlainText();
      s.append("\n|---Program is finished.---|\n");
      extraOutput->resize(ew,2*eh);
      }else{
      s.append("\n|---Program is finished.---|\n");
      QString dn=dirName.section('/',0,-2), argument=dirName.section('/',-1);
      argument.remove(QRegExp(".res$|.ins$",Qt::CaseInsensitive));
      QDir work=QDir(QString("%1/").arg(dn));
      QStringList filter;
      filter << QString("%1*.res").arg(argument)<< QString("%1*.ins").arg(argument);;
      QStringList resfs;
      resfs=work.entryList(filter,QDir::Files,QDir::Time|QDir::Reversed);
      QHBoxLayout *hbl=new QHBoxLayout();
      QToolButton *tbb0=new QToolButton();
      QAction *ac0=new QAction(QString("cancel"),this);
      connect(ac0,SIGNAL(triggered()),extraOutput,SLOT(reject()));
      tbb0->setDefaultAction(ac0);
      for (int i=0; i<resfs.size(); i++){
        QAction *ac=new QAction(QString("load %1").arg(resfs.at(i)),this);
        ac->setData(QString("%1/%2").arg(dn).arg(resfs.at(i)));
        connect(ac,SIGNAL(triggered()),this,SLOT(loadThisFile())); 
        QToolButton *tbb=new QToolButton();
        tbb->setDefaultAction(ac);
        hbl->addWidget(tbb);
      }
      hbl->addWidget(tbb0);
      lt->addLayout(hbl);
      }//-21
      extraIndex = -1;
    }
    extraOutPut->setPlainText(s);
    extraOutPut->moveCursor(QTextCursor::End); 
    extraOutPut->ensureCursorVisible ();
    extraOutPut->setReadOnly(true);
  }
}

void Window::loadThisFile(){
  extraOutput->hide();
  QAction *action = qobject_cast<QAction *>(sender());
  QString name="";
  if (action)
    name=action->data().toString();
  else return;
  if (name.isEmpty()) return;


  loadFile(name);
}

void Window::configureBottomToolbar(){
  QAction *action = qobject_cast<QAction *>(sender());
  int index=0;
  if (action)
    index=action->data().toInt();
  else return;
  if ((index>=0)&&(index<5)) bottomToolBar->setToolButtonStyle((Qt::ToolButtonStyle) index);
  if (index>32) {
    index-=32;
    addToolBarBreak();
    addToolBar((Qt::ToolBarArea) index,bottomToolBar);
  }
  mole.einstellung->beginGroup("ToolBar");
  mole.einstellung->setValue("SelectionToolBarStyle",bottomToolBar->toolButtonStyle());
  mole.einstellung->endGroup();

}

void Window::grossRC(const QString &text){
  QString s=text.toUpper ();
  resiResiClass->setText(s);
  update();
}

void Window::defineBarray() {
  //! This method adjusts the value for the B array in SHELXL according to the number of atoms.
  //! The calculation is not rocket science, but should work in every case.
  int barray;
  if (useMyBArray) {
    return;  // the user wants to have his own value;
  }
  barray = mole.asymm.size() * 9; // Can fail with very large molecules.
  if (barray > 3000) {  // B array == 3000 is defult
    shelxlArgs = shelxlArgs.simplified();
    if (!shelxlArgs.contains("-b")) {
      shelxlArgs += QString(" -b%1").arg(barray);
    } else {
      shelxlArgs.replace(QRegExp("\\s{0,2}\\-b\\s{0,1}\\d{0,8}"), QString(" -b%1").arg(barray));
    }
  }
}

void Window::runShelXL(){
  QAction *action = qobject_cast<QAction *>(sender());
  if (action){
    if (action->data().toInt()==1) {editor->insertAnis(); if (!fileSave(true,false)) return;}
    if (action->data().toInt()==2) {editor->insertActa(); if (!fileSave(true,false)) return;}
  }
  if (maybeSave2()){
    if (mole.qbeforehkl) deleteAllQ();
    //    printf("runXL line %d",__LINE__);
    editor->insertList6();
    xlPutor->clear();

    xlPutor->ListFile=false;
    //xlPutor->highlighter->loadHighlightPatterns(lstpatternfile);
    shxOutputDock->show();
    stoppRefinement->show();
    finishRefinement->show();    
    finishRefinement->setFocus();
    QObject::disconnect(stoppRefinement, 0, this, 0);
    if (infotainmentDock->isVisible())finishRefinement2->setFocus();
    stoppRefinement2->show();
    finishRefinement2->show();
    QObject::disconnect(stoppRefinement2, 0, this, 0);
    refineButtonBox->hide();
    pro7->hide();
    loadRes->show();
    refineButtonBox2->hide();
    loadRes2->show();
    shxEditorDock->hide();
    dock->hide();
    histDock->hide();
    renamDock->hide();
    QString dn=dirName.section('/',0,-2),
            argument=dirName.section('/',-1);
    argument.remove(QRegExp(".res$|.ins$",Qt::CaseInsensitive));
    if (dirName.contains(QRegExp(".res$",Qt::CaseInsensitive))){
      QString insname =dirName;
      insname.replace(QRegExp(".res$",Qt::CaseInsensitive),".ins");

      QString fcfname = dirName;
      fcfname.replace(QRegExp(".res$",Qt::CaseInsensitive),".fcf");
      QString fcfname2 = dirName;
      fcfname2.replace(QRegExp(".res$",Qt::CaseInsensitive),".2fcf");
      //      qDebug()<<QFileInfo(insname).lastModified().toString(Qt::TextDate)<<QFileInfo(dirName).lastModified().toString(Qt::TextDate)<<(QFileInfo(dirName).lastModified()>=QFileInfo(insname).lastModified());
      if (//(0)&&  
          (QFileInfo(dirName).lastModified()>=QFileInfo(insname).lastModified())){
        QDir work=QDir(QString("%1/%2saves/").arg(dn).arg(PROGRAM_NAME));
        QStringList filter;
        filter << QString("%1_*_.ins").arg(argument);
        QStringList resfs;
        resfs=work.entryList(filter,QDir::Files,QDir::Time|QDir::Reversed);
        int vers=0;
        if (resfs.isEmpty()) vers=1;
        else { 
          bool ok=true;
          for (int i = 0; i < resfs.size(); i++)
            vers = qMax(resfs.at(i).section("_",-2,-2).toInt(&ok,36),vers);
          vers++;
        }
        if (!work.exists ( QString("%1/%2saves/").arg(dn).arg(PROGRAM_NAME))) work.mkdir (QString("%1/%2saves/").arg(dn).arg(PROGRAM_NAME));
        QFile::copy(insname,QString("%1/%4saves/%2_%3_.ins").arg(dn).arg(argument).arg(vers,2,36,QLatin1Char('0')).arg(PROGRAM_NAME));
        QFile::remove(insname);
        QFile::copy(dirName,insname);

        QFile::copy(fcfname2,QString("%1/%4saves/%2_%3_.fcf").arg(dn).arg(argument).arg(vers,2,36,QLatin1Char('0')).arg(PROGRAM_NAME));
        QFile::remove(fcfname2);
        QFile::copy(fcfname,fcfname2);
      }
      else {
        int but=QMessageBox::information(0,"information",
            QString("<h3>The <b>ins</b>truction file is newer than the <b>res</b>ult file you are working on!</h3> %1 %2 <br> %3 <br> %4<br>Maybe you edited it outside of this program.\
              <br> Now the your computer clock says: %5<br>%6 %7 (negative numbers here probably indicate asynchronous clocks on network file systems.)<br><hr><b> Click on 'Ignore' to copy your current .res to .ins file and refine.</b>")
            .arg(insname)
            .arg(dirName)
            .arg(QFileInfo(insname).lastModified().toString(Qt::TextDate))
            .arg(QFileInfo(dirName).lastModified().toString(Qt::TextDate))
            .arg(QDateTime::currentDateTime().toString(Qt::TextDate))
#if (QT_VERSION >= 0x040700)
            .arg(QFileInfo(insname).lastModified().msecsTo(QDateTime::currentDateTime()))
            .arg(QFileInfo(dirName).lastModified().msecsTo(QDateTime::currentDateTime()))
#else 
            .arg(QFileInfo(insname).lastModified().secsTo(QDateTime::currentDateTime()))
            .arg(QFileInfo(dirName).lastModified().secsTo(QDateTime::currentDateTime()))

#endif
            ,QMessageBox::Ignore|QMessageBox::Ok);
        if (but==QMessageBox::Ignore){
          QDir work=QDir(QString("%1/%2saves/").arg(dn).arg(PROGRAM_NAME));
          QStringList filter;
          filter << QString("%1_*_.ins").arg(argument);
          QStringList resfs;
          resfs=work.entryList(filter,QDir::Files,QDir::Time|QDir::Reversed);
          int vers=0;
          if (resfs.isEmpty()) vers=1;
          else {
            bool ok=true;
            for (int i = 0; i < resfs.size(); i++)
              vers = qMax(resfs.at(i).section("_",-2,-2).toInt(&ok,36),vers);
            vers++;
          }
          if (!work.exists ( QString("%1/%2saves/").arg(dn).arg(PROGRAM_NAME))) work.mkdir (QString("%1/%2saves/").arg(dn).arg(PROGRAM_NAME));
          QFile::copy(insname,QString("%1/%4saves/%2_%3_.ins").arg(dn).arg(argument).arg(vers,2,36,QLatin1Char('0')).arg(PROGRAM_NAME));
          QFile::remove(insname);
          QFile::copy(dirName,insname);

          QFile::copy(fcfname2,QString("%1/%4saves/%2_%3_.fcf").arg(dn).arg(argument).arg(vers,2,36,QLatin1Char('0')).arg(PROGRAM_NAME));
          QFile::remove(fcfname2);
          QFile::copy(fcfname,fcfname2);
        }else{
          shxOutputDock->hide();
          infotainmentDock->hide();
          refineButtonBox->hide();
          pro7->hide();
          refineButtonBox2->hide();
          finishRefinement->hide();
          finishRefinement2->hide();
          stoppRefinement->hide();
          stoppRefinement2->hide();
          shxEditorDock->show();
          dock->show();
          histDock->show();
          return;
        }
      }
    }else{
      QDir work=QDir(QString("%1/%2saves/").arg(dn).arg(PROGRAM_NAME));
      QStringList filter;
      filter << QString("%1_*_.ins").arg(argument);
      QStringList resfs;
      resfs=work.entryList(filter,QDir::Files,QDir::Time|QDir::Reversed);
      int vers=0;
      if (resfs.isEmpty()) vers=1;
      else {
        bool ok=true;
        for (int i = 0; i < resfs.size(); i++)
          vers = qMax(resfs.at(i).section("_",-2,-2).toInt(&ok,36),vers);
        vers++;
      }
      if (!work.exists ( QString("%1/%2saves/").arg(dn).arg(PROGRAM_NAME))) work.mkdir (QString("%1/%2saves/").arg(dn).arg(PROGRAM_NAME));
      QFile::copy(dirName,QString("%1/%4saves/%2_%3_.ins").arg(dn).arg(argument).arg(vers,2,36,QLatin1Char('0')).arg(PROGRAM_NAME));

    }

    shxOutputDock->setWindowTitle(QString("SHELXL OUTPUT: %1").arg(argument));
    shelxl = new QProcess(this);

    QStringList al;
    al.append(argument);

    defineBarray();
    finishRefinement->setFocus();
    vis_settings->beginGroup("infotaiment");
    bool lastvis = vis_settings->value("info_as_default").toBool();
    vis_settings->endGroup();
    if (lastvis) {
      raiseTaff();
      finishRefinement2->setFocus();
    }
    al+=shelxlArgs.split(' ',skipEmptyParts);
    shelxl->setWorkingDirectory(dn);                           // updateXLput()
    connect(shelxl,SIGNAL(readyReadStandardOutput ()),this,SLOT(updateXLput()));
    connect(shelxl,SIGNAL(finished(int,QProcess::ExitStatus)),refineButtonBox ,SLOT(show()));
    if (focusSet) connect(shelxl,SIGNAL(finished(int,QProcess::ExitStatus)),loadRes ,SLOT(setFocus()));
    connect(shelxl,SIGNAL(finished(int,QProcess::ExitStatus)),refineButtonBox2 ,SLOT(show()));
    if ((lastvis)&&(focusSet)) connect(shelxl,SIGNAL(finished(int,QProcess::ExitStatus)),loadRes2 ,SLOT(setFocus()));
    connect(shelxl,SIGNAL(finished(int,QProcess::ExitStatus)),stoppRefinement ,SLOT(hide()));
    connect(shelxl,SIGNAL(finished(int,QProcess::ExitStatus)),finishRefinement ,SLOT(hide()));
    connect(shelxl,SIGNAL(finished(int,QProcess::ExitStatus)),finishRefinement2 ,SLOT(hide()));
    connect(shelxl,SIGNAL(finished(int,QProcess::ExitStatus)),stoppRefinement2 ,SLOT(hide()));
    connect(shelxl,SIGNAL(finished(int,QProcess::ExitStatus)),this,SLOT(updateXLput()));
    connect(shelxl,SIGNAL(finished(int,QProcess::ExitStatus)),this,SLOT(displayDisagreeableRestraints()));

    connect(shelxl,SIGNAL(error(QProcess::ProcessError)),this,SLOT(updateXLput())); 
    connect(finishRefinement,SIGNAL(clicked()),this,SLOT(finXL()));
    connect(finishRefinement2,SIGNAL(clicked()),this,SLOT(finXL()));
#if defined Q_WS_WIN || defined Q_OS_WIN
    connect(stoppRefinement,SIGNAL(clicked()),shelxl,SLOT(kill()));
    connect(stoppRefinement2,SIGNAL(clicked()),shelxl,SLOT(kill()));
#else
    connect(stoppRefinement,SIGNAL(clicked()),shelxl,SLOT(terminate()));
    connect(stoppRefinement2,SIGNAL(clicked()),shelxl,SLOT(terminate()));
#endif
    connect(stoppRefinement,SIGNAL(clicked()),loadRes,SLOT(hide()));
    connect(stoppRefinement2,SIGNAL(clicked()),loadRes2,SLOT(hide()));
    shelxl->start(shelxlPath,al);
    pro7->show();
  }
}

void Window::displayResiduals(XLOutputParser &lfo, QString s) {
  //! Draws the residuals of the refinement as a table
  //qDebug()<<s;
  RGraph lsdata;
  lsdata.cycle = 0;
  restr_table->clear();
  foreach (QString line, s.split(QRegExp("\n|\r\n|\r"))) {
    resid_label->setText(lfo.residualsTextDisplay(line, ls_cycls));
  }
}

void Window::displayDisagreeableRestraints() {
  //! Displays the list of disagreeable restraints in the restr_table widget
  //! This has to be started ofter SHELXL is finished! (via signal)
  QFileInfo lfi(dirName);
  QString restrtext = "There is no SHELXL list file available for this structure. Please refine to get output here.";
  QString lfpath;
  lfpath = lfi.absoluteFilePath().replace(".res", ".lst");
  if (QFile(lfpath).exists()) {
    ListFileHandler lf(lfpath);
    restrtext = lf.restraintsTable();
  }
  restr_table->setText(restrtext);
}

void Window::updateXLput(){
  XLOutputParser xlo;
  QString warn = "** NO running Process maybe the 'shelxl' is not in PATH or is spelled differently **\n\n"
    "** Please give a correct path to an existing executable of shelxl. **\n\n"
    "** Check SHELXL -> 'Specify SHELXL runtime options' **";
  if (infotainmentDock->isVisible())finishRefinement2->setFocus(); else finishRefinement->setFocus();
  if (shelxl->pid()&&shelxl->isOpen()) {
    xlPutor->setReadOnly(false);
    QString s=xlPutor->toPlainText();
    s.append(shelxl->readAllStandardOutput());
    s.append(shelxl->readAllStandardError());
    //qDebug()<<__LINE__<<s;
    displayResiduals(xlo, s);
    if (shelxl->state()==QProcess::NotRunning) {
      s.append(warn);
      resid_label->append("<b>" + warn.replace("\n", "<br>") + "</b>");
      refineButtonBox->show();
      stoppRefinement->hide();
      finishRefinement->hide();
      finishRefinement2->hide();
      refineButtonBox2->show();
      stoppRefinement2->hide();
    }
    xlPutor->setPlainText(s);
    falschAtom=-1;
    xlPutor->setReadOnly(true);
    loadRes->setEnabled((s.contains("for all data")));
    loadRes2->setEnabled((s.contains("for all data")));
    if ((focusSet)&&(!s.contains("for all data"))) withdraw->setFocus();
    if (s.contains(" ** ")) {
      QString Fehl=s.section("**",1,1).simplified();
      Fehl=Fehl.remove("UNSUITABLE AFIX HYDROGENS FOLLOW ");
      Fehl=Fehl.remove("BAD Ueq DEPENDENCE FOR ");
      Fehl=Fehl.remove("BAD AFIX FOR ");
      Fehl=Fehl.remove("BAD AFIX CONNECTIVITY: ");
      Fehl=Fehl.remove("NO PIVOT ATOM FOR RIGID GROUP CONTAINING ");
      Fehl=Fehl.simplified();
      Fehl=Fehl.section(' ',0,0);
      if ((Fehl.size()<5)||Fehl.contains('_')){
        chgl->mol->selectedatoms.clear();
        for (int i=0; i<chgl->mol->showatoms.size(); i++){
          if (!Fehl.compare(chgl->mol->showatoms.at(i).Label,Qt::CaseInsensitive)){
            chgl->mol->selectedatoms.append(chgl->mol->showatoms[i]);
            chgl->mol->selectedatoms.last().style=i;
          }
        }
        if (!chgl->mol->selectedatoms.isEmpty()) {
          chgl->centerSelection->setChecked(true);
          chgl->updateBondActions();
          chgl->updateGL();
          update();
          chgl->updateGL();
          falschAtom=chgl->mol->selectedatoms.last().style;
          jumpToAtom(chgl->mol->selectedatoms.last().style);

        }
      }
    }
  }else{
    xlPutor->setReadOnly(false);
    QString s=xlPutor->toPlainText();
    if (shelxl->isOpen()) {
    s.append(shelxl->readAllStandardOutput());
    s.append(shelxl->readAllStandardError());
    }
    //qDebug()<<__LINE__<<s;
    if (s.isEmpty()){
      s.append(warn);
      resid_label->append("<b>" + warn.replace("\n", "<br>") + "</b>");
    }
    xlPutor->setPlainText(s);
    xlPutor->setReadOnly(true);
    if (!s.contains("WGHT")){
      loadRes->setEnabled((s.contains("for all data")));
      loadRes2->setEnabled((s.contains("for all data")));
      refineButtonBox->show();
      stoppRefinement->hide();
      finishRefinement->hide();
      finishRefinement2->hide();
      refineButtonBox2->show();
      stoppRefinement2->hide();
    }
    if (!s.contains("Total elapsed")) {
      // SHELXL executed but didn't finish:
      resid_label->append("<b>SHELXL was terminated!</b>");
    }
  }

  QTextCursor tc = xlPutor->textCursor();
  tc.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
  xlPutor->setTextCursor(tc);
  xlPutor->ensureCursorVisible();
  update();
  if (infotainmentDock->isVisible())finishRefinement2->setFocus(); else finishRefinement->setFocus();
}

void Window::loadrefres(){
  dirName.replace(QRegExp(".ins$",Qt::CaseInsensitive),".res");
  shxOutputDock->hide();
  infotainmentDock->hide();

  refineButtonBox->hide();
  refineButtonBox2->hide();
  shxEditorDock->show();
  shxEditorDock->raise();

  loadFile(dirName);
}

void Window::replyFinished(QNetworkReply* antwort){
  QSettings *einstellung =new QSettings( QSettings::IniFormat, QSettings::UserScope ,PROGRAM_NAME,mole.mynewnameis );
  int ignore=0;
  einstellung->beginGroup("Updates");
  if (einstellung->contains("IgnoreUpdates"))
    ignore=einstellung->value("IgnoreUpdates").toInt();
  einstellung->endGroup();
  QString a=antwort->readAll();
  latestRev=a;
  bool ok;
  int lat=a.toInt(&ok,10);
  if (ok&&lat&&(0==(ignore&QMessageBox::No))){
    if ((lat-7)>Revision) {
      int later=
        QMessageBox::information(
            0,"information",QString(
              "<h3>This is revision: <font color=#aa66cc>%1"
              "</font><br> The latest available version is revision: <font color=#aa66cc> %2</font> "
              "New versions can be downloaded here: "
              "<a href=\"http://shelxle.org/shelx/index.php\">"
              "http://shelxle.org/shelx/index.php</a></h3>"
              "<h4>Please contact the author"
              " <a href=\"mailto:chuebsch@moliso.de\">chuebsch@moliso.de</a> if you find any bugs.<br> Thank you!</h4>"
              "<h3>Do you want to be reminded later?</h3>").arg(Revision).arg(lat)
            ,QMessageBox::Yes|QMessageBox::No,QMessageBox::Yes);

      einstellung->beginGroup("Updates");
      einstellung->setValue("IgnoreUpdates",later);
      einstellung->endGroup();
    }
  }else{
    latestRev="<font color=red> network unavailable, check failed.</font>";
  }
  antwort->close();
  antwort->deleteLater();
  disconnect(net,SIGNAL(finished(QNetworkReply*)),0,0);
  delete einstellung;
}

void Window::checkForUpdates(){
  //disconnect(net,SIGNAL(finished(QNetworkReply*)),0,0);
  connect(net, SIGNAL(finished(QNetworkReply*)), this, SLOT(isUpToDate(QNetworkReply*)));
  reply = net->get(QNetworkRequest(QUrl("http://shelxle.org/shelx/revision.php")));
}

void Window::isUpToDate(QNetworkReply* antwort){
  QSettings *einstellung =new QSettings( QSettings::IniFormat, QSettings::UserScope ,PROGRAM_NAME,mole.mynewnameis);
  //int ignore=0;
  einstellung->beginGroup("Updates");
  if (einstellung->contains("IgnoreUpdates"))
    //    ignore=
    einstellung->value("IgnoreUpdates").toInt();
  einstellung->endGroup();
  QString a=antwort->readAll();
  latestRev=a;
  bool ok;
  int lat=a.toInt(&ok,10);
  if (ok&&lat){
    int later=
      QMessageBox::information(
          0,"information",QString(
            "<h3>This is revision: <font color=#aa66cc>%1"
            "</font><br> The latest available version is revision: <font color=#aa66cc> %2</font> "
            "<h3>%3</h3>"
            "New versions can be downloaded here: "
            "<a href=\"http://shelxle.org/shelx/index.php\">"
            "http://shelxle.org/shelx/index.php</a></h3>"
            "<h4>Please contact the author"
            " <a href=\"mailto:chuebsch@moliso.de\">chuebsch@moliso.de</a> if you find any bugs.<br> Thank you!</h4>"
            "<h3>Do you want to be reminded for new versions at startup?</h3>").arg(Revision).arg(lat).arg(((lat-3)>Revision)?"You should probably update ShelXle.":"Your ShelXle is rather up to date.")
          ,QMessageBox::Yes|QMessageBox::No,QMessageBox::Yes);

    einstellung->beginGroup("Updates");
    einstellung->setValue("IgnoreUpdates",later);
    einstellung->endGroup();
  }else{
    latestRev="<font color=red> network unavailable, check failed.</font>";
    QMessageBox::information( 0,"information",latestRev);
  }
  antwort->close();
  antwort->deleteLater();

  disconnect(net,SIGNAL(finished(QNetworkReply*)),0,0);

}

void Window::changeLabelFont(){
  bool ok;
  QFont font = QFontDialog::getFont(&ok, chgl->myFont, this,"Change Label Font");
  if (ok) {
    font.setStyleStrategy(QFont::OpenGLCompatible);
    chgl->myFont=font;
    mole.einstellung->beginGroup("Fonts");
    mole.einstellung->setValue("LabelFont",chgl->myFont);
    mole.einstellung->endGroup();
    chgl->updateLabelTextures();
    chgl->updateGL();
  }
}

void Window::changeEditorFont(){
  bool ok;
  QFont font = QFontDialog::getFont(&ok, editor->font(), this,"Change Editor Font");
  if (ok) {
    font.setFixedPitch(true);
    mole.einstellung->beginGroup("Fonts");
    mole.einstellung->setValue("EditorFont",font);
    mole.einstellung->endGroup();
    editor->setFont(font);
    xlPutor->setFont(font);
  }
}

void Window::withdrawres(){
  if (dirName.contains(QRegExp(".res$",Qt::CaseInsensitive))){
    QString insname =dirName;
    insname.replace(QRegExp(".res$",Qt::CaseInsensitive),".ins");
    QString fcfname = dirName;
    fcfname.replace(QRegExp(".res$",Qt::CaseInsensitive),".fcf");
    QString fcfname2 = dirName;
    fcfname2.replace(QRegExp(".res$",Qt::CaseInsensitive),".2fcf");
    QFile::remove(dirName);
    QFile::copy(insname,dirName);
    QFile::remove(fcfname);
    QFile::copy(fcfname2,fcfname);
    editor->document()->setModified(false);
    loadFile(dirName);
  }
  shxOutputDock->hide();
  infotainmentDock->hide();
  refineButtonBox->hide();
  shxEditorDock->show();
  if (falschAtom!=-1){
    //    qDebug()<<"tata"<<falschAtom;
    chgl->mol->selectedatoms.clear();
    chgl->mol->selectedatoms.append(chgl->mol->showatoms[falschAtom]);
    chgl->mol->selectedatoms.last().style=falschAtom;
    chgl->centerSelection->setChecked(true);
    chgl->updateBondActions();
    chgl->updateGL();
    update();
    chgl->updateGL();
    jumpToAtom(falschAtom);

  }
}

void Window::loadLst(){
  xlPutor->clear();
  pro7->hide();
  QString listName=dirName;
  listName.replace(QRegExp(".ins$",Qt::CaseInsensitive),".lst");
  listName.replace(QRegExp(".res$",Qt::CaseInsensitive),".lst");
  QFile lstf(listName);
  int wl=0;
  if (lstf.open(QIODevice::ReadOnly|QIODevice::Text)){
    xlPutor->setReadOnly(false);
    xlPutor->ListFile=true;
    //  xlPutor->highlighter->setOutputStyle();
    shxOutputDock->setWindowTitle(QString("LIST FILE: %1").arg(listName.section('/', -1)));
    //    shxOutputDock->setWhatsThis("<h1>.lst file viewer</h1> The .lst file contains useful information about the refinement of your structure.");
    QString testS=QString(lstf.readAll().replace('\0','~'));
    xlPutor->setPlainText(testS);
    wl=testS.count("\n");
    lstf.close();
    shxOutputDock->show();
    shxOutputDock->lower();
    mole.einstellung->beginGroup("Cursor");
    if (mole.einstellung->contains("ListFilePos")){
      xlPutor->setReadOnly(false);
      int mipo= qMin(wl,mole.einstellung->value("ListFilePos",0).toInt());
      // printf("mipo %d\n",mipo);
      QTextCursor c=xlPutor->textCursor();
      // qDebug()<<c.isNull();
      c.movePosition(QTextCursor::Start);
      c.movePosition(QTextCursor::Down,QTextCursor::MoveAnchor,mipo);
      if (!c.isNull()) xlPutor->setTextCursor(c);
      xlPutor->centerCursor();
      xlPutor->setReadOnly(true);
    }
    mole.einstellung->endGroup();
    xlPutor->setReadOnly(true);
    //  shxOutputDock->raise();
  }else {
      shxOutputDock->lower();
      shxOutputDock->hide();
  }

  update();
}

void Window::loadFile(QString fileName){
  //! Loads the shelxfile, sets the last cursor position in editor, saves "last file" entry in config,
  //! checks if file is valid in terms of UNIT, HKLF and END instructions, loads list file, runs the editor.
  mole.vtriangles.clear();
  mole.vorobas=0;
  chgl->setLabelSize(0.3);
  QDir directory(fileName);
  QString dn=directory.canonicalPath();
  if ((editor->toPlainText().length()>79)){//(dn!=dirName)&&
    QTextCursor c=editor->textCursor();
    if (!c.isNull()){
      myHash[dirName]=c.position();
      mole.einstellung->beginGroup("Cursor");
      mole.einstellung->setValue("lastCursorHash", myHash );
      mole.einstellung->setValue("ListFilePos",xlPutor->midCursorpos);
      mole.einstellung->endGroup();
    }
  }
  dirName=dn;
  mole.einstellung->beginGroup("Files");
  mole.einstellung->setValue("lastFile", dirName );
  mole.einstellung->endGroup();
  fileName=dirName;
  if (fileName.isEmpty()) return;
  bool gut=false;
  QFile test;
  // alltest will contain the shelxfile that is displayed:
  QString alltest;
  test.setFileName(fileName);
  if (test.exists()&&test.size()){
    test.open(QIODevice::ReadOnly|QIODevice::Text);
    alltest=test.readAll().replace('\0','~');// title can be empty. Fortran then has a string with many \0 this would leed to end of string in Rfactor REMARK section as the title is there 

    gut = ((alltest.contains("UNIT",Qt::CaseInsensitive))&&(alltest.contains("HKLF",Qt::CaseInsensitive)||alltest.contains("END",Qt::CaseInsensitive)));
    test.close();
  } 
  if (!gut){
    fileName.replace(QRegExp("res$",Qt::CaseInsensitive),"ins");
    test.setFileName(fileName);
    if (test.exists()&&test.size()){
      test.open(QIODevice::ReadOnly|QIODevice::Text);
      alltest=test.readAll();
      gut = ((alltest.contains("UNIT",Qt::CaseInsensitive))&&(alltest.contains("HKLF",Qt::CaseInsensitive)||alltest.contains("END",Qt::CaseInsensitive)));
      test.close();
      if (gut ) dirName=fileName;
    }
  }
  if (!gut) {
    QMessageBox::information(this, "information", QString("Can't open %1").arg(fileName));
    test.open(QIODevice::ReadOnly|QIODevice::Text);
    alltest=test.readAll();
    test.close();
    return;  
  }

  packMenu->setEnabled(true);

  if ((Revision%666)==0) {
    setWindowTitle(QString("%1 - A Qt GUI for sHELLxl (Rev: %2): %3[*] ")
        .arg(PROGRAM_NAME)
        .arg(Revision)
        .arg(fileName.section("/",-1)));
  } else {
    setWindowTitle(QString("%1 - A Qt GUI for SHELXL (Rev: %2)(%4bit): %3[*] ")
        .arg(PROGRAM_NAME)
        .arg(Revision)
        .arg(fileName.section("/",-1))
        .arg(BitWidth));
  }
  notRefine = alltest.contains("DISABLE_REFINE");// this has to be here to work correctly
  if (alltest.contains("OVERRIDEF000")) {
    double str = alltest.section("OVERRIDEF000",1,-1).section('\n',0,1).simplified().toDouble();
    fxle->overridef000=(float)str;
    //qDebug()<<str<<"hier";
  }
  runMenu->setDisabled(notRefine);
  packMenu->setDisabled(notRefine);
  refineToolBar->setDisabled(notRefine);
  refineToolBar->setVisible(!notRefine);
  alltest.replace(QRegExp("=\\s*[\\r\\n]+\\s{1,}"),"=");
  alltest.replace(QRegExp("REM[^\\n]*\n"),"\n");
  alltest.replace(QRegExp("![^\\n]*\n"),"\n");
  while (alltest.contains(QRegExp("[\\n^]\\++[^\\n]*\n"))) {
    QString incl=alltest.section(QRegExp("[\\n^]\\++"),1,1,QString::SectionSkipEmpty);
    incl=incl.section('\n',0,0);
    QString pre=dirName.section('/',0,-2);
//    qDebug()<<pre+"/"+incl<<QFileInfo(pre+"/"+incl).exists()<<dirName;
    if (QFileInfo(pre+"/"+incl).exists()) {
      QFile include(pre+"/"+incl);
      QString inst;
      if (include.open(QIODevice::ReadOnly|QIODevice::Text)) inst=include.readAll();
      alltest.replace("++" + incl, inst);
      alltest.replace("+" + incl, inst);
    } else {
      alltest.remove("++" + incl);
      alltest.remove("+" + incl);
    }
  }
  loadLst();
  //printf("after loadLst()\n");
  load_sheldrick(fileName, alltest);  
  //printf("after load_sheldrick()\n");
  shx_editor(fileName);  
 // printf("after shx_editor()\n");
  if (!fileName.contains("helXlesaves")){//do not remember files loaded from a saves folder ... lets see if this is a good idea :-P
  mole.einstellung->beginGroup("Files");
  mole.einstellung->setValue("lastFile", fileName );
  QStringList files = mole.einstellung->value("recentFileList").toStringList();
  files.removeAll(fileName); //alle identischen "fileName" aus der Liste entfernen
  files.prepend(fileName); // und dann vorne anfuegen...
  while (files.size() > MaxRecentFiles) {
    files.removeLast() ;//hinten abschneiden was laenger als MaxRecentFiles ist
  }
  mole.einstellung->setValue("recentFileList", files);
  foreach (QWidget *widget, QApplication::topLevelWidgets()) {
    Window *mainWin = qobject_cast<Window *>(widget);
    if (mainWin)
      mainWin->updateRecentFileActions();
  }
  mole.einstellung->endGroup();
  }
  hw->setPath(fileName, dock->width());
  if (hw->gooddata.size()) histDock->show();
  chgl->updateLabelTextures();
  emit fileLoaded();
  if ((toggleOrthoView->isChecked())&&(chgl->viewAngle>3.0)) {
    toggleOrtho(true);
    chgl->updateGL();
    // qDebug()<<chgl->viewAngle;  
  } 
  chgl->updateGL();
}

void Window::openRecentFile() {
  QAction *action = qobject_cast<QAction *>(sender());
  if (action)
    loadFile(action->data().toString());
}

void Window::setSDMLimit(){
  bool ok;
  int i = QInputDialog::getInt(this,"limit",
      "number of atoms in asymmetric unit to skip automatic distance calculation on loading" , chgl->SDM_Limit, 100, 10000, 1, &ok);
  if (ok)
    chgl->SDM_Limit=i;

}

void Window::closeEvent(QCloseEvent *event)  {
  //printf("Close Event\n");
  chgl->clearEnvi();
  //printf("Close Event survived clearEnvi\n");
  if (isFullScreen ())showNormal();
  if (maybeSave()){
    mole.einstellung->beginGroup("Window");
    mole.einstellung->setValue("geometry", saveGeometry());
    mole.einstellung->setValue("state", saveState());
    mole.einstellung->setValue("EditorState",shxMW->saveState());
    mole.einstellung->setValue("InvertMouseZoom",(chgl->invertMouseZoom->isChecked()));
    mole.einstellung->setValue("SDM-LIMIT", chgl->SDM_Limit);
    mole.einstellung->setValue("Calculate-Maps",fxle->doMaps->isChecked());
    mole.einstellung->setValue("KeepMapIsoValues",fxle->keepIso->isChecked());
    mole.einstellung->setValue("Fo-Map",chgl->foact->isChecked());
    mole.einstellung->setValue("Fc-Fo-Map",chgl->fofcact->isChecked());
    mole.einstellung->setValue("Map-truncation-type",fxle->mapSchnitt->currentIndex());
    mole.einstellung->setValue("Map-Line-Transparency",chgl->lintrans);
    mole.einstellung->setValue("Map-Line-Width", chgl->linwidth);
    mole.einstellung->setValue("Map-Resolution",fxle->rr);
    mole.einstellung->setValue("Map-Weight",fxle->rw);
    mole.einstellung->setValue("Map-Lighting",chgl->lighting->isChecked());
    mole.einstellung->setValue("Nice-Transparency",chgl->niceTrans->isChecked());
    mole.einstellung->setValue("Solid-Map",chgl->fillMap->isChecked());
    mole.einstellung->setValue("HighlightEquivalents",mole.highlightEquivalents);
    mole.einstellung->setValue("ADPs",togElli->isChecked());
    mole.einstellung->setValue("Tubes",tubeStyle->isChecked());
    mole.einstellung->setValue("Legend",chgl->atomLegend->isChecked());
    mole.einstellung->setValue("ShowLabels",togLabel->isChecked());
    mole.einstellung->setValue("BackGroundGradient",togBackGr->isChecked());
    mole.einstellung->setValue("SHELXL-PATH",shelxlPath);
    mole.einstellung->setValue("LevelOfDetail",mole.LOD);
    mole.einstellung->setValue("Use_GLSL_Shaders",mole.useShaders);
    mole.einstellung->setValue("WireModelOnRotate",chgl->wireButt->isChecked());
    mole.einstellung->endGroup();
    mole.einstellung->beginGroup("Colors");
    mole.einstellung->setValue("LabelColor",chgl->labelColor);
    mole.einstellung->setValue("BackGroundColor",chgl->backGroundColor);
    mole.einstellung->endGroup();
    mole.einstellung->beginGroup("Files");
    mole.einstellung->setValue("lastFile", dirName );
    mole.einstellung->endGroup();
    mole.einstellung->beginGroup("Fonts");
    mole.einstellung->setValue("EditorFont",editor->font());
    mole.einstellung->setValue("LabelFont",chgl->myFont);
    mole.einstellung->endGroup();
    mole.einstellung->beginGroup("ToolBarIcons");
    mole.einstellung->setValue("ToolBarIconSize",tbiconSize);
    mole.einstellung->endGroup();
    mole.einstellung->beginGroup("TextureLabels");
    mole.einstellung->setValue("useTextures4Labels",chgl->useTextureLabels->isChecked());
    mole.einstellung->endGroup();
    QTextCursor c=editor->textCursor();
    if (!c.isNull()){
      myHash[dirName]=c.position();
      mole.einstellung->beginGroup("Cursor");
      mole.einstellung->setValue("lastCursorHash", myHash );
      mole.einstellung->endGroup();
    }
    //printf("Close Event survived Einstellungen.\n");
    delete  mole.einstellung;
    //printf("deleting\n");
//  printf("%d\n",__LINE__);
    editor->clear();
	mole.asymm.clear();
//	printf("%d\n",__LINE__);
    mole.sdm.clear();
//	printf("%d\n",__LINE__);
    mole.showatoms.clear();
//	printf("%d\n",__LINE__);
    mole.showbonds.clear();
//	printf("%d\n",__LINE__);
    mole.cell.symmops.clear();
//	printf("%d\n",__LINE__);
    mole.cell.trans.clear();
//	printf("%d\n",__LINE__);
    mole.selectedatoms.clear();
//	printf("%d\n",__LINE__);
    editor->sfac.clear();
//	printf("%d\n",__LINE__);
    fvar.clear();
//	printf("%d\n",__LINE__);
    fvarCntr.clear();
//	printf("%d\n",__LINE__);
    mole.transEQIV.clear();
//	printf("%d\n",__LINE__);
    mole.symmopsEQIV.clear();
//	printf("%d\n",__LINE__);
    mole.labelEQIV.clear();
//	printf("%d\n",__LINE__);
    mole.freeatoms.clear();
//	printf("%d\n",__LINE__);
    mole.bindatoms.clear();
//	printf("%d\n",__LINE__);
    disconnect(this);
//	printf("%d\n",__LINE__);
    disconnect(editor);
//	printf("%d %p\n", __LINE__, chgl);
    disconnect(chgl);
	
//	printf("%d\n",__LINE__);
    mole.asymm.clear();
//	printf("%d\n",__LINE__);
    mole.sdm.clear();
//	printf("%d\n",__LINE__);
    mole.showbonds.clear();
//	printf("%d\n",__LINE__);
    mole.showatoms.clear();
//	printf("%d\n",__LINE__);
    mole.selectedatoms.clear();
//	printf("%d\n",__LINE__);

    mole.envi_sdm.clear();
//	printf("%d\n",__LINE__);
    mole.contact.clear();
//	printf("%d\n",__LINE__);
    mole.symmopsEQIV.clear();
//	printf("%d\n",__LINE__);
    mole.labelEQIV.clear();
//	printf("%d\n",__LINE__);
    mole.transEQIV.clear();
//	printf("%d\n",__LINE__);
    mole.freeatoms.clear();
//	printf("%d\n",__LINE__);
    mole.bindatoms.clear();
//	printf("%d\n",__LINE__);
    for (int i=0; i<mole.knoepfe.size();i++) mole.knoepfe[i].neighbors.clear();
    mole.knoepfe.clear();
//	printf("%d\n",__LINE__);
    mole.cell.symmops.clear();
//	printf("%d\n",__LINE__);
    mole.cell.trans.clear();
//	printf("%d\n",__LINE__);
    //printf("Close Event survived!! Good bye! Ade! Ciao!\n");
    event->accept();
  }
  else{
    event->ignore();
    //printf("Close Event survived and Ignored\n");
  }
}

void Window::changeScalefactor(){
  widthBox->disconnect();
  heightBox->disconnect();
  scalefBox->disconnect();
  widthBox->setValue(int(chgl->width()*scalePic+0.5));
  heightBox->setValue(int(chgl->height()*scalePic+0.5));
  scalefBox->setValue(scalePic*100.0);
  connect(widthBox,SIGNAL(valueChanged(int)),this,SLOT(updateScaleDlg()));
  connect(heightBox,SIGNAL(valueChanged(int)),this,SLOT(updateScaleDlg()));
  connect(scalefBox,SIGNAL(valueChanged(double)),this,SLOT(updateScaleDlg()));
  scalDlg->exec();  
}

void Window::updateScaleDlg(){
  QObject *o = qobject_cast<QObject *>(sender());
  if (o) {
    QString name = o->objectName();
    widthBox->disconnect();
    heightBox->disconnect();
    scalefBox->disconnect();
    if (name=="scalefBox"){
      scalePic=scalefBox->value()*0.01;
      widthBox->setValue(int(chgl->width()*scalePic+0.5));
      heightBox->setValue(int(chgl->height()*scalePic+0.5));
    } else if (name=="widthBox"){
      scalePic= (double (widthBox->value() -0.5) / chgl->width()) ;
      heightBox->setValue(int(chgl->height()*scalePic+0.5));
      scalefBox->setValue(scalePic*100.0);
    } else if (name=="heightBox"){
      scalePic= (double (heightBox->value() -0.5) / chgl->height()) ;
      widthBox->setValue(int(chgl->width()*scalePic+0.5));
      scalefBox->setValue(scalePic*100.0);
    }
    scalDlg->update();

    connect(widthBox,SIGNAL(valueChanged(int)),this,SLOT(updateScaleDlg()));
    connect(heightBox,SIGNAL(valueChanged(int)),this,SLOT(updateScaleDlg()));
    connect(scalefBox,SIGNAL(valueChanged(double)),this,SLOT(updateScaleDlg()));
  }
}

void Window::updateSelectResi(){
  QStringList l = editor->document()->toPlainText().split('\n');
  if (editor->resiFinder == NULL) return;
  editor->resiFinder->clear();
  editor->resiFinder->addItem("<Select residues>",-1);
  for (int i=0; i<l.size();i++){
    if ((l.at(i).startsWith("RESI",Qt::CaseInsensitive))&&(!l.at(i).contains(QRegExp(" 0\\b"))))
      editor->resiFinder->addItem(l.at(i).trimmed(),i);
    //    if (l.at(i).startsWith("MOLE",Qt::CaseInsensitive))
    //    resiFinder->addItem(l.at(i).trimmed(),i);
  }
  int mi=1,ma=-1;
  for (int i=0;i<editor->parenthesis2.size();i++){
    mi=qMin(editor->parenthesis2.at(i),mi);
    ma=qMax(editor->parenthesis2.at(i),ma);
  }
  spinSelectPart->setMinimum(mi);
  spinSelectPart->setMaximum(ma);
}

void Window::selectParts(){
  int pt=spinSelectPart->value();
  bool b=inculdePartNull->isChecked();
  chgl->mol->selectedatoms.clear();
  int hidden=0;
  if (selectPart->isChecked()){
    for (int i=0; i<chgl->mol->showatoms.size();i++){
      hidden+=chgl->mol->showatoms.at(i).hidden;
      if (chgl->mol->showatoms.at(i).part==pt){
        chgl->mol->selectedatoms.append(chgl->mol->showatoms[i]);
        chgl->mol->selectedatoms.last().style=i;
      }
      if ((pt!=0)&&(chgl->mol->showatoms.at(i).part==0)&&b){
        chgl->mol->selectedatoms.append(chgl->mol->showatoms[i]);
        chgl->mol->selectedatoms.last().style=i;
      }
    }
  }
  if (hidden) chgl->hideNonSelected();
  chgl->updateBondActions();
  chgl->updateGL();
  update();
  chgl->updateGL();
}

void Window::resiSelectorCheck(){
  QTextCursor tc = editor->textCursor();
  int l,c=0,rnr=-1;
  l=tc.blockNumber();
  while ((c<editor->resiFinder->count())&&(l>=(rnr=editor->resiFinder->itemData(c).toInt()))) {c++;}
  if (c) editor->resiFinder->setCurrentIndex(c-1);
  update();
}

void Window::fuse(){
  chgl->disSelection();
  chgl->mol->fuse();
  infoKanalNews(chgl->mol->HumanSymmetry);
  chgl->murx=__LINE__;
  chgl->setMolecule(&mole);
  chgl->fuse->setVisible(false);
  chgl->grow->setVisible(true);
  chgl->updateGL();
  update();
  chgl->updateGL();
}

void Window::uniq(){
  if (mole.asymm.isEmpty()) return;
  chgl->pause=true;
  chgl->disSelection();
  if ((mole.maxmols()==0)||(quickReLoadButton->isChecked())) sdm();
  chgl->mol->uniqueInCell();
  infoKanalNews(chgl->mol->HumanSymmetry);
  QTextDocument *document = editor->document();
  QTextCursor cursor = editor->textCursor();
  cursor.beginEditBlock ();

  for (int i=0; i<mole.asymm.size();i++){
    cursor.movePosition(QTextCursor::Start);
    QString label=mole.asymm.at(i).orginalLine.left(80).trimmed();
    cursor = document->find(label ,cursor);  

    if (cursor.isNull()){
      cursor = editor->textCursor();    
      cursor.movePosition(QTextCursor::Start);
      label.chop(10);
      cursor = document->find(label,cursor);
      if (cursor.isNull()) {
        cursor = editor->textCursor();
      }
    }
    QString vorherig,neues;
    cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
    cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
    while (cursor.selectedText().endsWith("=")) {
      cursor.movePosition(QTextCursor::Down,QTextCursor::KeepAnchor);
      cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);  
    }
    neues = vorherig= cursor.selectedText();
    QStringList sl = vorherig.split(QRegExp("\\s+"));
    sl.removeOne("=");
    if (sl.size()>=7)
      neues=QString("%1  %2  %3 %4 %5 %6 %7 ")
        .arg(mole.asymm.at(i).Label.section('_',0,0),-4)
        .arg(qMax(1,editor->sfac.indexOf(mole.asymm.at(i).an)+1))
        .arg(mole.asymm.at(i).frac.x,10,'f',6)
        .arg(mole.asymm.at(i).frac.y,10,'f',6)
        .arg(mole.asymm.at(i).frac.z,10,'f',6)
        .arg(mole.asymm.at(i).sof_org,9,'f',5)
        .arg((mole.asymm.at(i).isIso)?mole.asymm.at(i).ufiso_org:QString("%1").arg(mole.asymm.at(i).uf.m11,9,'f',5));
    if (mole.asymm.at(i).an<0) {
      neues.append(QString("%1 ")
          .arg(mole.asymm.at(i).peakHeight,9,'f',2));
    } else
      if (!mole.asymm.at(i).isIso){
        neues.append(QString("%1 =\n    %2 %3 %4 %5")
            .arg(mole.asymm.at(i).uf.m22,9,'f',5)
            .arg(mole.asymm.at(i).uf.m33,9,'f',5)
            .arg(mole.asymm.at(i).uf.m23,9,'f',5)
            .arg(mole.asymm.at(i).uf.m13,9,'f',5)
            .arg(mole.asymm.at(i).uf.m12,9,'f',5));
      } 
    cursor.deleteChar();
    cursor.insertText(neues);
    mole.asymm[i].orginalLine=neues.section("=",0,0);

  }//i
  cursor.endEditBlock ();

  grow();
  chgl->pause=false;
//  printf("%d\n",__LINE__);
}

void Window::grow(){
  chgl->disSelection();
  chgl->mol->grow();
  infoKanalNews(chgl->mol->HumanSymmetry);
  chgl->murx=__LINE__;
  chgl->setMolecule(&mole);
  chgl->fuse->setVisible(true);
  chgl->grow->setVisible(false);
  chgl->updateGL();
  update();
  chgl->updateGL();
}

void Window::expandAll(){
  chgl->disSelection();
  chgl->mol->expandAll();
  infoKanalNews(chgl->mol->HumanSymmetry);
  chgl->murx=__LINE__;
  chgl->setMolecule(&mole);
  chgl->fuse->setVisible(true);
  chgl->grow->setVisible(false);
  chgl->updateGL();
}

void Window::fillCell(){
  chgl->disSelection();
  chgl->mol->fillCell();
  infoKanalNews(chgl->mol->HumanSymmetry);
  chgl->murx=__LINE__;
  chgl->setMolecule(&mole);
  chgl->fuse->setVisible(true);
  chgl->grow->setVisible(false);
  chgl->updateGL();
}

void Window::packInLimits(){
  QDialog *boxpack= new QDialog(this);
  QDoubleSpinBox 
    *aminlim,*amaxlim,
    *bminlim,*bmaxlim,
    *cminlim,*cmaxlim;
  aminlim = new QDoubleSpinBox(boxpack);
  amaxlim = new QDoubleSpinBox(boxpack);
  bminlim = new QDoubleSpinBox(boxpack);
  bmaxlim = new QDoubleSpinBox(boxpack);
  cminlim = new QDoubleSpinBox(boxpack);
  cmaxlim = new QDoubleSpinBox(boxpack);
  aminlim->setMinimum(-10.0);
  amaxlim->setMinimum(0.0);
  bminlim->setMinimum(-10.0);
  bmaxlim->setMinimum(0.0);
  cminlim->setMinimum(-10.0);
  cmaxlim->setMinimum(0.0);
  aminlim->setMaximum(1.0);
  amaxlim->setMaximum(10.0);
  bminlim->setMaximum(1.0);
  bmaxlim->setMaximum(10.0);
  cminlim->setMaximum(1.0);
  cmaxlim->setMaximum(10.0);
  aminlim->setValue(0.0);
  amaxlim->setValue(1.0);
  bminlim->setValue(0.0);
  bmaxlim->setValue(1.0);
  cminlim->setValue(0.0);
  cmaxlim->setValue(1.0);
  QDialogButtonBox *buttonBox = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
  connect(buttonBox, SIGNAL(rejected()), boxpack, SLOT(reject())); 
  connect(buttonBox, SIGNAL(accepted()), boxpack, SLOT(accept())); 
  QGridLayout *g = new QGridLayout(boxpack);
  g->addWidget(new QLabel("pack range along a "),0,0);
  g->addWidget(aminlim,1,0);
  g->addWidget(amaxlim,2,0);
  g->addWidget(new QLabel("pack range along b "),0,1);
  g->addWidget(bminlim,1,1);
  g->addWidget(bmaxlim,2,1);
  g->addWidget(new QLabel("pack range along c "),0,2);
  g->addWidget(cminlim,1,2);
  g->addWidget(cmaxlim,2,2);
  g->addWidget(buttonBox,10,0,1,3);
  if (QDialog::Accepted==boxpack->exec()){
    chgl->disSelection();
    chgl->mol->showatoms.clear();
    chgl->mol->packInLimits(aminlim->value(),amaxlim->value(),bminlim->value(),bmaxlim->value(),cminlim->value(),cmaxlim->value());
    chgl->murx=__LINE__;
    chgl->setMolecule(&mole);
    chgl->fuse->setVisible(true);
    chgl->grow->setVisible(false);
    chgl->updateGL();
  }

}

void Window::complete(){
  chgl->disSelection();
  chgl->mol->grow_plus();
  infoKanalNews(chgl->mol->HumanSymmetry);
  chgl->murx=__LINE__;
  chgl->setMolecule(&mole);
  chgl->fuse->setVisible(true);
  chgl->grow->setVisible(false);
  chgl->updateGL();
}

struct Dtocom{//distance to center of mass
  int idx;
  double d;
};

inline bool operator < (const Dtocom &d1, const Dtocom &d2) {return (d1.d<d2.d);};

void Window::inheritLabels(){

  QList <int> imapperA,imapperB, istfalsch,istsuper;

  QAction *action = qobject_cast<QAction *>(sender());
  QList<int> index;
  if (action){
    //printf("inher it\n");
    index = chgl->lastClicked();
  }
  else return;
  if (index.size()<2) return;
  //*
  CEnvironment molecule[2];
  QList<Dtocom> dc[2];
  int nn=0, ne=0;
  //printf("asymmetric unit size: %d\n",mole.asymm.size());
  //printf("%d(%d) %d(%d)\n",mole.asymm.at(index.at(0)).molindex,index.at(0),mole.asymm.at(index.at(1)).molindex,index.at(1));
  //qDebug()<<index;
  V3 middle[2];
  middle[0]=V3(0.,0.,0.);
  middle[1]=V3(0.,0.,0.);
  // QList<SdmItem> sdms[2];
  Matrix amat[2];
  amat[0]=Matrix(1.,0.,0., 0.,1.,0., 0.,0.,1.);
  amat[1]=Matrix(1.,0.,0., 0.,1.,0., 0.,0.,1.);
  for (int j =0; j < mole.showatoms.size(); j++){
    mole.showatoms[j].hidden=1;
    if ((mole.asymm.at(index.at(0)).molindex == mole.showatoms.at(j).molindex)||
        (mole.asymm.at(index.at(1)).molindex == mole.showatoms.at(j).molindex)){
      mole.showatoms[j].hidden=0;
    }
  }
  for (int i =0; i < 2; i++){
    for (int j =0; j < mole.asymm.size(); j++){
      if (mole.asymm.at(index.at(i)).molindex == mole.asymm.at(j).molindex) {
        molecule[i].append(mole.asymm[j]);
        molecule[i].last().scod = j;
        molecule[i].last().sg = i;
        middle[i]+=mole.asymm.at(j).pos;
      }
    }
    middle[i]*=1.0/molecule[i].size();
    //sdms[i] = mole.computeSDM(molecule[i]);
    for (int j = 0; j < molecule[i].size(); j++){
      Dtocom cc;
      cc.idx=j;
      cc.d=Distance(molecule[i].at(j).pos, middle[i]);
      dc[i].append(cc);
    }
#if (QT_VERSION >= 0x050000)
    std::sort(dc[i].begin(),dc[i].end());
#else
    qSort(dc[i].begin(),dc[i].end());
#endif

    for (int n0=0; n0<dc[i].size(); n0++){
      printf("distance to center of mass %s %f\n",molecule[i][dc[i].at(n0).idx].Label.toStdString().c_str(),sqrt(dc[i].at(n0).d));
    }

    nn=0;
    ne=dc[i].size();
    V3 a1,a2,a3;
    do{
      a1=Normalize(middle[i]-molecule[i].at(dc[i].at((nn+1)%ne).idx).pos);//a1=(A-B)/|A-B|
      a2=Normalize(middle[i]-molecule[i].at(dc[i].at((nn)%ne).idx).pos);//a2=(A-C)/|A-B|
      a3=Normalize(a1%a2);//a3=(a1 x a2)/(a1 x a2)
      a2=a3%a1;//a2 = a3 x a1
      printf("Determinant of fit matrix%d %g %f %f %d %d %d\n",i, a1*(a2%a3), sqrt(dc[i].at(nn%ne).d), sqrt(dc[i].at((nn+1)%ne).d) ,nn%ne,(nn+1)%ne,ne);
      nn++;
    } while((a1*(a2%a3))<0.9);
    amat[i]=(i==0)?transponse(Matrix(a1,a2,a3)):Matrix(a1,a2,a3);


  }

  if (molecule[0].size()!=molecule[1].size()) {
    QMessageBox::information(0,"information",QString("The Number of atoms in the two molecules is not the same. This program can not help here, sorry! %1 %2")
        .arg(molecule[0].size()).arg(molecule[1].size()));
    return;
  }

  for (int j = 0; j < molecule[0].size(); j++){
    //molecule[0][j].pos+=-1.0*middle[0];
    molecule[0][j].style=0;
    molecule[0][j].frac=(((molecule[0][j].pos-(1.0*middle[0]))*amat[1])*amat[0])+middle[1];
    printf("#%-5d %f %f %f %s\n       %f %f %f %s\n",j
        ,molecule[0][j].frac.x, molecule[0][j].frac.y, molecule[0][j].frac.z, molecule[0][j].Label.toStdString().c_str()
        ,molecule[1][j].pos.x, molecule[1][j].pos.y, molecule[1][j].pos.z, molecule[1][j].Label.toStdString().c_str()
        );// * /
  }
  double dmd=0.0,dmdmin=1e37;
  int ia1min=0,ia2min=0;

  //middle[0]=middle[1];
  for (int n0=0; n0<dc[0].size(); n0++){
    printf("I.  distance to center of mass %s %f\n",molecule[0][dc[0].at(n0).idx].Label.toStdString().c_str()
        ,sqrt(Distance(molecule[0][dc[0].at(n0).idx].frac,middle[0])));
    printf("II. distance to center of mass %s %f\n",molecule[1][dc[1].at(n0).idx].Label.toStdString().c_str()
        ,sqrt(Distance(molecule[1][dc[1].at(n0).idx].pos,middle[1])));
  }
  for (int ia1=0; ia1<ne; ia1++){
    for (int ia2=0; ia2<ne; ia2++){
      if (ia1==ia2) continue;
      V3 a1,a2,a3;
      a1=Normalize(middle[0]-molecule[0].at(dc[0].at(ia1).idx).pos);//a1=(A-B)/|A-B|
      a2=Normalize(middle[0]-molecule[0].at(dc[0].at(ia2).idx).pos);//a2=(A-C)/|A-B|
      a3=Normalize(a1%a2);//a3=(a1 x a2)/(a1 x a2)
      a2=a3%a1;//a2 = a3 x a1
      printf("_Determinant of fit matrix0 %g %f %f %d %d %d\n", a1*(a2%a3), sqrt(dc[0].at(ia1).d), sqrt(dc[0].at(ia2).d), ia1, ia2,ne);

      amat[0]=transponse(Matrix(a1,a2,a3));
      for (int j = 0; j < molecule[0].size(); j++){
        //molecule[0][j].pos+=-1.0*middle[0];
        molecule[0][j].style=0;
        molecule[0][j].frac=(((molecule[0][j].pos-(1.0*middle[0]))*amat[1])*amat[0])+middle[1];
        //printf("#%-5d %f %f %f %s\n       %f %f %f %s\n",j
        //      ,molecule[0][j].pos.x,molecule[0][j].pos.y,molecule[0][j].pos.z,molecule[0][j].Label.toStdString().c_str()
        //    ,molecule[1][j].pos.x,molecule[1][j].pos.y,molecule[1][j].pos.z,molecule[1][j].Label.toStdString().c_str()
        //  );
      }
      //mole.selectedatoms.append(xd);
      dmd=0.0;
      for (int i = 0; i < molecule[1].size(); i++){
        double dm = 1.0e35;
        int k=0;
        for (int j = 0; j < molecule[0].size(); j++){
          if (molecule[0][j].style!=0) continue;
          double d = Distance(molecule[0].at(i).frac, molecule[1].at(j).pos);
          if (d<dm){
            k=j;
            dm=d;
          }
        }
        molecule[0][k].style=1;
        dmd+=dm;
      }
      dmd/=molecule[0].size();
      if (dmd<dmdmin){
        dmdmin=dmd;
        ia1min=ia1;
        ia2min=ia2;
      }
      //printf("#####  %f  #### %f\n",dmd,dmdmin);

    }
  }
  {
    V3 a1,a2,a3;
    a1=Normalize(middle[0]-molecule[0].at(dc[0].at(ia1min).idx).pos);//a1=(A-B)/|A-B|
    a2=Normalize(middle[0]-molecule[0].at(dc[0].at(ia2min).idx).pos);//a2=(A-C)/|A-B|
    a3=Normalize(a1%a2);//a3=(a1 x a2)/(a1 x a2)
    a2=a3%a1;//a2 = a3 x a1
    printf("_Determinant of fit final matrix0 %g %f %f %d %d %d\n", a1*(a2%a3), sqrt(dc[0].at(ia1min).d), sqrt(dc[0].at(ia2min).d), ia1min, ia2min,ne);

    amat[0]=transponse(Matrix(a1,a2,a3));

    for (int j = 0; j < molecule[0].size(); j++){
      //molecule[0][j].pos+=-1.0*middle[0];
      molecule[0][j].style=0;
      molecule[0][j].pos=(((molecule[0][j].pos-(1.0*middle[0]))*amat[1])*amat[0])+middle[1];
      printf("#%-5d %f %f %f %s\n       %f %f %f %s\n",j
          ,molecule[0][j].pos.x,molecule[0][j].pos.y,molecule[0][j].pos.z,molecule[0][j].Label.toStdString().c_str()
          ,molecule[1][j].pos.x,molecule[1][j].pos.y,molecule[1][j].pos.z,molecule[1][j].Label.toStdString().c_str()
          );// * /
    }
    dmd=0.0;
    for (int i = 0; i < molecule[1].size(); i++){
      double dm = 100.0;
      int k=0;
      for (int j = 0; j < molecule[0].size(); j++){
        if (molecule[0][j].style!=0) continue;
        double d = Distance(molecule[0].at(i).pos, molecule[1].at(j).pos);
        if (d<dm){
          k=j;
          dm=d;
        }
      }
      molecule[0][k].style=1;
      printf("%s -> %s %f %f %f\n"
          ,molecule[0][i].Label.toStdString().c_str()
          ,molecule[1][k].Label.toStdString().c_str()
          ,sqrt(dm)
          ,sqrt(Distance(molecule[0].at(i).pos, middle[0]))
          ,sqrt(Distance(molecule[1].at(k).pos, middle[1]))
          );
      dmd+=dm;
      imapperA.append(molecule[1][k].scod);
      imapperB.append(molecule[0][i].scod);
    }
    dmd/=molecule[0].size();
    //printf("#####  %f  ####\n",dmd);
  }

  chgl->setRotationCenter(middle[1]);
  mole.fitatoms.clear();
  MyAtom m;
  m.an=-42;
  m.pos=middle[1];
  m.Label="com";

  m.part=0;
  m.resiNr=0;
  m.hidden=0;
  m.symmGroup=0;
  m.sg=0;
  m.scod=555;//the identity
  m.sof=0;
  m.sof_org=0;
  m.screenX=0;
  m.screenY=0;
  m.afix=0;
  mole.fitatoms.append(molecule[1]);
  mole.fitatoms.append(molecule[0]);
  mole.fitatoms.append(m);
  /* xyz file output
     QFile ff("fit.xyz");
     ff.open(QIODevice::WriteOnly|QIODevice::Text);
     for (int i=0; i<mole.fitatoms.size();i++){
     ff.write(QString("%1 %2 %3 %4\n")
     .arg(mole.pse(mole.fitatoms.at(i).an))
     .arg(mole.fitatoms.at(i).pos.x)
     .arg(mole.fitatoms.at(i).pos.y)
     .arg(mole.fitatoms.at(i).pos.z).toLatin1());
     }
     ff.close();
     */
  //  printf("%d\n",mole.fitatoms.size());
  Connection abond,bbond;
  abond = mole.connecting(molecule[1],true);
  mole.fitbonds = mole.connecting(molecule[0],true);
  mole.fitbonds.append(abond);

  //    chgl->pairing(imapperA,imapperB);
  chgl->murx=421;
  chgl->updateGL();



  DragDropAtomsDialog  *ddad = new DragDropAtomsDialog(chgl, mole, imapperA, &imapperB,this);
  connect(ddad,SIGNAL(pairs(const QString&)),chgl,SLOT(selectPair(const QString&)));
  ddad->resiFinder=editor->resiFinder;
  //ddad->show();
  //*
  if (ddad->exec()==QDialog::Accepted){

    resiNrSpin->setValue(ddad->resiNrSpin->value());
    resiResiClass->setText(ddad->resiResiClass->text());
    bool mrsave = rufModeBox->isChecked();
    rufModeBox->setChecked(false);
    for (int i=0;i<imapperB.size();i++){
      update();
      QRegExp num=QRegExp("\\d+");
      if (mole.asymm.at(imapperA.at(i)).Label.contains(num)) {
        int p=mole.asymm.at(imapperA.at(i)).an;
        labelPSE=mole.pse(p);

        labelIndex=mole.asymm.at(imapperA.at(i)).Label.section(QRegExp("\\D+"),0,0,QString::SectionSkipEmpty).toInt();
        labelSuffix=mole.asymm.at(imapperA.at(i)).Label.section(num,1,1);
        labelSuffix.remove(QRegExp("[^A-Za-z']+"));
      }
      else{
        int p=mole.asymm.at(imapperA.at(i)).an;
        labelPSE=mole.pse(p);
        labelIndex=-1;
        labelSuffix=mole.asymm.at(imapperA.at(i)).Label;
        labelSuffix.remove(0,labelPSE.size());
        labelSuffix.remove(QRegExp("[^A-Za-z']+"));
      }
      updateLabel();
      renameThisAtom(imapperB.at(i));
    }    
    rufModeBox->setChecked(mrsave);
  }// */
  //return;
  molecule[0].clear();
  molecule[1].clear();
  imapperA.clear();
  imapperB.clear();
  mole.fitatoms.clear();
  mole.fitbonds.clear();
  mole.showbonds.clear();
  mole.showbonds=mole.connecting(mole.showatoms);
  chgl->rotCenter();
  chgl->rCenter->hide();
  chgl->showHidden();
  //sdms[0].clear();
  //sdms[1].clear();
  delete ddad;
  //  */
}

void Window::obj(){
    mole.exportOBJ(dirName,mole.showatoms,mole.showbonds);
}

void Window::sina(){//anis rueckrwaerts
  if (mole.asymm.isEmpty()) return;
  if (chgl->mol->selectedatoms.isEmpty()) {
    QAction *action = qobject_cast<QAction *>(sender());
    int index=-1;
    if (action)
      index=action->data().toInt();
    else index=-1;
    if (index>mole.asymm.size()) index=-1;
    if (index!=-1) {
      chgl->mol->selectedatoms.clear();
      chgl->mol->selectedatoms.append(chgl->mol->showatoms[index]);
      chgl->mol->selectedatoms.last().style=index;
    }
  }
  QTextDocument *document = editor->document();
  QTextCursor cursor = editor->textCursor();
  if (chgl->mol->selectedatoms.isEmpty()){
    double uEQ;
    cursor.beginEditBlock();
    for (int i=0; i<mole.asymm.size(); i++){    
      if (!mole.asymm.at(i).isIso){
        uEQ=0.05;//mole.ueq(mole.asymm.at(i).uf);
        mole.asymm[i].uf.m11=
          mole.asymm[i].uf.m22=
          mole.asymm[i].uf.m33=
          mole.asymm[i].uc.m11=
          mole.asymm[i].uc.m22=
          mole.asymm[i].uc.m33=uEQ;
        mole.asymm[i].isIso=true;
        mole.asymm[i].uf.m12 = mole.asymm[i].uf.m21 = uEQ * mole.cell.cosrg;
        mole.asymm[i].uf.m13 = mole.asymm[i].uf.m31 = uEQ * mole.cell.cosrb;
        mole.asymm[i].uf.m23 = mole.asymm[i].uf.m32 = uEQ * mole.cell.cosra;
        mole.asymm[i].uc.m21=
          mole.asymm[i].uc.m12=
          mole.asymm[i].uc.m13=
          mole.asymm[i].uc.m31=
          mole.asymm[i].uc.m32=
          mole.asymm[i].uc.m23=0.0;
        QString  label = mole.asymm.at(i).orginalLine.left(80).trimmed();
        cursor.movePosition(QTextCursor::Start);
        cursor = document->find(label,cursor);
        if (cursor.isNull()){
          cursor = editor->textCursor();
          cursor.movePosition(QTextCursor::Start);
          label.chop(10);
          cursor = document->find(label,cursor);
          if (cursor.isNull()) {
            cursor = editor->textCursor();
            printf("hab was nicht %d %s\n",i,label.toStdString().c_str());
            continue;
          }
        }
        cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
        cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
        while (cursor.selectedText().endsWith("=")) {
          cursor.movePosition(QTextCursor::Down,QTextCursor::KeepAnchor);
          cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
        }
        cursor.deleteChar();
        mole.asymm[i].orginalLine=
          QString("%1  %2  %3 %4 %5 %6 %7")
          .arg(mole.asymm.at(i).Label.section('_',0,0),-4)
          .arg(qMax(1,editor->sfac.indexOf(mole.asymm.at(i).an)+1))
          .arg(mole.asymm.at(i).frac.x,9,'f',5)
          .arg(mole.asymm.at(i).frac.y,9,'f',5)
          .arg(mole.asymm.at(i).frac.z,9,'f',5)
          .arg(mole.asymm.at(i).sof_org,9,'f',5)
          .arg(mole.asymm.at(i).uf.m11,9,'f',5);
        cursor.insertText(mole.asymm[i].orginalLine);
        QString s =
          QString("<font color=blue>Isotropyfied atom: %1 part:%2 residue:%3 %4 </font> Please save to update structure view.")
          .arg(mole.asymm.at(i).Label)
          .arg(mole.asymm.at(i).part)
          .arg(mole.asymm.at(i).resiNr)
          .arg(mole.asymm.at(i).ResiClass);
        infoKanalNews(s);
      }
    }
    cursor.endEditBlock();
    mole.showatoms.clear();
    mole.showbonds.clear();
    chgl->mol->showatoms.clear();
    chgl->mol->showbonds.clear();
    chgl->mol->selectedatoms.clear();
    for (int o=0; o<mole.asymm.size();o++)
      mole.showatoms.append(mole.asymm[o]);
    mole.showbonds =
      mole.connecting(mole.showatoms);
    chgl->mol->selectedatoms.clear();
    chgl->murx=__LINE__;
    bool growYes=chgl->fuse->isVisible ();
    chgl->mol->fuse();
    if (growYes) chgl->mol->grow();

    chgl->pause=false;
//    printf("%d\n",__LINE__);
    chgl->updateBondActions();
    chgl->updateGL();
    update();
    chgl->updateGL();
  }
  else
  {
    double uEQ;
    cursor.beginEditBlock();
    for (int j=0; j<mole.selectedatoms.size(); j++){    
      int i=mole.selectedatoms.at(j).style;
      if ((i>=mole.asymm.size())||(i<0)) continue;
      if (!mole.asymm.at(i).isIso){
        uEQ=0.05;//mole.ueq(mole.asymm.at(i).uf);
        mole.asymm[i].uf.m11=
          mole.asymm[i].uf.m22=
          mole.asymm[i].uf.m33=
          mole.asymm[i].uc.m11=
          mole.asymm[i].uc.m22=
          mole.asymm[i].uc.m33=uEQ;
        mole.asymm[i].isIso=true;
        mole.asymm[i].uf.m12 = mole.asymm[i].uf.m21 = uEQ * mole.cell.cosrg;
        mole.asymm[i].uf.m13 = mole.asymm[i].uf.m31 = uEQ * mole.cell.cosrb;
        mole.asymm[i].uf.m23 = mole.asymm[i].uf.m32 = uEQ * mole.cell.cosra;
        mole.asymm[i].uc.m21=
          mole.asymm[i].uc.m12=
          mole.asymm[i].uc.m13=
          mole.asymm[i].uc.m31=
          mole.asymm[i].uc.m32=
          mole.asymm[i].uc.m23=0.0;
        QString  label = mole.asymm.at(i).orginalLine.left(80).trimmed();
        cursor.movePosition(QTextCursor::Start);
        cursor = document->find(label,cursor);
        if (cursor.isNull()){
          cursor = editor->textCursor();
          cursor.movePosition(QTextCursor::Start);
          label.chop(10);
          cursor = document->find(label,cursor);
          if (cursor.isNull()) {
            cursor = editor->textCursor();
            printf("hab was nicht %d %s\n",i,label.toStdString().c_str());
            continue;
          }
        }
        cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
        cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
        while (cursor.selectedText().endsWith("=")) {
          cursor.movePosition(QTextCursor::Down,QTextCursor::KeepAnchor);
          cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
        }
        cursor.deleteChar();
        mole.asymm[i].orginalLine=
          QString("%1  %2  %3 %4 %5 %6 %7")
          .arg(mole.asymm.at(i).Label.section('_',0,0),-4)
          .arg(qMax(1,editor->sfac.indexOf(mole.asymm.at(i).an)+1))
          .arg(mole.asymm.at(i).frac.x,9,'f',5)
          .arg(mole.asymm.at(i).frac.y,9,'f',5)
          .arg(mole.asymm.at(i).frac.z,9,'f',5)
          .arg(mole.asymm.at(i).sof_org,9,'f',5)
          .arg(mole.asymm.at(i).uf.m11,9,'f',5);
        cursor.insertText(mole.asymm[i].orginalLine);
        QString s =
          QString("<font color=blue>Isotropyfied atom: %1 part:%2 residue:%3 %4 </font> Please save to update structure view.")
          .arg(mole.asymm.at(i).Label)
          .arg(mole.asymm.at(i).part)
          .arg(mole.asymm.at(i).resiNr)
          .arg(mole.asymm.at(i).ResiClass);
        infoKanalNews(s);
      }
    }
    cursor.endEditBlock();
    mole.showatoms.clear();
    mole.showbonds.clear();
    chgl->mol->showatoms.clear();
    chgl->mol->showbonds.clear();
    chgl->mol->selectedatoms.clear();
    for (int o=0; o<mole.asymm.size();o++)
      mole.showatoms.append(mole.asymm[o]);
    mole.sdmcompleter();
    mole.showbonds =
      mole.connecting(mole.showatoms);
    chgl->mol->selectedatoms.clear();
    chgl->murx=__LINE__;
    bool growYes=chgl->fuse->isVisible ();
    chgl->mol->fuse();
    if (growYes) chgl->mol->grow();

    chgl->pause=false;
//    printf("%d\n",__LINE__);
    chgl->updateBondActions();
    chgl->updateGL();
    update();
    chgl->updateGL();

  }
}

void Window::autoHFix(){
  if (mole.asymm.isEmpty()) return;
  int warmal=mole.asymm.size();
  int warmalAtome=0;
  for (int i=0; i<mole.asymm.size();i++) if (mole.asymm.at(i).an>=0)warmalAtome++;
  QStringList alab;
  for (int i =0; i<mole.asymm.size(); i++){
    alab.append(mole.asymm.at(i).Label);
  }
  QString nn;
  chgl->disSelection();
  chgl->mol->grow();

  MyAtom htest,qtest;

  double xh[8]={
    0.98,//1
    0.97,//2
    0.96,//3
    0.93,//4
    1.10,//15 B
    0.82,//8 O
    0.93,//9
    0.93// 16
  };

  if (editor->sfac.indexOf(0)==-1)addNewScatteringFactor(0);
  htest.an=0;
  htest.part=0;
  htest.resiNr=0;
  htest.hidden=0;
  htest.symmGroup=0;
  htest.sg=0;
  htest.scod=555;//the identity
  htest.auidx=-1;
  htest.uc.m12=htest.uc.m23=htest.uc.m13=0.0;
  htest.uc.m21=htest.uc.m32=htest.uc.m31=0.0;
  htest.uf.m12=htest.uf.m23=htest.uf.m13=0.0;
  htest.uf.m21=htest.uf.m32=htest.uf.m31=0.0;
  qtest=htest;
  qtest.an=-1;
  QTextDocument *document = editor->document();
  QTextCursor cursor = editor->textCursor();
  cursor.beginEditBlock ();
  QMap<int,int> keinDonor;
  QMap<int,int> istDonor;
  for (int j=0;j<mole.contact.size();j++){
    double ch1,ch2;
    if (mole.knoepfe.at(mole.contact.at(j).a1).neighbors.size()==0) keinDonor[mole.contact.at(j).a1]++;
    if (mole.knoepfe.at(mole.contact.at(j).a2).neighbors.size()==0) keinDonor[mole.contact.at(j).a2]++;
    if ((mole.asymm.at(mole.contact.at(j).a1).an==7)&&(mole.knoepfe.at(mole.contact.at(j).a1).neighbors.size()>1)) keinDonor[mole.contact.at(j).a1]++;
    if ((mole.asymm.at(mole.contact.at(j).a2).an==7)&&(mole.knoepfe.at(mole.contact.at(j).a2).neighbors.size()>1)) keinDonor[mole.contact.at(j).a2]++;
    if ((mole.contact.at(j).covalent)){//
      ch1=ch2=0;

      for (int k=0; k<mole.knoepfe.at(mole.contact.at(j).a1).neighbors.size(); k++){
        ch1 += sqrt(Distance(mole.asymm.at(mole.contact.at(j).a1).pos,
              mole.showatoms.at(mole.knoepfe.at(mole.contact.at(j).a1).neighbors.at(k)).pos))-
          ((mole.Kovalenz_Radien[mole.asymm.at(mole.contact.at(j).a1).an]+
            mole.Kovalenz_Radien[mole.showatoms.at(mole.knoepfe.at(mole.contact.at(j).a1).neighbors.at(k)).an])*0.0095);

      }
      if (mole.knoepfe.at(mole.contact.at(j).a1).neighbors.size()) 
        ch1*=1.0/mole.knoepfe.at(mole.contact.at(j).a1).neighbors.size();

      for (int k=0; k<mole.knoepfe.at(mole.contact.at(j).a2).neighbors.size(); k++){
        ch2 += sqrt(Distance(mole.asymm.at(mole.contact.at(j).a2).pos,
              mole.showatoms.at(mole.knoepfe.at(mole.contact.at(j).a2).neighbors.at(k)).pos))-
          ((mole.Kovalenz_Radien[mole.asymm.at(mole.contact.at(j).a2).an]+
            mole.Kovalenz_Radien[mole.showatoms.at(mole.knoepfe.at(mole.contact.at(j).a2).neighbors.at(k)).an])*0.0095);
      }
      if (mole.knoepfe.at(mole.contact.at(j).a2).neighbors.size()) 
        ch2*=1.0/mole.knoepfe.at(mole.contact.at(j).a2).neighbors.size();
      /*printf("%s %s %d %d %g %g\n"
             ,mole.asymm.at(mole.contact.at(j).a1).Label.toStdString().c_str()
             ,mole.asymm.at(mole.contact.at(j).a2).Label.toStdString().c_str(),
             ((ch1-0.01)>ch2),((ch2-0.01)>ch1),ch1,ch2
             );*/
      if (ch1<-0.2 ) keinDonor[mole.contact.at(j).a1]++;
      if (ch2<-0.2 ) keinDonor[mole.contact.at(j).a2]++;
      if ((ch1-0.01)>ch2) istDonor[mole.contact.at(j).a1]++;
      if ((ch2-0.01)>ch1) istDonor[mole.contact.at(j).a2]++;
    }
  }
  for (int i =0; i<mole.asymm.size(); i++){
    if ((mole.asymm.at(i).an==5)||(mole.asymm.at(i).an==6)){
      double nh= (mole.asymm.at(i).an==6) ? 0.07 : 0;
      if (mole.is2Dissordered4H(mole.asymm.at(i))) continue;
      double plan=1.0;
      if (mole.knoepfe.at(i).neighbors.size()==1)  {
        if ((mole.asymm.at(i).an==6)&&(!istDonor.contains(i))) {
            printf("%s is probably no donor \n",mole.asymm.at(i).Label.toStdString().c_str());
            continue;
        }
        V3 v=V3(0,0,0),w=V3(0,0,0),u=V3(0,0,0) ,a=V3(0,0,0);//,b=V3(0,0,0),c=V3(0,0,0);
        a = mole.showatoms.at(mole.knoepfe.at(i).neighbors.at(0)).pos - mole.asymm.at(i).pos;
        //printf("A = %s-%s %g %g %g\n",mole.showatoms.at(mole.knoepfe.at(i).neighbors.at(0)).Label.toStdString().c_str(),mole.asymm.at(i).Label.toStdString().c_str(),a.x,a.y,a.z);
        double chi = sqrt(Norm(a))-((mole.Kovalenz_Radien[mole.showatoms.at(mole.knoepfe.at(i).neighbors.at(0)).an]+mole.Kovalenz_Radien[mole.asymm.at(i).an])/100.0);
        if (chi>-0.09) {//afix 137 127
          int j,k,l;
          a=Normalize(a);
          double jx,kx,lx,mx,my,mz;
          double val[24],merg[8],wink=0,t=0,mt=0;
          for (int z=0; z<8;z++) merg[z]=0;
          if (fxle->n5){
            for (int z=0; z<24; z++){
              if ((a==V3(0,0,-1))||(a==V3(0,0,1))) {
                w=Normalize(V3(1,1,1)%a);
              } else {
                w=Normalize(V3(0,0,1)%a);
              }
              //printf("w= %g %g %g\n",w.x,w.y,w.z);
              u=Normalize(w%a);
              v=(-(xh[2]-nh)*0.33333*a)+ mole.asymm.at(i).pos+(xh[2]-nh)*0.942809041582*(sin(wink)*u+cos(wink)*w);
              qtest.pos=v;
              mole.kart2frac(v,v);
              int zplu=0;
              do {
                jx=((zplu+v.x)*fxle->n1+0.5);
                zplu++;
              }while (jx<0);
              zplu=0;
              do {
                kx=((zplu+v.y)*fxle->n2+0.5);
                zplu++;
              }while (kx<0);
              zplu=0;
              do {
                lx=((zplu+v.z)*fxle->n3+0.5);
                zplu++;
              }while (lx<0);
              mx=jx-floor(jx);
              my=kx-floor(kx);
              mz=lx-floor(lx);
              j=((int)jx)%fxle->n1;//
              k=((int)kx)%fxle->n2;//
              l=((int)lx)%fxle->n3;//
              merg[z%8]+=val[z]=(
                  (1-mx)*fxle->datfo_fc[(j+fxle->n1*(k+l*fxle->n2))%fxle->n5]+
                  mx*fxle->datfo_fc[((j+1)+fxle->n1*(k+l*fxle->n2))%fxle->n5]+
                  (1-my)*fxle->datfo_fc[(j+fxle->n1*(k+l*fxle->n2))%fxle->n5]+
                  my*fxle->datfo_fc[(j+fxle->n1*((k+1)+l*fxle->n2))%fxle->n5]+
                  (1-mz)*fxle->datfo_fc[(j+fxle->n1*(k+l*fxle->n2))%fxle->n5]+
                  mz*fxle->datfo_fc[(j+fxle->n1*(k+(l+1)*fxle->n2))%fxle->n5])/3.0;
              qtest.peakHeight=val[z];
              qtest.frac=v;
              qtest.Label=QString("Q%1#").arg(z,-2);
              mole.pmin=qMin(mole.pmin, qtest.peakHeight);
              mole.pmax=qMax(mole.pmax, qtest.peakHeight);
              qpv->cutoff=0;//mole.pmin;
              qpv->setMin(mole.pmin);
              qpv->setMax(mole.pmax);
              mole.asymm.append(qtest);
              wink+=0.261799387799;
            }
            for (int z=0; z<8;z++) {
              t =merg[(z+8)%8] ;
              double x = t - merg[(z+9)%8];
              double u = t - merg[(z+7)%8];
              if (fmin(x,u)<0) continue;
              double p=0.5*(u-x)/(u+x);
              t=t+0.25*(p*(u-x));
              mt=(mt>t)?mt:t;
              if (t<mt)continue;
              wink=((double) z + p )*0.261799387799; 
            }
          } else {
            int zzz=0;
            int z=mole.knoepfe.at(mole.knoepfe.at(i).neighbors.at(0)).neighbors.at(zzz++);
            while ((z==i)&&(zzz<mole.knoepfe.at(mole.knoepfe.at(i).neighbors.at(0)).neighbors.size())) {
              z=mole.knoepfe.at(mole.knoepfe.at(i).neighbors.at(0)).neighbors.at(zzz++);
            }
            if ((a==V3(0,0,-1))||(a==V3(0,0,1))) {
              w=Normalize(V3(1,1,1)%a);
            } else {
              w=Normalize(V3(0,0,1)%a);
            }
            u=Normalize(w%a);
            v=(-(xh[2]-nh)*0.33333*a)+ mole.asymm.at(i).pos+(xh[2]-nh)*0.942809041582*(sin(wink)*u+cos(wink)*w);
            // if z == i then dieder() returns nan, because A in dieder gets (0,0,0)
            V3 increm = V3(0.0, 0.0, 0.0);
            if ( z == i ) {
              increm = V3(0.00001, 0.00001, 0.00001);
            }
            wink=mole.dieder(mole.showatoms.at(mole.knoepfe.at(i).neighbors.at(0)).pos+increm-mole.asymm.at(z).pos,
                mole.asymm.at(i).pos-mole.showatoms.at(mole.knoepfe.at(i).neighbors.at(0)).pos,
                v-mole.asymm.at(i).pos)/180.0*M_PI;
          }
          v=(-(xh[2]-nh)*0.33333*a)+ mole.asymm.at(i).pos+(xh[2]-nh)*0.942809041582*(sin(wink)*u+cos(wink)*w);
          htest.Label=mole.asymm.at(i).Label.section('_',0,0);
          htest.part=mole.asymm.at(i).part;
          htest.resiNr=mole.asymm.at(i).resiNr;
          htest.Label.replace(0,1,'H');
          QString baslab=htest.Label;
          int hindex=1;
          QString nnn=htest.Label;
          do {
            htest.Label=baslab;
            if (hindex) nnn=htest.Label.left(3).append(QString::number(hindex+9,36));
            if (nnn.size()>4) nnn=htest.Label.left(2).append(QString::number(hindex+9,36));
            if (htest.resiNr)
              nn=QString("%1_%2")//for shelxl same names in different parts are no problem but for platon so this should fix it.
                .arg(nnn)
                .arg((htest.resiNr)?QString::number(htest.resiNr):"");
            else nn=nnn;
            //             qDebug()<<nn<<nnn<<(alab.contains(nn,Qt::CaseInsensitive));
            hindex++;
          }while(alab.contains(nn,Qt::CaseInsensitive));
          htest.Label=nnn;
          alab.append(nn);
          double uIso = mole.ueq(mole.asymm.at(i).uf)*1.5;
          htest.uf.m11 = htest.uf.m22 = htest.uf.m33 = uIso;
          htest.uf.m23 = uIso * mole.cell.cosra; 
          htest.uf.m13 = uIso * mole.cell.cosrb; 
          htest.uf.m12 = uIso * mole.cell.cosrg; 
          htest.isIso=true;
          htest.ufiso_org=QString("-1.5");
          mole.Uf2Uo(htest.uf,htest.uc);
          htest.pos=v;
          mole.kart2frac(htest.pos,htest.frac);
          htest.orginalLine=QString("%1  %2  %3 %4 %5 %6 %7")
            .arg(htest.Label)
            .arg(qMax(1,editor->sfac.indexOf(0)+1))
            .arg(htest.frac.x,9,'f',5)
            .arg(htest.frac.y,9,'f',5)
            .arg(htest.frac.z,9,'f',5)
            .arg(mole.asymm.at(i).sof_org)
            .arg("-1.5");
          mole.asymm.append(htest);
          wink+=2.09439510239;
          v=(-(xh[2]-nh)*0.33333*a)+ mole.asymm.at(i).pos+(xh[2]-nh)*0.942809041582*(sin(wink)*u+cos(wink)*w);
          do {
            htest.Label=baslab;
            if (hindex) nnn=htest.Label.left(3).append(QString::number(hindex+9,36));
            if (nnn.size()>4) nnn=htest.Label.left(2).append(QString::number(hindex+9,36));
            if (htest.resiNr)
              nn=QString("%1_%2")//for shelxl same names in different parts are no problem but for platon so this should fix it.
                .arg(nnn)
                .arg((htest.resiNr)?QString::number(htest.resiNr):"");
            else nn=nnn;
            //            qDebug()<<nn<<nnn<<(alab.contains(nn,Qt::CaseInsensitive));
            hindex++;
          }while(alab.contains(nn,Qt::CaseInsensitive));
          htest.Label=nnn;
          alab.append(nn);
          htest.pos=v;
          mole.kart2frac(htest.pos,htest.frac);	
          htest.orginalLine=QString("%1  %2  %3 %4 %5 %6 %7")
            .arg(htest.Label)
            .arg(qMax(1,editor->sfac.indexOf(0)+1))
            .arg(htest.frac.x,9,'f',5)
            .arg(htest.frac.y,9,'f',5)
            .arg(htest.frac.z,9,'f',5)
            .arg(mole.asymm.at(i).sof_org)
            .arg("-1.5");
          mole.asymm.append(htest);
          wink+=2.09439510239;
          v=(-(xh[2]-nh)*0.33333*a)+ mole.asymm.at(i).pos+(xh[2]-nh)*0.942809041582*(sin(wink)*u+cos(wink)*w);
          do {
            htest.Label=baslab;
            if (hindex) nnn=htest.Label.left(3).append(QString::number(hindex+9,36));
            if (nnn.size()>4) nnn=htest.Label.left(2).append(QString::number(hindex+9,36));
            if (htest.resiNr)
              nn=QString("%1_%2")//for shelxl same names in different parts are no problem but for platon so this should fix it.
                .arg(nnn)
                .arg((htest.resiNr)?QString::number(htest.resiNr):"");
            else nn=nnn;
            //            qDebug()<<nn<<nnn<<(alab.contains(nn,Qt::CaseInsensitive));
            hindex++;
          }while(alab.contains(nn,Qt::CaseInsensitive));
          htest.Label=nnn;
          alab.append(nn);
          htest.pos=v;
          mole.kart2frac(htest.pos,htest.frac);	
          htest.orginalLine=QString("%1  %2  %3 %4 %5 %6 %7")
            .arg(htest.Label)
            .arg(qMax(1,editor->sfac.indexOf(0)+1))
            .arg(htest.frac.x,9,'f',5)
            .arg(htest.frac.y,9,'f',5)
            .arg(htest.frac.z,9,'f',5)
            .arg(mole.asymm.at(i).sof_org)
            .arg("-1.5");
          mole.asymm.append(htest);
          QString label = mole.showatoms.at(i).orginalLine.left(80).trimmed();
          //          int afixfuenf=(mole.showatoms.at(i).afix/10)?(mole.showatoms.at(i).afix/10)*10+5:0;
          cursor.movePosition(QTextCursor::Start);
          cursor = document->find(label,cursor);
          if (cursor.isNull()){
            cursor = editor->textCursor();
            cursor.movePosition(QTextCursor::Start);
            label.chop(10);
            cursor = document->find(label,cursor);
            if (cursor.isNull()) {
              cursor = editor->textCursor();
            }
          }
          cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
          cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
          while (cursor.selectedText().endsWith("=")) {
            cursor.movePosition(QTextCursor::Down,QTextCursor::KeepAnchor);
            cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
          }
          cursor.clearSelection();
          cursor.movePosition(QTextCursor::Down);
          cursor.insertText(QString("AFIX 137\n%1\n%2\n%3\nAFIX %4\n")
              .arg(mole.asymm.at(mole.asymm.size()-3).orginalLine)
              .arg(mole.asymm.at(mole.asymm.size()-2).orginalLine)
              .arg(mole.asymm.at(mole.asymm.size()-1).orginalLine)
              .arg(mole.afix5(i))
              );
        }else if (chi> -0.27){//afix 93
          int j,k,l;
          a=Normalize(a);
          double jx,kx,lx,mx,my,mz;
          double val[24],merg[12],wink=0,t=0,mt=0;
          if (fxle->n5){
            for (int z=0; z<12;z++) merg[z]=0;
            for (int z=0; z<24; z++){
              wink=z*0.261799387799;
              w=Normalize(V3(0,0,1)%a);
              u=Normalize(w%a);
              v=(-(xh[6]-nh)*0.33333*a)+ mole.asymm.at(i).pos+(xh[6]-nh)*0.942809041582*(sin(wink)*u+cos(wink)*w);
              qtest.pos=v;
              mole.kart2frac(v,v);
              jx=(v.x>0)?(v.x*fxle->n1+0.5):((1.0+v.x)*fxle->n1+0.5);    
              kx=(v.y>0)?(v.y*fxle->n2+0.5):((1.0+v.y)*fxle->n2+0.5);   
              lx=(v.z>0)?(v.z*fxle->n3+0.5):((1.0+v.z)*fxle->n3+0.5);   
              mx=jx-floor(jx);
              my=kx-floor(kx);
              mz=lx-floor(lx);
              j=((int)jx)%fxle->n1;//
              k=((int)kx)%fxle->n2;//
              l=((int)lx)%fxle->n3;//
              merg[z%12]+=val[z]=(
                  (1-mx)*fxle->datfo_fc[(j+fxle->n1*(k+l*fxle->n2))%fxle->n5]+
                  mx*fxle->datfo_fc[((j+1)+fxle->n1*(k+l*fxle->n2))%fxle->n5]+
                  (1-my)*fxle->datfo_fc[(j+fxle->n1*(k+l*fxle->n2))%fxle->n5]+
                  my*fxle->datfo_fc[(j+fxle->n1*((k+1)+l*fxle->n2))%fxle->n5]+
                  (1-mz)*fxle->datfo_fc[(j+fxle->n1*(k+l*fxle->n2))%fxle->n5]+
                  mz*fxle->datfo_fc[(j+fxle->n1*(k+(l+1)*fxle->n2))%fxle->n5])/3.0;
              qtest.peakHeight=val[z];
              qtest.frac=v;
              qtest.Label=QString("Q%1").arg(z+100);
              mole.pmin=qMin(mole.pmin, qtest.peakHeight);
              mole.pmax=qMax(mole.pmax, qtest.peakHeight);
              qpv->cutoff=0;//mole.pmin;
              qpv->setMin(mole.pmin);
              qpv->setMax(mole.pmax);
              mole.asymm.append(qtest);
            }
            for (int z=0; z<12;z++) {
              t =merg[(z+12)%12] ;
              double x = t - merg[(z+13)%12];
              double u = t - merg[(z+11)%12];
              if (fmin(x,u)<0) continue;
              double p=0.5*(u-x)/(u+x);
              t=t+0.25*(p*(u-x));
              mt=(mt>t)?mt:t;
              if (t<mt)continue;
              wink=((double) z + p )*0.261799387799; 

              /////////////////
            }
          }else{
            int zzz=0;
            int z=mole.knoepfe.at(mole.knoepfe.at(i).neighbors.at(0)).neighbors.at(zzz++);
            while ((z==i)&&(zzz<mole.knoepfe.at(mole.knoepfe.at(i).neighbors.at(0)).neighbors.size()))
              z=mole.knoepfe.at(mole.knoepfe.at(i).neighbors.at(0)).neighbors.at(zzz++);
            w=Normalize(V3(0,0,1)%a);
            u=Normalize(w%a);
            v=(-(xh[2]-nh)*0.33333*a)+ mole.asymm.at(i).pos+(xh[2]-nh)*0.942809041582*(sin(wink)*u+cos(wink)*w);
            // if z == i then dieder() returns nan, because A in dieder gets (0,0,0)
            V3 increm = V3(0.0, 0.0, 0.0);
            if ( z == i ) {
              increm = V3(0.00001, 0.00001, 0.00001);
            }
            wink=mole.dieder(mole.showatoms.at(mole.knoepfe.at(i).neighbors.at(0)).pos+increm-mole.asymm.at(z).pos,
                mole.asymm.at(i).pos-mole.showatoms.at(mole.knoepfe.at(i).neighbors.at(0)).pos,
                v-mole.asymm.at(i).pos)/180.0*M_PI;

          }

          v=(-(xh[6]-nh)*0.5*a)+ mole.asymm.at(i).pos+(xh[6]-nh)*0.866025403784*(sin(wink)*u+cos(wink)*w);
          htest.Label=mole.asymm.at(i).Label.section('_',0,0);
          htest.part=mole.asymm.at(i).part;
          htest.resiNr=mole.asymm.at(i).resiNr;
          htest.Label.replace(0,1,'H');
          int hindex=1;
          QString nnn=htest.Label;
          QString baslab=htest.Label;
          do {
            htest.Label=baslab;
            if (hindex) nnn=htest.Label.left(3).append(QString::number(hindex+9,36));
            if (nnn.size()>4) nnn=htest.Label.left(2).append(QString::number(hindex+9,36));
            if (htest.resiNr)
              nn=QString("%1_%2")//for shelxl same names in different parts are no problem but for platon so this should fix it.
                .arg(nnn)
                .arg((htest.resiNr)?QString::number(htest.resiNr):"");
            else nn=nnn;
            // qDebug()<<nn<<nnn<<(alab.contains(nn,Qt::CaseInsensitive));
            hindex++;
          }while(alab.contains(nn,Qt::CaseInsensitive));
          htest.Label=nnn;
          alab.append(nn);
          htest.isIso=true;
          htest.ufiso_org=QString("-1.2");
          double uIso = mole.ueq(mole.asymm.at(i).uf)*1.2;
          htest.uf.m11 = htest.uf.m22 = htest.uf.m33 = uIso;
          htest.uf.m23 = uIso * mole.cell.cosra; 
          htest.uf.m13 = uIso * mole.cell.cosrb; 
          htest.uf.m12 = uIso * mole.cell.cosrg; 
          mole.Uf2Uo(htest.uf,htest.uc);
          htest.pos=v;
          mole.kart2frac(htest.pos,htest.frac);	
          htest.orginalLine=QString("%1  %2  %3 %4 %5 %6 %7")
            .arg(htest.Label)
            .arg(qMax(1,editor->sfac.indexOf(0)+1))
            .arg(htest.frac.x,9,'f',5)
            .arg(htest.frac.y,9,'f',5)
            .arg(htest.frac.z,9,'f',5)
            .arg(mole.asymm.at(i).sof_org)
            .arg("-1.2");
          mole.asymm.append(htest);
          wink+=3.14159265359;
          v=(-(xh[6]-nh)*0.5*a)+ mole.asymm.at(i).pos+(xh[6]-nh)*0.866025403784*(sin(wink)*u+cos(wink)*w);
          do {
            htest.Label=baslab;
            if (hindex) nnn=htest.Label.left(3).append(QString::number(hindex+9,36));
            if (nnn.size()>4) nnn=htest.Label.left(2).append(QString::number(hindex+9,36));
            if (htest.resiNr)
              nn=QString("%1_%2")//for shelxl same names in different parts are no problem but for platon so this should fix it.
                .arg(nnn)
                .arg((htest.resiNr)?QString::number(htest.resiNr):"");
            else nn=nnn;
            // qDebug()<<nn<<nnn<<(alab.contains(nn,Qt::CaseInsensitive));
            hindex++;
          }while(alab.contains(nn,Qt::CaseInsensitive));
          htest.Label=nnn;
          alab.append(nn);
          htest.pos=v;
          mole.kart2frac(htest.pos,htest.frac);	
          htest.orginalLine=QString("%1  %2  %3 %4 %5 %6 %7")
            .arg(htest.Label)
            .arg(qMax(1,editor->sfac.indexOf(0)+1))
            .arg(htest.frac.x,9,'f',5)
            .arg(htest.frac.y,9,'f',5)
            .arg(htest.frac.z,9,'f',5)
            .arg(mole.asymm.at(i).sof_org)
            .arg("-1.2");
          mole.asymm.append(htest);

          QString label = mole.showatoms.at(i).orginalLine.left(80).trimmed();
          //          int afixfuenf=(mole.showatoms.at(i).afix/10)?(mole.showatoms.at(i).afix/10)*10+5:0;
          cursor.movePosition(QTextCursor::Start);
          cursor = document->find(label,cursor);
          if (cursor.isNull()){
            cursor = editor->textCursor();
            cursor.movePosition(QTextCursor::Start);
            label.chop(10);
            cursor = document->find(label,cursor);
            if (cursor.isNull()) {
              cursor = editor->textCursor();
            }
          }
          cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
          cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
          while (cursor.selectedText().endsWith("=")) {
            cursor.movePosition(QTextCursor::Down,QTextCursor::KeepAnchor);
            cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
          }
          cursor.clearSelection();
          cursor.movePosition(QTextCursor::Down);
          cursor.insertText(QString("AFIX 93\n%1\n%2\nAFIX %3\n")
              .arg(mole.asymm.at(mole.asymm.size()-2).orginalLine)
              .arg(mole.asymm.at(mole.asymm.size()-1).orginalLine)
              .arg(mole.afix5(i))
              );
        }else{//afix 163
          if (mole.asymm.at(i).an==5){
            a = Normalize(mole.showatoms.at(mole.knoepfe.at(i).neighbors.at(0)).pos - mole.asymm.at(i).pos);
            v=(-(xh[7]-nh)*a)+ mole.asymm.at(i).pos;
            htest.Label=mole.asymm.at(i).Label.section('_',0,0);
            htest.part=mole.asymm.at(i).part;
            htest.resiNr=mole.asymm.at(i).resiNr;
            htest.Label.replace(0,1,'H');
            int hindex=0;
            QString nnn=htest.Label;
            do {
              if (hindex) nnn=htest.Label.left(3).append(QString::number(hindex+9,36));
              if (nnn.size()>4) nnn=htest.Label.left(2).append(QString::number(hindex+9,36));
              if (htest.resiNr)
                nn=QString("%1_%2")//for shelxl same names in different parts are no problem but for platon so this should fix it.
                  .arg(nnn)
                  .arg((htest.resiNr)?QString::number(htest.resiNr):"");
              else nn=nnn;
              // qDebug()<<nn<<nnn<<(alab.contains(nn,Qt::CaseInsensitive));
              hindex++;
            }while(alab.contains(nn,Qt::CaseInsensitive));
            htest.Label=nnn;
            alab.append(nn);
            htest.isIso=true;
            htest.ufiso_org=QString("-1.2");
            double uIso = mole.ueq(mole.asymm.at(i).uf)*1.2;
            htest.uf.m11 = htest.uf.m22 = htest.uf.m33 = uIso;
            htest.uf.m23 = uIso * mole.cell.cosra; 
            htest.uf.m13 = uIso * mole.cell.cosrb; 
            htest.uf.m12 = uIso * mole.cell.cosrg; 
            mole.Uf2Uo(htest.uf,htest.uc);
            htest.pos=v;
            mole.kart2frac(htest.pos,htest.frac);
            htest.orginalLine=QString("%1  %2  %3 %4 %5 %6 %7")
              .arg(htest.Label)
              .arg(qMax(1,editor->sfac.indexOf(0)+1))
              .arg(htest.frac.x,9,'f',5)
              .arg(htest.frac.y,9,'f',5)
              .arg(htest.frac.z,9,'f',5)
              .arg(mole.asymm.at(i).sof_org)
              .arg("-1.2");
            mole.asymm.append(htest);

            QString label = mole.showatoms.at(i).orginalLine.left(80).trimmed();
            //            int afixfuenf=(mole.showatoms.at(i).afix/10)?(mole.showatoms.at(i).afix/10)*10+5:0;
            cursor.movePosition(QTextCursor::Start);
            cursor = document->find(label,cursor);
            if (cursor.isNull()){
              cursor = editor->textCursor();
              cursor.movePosition(QTextCursor::Start);
              label.chop(10);
              cursor = document->find(label,cursor);
              if (cursor.isNull()) {
                cursor = editor->textCursor();
              }
            }
            cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
            cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
            while (cursor.selectedText().endsWith("=")) {
              cursor.movePosition(QTextCursor::Down,QTextCursor::KeepAnchor);
              cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
            }
            cursor.clearSelection();
            cursor.movePosition(QTextCursor::Down);
            cursor.insertText(QString("AFIX 163\n%1\nAFIX %2\n")
                .arg(mole.asymm.at(mole.asymm.size()-1).orginalLine)
                .arg(mole.afix5(i))
                );
          }
        }
      }
      if (mole.knoepfe.at(i).neighbors.size()==2){//afix 43 oder 23
        if ((mole.asymm.at(i).an==6)&&(!istDonor.contains(i))) {
            printf("%s is probably no donor \n",mole.asymm.at(i).Label.toStdString().c_str());
            continue;
        }
        double angle=0;
        V3 v=V3(0,0,0),w=V3(0,0,0),u=V3(0,0,0) ,a=V3(0,0,0),b=V3(0,0,0),c=V3(0,0,0);
        a = mole.showatoms.at(mole.knoepfe.at(i).neighbors.at(0)      ).pos - mole.asymm.at(i).pos;
        b = mole.showatoms.at(mole.knoepfe.at(i).neighbors.at(1)      ).pos - mole.asymm.at(i).pos;
        double chi1 = sqrt(Norm(a))-
          ((mole.Kovalenz_Radien[mole.showatoms.at(mole.knoepfe.at(i).neighbors.at(0)).an]+
            mole.Kovalenz_Radien[mole.asymm.at(i).an])/100.0);
        double chi2 = sqrt(Norm(b))-
          ((mole.Kovalenz_Radien[mole.showatoms.at(mole.knoepfe.at(i).neighbors.at(1)).an]+
            mole.Kovalenz_Radien[mole.asymm.at(i).an])/100.0);
        a = c = Normalize(a) ;
        c = c+ (b= Normalize(b));
        angle=mole.winkel(a,b);
        c = Normalize(c);
        double andi=(mole.showatoms.at(mole.knoepfe.at(i).neighbors.at(1)).an+mole.showatoms.at(mole.knoepfe.at(i).neighbors.at(0)).an)/2.0-5.0;
        andi= (andi)?0.8:1.0;
        if (angle<160) {
          if ((andi*(chi1+chi2))<-0.13) {//43
            c = (-(xh[3]-nh) * c)+mole.asymm.at(i).pos;    
            htest.Label=mole.asymm.at(i).Label.section('_',0,0);
            htest.part=mole.asymm.at(i).part;
            htest.resiNr=mole.asymm.at(i).resiNr;
            htest.Label.replace(0,1,'H');
            int hindex=0;
            QString nnn=htest.Label;
            do {
              if (hindex) nnn=htest.Label.left(3).append(QString::number(hindex+9,36));
              if (nnn.size()>4) nnn=htest.Label.left(2).append(QString::number(hindex+9,36));
              if (htest.resiNr)
                nn=QString("%1_%2")//for shelxl same names in different parts are no problem but for platon so this should fix it.
                  .arg(nnn)
                  .arg((htest.resiNr)?QString::number(htest.resiNr):"");
              else nn=nnn;
              // qDebug()<<nn<<nnn<<(alab.contains(nn,Qt::CaseInsensitive));
              hindex++;
            }while(alab.contains(nn,Qt::CaseInsensitive));
            htest.Label=nnn;
            alab.append(nn);
            htest.isIso=true;
            htest.ufiso_org=QString("-1.2");
            double uIso = mole.ueq(mole.asymm.at(i).uf)*1.2;
            htest.uf.m11 = htest.uf.m22 = htest.uf.m33 = uIso;
            htest.uf.m23 = uIso * mole.cell.cosra; 
            htest.uf.m13 = uIso * mole.cell.cosrb; 
            htest.uf.m12 = uIso * mole.cell.cosrg; 
            mole.Uf2Uo(htest.uf,htest.uc);
            htest.pos=c;
            mole.kart2frac(htest.pos,htest.frac);	
            htest.orginalLine=QString("%1  %2  %3 %4 %5 %6 %7")
              .arg(htest.Label)
              .arg(qMax(1,editor->sfac.indexOf(0)+1))
              .arg(htest.frac.x,9,'f',5)
              .arg(htest.frac.y,9,'f',5)
              .arg(htest.frac.z,9,'f',5)
              .arg(mole.asymm.at(i).sof_org)
              .arg("-1.2");
            mole.asymm.append(htest);
            QString label = mole.showatoms.at(i).orginalLine.left(80).trimmed();
            //            int afixfuenf=(mole.showatoms.at(i).afix/10)?(mole.showatoms.at(i).afix/10)*10+5:0;
            cursor.movePosition(QTextCursor::Start);
            cursor = document->find(label,cursor);
            if (cursor.isNull()){
              cursor = editor->textCursor();
              cursor.movePosition(QTextCursor::Start);
              label.chop(10);
              cursor = document->find(label,cursor);
              if (cursor.isNull()) {
                cursor = editor->textCursor();
              }
            }
            cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
            cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
            while (cursor.selectedText().endsWith("=")) {
              cursor.movePosition(QTextCursor::Down,QTextCursor::KeepAnchor);
              cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
            }
            cursor.clearSelection();
            cursor.movePosition(QTextCursor::Down);
            cursor.insertText(QString("AFIX 43\n%1\nAFIX %2\n")
                .arg(mole.asymm.at(mole.asymm.size()-1).orginalLine)
                .arg(mole.afix5(i)));
          }
          else{//23
            w = Normalize(a);
            u = Normalize(b);
            double si=1.0376-0.0346*Norm(w-u);    //=1.91063323625-((acos(u*w)-1.91063323625)/5.0);//-1.91063323625 = 109.47 grad ; 3.7 empirischer Wert
            c = (-cos(si)*(xh[1]-nh) * c);
            v = sin(si)  *(xh[1]-nh) * Normalize(c%a);
            a = mole.asymm.at(i).pos + c + v;
            b = mole.asymm.at(i).pos + c - v;
            c = c + mole.asymm.at(i).pos;

            htest.Label=mole.asymm.at(i).Label.section('_',0,0);
            htest.part=mole.asymm.at(i).part;
            htest.resiNr=mole.asymm.at(i).resiNr;
            htest.Label.replace(0,1,'H');
            int hindex=1;
            QString nnn=htest.Label;
            QString ann=htest.Label;
            do {
              if (hindex) nnn=htest.Label.left(3).append(QString::number(hindex+9,36));
              if (nnn.size()>4) nnn=htest.Label.left(2).append(QString::number(hindex+9,36));
              if (htest.resiNr)
                nn=QString("%1_%2")//for shelxl same names in different parts are no problem but for platon so this should fix it.
                  .arg(nnn)
                  .arg((htest.resiNr)?QString::number(htest.resiNr):"");
              else nn=nnn;
              // qDebug()<<nn<<nnn<<(alab.contains(nn,Qt::CaseInsensitive));
              hindex++;
            }while(alab.contains(nn,Qt::CaseInsensitive));
            htest.Label=nnn;
            alab.append(nn);
            htest.isIso=true;
            htest.ufiso_org=QString("-1.2");
            double uIso = mole.ueq(mole.asymm.at(i).uf)*1.2;
            htest.uf.m11 = htest.uf.m22 = htest.uf.m33 = uIso;
            htest.uf.m23 = uIso * mole.cell.cosra; 
            htest.uf.m13 = uIso * mole.cell.cosrb;
            htest.uf.m12 = uIso * mole.cell.cosrg;
            mole.Uf2Uo(htest.uf,htest.uc);
            htest.pos=a;
            mole.kart2frac(htest.pos,htest.frac);	
            htest.orginalLine=QString("%1  %2  %3 %4 %5 %6 %7")
              .arg(htest.Label)
              .arg(qMax(1,editor->sfac.indexOf(0)+1))
              .arg(htest.frac.x,9,'f',5)
              .arg(htest.frac.y,9,'f',5)
              .arg(htest.frac.z,9,'f',5)
              .arg(mole.asymm.at(i).sof_org)
              .arg("-1.2");
            mole.asymm.append(htest);
            //printf("AB problem: htest%s nnn%s ann%s\n",htest.Label.toStdString().c_str(),nnn.toStdString().c_str(),ann.toStdString().c_str());
            do {
              if (hindex) nnn=ann.left(3).append(QString::number(hindex+9,36));
              if (nnn.size()>4) nnn=ann.left(2).append(QString::number(hindex+9,36));
              if (htest.resiNr)
                nn=QString("%1_%2")//for shelxl same names in different parts are no problem but for platon so this should fix it.
                  .arg(nnn)
                  .arg((htest.resiNr)?QString::number(htest.resiNr):"");
              else nn=nnn;
              // qDebug()<<nn<<nnn<<(alab.contains(nn,Qt::CaseInsensitive));
              hindex++;
            }while(alab.contains(nn,Qt::CaseInsensitive));
            htest.Label=nnn;
            alab.append(nn);
            //printf("AB problems: htest%s nnn%s nn%s\n",htest.Label.toStdString().c_str(),nnn.toStdString().c_str(),nn.toStdString().c_str());
            htest.pos=b;
            mole.kart2frac(htest.pos,htest.frac);	
            htest.orginalLine=QString("%1  %2  %3 %4 %5 %6 %7")
              .arg(htest.Label)
              .arg(qMax(1,editor->sfac.indexOf(0)+1))
              .arg(htest.frac.x,9,'f',5)
              .arg(htest.frac.y,9,'f',5)
              .arg(htest.frac.z,9,'f',5)
              .arg(mole.asymm.at(i).sof_org)
              .arg("-1.2");
            mole.asymm.append(htest);
            QString label = mole.showatoms.at(i).orginalLine.left(80).trimmed();
            //            int afixfuenf=(mole.showatoms.at(i).afix/10)?(mole.showatoms.at(i).afix/10)*10+5:0;
            cursor.movePosition(QTextCursor::Start);
            cursor = document->find(label,cursor);
            if (cursor.isNull()){
              cursor = editor->textCursor();
              cursor.movePosition(QTextCursor::Start);
              label.chop(10);
              cursor = document->find(label,cursor);
              if (cursor.isNull()) {
                cursor = editor->textCursor();
              }
            }
            cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
            cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
            while (cursor.selectedText().endsWith("=")) {
              cursor.movePosition(QTextCursor::Down,QTextCursor::KeepAnchor);
              cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
            }
            cursor.clearSelection();
            cursor.movePosition(QTextCursor::Down);
            cursor.insertText(QString("AFIX 23\n%1\n%2\nAFIX %3\n")
                .arg(mole.asymm.at(mole.asymm.size()-2).orginalLine)
                .arg(mole.asymm.at(mole.asymm.size()-1).orginalLine)
                .arg(mole.afix5(i)));

          }
        }
      }

      if (mole.knoepfe.at(i).neighbors.size()==3) {
        if ((mole.asymm.at(i).an==6)&&(!istDonor.contains(i))) continue; 
        V3 v,w=V3(0,0,0),u ,a,b,c=V3(0,0,0);
        double ch1=0;
        for (int k=0; k<3; k++){
          a = Normalize(mole.showatoms.at(mole.knoepfe.at(i).neighbors.at(k)      ).pos - mole.asymm.at(i).pos);
          b = Normalize(mole.showatoms.at(mole.knoepfe.at(i).neighbors.at((k+1)%3)).pos - mole.asymm.at(i).pos);
          c = c + a;
          v = Normalize(a%b);
          if (k) {plan*=fabs(w*v);//1 for perfect flat 
          }
          w = v;
          ch1 += sqrt(Distance(mole.asymm.at(i).pos,
                mole.showatoms.at(mole.knoepfe.at(i).neighbors.at(k)).pos))-
            ((mole.Kovalenz_Radien[mole.asymm.at(i).an]+
              mole.Kovalenz_Radien[mole.showatoms.at(mole.knoepfe.at(i).neighbors.at(k)).an])*0.01);

        }
        c = Normalize(c);
        ch1*=1.0/3;
        if ((plan<0.8)&&(ch1>-0.09)){// not flat and not to short bonds
          c *=-(xh[0]-nh);
          htest.Label=mole.asymm.at(i).Label.section('_',0,0);
          htest.part=mole.asymm.at(i).part;
          htest.resiNr=mole.asymm.at(i).resiNr;
          htest.Label.replace(0,1,'H');
          int hindex=0;
          QString nnn=htest.Label;
          do {
            if (hindex) nnn=htest.Label.left(3).append(QString::number(hindex+9,36));
            if (nnn.size()>4) nnn=htest.Label.left(2).append(QString::number(hindex+9,36));
            if (htest.resiNr)
              nn=QString("%1_%2")//for shelxl same names in different parts are no problem but for platon so this should fix it.
                .arg(nnn)
                .arg((htest.resiNr)?QString::number(htest.resiNr):"");
            else nn=nnn;
            // qDebug()<<nn<<nnn<<(alab.contains(nn,Qt::CaseInsensitive));
            hindex++;
          }while(alab.contains(nn,Qt::CaseInsensitive));
          htest.Label=nnn;
          alab.append(nn);
          htest.isIso=true;
          htest.ufiso_org=QString("-1.2");
          double uIso = mole.ueq(mole.asymm.at(i).uf)*1.2;
          htest.uf.m11 = htest.uf.m22 = htest.uf.m33 = uIso;
          htest.uf.m23 = uIso * mole.cell.cosra; 
          htest.uf.m13 = uIso * mole.cell.cosrb;
          htest.uf.m12 = uIso * mole.cell.cosrg;
          mole.Uf2Uo(htest.uf,htest.uc);
          htest.pos = mole.asymm.at(i).pos + c;
          mole.kart2frac(htest.pos,htest.frac);
          QString label = mole.showatoms.at(i).orginalLine.left(80).trimmed();
          //          int afixfuenf=(mole.showatoms.at(i).afix/10)?(mole.showatoms.at(i).afix/10)*10+5:0;
          cursor.movePosition(QTextCursor::Start);
          cursor = document->find(label,cursor);
          if (cursor.isNull()){
            cursor = editor->textCursor();
            cursor.movePosition(QTextCursor::Start);
            label.chop(10);
            cursor = document->find(label,cursor);
            if (cursor.isNull()) {
              cursor = editor->textCursor();
            }
          }
          cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
          cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
          while (cursor.selectedText().endsWith("=")) {
            cursor.movePosition(QTextCursor::Down,QTextCursor::KeepAnchor);
            cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
          }
          cursor.clearSelection();
          cursor.movePosition(QTextCursor::Down);
          htest.orginalLine=QString("%1  %2  %3 %4 %5 %6 %7")
            .arg(htest.Label)
            .arg(qMax(1,editor->sfac.indexOf(0)+1))
            .arg(htest.frac.x,9,'f',5)
            .arg(htest.frac.y,9,'f',5)
            .arg(htest.frac.z,9,'f',5)
            .arg(mole.asymm.at(i).sof_org)
            .arg("-1.2");
          cursor.insertText(QString("AFIX 13\n%1\nAFIX %2\n").arg(htest.orginalLine).arg(mole.afix5(i)));
          mole.asymm.append(htest);
        }
      }
    }
    if (((mole.asymm.at(i).an==4)||(mole.asymm.at(i).an==5))&&((mole.knoepfe.at(i).neighbors.size()==4)||(mole.knoepfe.at(i).neighbors.size()==5))){//boron with 4 or 5 neighbors AFIX 153
        //qDebug()<<mole.knoepfe.at(i).neighbors.size()<<mole.asymm.at(i).Label;
        V3 vsum = V3(0.,0.,0.);
        int nbs=mole.knoepfe.at(i).neighbors.size();
        int nbr=0;
        for (int k=0; k<mole.knoepfe.at(i).neighbors.size();k++){
            if (abs(mole.showatoms.at(mole.knoepfe.at(i).neighbors.at(k)).an-5)<2){
                nbr++;
            vsum+=(mole.showatoms.at(mole.knoepfe.at(i).neighbors.at(k)      ).pos - mole.asymm.at(i).pos);
            }
        }
        printf("153 test length = %f %d==%d %s\n",Norm(vsum), nbs, nbr, mole.asymm.at(i).Label.toStdString().c_str());
        if ((nbs==nbr)&&(Norm(vsum)>10)){
        vsum=Normalize(vsum);
        vsum*=-1.0*xh[4];
        htest.Label=mole.asymm.at(i).Label.section('_',0,0);
        htest.part=mole.asymm.at(i).part;
        htest.resiNr=mole.asymm.at(i).resiNr;
        htest.Label.replace(0,1,'H');
        int hindex=0;
        QString nnn=htest.Label;
        do {
          if (hindex) nnn=htest.Label.left(3).append(QString::number(hindex+9,36));
          if (nnn.size()>4) nnn=htest.Label.left(2).append(QString::number(hindex+9,36));
          if (htest.resiNr)
            nn=QString("%1_%2")//for shelxl same names in different parts are no problem but for platon so this should fix it.
              .arg(nnn)
              .arg((htest.resiNr)?QString::number(htest.resiNr):"");
          else nn=nnn;
          // qDebug()<<nn<<nnn<<(alab.contains(nn,Qt::CaseInsensitive));
          hindex++;
        }while(alab.contains(nn,Qt::CaseInsensitive));
        htest.Label=nnn;
        alab.append(nn);
        htest.isIso=true;
        htest.ufiso_org=QString("-1.2");
        double uIso = mole.ueq(mole.asymm.at(i).uf)*1.2;
        htest.uf.m11 = htest.uf.m22 = htest.uf.m33 = uIso;
        htest.uf.m23 = uIso * mole.cell.cosra;
        htest.uf.m13 = uIso * mole.cell.cosrb;
        htest.uf.m12 = uIso * mole.cell.cosrg;
        mole.Uf2Uo(htest.uf,htest.uc);
        htest.pos = mole.asymm.at(i).pos + vsum;
        mole.kart2frac(htest.pos,htest.frac);
        QString label = mole.showatoms.at(i).orginalLine.left(80).trimmed();
        //          int afixfuenf=(mole.showatoms.at(i).afix/10)?(mole.showatoms.at(i).afix/10)*10+5:0;
        cursor.movePosition(QTextCursor::Start);
        cursor = document->find(label,cursor);
        if (cursor.isNull()){
          cursor = editor->textCursor();
          cursor.movePosition(QTextCursor::Start);
          label.chop(10);
          cursor = document->find(label,cursor);
          if (cursor.isNull()) {
            cursor = editor->textCursor();
          }
        }
        cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
        cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
        while (cursor.selectedText().endsWith("=")) {
          cursor.movePosition(QTextCursor::Down,QTextCursor::KeepAnchor);
          cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
        }
        cursor.clearSelection();
        cursor.movePosition(QTextCursor::Down);
        htest.orginalLine=QString("%1  %2  %3 %4 %5 %6 %7")
          .arg(htest.Label)
          .arg(qMax(1,editor->sfac.indexOf(0)+1))
          .arg(htest.frac.x,9,'f',5)
          .arg(htest.frac.y,9,'f',5)
          .arg(htest.frac.z,9,'f',5)
          .arg(mole.asymm.at(i).sof_org)
          .arg("-1.2");
        cursor.insertText(QString("AFIX 153\n%1\nAFIX %2\n").arg(htest.orginalLine).arg(mole.afix5(i)));
        mole.asymm.append(htest);
        }
    }
  }
  for (int j=0;j<mole.contact.size();j++){
  /*    printf("??LINE %d %s %s\n",__LINE__,
             mole.asymm.at(mole.contact.at(j).a1).Label.toStdString().c_str(),
             mole.asymm.at(mole.contact.at(j).a2).Label.toStdString().c_str());*/
    if ((istDonor.contains(mole.contact.at(j).a1)||(!keinDonor.contains(mole.contact.at(j).a1)))
        &&(mole.asymm.at(mole.contact.at(j).a1).an==7)) {
      if (keinDonor.contains(mole.contact.at(j).a1)) continue;
      if (fxle->n5) {
        htest = findOH(mole.cell.symmops.at(mole.contact.at(j).sn) * mole.asymm.at(mole.contact.at(j).a1).frac
            + mole.cell.trans.at(mole.contact.at(j).sn) - mole.contact.at(j).floorD,
            mole.asymm.at(mole.contact.at(j).a2).frac,
            mole.contact.at(j).a1,alab);

        /*printf("LINE %d %s %s\n",__LINE__,
               mole.asymm.at(mole.contact.at(j).a1).Label.toStdString().c_str(),
               mole.asymm.at(mole.contact.at(j).a2).Label.toStdString().c_str());*/

        if (Distance(htest.pos,V3(0,0,0))<0.001){
          htest = findOH(mole.asymm.at(mole.contact.at(j).a1).frac,
              mole.cell.symmops.at(mole.contact.at(j).sn) * mole.asymm.at(mole.contact.at(j).a2).frac
              + mole.cell.trans.at(mole.contact.at(j).sn) ,
              mole.contact.at(j).a1,alab);
         /* printf("LINE %d %s %s\n",__LINE__,
                 mole.asymm.at(mole.contact.at(j).a1).Label.toStdString().c_str(),
                 mole.asymm.at(mole.contact.at(j).a2).Label.toStdString().c_str());*/
          //          if (Distance(htest.pos,V3(0,0,0))<0.001){ keinDonor[mole.contact.at(j).a2]++; }
        } else {
          keinDonor[mole.contact.at(j).a1]++;
          //         qDebug()<<"done"<<mole.asymm.at(mole.contact.at(j).a2).Label;
        }
        if (Distance(htest.pos,V3(0,0,0))){
          htest.orginalLine=QString("%1  %2  %3 %4 %5 %6 %7")
            .arg(htest.Label)
            .arg(qMax(1,editor->sfac.indexOf(0)+1))
            .arg(htest.frac.x,9,'f',5)
            .arg(htest.frac.y,9,'f',5)
            .arg(htest.frac.z,9,'f',5)
            .arg(mole.asymm.at(mole.contact.at(j).a1).sof_org)
            .arg("-1.5");
          mole.asymm.append(htest);
          QString label = mole.showatoms.at(mole.contact.at(j).a1).orginalLine.left(80).trimmed();
          //          int afixfuenf=(mole.showatoms.at(mole.contact.at(j).a1).afix/10)?(mole.showatoms.at(mole.contact.at(j).a1).afix/10)*10+5:0;
          cursor.movePosition(QTextCursor::Start);
          cursor = document->find(label,cursor);
          if (cursor.isNull()){
            cursor = editor->textCursor();
            cursor.movePosition(QTextCursor::Start);
            label.chop(10);
            cursor = document->find(label,cursor);
            if (cursor.isNull()) {
              cursor = editor->textCursor();
            }
          }
          cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
          cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
          while (cursor.selectedText().endsWith("=")) {
            cursor.movePosition(QTextCursor::Down,QTextCursor::KeepAnchor);
            cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
          }
          cursor.clearSelection();
          cursor.movePosition(QTextCursor::Down);
          cursor.insertText(QString("AFIX 148\n%1\nAFIX %2\n")
              .arg(mole.asymm.last().orginalLine)
              .arg(mole.afix5(mole.contact.at(j).a1))
              );
        }//Dist
      }//fxle->n5
    }// is O is in list of donors and not in list of no donors

  }// all contacts
  cursor.endEditBlock();
  if (gehtMichAn.size()) gehtMichAn.takeLast();
  if (mole.asymm.size()!=warmal){
    gehtMichAn.append(mole.asymm.size()-warmal+2);
  }

  int jetztAtome=0;
  for (int i=0; i<mole.asymm.size();i++) if (mole.asymm.at(i).an>=0)jetztAtome++;
  actionHFix->setDisabled(true);
  fuse();
  QString info=QString("<font color=\"green\"><b>%1</b> Hydrogen atoms added. <h2>Please SAVE NOW!</h2></font>").arg(jetztAtome-warmalAtome);
  infoKanalNews(info); 

  switch (duplicates()){
    case 1:infoKanalNews("<font color=orange >Some hydrogen atoms have identical names please check.</font>");break;
    case 2:infoKanalNews("<font color=red >Some non-hydrogen atoms have identical names. YOU HAVE TO CHECK BEFORE REFINING!</font>");break;
    case 3:infoKanalNews("<font color=red >Some atoms have identical names. YOU HAVE TO CHECK BEFORE REFINING!</font>");break;
  }
  chgl->updateGL();
}

MyAtom Window::findOH(V3 donor, V3 acceptor,int dindex,QStringList alab){
  CEnvironment peaks;
  QString nn;
  peaks.clear();
  double minGoofy=100000.0,g=0;
  int minG=0;
  V3 mdz=(0.5*fxle->dx)+(0.5*fxle->dy)+(0.5*fxle->dz);
  V3 df=donor;
  V3 af=acceptor;
  if (mole.fl(af.x-df.x, af.y-df.y,af.z-df.z)>3.3){
    V3 floors;
    floors = af-df+ V3(0.5,0.5,0.5);
    floors = V3(floor(floors.x),floor(floors.y),floor(floors.z));
    af+=-1.0*floors;
  }
  double ad=mole.fl(af.x-df.x, af.y-df.y,af.z-df.z);
  MyAtom htest;
  htest.an=0;
  htest.part=0;
  htest.resiNr=0;
  htest.hidden=0;
  htest.Label=mole.asymm.at(dindex).Label.section('_',0,0);
  htest.part=mole.asymm.at(dindex).part;
  htest.resiNr=mole.asymm.at(dindex).resiNr;
  htest.Label.replace(0,1,'H');
  int hindex=0;
  QString nnn=htest.Label;
  do {
    if (hindex) nnn=htest.Label.left(3).append(QString::number(hindex+9,36));
    if (nnn.size()>4) nnn=htest.Label.left(2).append(QString::number(hindex+9,36));
    if (htest.resiNr)
      nn=QString("%1_%2")//for shelxl same names in different parts are no problem but for platon so this should fix it.
        .arg(nnn)
        .arg((htest.resiNr)?QString::number(htest.resiNr):"");
    else nn=nnn;
    // qDebug()<<nn<<nnn<<(alab.contains(nn,Qt::CaseInsensitive));
    hindex++;
  }while(alab.contains(nn,Qt::CaseInsensitive));
  htest.Label=nnn;
  alab.append(nn);
  htest.symmGroup=0;
  htest.sg=0;
  htest.scod=555;//the identity
  htest.auidx=-1;
  htest.frac=V3(0,0,0);
  htest.pos=V3(0,0,0);
  htest.isIso=true;
  htest.ufiso_org=QString("-1.5");
  double uIso = mole.ueq(mole.asymm.at(dindex).uf)*1.5;
  htest.uf.m11 = htest.uf.m22 = htest.uf.m33 = uIso;
  htest.uf.m23 = uIso * mole.cell.cosra; 
  htest.uf.m13 = uIso * mole.cell.cosrb;
  htest.uf.m12 = uIso * mole.cell.cosrg;
  mole.Uf2Uo(htest.uf,htest.uc);
  if (fxle->n5==0) return htest;
  double x,y,z,u,v,w,p,q,r,t;
  for (int k=0;k<fxle->n3;k++){
    for (int j=0;j<fxle->n2;j++){
      for (int i=0;i<fxle->n1;i++){
        V3 o= (i*fxle->dx+j*fxle->dy+k*fxle->dz) + mdz;
        mole.kart2frac(o,o);
        V3 floors;
        floors = o-df+ V3(0.5,0.5,0.5);
        floors = V3(floor(floors.x),floor(floors.y),floor(floors.z));
        o+=-1.0*floors;
        double ha,hd;
        hd=mole.fl(df.x-o.x, df.y-o.y,df.z-o.z);
        ha=mole.fl(af.x-o.x, af.y-o.y,af.z-o.z);
        if (1.2<hd) continue;//donor H must be smaller 1.2 A
        if (2.6<ha) continue;//donor H must be smaller 2.6 A
        if (hd<0.6) continue;//donor H must be greater 0.6 A
        if (((ha*ha+hd*hd-ad*ad)/(2*hd*ha))>-0.57)continue; //angle greater 125deg ok!
        t = fxle->datfo_fc[i+ fxle->n1*(j+k*fxle->n2)];
        x = t -  fxle->datfo_fc[((i+1)%fxle->n1) + fxle->n1*(j+k*fxle->n2)];
        y = t -  fxle->datfo_fc[i+ fxle->n1*(((j+1)%fxle->n2)+k*fxle->n2)];
        z = t -  fxle->datfo_fc[i+ fxle->n1*(j+((k+1)%fxle->n3)*fxle->n2)];
        u = t -  fxle->datfo_fc[((i+fxle->n1-1)%fxle->n1)+ fxle->n1*(j+k*fxle->n2)];
        v = t -  fxle->datfo_fc[i+ fxle->n1*(((j+fxle->n2-1)%fxle->n2)+k*fxle->n2)];
        w = t -  fxle->datfo_fc[i+ fxle->n1*(j+((k+fxle->n2-1)%fxle->n3)*fxle->n2)];
        if (fmin(x,fmin(y,fmin(z,fmin(u,fmin(v,w)))))<0) continue;//if this is not a maximum then skip
        p=0.5*(u-x)/(u+x);
        q=0.5*(v-y)/(v+y);
        r=0.5*(w-z)/(w+z);
        t=t+0.25*(p*(u-x)+q*(v-y)+r*(w-z));
        if (t<fabs(fxle->iso[1])*1.2) continue;// if this is below the green iso surface then skip
        htest.peakHeight=t;  
        htest.frac.x = ((double) i + p +0.5)/fxle->n1; 
        htest.frac.y = ((double) j + q +0.5)/fxle->n2;
        htest.frac.z = ((double) k + r +0.5)/fxle->n3;
        hd=mole.fl(df.x-htest.frac.x, df.y-htest.frac.y,df.z-htest.frac.z);
        ha=mole.fl(af.x-htest.frac.x, af.y-htest.frac.y,af.z-htest.frac.z);
        if (hd<0.6) continue;//to close to donor
        g=(ha+hd)/htest.peakHeight;
        minG=(g<minGoofy)?peaks.size():minG;
        minGoofy=(g<minGoofy)?g:minGoofy;
        mole.frac2kart( htest.frac, htest.pos);
        peaks.append(htest); 
      }
    }
  }
  if (peaks.isEmpty()) {
    htest.frac=htest.pos=V3(0,0,0);
    return htest;
  }
  V3 D,floorD,prime,nf,dp;
  double min=1000,dk=0;
  for (int nn=0;nn<mole.cell.symmops.size();  nn++){
    prime=mole.cell.symmops.at(nn) * peaks.at(minG).frac + mole.cell.trans.at(nn);
    D=prime - mole.asymm.at(dindex).frac + V3(0.5,0.5,0.5) ;
    floorD=V3(floor(D.x),floor(D.y),floor(D.z));
    dp=D - floorD - V3(0.5,0.5,0.5);
    dk=mole.fl(dp.x,dp.y,dp.z);
    if (dk<min){
      min=dk;
      nf=prime-floorD;
    }
  }
  peaks[minG].frac=nf;
  mole.frac2kart(peaks[minG].frac,peaks[minG].pos);
  return peaks[minG];
}

void Window::invert(){
  if (mole.asymm.isEmpty()) return;
  //inverting structure
  QList<V3> moves;
  moves.append(V3(1,1,1));//most of the space groups
  moves.append(V3(1,0.5,1));//I41, I41md, I41cd  
  moves.append(V3(1,0.5,0.25));//I4122, I-42d
  moves.append(V3(0.25,0.25,1));//Fdd2
  moves.append(V3(0.25,0.25,0.25));//F4132
  int enantio=0;
  QString kep,nextli;
  QTextDocument *document = editor->document();
  QTextCursor cursor = editor->textCursor();
  cursor.beginEditBlock ();
  if ((!mole.cell.centered)&&(!mole.cell.centeric)){
    for (int i=0; i<mole.cell.trans.size(); i++){
      V3 t = V3(1,1,1) - mole.cell.trans.at(i);
      t.x=fmod(t.x,1);
      t.y=fmod(t.y,1);
      t.z=fmod(t.z,1);
      if (!(t==mole.cell.trans.at(i))) {
        enantio++;
        mole.cell.trans[i]=t;
      }

    }   
  }
  if (enantio){

    editor->replace->setText("REM SYMM ");
    editor->searchLE->setText("^SYMM ");
    editor->replaceAll();
    cursor.movePosition(QTextCursor::Start,QTextCursor::MoveAnchor);
    cursor = document->find("REM SYMM",cursor);
    cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
    for (int i=1; i<mole.cell.symmops.size(); i++){
      cursor.insertText(QString("SYMM %1\n").arg(mole.symmcode2human(i)));
    }

    cursor.insertText("REM enantiomorph space group. SYMM cards changed!\n");  
    editor->searchLE->setText("");
    editor->replace->setText("");
  }
  //qDebug("test %d\n",enantio);
  V3 testP=V3(0.3234,0.2234,0.1234); 
  QList<V3> tps,ips;
  Matrix inv(-1.0,0.0,0.0, 0.0,-1.0,0.0, 0.0,0.0,-1.0);  
  for (int n=0;n<mole.cell.symmops.size();  n++){
    V3 pt=mole.cell.symmops.at(n) * testP + mole.cell.trans.at(n);
    ips.append(pt);
  }
  int kkk=0,jjj=0,mo=0;
  if (mole.cell.centered) do{
    kkk=jjj=0;
    tps.clear();
    for (int z=0; z<ips.size();z++){
      V3 pt=inv*ips.at(z)+moves.at(mo);
      tps.append(pt);
    }
    double dk;
    V3 prime,dp,D,floorD;
    for (int i=0; i<tps.size();i++){
      for (int j=0; j<tps.size();j++){
        for (int n=0;n<mole.cell.symmops.size();  n++){
          prime=mole.cell.symmops.at(n) * tps.at(i) + mole.cell.trans.at(n);
          D=prime - tps.at(j)+ V3(0.5,0.5,0.5) ;
          floorD=V3(floor(D.x),floor(D.y),floor(D.z));
          dp=D - floorD - V3(0.5,0.5,0.5);
          dk=mole.fl(dp.x,dp.y,dp.z);
          if (dk<0.1) kkk++;
        }
      }
    }
    for (int i=0; i<ips.size();i++){
      for (int j=0; j<ips.size();j++){
        for (int n=0;n<mole.cell.symmops.size();  n++){
          prime=mole.cell.symmops.at(n) * ips.at(i) + mole.cell.trans.at(n);
          D=prime - ips.at(j)+ V3(0.5,0.5,0.5) ;
          floorD=V3(floor(D.x),floor(D.y),floor(D.z));
          dp=D - floorD - V3(0.5,0.5,0.5);
          dk=mole.fl(dp.x,dp.y,dp.z);
          if (dk<0.1) jjj++;
        }
      }
    }
    mo++;
  }while (kkk-jjj);
  if (mo) mo--;
  //printf("Move : %g %g %g\n",moves.at(mo).x,moves.at(mo).y,moves.at(mo).z);
  for (int i = 0; i < mole.asymm.size(); i++){
    V3 f = inv * mole.asymm.at(i).frac + moves.at(mo);
    mole.asymm[i].frac=f;
    mole.frac2kart(mole.asymm.at(i).frac,mole.asymm[i].pos);

    if (mole.asymm.at(i).an==-1) continue;
    QString source,target;
    source=mole.asymm.at(i).Label;
    target=source.section(QString::fromUtf8("»"),0,0);
    MyAtom ato=mole.asymm.at(i);
    ato.Label=target;
    ato.symmGroup=0;
    ato.sg=0;
    ato.scod=555;//the identity
    ato.auidx=-1;
    int that=mole.asymm.indexOf(ato);
    if ((that>=mole.asymm.size())||(that<0)) return;
    QString susu=mole.asymm.at(that).orginalLine;
    cursor.movePosition(QTextCursor::Start);
    cursor = document->find(susu,cursor);
    if (mole.asymm.at(that).isIso){
      ato.ufiso_org=mole.asymm.at(that).ufiso_org;
      kep=QString("%1 %2 %3 %4 %5 %6 %7")
        .arg(ato.Label.section('_',0,0),-5)
        .arg(qMax(1,editor->sfac.indexOf(ato.an)+1))
        .arg(ato.frac.x,10,'f',6)
        .arg(ato.frac.y,10,'f',6)
        .arg(ato.frac.z,10,'f',6)
        .arg(mole.asymm.at(that).sof_org,9,'f',5)
        .arg(ato.ufiso_org)
        ;
      cursor.deleteChar();
      cursor.insertText(kep);
      cursor.setPosition(cursor.position(), QTextCursor::MoveAnchor);
      ato.sof_org=mole.asymm.at(that).sof_org;
      //      printf("debug:iso sof==%g atom#%d mole.asymm.at(that).afixParent %d \n",mole.asymm.at(that).sof_org,that,mole.asymm.at(that).afixParent);
      ato.uf= mole.asymm.at(that).uf;
      ato.uc= mole.asymm.at(that).uc;
      ato.isIso=true;
      editor->wholeLine->setChecked(false);
      editor->replaceNext();
    }else{
      kep=QString("%1 %2 %3 %4 %5 %6 %7 %8 ")
        .arg(ato.Label.section('_',0,0),-5)
        .arg(qMax(1,editor->sfac.indexOf(ato.an)+1))
        .arg(ato.frac.x,10,'f',6)
        .arg(ato.frac.y,10,'f',6)
        .arg(ato.frac.z,10,'f',6)
        .arg(mole.asymm.at(that).sof_org,9,'f',5)
        .arg(ato.uf.m11,9,'f',5)
        .arg(ato.uf.m22,9,'f',5);
      //    printf("debug:anis sof==%g atom#%d\n",mole.asymm.at(that).sof_org,that);
      ato.sof_org=mole.asymm.at(that).sof_org;
      cursor.deleteChar();
      cursor.insertText(kep);
      cursor.setPosition(cursor.position(), QTextCursor::MoveAnchor);
      cursor.movePosition(QTextCursor::Down);
      cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
      cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
      nextli=cursor.selectedText();
      cursor = document->find(nextli,cursor);

      cursor.deleteChar();
      cursor.insertText(QString("     %1 %2 %3 %4")
          .arg(ato.uf.m33,9,'f',5)
          .arg(ato.uf.m23,9,'f',5)
          .arg(ato.uf.m13,9,'f',5)
          .arg(ato.uf.m12,9,'f',5));
      cursor.setPosition(cursor.position(), QTextCursor::MoveAnchor);
    }
    ato.orginalLine=kep.section("=",0,0);
    mole.asymm[that]=ato;
  }

  cursor = editor->textCursor();
  cursor.endEditBlock();
  chgl->pause=true;
  mole.showatoms.clear();
  mole.showbonds.clear();
  chgl->mol->showatoms.clear();
  chgl->mol->showbonds.clear();
  chgl->mol->selectedatoms.clear();
  for (int o=0; o<mole.asymm.size();o++)
    mole.showatoms.append(mole.asymm[o]);
  mole.sdmcompleter();
  mole.showbonds =
    mole.connecting(mole.showatoms);
  chgl->setMolecule(&mole);
  chgl->mol->selectedatoms.clear();
  chgl->murx=__LINE__;
  bool growYes=chgl->fuse->isVisible ();
  chgl->mol->fuse();
  if (growYes) chgl->mol->grow();
  editor->searchLE->setText("");
  editor->hideSearch();
  chgl->pause=false;
//  printf("%d\n",__LINE__);
  chgl->updateGL();
  update();

}

void Window::addDissorderedMethyl(){//127
  QAction *action = qobject_cast<QAction *>(sender());
  int i=0;
  if (action)
    i=action->data().toInt();
  else return;
  if (i>mole.asymm.size()) return;
  int warmalAtome=0;
  for (int i=0; i<mole.asymm.size();i++) if (mole.asymm.at(i).an>=0)warmalAtome++;

  chgl->disSelection();
  MyAtom htest,qtest;
  QStringList alab;
  for (int i =0; i<mole.asymm.size(); i++){
    alab.append(mole.asymm.at(i).Label);
  }
  QString nn;
  if (editor->sfac.indexOf(0)==-1)addNewScatteringFactor(0);
  htest.an=0;
  htest.part=0;
  htest.resiNr=0;
  htest.hidden=0;
  htest.symmGroup=0;
  htest.sg=0;
  htest.scod=555;//the identity
  htest.auidx=-1;
  htest.uc.m12=htest.uc.m23=htest.uc.m13=0.0;
  htest.uc.m21=htest.uc.m32=htest.uc.m31=0.0;
  htest.uf.m12=htest.uf.m23=htest.uf.m13=0.0;
  htest.uf.m21=htest.uf.m32=htest.uf.m31=0.0;
  qtest=htest;
  qtest.an=-1;
  QTextDocument *document = editor->document();
  QTextCursor cursor = editor->textCursor();
  cursor.beginEditBlock ();
  //  !!!Neue Freie Variable anlegen!!!
  cursor.movePosition(QTextCursor::End);	
  cursor = document->find("FVAR",cursor,QTextDocument::FindBackward);
  cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
  cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
  while (cursor.selectedText().endsWith("=")) {
    cursor.movePosition(QTextCursor::Down,QTextCursor::KeepAnchor);
    cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);  
  }
  QString fvstr = cursor.selectedText().trimmed();
  fvstr.append(" 0.666 ");
  fvar.append(0.667);
  cursor.deleteChar();
  cursor.insertText(fvstr);
  updateTieFreeVar();
  int frei=fvar.size();
  // !!!!
  double xh[8]={
    0.98,//1
    0.97,//2
    0.96,//3
    0.93,//4
    1.10,//15 B
    0.82,//8 O
    0.93,//9
    0.93// 16
  };
  V3 v=V3(0,0,0),w=V3(0,0,0),u=V3(0,0,0) ,a=V3(0,0,0);//,b=V3(0,0,0),c=V3(0,0,0);
  a = mole.showatoms.at(mole.knoepfe.at(i).neighbors.at(0)).pos - mole.asymm.at(i).pos;
  int ji,ki,li;
  a=Normalize(a);
  double jx,kx,lx,mx,my,mz;
  double val[24],merg[4],wink=0,t=0,mt=0;
  for (int z=0; z<4;z++) merg[z]=0;
  if (fxle->n5){
    for (int z=0; z<24; z++){
      w=Normalize(V3(0,0,1)%a);
      u=Normalize(w%a);
      v=(-(xh[2])*0.33333*a)+ mole.asymm.at(i).pos+(xh[2])*0.942809041582*(sin(wink)*u+cos(wink)*w);
      qtest.pos=v;
      mole.kart2frac(v,v);
      int zplu=0;
      do {
        jx=((zplu+v.x)*fxle->n1+0.5);
        zplu++;
      }while (jx<0);
      zplu=0;
      do {
        kx=((zplu+v.y)*fxle->n2+0.5);
        zplu++;
      }while (kx<0);
      zplu=0;
      do {
        lx=((zplu+v.z)*fxle->n3+0.5);
        zplu++;
      }while (lx<0);
      mx=jx-floor(jx);
      my=kx-floor(kx);
      mz=lx-floor(lx);
      ji=((int)jx)%fxle->n1;//
      ki=((int)kx)%fxle->n2;//
      li=((int)lx)%fxle->n3;//
      merg[z%4]+=val[z]=(
          (1-mx)*fxle->datfo_fc[(ji+fxle->n1*(ki+li*fxle->n2))%fxle->n5]+
          mx*fxle->datfo_fc[((ji+1)+fxle->n1*(ki+li*fxle->n2))%fxle->n5]+
          (1-my)*fxle->datfo_fc[(ji+fxle->n1*(ki+li*fxle->n2))%fxle->n5]+
          my*fxle->datfo_fc[(ji+fxle->n1*((ki+1)+li*fxle->n2))%fxle->n5]+
          (1-mz)*fxle->datfo_fc[(ji+fxle->n1*(ki+li*fxle->n2))%fxle->n5]+
          mz*fxle->datfo_fc[(ji+fxle->n1*(ki+(li+1)*fxle->n2))%fxle->n5])/3.0;
      qtest.peakHeight=val[z];
      qtest.frac=v;
      qtest.Label=QString("Q%1").arg(z,-3);
      mole.pmin=qMin(mole.pmin, qtest.peakHeight);
      mole.pmax=qMax(mole.pmax, qtest.peakHeight);
      qpv->cutoff=0;//mole.pmin;
      qpv->setMin(mole.pmin);
      qpv->setMax(mole.pmax);
      mole.asymm.append(qtest);
      wink+=0.261799387799;
    }
    for (int z=0; z<4;z++) {
      t =merg[(z+4)%4] ;
      double x = t - merg[(z+5)%4];
      double u = t - merg[(z+3)%4];
      if (fmin(x,u)<0) continue;
      double p=0.5*(u-x)/(u+x);
      t=t+0.25*(p*(u-x));
      mt=(mt>t)?mt:t;
      if (t<mt)continue;
      wink=((double) z + p )*0.261799387799; 
    }
  }else{
    int zzz=0;
    int z=mole.knoepfe.at(mole.knoepfe.at(i).neighbors.at(0)).neighbors.at(zzz++);
    while ((z==i)&&(zzz<mole.knoepfe.at(mole.knoepfe.at(i).neighbors.at(0)).neighbors.size())) {
      z=mole.knoepfe.at(mole.knoepfe.at(i).neighbors.at(0)).neighbors.at(zzz++);
    }
    w=Normalize(V3(0,0,1)%a);
    u=Normalize(w%a);
    v=(-(xh[2])*0.33333*a)+ mole.asymm.at(i).pos+(xh[2])*0.942809041582*(sin(wink)*u+cos(wink)*w);
    // if z == i then dieder() returns nan, because A in dieder gets (0,0,0)
    V3 increm = V3(0.0, 0.0, 0.0);
    if ( z == i ) {
      increm = V3(0.00001, 0.00001, 0.00001);
    }
    wink=mole.dieder(mole.showatoms.at(mole.knoepfe.at(i).neighbors.at(0)).pos+increm-mole.asymm.at(z).pos,
        mole.asymm.at(i).pos-mole.showatoms.at(mole.knoepfe.at(i).neighbors.at(0)).pos,
        v-mole.asymm.at(i).pos)/180.0*M_PI;
  }
  v=(-(xh[2])*0.33333*a)+ mole.asymm.at(i).pos+(xh[2])*0.942809041582*(sin(wink)*u+cos(wink)*w);
  htest.Label=mole.asymm.at(i).Label.section('_',0,0);
  htest.Label.replace(0,1,'H');
  int hindex=1;
  QString nnn=htest.Label;
  QString ann=htest.Label;
  do {
    if (hindex) nnn=ann.left(3).append(QString::number(hindex+9,36));
    if (nnn.size()>4) nnn=ann.left(2).append(QString::number(hindex+9,36));
    if (htest.resiNr)
      nn=QString("%1_%2")//for shelxl same names in different parts are no problem but for platon so this should fix it.
        .arg(nnn)
        .arg((htest.resiNr)?QString::number(htest.resiNr):"");
    else nn=nnn;
    // qDebug()<<nn<<nnn<<(alab.contains(nn,Qt::CaseInsensitive));
    hindex++;
  }while(alab.contains(nn,Qt::CaseInsensitive));
  htest.Label=nnn;
  alab.append(nn);

  htest.part=mole.asymm.at(i).part;
  htest.resiNr=mole.asymm.at(i).resiNr;
  htest.isIso=true;
  htest.ufiso_org=QString("-1.5");
  double uIso = mole.ueq(mole.asymm.at(i).uf)*1.5;
  htest.uf.m11 = htest.uf.m22 = htest.uf.m33 = uIso;
  htest.uf.m23 = uIso * mole.cell.cosra; 
  htest.uf.m13 = uIso * mole.cell.cosrb; 
  htest.uf.m12 = uIso * mole.cell.cosrg; 
  mole.Uf2Uo(htest.uf,htest.uc);
  htest.pos=v;
  mole.kart2frac(htest.pos,htest.frac);	
  htest.orginalLine=QString("%1  %2  %3 %4 %5 %6 %7")
    .arg(htest.Label)
    .arg(qMax(1,editor->sfac.indexOf(0)+1))
    .arg(htest.frac.x,9,'f',5)
    .arg(htest.frac.y,9,'f',5)
    .arg(htest.frac.z,9,'f',5)
    .arg(mole.asymm.at(i).sof+10*frei)
    .arg("-1.5");
  mole.asymm.append(htest);
  wink+=1.04719755119;
  v=(-(xh[2])*0.33333*a)+ mole.asymm.at(i).pos+(xh[2])*0.942809041582*(sin(wink)*u+cos(wink)*w);
  hindex+=2;
  do {
    if (hindex) nnn=ann.left(3).append(QString::number(hindex+9,36));
    if (nnn.size()>4) nnn=ann.left(2).append(QString::number(hindex+9,36));
    if (htest.resiNr)
      nn=QString("%1_%2")//for shelxl same names in different parts are no problem but for platon so this should fix it.
        .arg(nnn)
        .arg((htest.resiNr)?QString::number(htest.resiNr):"");
    else nn=nnn;
    // qDebug()<<nn<<nnn<<(alab.contains(nn,Qt::CaseInsensitive));
    hindex++;
  }while(alab.contains(nn,Qt::CaseInsensitive));
  hindex-=3;
  htest.Label=nnn;
  alab.append(nn);
  htest.pos=v;
  mole.kart2frac(htest.pos,htest.frac);	
  htest.orginalLine=QString("%1  %2  %3 %4 %5 %6 %7")
    .arg(htest.Label)
    .arg(qMax(1,editor->sfac.indexOf(0)+1))
    .arg(htest.frac.x,9,'f',5)
    .arg(htest.frac.y,9,'f',5)
    .arg(htest.frac.z,9,'f',5)
    .arg(-1*(mole.asymm.at(i).sof+10*frei))
    .arg("-1.5");
  mole.asymm.append(htest);
  wink+=1.04719755119;
  v=(-(xh[2])*0.33333*a)+ mole.asymm.at(i).pos+(xh[2])*0.942809041582*(sin(wink)*u+cos(wink)*w);
  do {
    if (hindex) nnn=ann.left(3).append(QString::number(hindex+9,36));
    if (nnn.size()>4) nnn=ann.left(2).append(QString::number(hindex+9,36));
    if (htest.resiNr)
      nn=QString("%1_%2")//for shelxl same names in different parts are no problem but for platon so this should fix it.
        .arg(nnn)
        .arg((htest.resiNr)?QString::number(htest.resiNr):"");
    else nn=nnn;
    // qDebug()<<nn<<nnn<<(alab.contains(nn,Qt::CaseInsensitive));
    hindex++;
  }while(alab.contains(nn,Qt::CaseInsensitive));
  htest.Label=nnn;
  hindex+=2;
  alab.append(nn);
  htest.pos=v;
  mole.kart2frac(htest.pos,htest.frac);	
  htest.orginalLine=QString("%1  %2  %3 %4 %5 %6 %7")
    .arg(htest.Label)
    .arg(qMax(1,editor->sfac.indexOf(0)+1))
    .arg(htest.frac.x,9,'f',5)
    .arg(htest.frac.y,9,'f',5)
    .arg(htest.frac.z,9,'f',5)
    .arg(mole.asymm.at(i).sof+10*frei)
    .arg("-1.5");
  mole.asymm.append(htest);
  wink+=1.04719755119;
  v=(-(xh[2])*0.33333*a)+ mole.asymm.at(i).pos+(xh[2])*0.942809041582*(sin(wink)*u+cos(wink)*w);
  do {
    if (hindex) nnn=ann.left(3).append(QString::number(hindex+9,36));
    if (nnn.size()>4) nnn=ann.left(2).append(QString::number(hindex+9,36));
    if (htest.resiNr)
      nn=QString("%1_%2")//for shelxl same names in different parts are no problem but for platon so this should fix it.
        .arg(nnn)
        .arg((htest.resiNr)?QString::number(htest.resiNr):"");
    else nn=nnn;
    // qDebug()<<nn<<nnn<<(alab.contains(nn,Qt::CaseInsensitive));
    hindex++;
  }while(alab.contains(nn,Qt::CaseInsensitive));
  htest.Label=nnn;
  alab.append(nn);
  htest.pos=v;
  hindex-=3;
  mole.kart2frac(htest.pos,htest.frac);	
  htest.orginalLine=QString("%1  %2  %3 %4 %5 %6 %7")
    .arg(htest.Label)
    .arg(qMax(1,editor->sfac.indexOf(0)+1))
    .arg(htest.frac.x,9,'f',5)
    .arg(htest.frac.y,9,'f',5)
    .arg(htest.frac.z,9,'f',5)
    .arg(-1*(mole.asymm.at(i).sof+10*frei))
    .arg("-1.5");
  mole.asymm.append(htest);
  wink+=1.04719755119;
  v=(-(xh[2])*0.33333*a)+ mole.asymm.at(i).pos+(xh[2])*0.942809041582*(sin(wink)*u+cos(wink)*w);
  do {
    if (hindex) nnn=ann.left(3).append(QString::number(hindex+9,36));
    if (nnn.size()>4) nnn=ann.left(2).append(QString::number(hindex+9,36));
    if (htest.resiNr)
      nn=QString("%1_%2")//for shelxl same names in different parts are no problem but for platon so this should fix it.
        .arg(nnn)
        .arg((htest.resiNr)?QString::number(htest.resiNr):"");
    else nn=nnn;
    // qDebug()<<nn<<nnn<<(alab.contains(nn,Qt::CaseInsensitive));
    hindex++;
  }while(alab.contains(nn,Qt::CaseInsensitive));
  htest.Label=nnn;
  alab.append(nn);
  htest.pos=v;
  hindex+=2;
  mole.kart2frac(htest.pos,htest.frac);	
  htest.orginalLine=QString("%1  %2  %3 %4 %5 %6 %7")
    .arg(htest.Label)
    .arg(qMax(1,editor->sfac.indexOf(0)+1))
    .arg(htest.frac.x,9,'f',5)
    .arg(htest.frac.y,9,'f',5)
    .arg(htest.frac.z,9,'f',5)
    .arg(mole.asymm.at(i).sof+10*frei)
    .arg("-1.5");
  mole.asymm.append(htest);
  wink+=1.04719755119;
  v=(-(xh[2])*0.33333*a)+ mole.asymm.at(i).pos+(xh[2])*0.942809041582*(sin(wink)*u+cos(wink)*w);
  do {
    if (hindex) nnn=ann.left(3).append(QString::number(hindex+9,36));
    if (nnn.size()>4) nnn=ann.left(2).append(QString::number(hindex+9,36));
    if (htest.resiNr)
      nn=QString("%1_%2")//for shelxl same names in different parts are no problem but for platon so this should fix it.
        .arg(nnn)
        .arg((htest.resiNr)?QString::number(htest.resiNr):"");
    else nn=nnn;
    // qDebug()<<nn<<nnn<<(alab.contains(nn,Qt::CaseInsensitive));
    hindex++;
  }while(alab.contains(nn,Qt::CaseInsensitive));
  htest.Label=nnn;
  alab.append(nn);
  htest.pos=v;
  mole.kart2frac(htest.pos,htest.frac);	
  htest.orginalLine=QString("%1  %2  %3 %4 %5 %6 %7")
    .arg(htest.Label)
    .arg(qMax(1,editor->sfac.indexOf(0)+1))
    .arg(htest.frac.x,9,'f',5)
    .arg(htest.frac.y,9,'f',5)
    .arg(htest.frac.z,9,'f',5)
    .arg(-1*(mole.asymm.at(i).sof+10*frei))
    .arg("-1.5");
  mole.asymm.append(htest);
  QString label = mole.showatoms.at(i).orginalLine.left(80).trimmed();
  //  int afixfuenf=(mole.showatoms.at(i).afix/10)?(mole.showatoms.at(i).afix/10)*10+5:0;
  cursor.movePosition(QTextCursor::Start);
  cursor = document->find(label,cursor);
  if (cursor.isNull()){
    cursor = editor->textCursor();
    cursor.movePosition(QTextCursor::Start);
    label.chop(10);
    cursor = document->find(label,cursor);
    if (cursor.isNull()) {
      cursor = editor->textCursor();
    }
  }
  cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
  cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
  while (cursor.selectedText().endsWith("=")) {
    cursor.movePosition(QTextCursor::Down,QTextCursor::KeepAnchor);
    cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
  }
  cursor.clearSelection();
  cursor.movePosition(QTextCursor::Down);
  cursor.insertText(QString("AFIX 127\n%1\n%2\n%3\n%5\n%6\n%7\nAFIX %4\n")
      .arg(mole.asymm.at(mole.asymm.size()-6).orginalLine)
      .arg(mole.asymm.at(mole.asymm.size()-4).orginalLine)
      .arg(mole.asymm.at(mole.asymm.size()-2).orginalLine)
      .arg(mole.afix5(i))
      .arg(mole.asymm.at(mole.asymm.size()-5).orginalLine)//-
      .arg(mole.asymm.at(mole.asymm.size()-3).orginalLine)//-
      .arg(mole.asymm.at(mole.asymm.size()-1).orginalLine)//-
      );

  cursor.endEditBlock();
  int jetztAtome=0;
  for (int i=0; i<mole.asymm.size();i++) if (mole.asymm.at(i).an>=0)jetztAtome++;
  actionHFix->setDisabled(true);
  fuse();
  QString info=QString("<font color=\"green\"><b>%1</b> Hydrogen atoms added. <b>Please SAVE before GROW!</font>").arg(jetztAtome-warmalAtome);
  infoKanalNews(info); 
}

void Window::addH43(){//43
  QAction *action = qobject_cast<QAction *>(sender());
  int i=0;
  if (action)
    i=action->data().toInt();
  else return;
  if (i>mole.asymm.size()) return;
  if (mole.knoepfe.at(i).neighbors.size()!=2)return;//we need 2 non h neighbors
  int warmalAtome=0;
  for (int j=0; j<mole.asymm.size();j++) if (mole.asymm.at(j).an>=0)warmalAtome++;
  QStringList alab;
  for (int i =0; i<mole.asymm.size(); i++){
    alab.append(mole.asymm.at(i).Label);
  }
  QString nn;
  double nh= (mole.asymm.at(i).an==6) ? 0.07 : 0;

  chgl->disSelection();
  MyAtom htest,qtest;
  if (editor->sfac.indexOf(0)==-1)addNewScatteringFactor(0);
  htest.an=0;
  htest.part=0;
  htest.resiNr=0;
  htest.hidden=0;
  htest.symmGroup=0;
  htest.sg=0;
  htest.scod=555;//the identity
  htest.auidx=-1;
  htest.uc.m12=htest.uc.m23=htest.uc.m13=0.0;
  htest.uc.m21=htest.uc.m32=htest.uc.m31=0.0;
  htest.uf.m12=htest.uf.m23=htest.uf.m13=0.0;
  htest.uf.m21=htest.uf.m32=htest.uf.m31=0.0;
  qtest=htest;
  qtest.an=-1;
  QTextDocument *document = editor->document();
  QTextCursor cursor = editor->textCursor();
  cursor.beginEditBlock ();
  double xh[8]={
    0.98,//1
    0.97,//2
    0.96,//3
    0.93,//4
    1.10,//15 B
    0.82,//8 O
    0.93,//9
    0.93// 16
  };

  double angle=0;
  V3 a=V3(0,0,0),b=V3(0,0,0),c=V3(0,0,0);
  a = mole.showatoms.at(mole.knoepfe.at(i).neighbors.at(0)      ).pos - mole.asymm.at(i).pos;
  b = mole.showatoms.at(mole.knoepfe.at(i).neighbors.at(1)      ).pos - mole.asymm.at(i).pos;
  a = c = Normalize(a) ;
  c = c+ (b= Normalize(b));
  angle=mole.winkel(a,b);
  c = Normalize(c);
  if (angle<160) {
    c = (-(xh[3]-nh) * c)+mole.asymm.at(i).pos;    
    htest.Label=mole.asymm.at(i).Label.section('_',0,0);
    htest.part=mole.asymm.at(i).part;
    htest.resiNr=mole.asymm.at(i).resiNr;
    htest.Label.replace(0,1,'H');
    int hindex=0;
    QString nnn=htest.Label;
    do {
      if (hindex) nnn=htest.Label.left(3).append(QString::number(hindex+9,36));
      if (nnn.size()>4) nnn=htest.Label.left(2).append(QString::number(hindex+9,36));
      if (htest.resiNr)
        nn=QString("%1_%2")//for shelxl same names in different parts are no problem but for platon so this should fix it.
          .arg(nnn)
          .arg((htest.resiNr)?QString::number(htest.resiNr):"");
      else nn=nnn;
      // qDebug()<<nn<<nnn<<(alab.contains(nn,Qt::CaseInsensitive));
      hindex++;
    }while(alab.contains(nn,Qt::CaseInsensitive));
    htest.Label=nnn;
    alab.append(nn);
    htest.isIso=true;
    htest.ufiso_org=QString("-1.2");
    double uIso = mole.ueq(mole.asymm.at(i).uf)*1.2;
    htest.uf.m11 = htest.uf.m22 = htest.uf.m33 = uIso;
    htest.uf.m23 = uIso * mole.cell.cosra; 
    htest.uf.m13 = uIso * mole.cell.cosrb; 
    htest.uf.m12 = uIso * mole.cell.cosrg; 
    mole.Uf2Uo(htest.uf,htest.uc);
    htest.pos=c;
    mole.kart2frac(htest.pos,htest.frac);	
    htest.orginalLine=QString("%1  %2  %3 %4 %5 %6 %7")
      .arg(htest.Label)
      .arg(qMax(1,editor->sfac.indexOf(0)+1))
      .arg(htest.frac.x,9,'f',5)
      .arg(htest.frac.y,9,'f',5)
      .arg(htest.frac.z,9,'f',5)
      .arg(mole.asymm.at(i).sof_org)
      .arg("-1.2");
    mole.asymm.append(htest);
    QString label = mole.showatoms.at(i).orginalLine.left(80).trimmed();
    //    int afixfuenf=(mole.showatoms.at(i).afix/10)?(mole.showatoms.at(i).afix/10)*10+5:0;
    cursor.movePosition(QTextCursor::Start);
    cursor = document->find(label,cursor);
    if (cursor.isNull()){
      cursor = editor->textCursor();
      cursor.movePosition(QTextCursor::Start);
      label.chop(10);
      cursor = document->find(label,cursor);
      if (cursor.isNull()) {
        cursor = editor->textCursor();
      }
    }
    cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
    cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
    while (cursor.selectedText().endsWith("=")) {
      cursor.movePosition(QTextCursor::Down,QTextCursor::KeepAnchor);
      cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
    }
    cursor.clearSelection();
    cursor.movePosition(QTextCursor::Down);
    cursor.insertText(QString("AFIX 43\n%1\nAFIX %2\n")
        .arg(mole.asymm.at(mole.asymm.size()-1).orginalLine)
        .arg(mole.afix5(i)));
  }//angle 
  cursor.endEditBlock();
  int jetztAtome=0;
  for (int i=0; i<mole.asymm.size();i++) if (mole.asymm.at(i).an>=0)jetztAtome++;
  actionHFix->setDisabled(true);
  fuse();
  QString info=QString("<font color=\"green\"><b>%1</b> Hydrogen atoms added. <b>Please SAVE before GROW!</font>").arg(jetztAtome-warmalAtome);
  infoKanalNews(info); 
}//43

void Window::addH23(){//23
  QAction *action = qobject_cast<QAction *>(sender());
  int i=0;
  if (action)
    i=action->data().toInt();
  else return;
  if (i>mole.asymm.size()) return;
  if (mole.knoepfe.at(i).neighbors.size()!=2)return;//we need 2 non h neighbors
  int warmalAtome=0;
  for (int j=0; j<mole.asymm.size();j++) if (mole.asymm.at(j).an>=0)warmalAtome++;
  QStringList alab;
  for (int i =0; i<mole.asymm.size(); i++){
    alab.append(mole.asymm.at(i).Label);
  }
  QString nn;
  double nh= (mole.asymm.at(i).an==6) ? 0.07 : 0;

  chgl->disSelection();
  MyAtom htest,qtest;
  if (editor->sfac.indexOf(0)==-1)addNewScatteringFactor(0);
  htest.an=0;
  htest.part=0;
  htest.resiNr=0;
  htest.hidden=0;
  htest.symmGroup=0;
  htest.sg=0;
  htest.scod=555;//the identity
  htest.auidx=-1;
  htest.uc.m12=htest.uc.m23=htest.uc.m13=0.0;
  htest.uc.m21=htest.uc.m32=htest.uc.m31=0.0;
  htest.uf.m12=htest.uf.m23=htest.uf.m13=0.0;
  htest.uf.m21=htest.uf.m32=htest.uf.m31=0.0;
  qtest=htest;
  qtest.an=-1;
  QTextDocument *document = editor->document();
  QTextCursor cursor = editor->textCursor();
  cursor.beginEditBlock ();
  double xh[8]={
    0.98,//1
    0.97,//2
    0.96,//3
    0.93,//4
    1.10,//15 B
    0.82,//8 O
    0.93,//9
    0.93// 16
  };
  V3 v=V3(0,0,0),w=V3(0,0,0),u=V3(0,0,0) ,a=V3(0,0,0),b=V3(0,0,0),c=V3(0,0,0);
  a = mole.showatoms.at(mole.knoepfe.at(i).neighbors.at(0)      ).pos - mole.asymm.at(i).pos;
  b = mole.showatoms.at(mole.knoepfe.at(i).neighbors.at(1)      ).pos - mole.asymm.at(i).pos;
  a = c = Normalize(a) ;
  c = c+ (b= Normalize(b));
  double angle=mole.winkel(a,b);
  c = Normalize(c);
  if (angle<160) {

    w = Normalize(a);
    u = Normalize(b);
    double si=1.0376-0.0346*Norm(w-u);    //=1.91063323625-((acos(u*w)-1.91063323625)/5.0);//-1.91063323625 = 109.47 grad ; 3.7 empirischer Wert
    c = (-cos(si)*(xh[1]-nh) * c);
    v = sin(si)  *(xh[1]-nh) * Normalize(c%a);
    a = mole.asymm.at(i).pos + c + v;
    b = mole.asymm.at(i).pos + c - v;
    c = c + mole.asymm.at(i).pos;

    htest.Label=mole.asymm.at(i).Label.section('_',0,0);
    htest.part=mole.asymm.at(i).part;
    htest.resiNr=mole.asymm.at(i).resiNr;
    htest.Label.replace(0,1,'H');
    int hindex=1;
    QString nnn=htest.Label;
    QString ann=htest.Label;
    do {
      if (hindex) nnn=htest.Label.left(3).append(QString::number(hindex+9,36));
      if (nnn.size()>4) nnn=htest.Label.left(2).append(QString::number(hindex+9,36));
      if (htest.resiNr)
        nn=QString("%1_%2")//for shelxl same names in different parts are no problem but for platon so this should fix it.
          .arg(nnn)
          .arg((htest.resiNr)?QString::number(htest.resiNr):"");
      else nn=nnn;
      // qDebug()<<nn<<nnn<<(alab.contains(nn,Qt::CaseInsensitive));
      hindex++;
    }while(alab.contains(nn,Qt::CaseInsensitive));
    htest.Label=nnn;
    alab.append(nn);
    htest.isIso=true;
    htest.ufiso_org=QString("-1.2");
    double uIso = mole.ueq(mole.asymm.at(i).uf)*1.2;
    htest.uf.m11 = htest.uf.m22 = htest.uf.m33 = uIso;
    htest.uf.m23 = uIso * mole.cell.cosra; 
    htest.uf.m13 = uIso * mole.cell.cosrb; 
    htest.uf.m12 = uIso * mole.cell.cosrg; 
    mole.Uf2Uo(htest.uf,htest.uc);
    htest.pos=a;
    mole.kart2frac(htest.pos,htest.frac);	
    htest.orginalLine=QString("%1  %2  %3 %4 %5 %6 %7")
      .arg(htest.Label)
      .arg(qMax(1,editor->sfac.indexOf(0)+1))
      .arg(htest.frac.x,9,'f',5)
      .arg(htest.frac.y,9,'f',5)
      .arg(htest.frac.z,9,'f',5)
      .arg(mole.asymm.at(i).sof_org)
      .arg("-1.2");
    mole.asymm.append(htest);
    nnn=ann;//pevent HnAB labels
    do {
      if (hindex) nnn=ann.left(3).append(QString::number(hindex+9,36));
      if (nnn.size()>4) nnn=ann.left(2).append(QString::number(hindex+9,36));
      if (htest.resiNr)
        nn=QString("%1_%2")//for shelxl same names in different parts are no problem but for platon so this should fix it.
          .arg(nnn)
          .arg((htest.resiNr)?QString::number(htest.resiNr):"");
      else nn=nnn;
      // qDebug()<<nn<<nnn<<(alab.contains(nn,Qt::CaseInsensitive));
      hindex++;
    }while(alab.contains(nn,Qt::CaseInsensitive));
    htest.Label=nnn;
    alab.append(nn);
    htest.pos=b;
    mole.kart2frac(htest.pos,htest.frac);	
    htest.orginalLine=QString("%1  %2  %3 %4 %5 %6 %7")
      .arg(htest.Label)
      .arg(qMax(1,editor->sfac.indexOf(0)+1))
      .arg(htest.frac.x,9,'f',5)
      .arg(htest.frac.y,9,'f',5)
      .arg(htest.frac.z,9,'f',5)
      .arg(mole.asymm.at(i).sof_org)
      .arg("-1.2");
    mole.asymm.append(htest);
    QString label = mole.showatoms.at(i).orginalLine.left(80).trimmed();
    //  int afixfuenf=(mole.showatoms.at(i).afix/10)?(mole.showatoms.at(i).afix/10)*10+5:0;
    cursor.movePosition(QTextCursor::Start);
    cursor = document->find(label,cursor);
    if (cursor.isNull()){
      cursor = editor->textCursor();
      cursor.movePosition(QTextCursor::Start);
      label.chop(10);
      cursor = document->find(label,cursor);
      if (cursor.isNull()) {
        cursor = editor->textCursor();
      }
    }
    cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
    cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
    while (cursor.selectedText().endsWith("=")) {
      cursor.movePosition(QTextCursor::Down,QTextCursor::KeepAnchor);
      cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
    }
    cursor.clearSelection();
    cursor.movePosition(QTextCursor::Down);
    cursor.insertText(QString("AFIX 23\n%1\n%2\nAFIX %3\n")
        .arg(mole.asymm.at(mole.asymm.size()-2).orginalLine)
        .arg(mole.asymm.at(mole.asymm.size()-1).orginalLine)
        .arg(mole.afix5(i)));
  }//angle
  cursor.endEditBlock();
  int jetztAtome=0;
  for (int i=0; i<mole.asymm.size();i++) if (mole.asymm.at(i).an>=0)jetztAtome++;
  actionHFix->setDisabled(true);
  fuse();
  QString info=QString("<font color=\"green\"><b>%1</b> Hydrogen atoms added. <b>Please SAVE before GROW!</font>").arg(jetztAtome-warmalAtome);
  infoKanalNews(info); 

}//23

void Window::addH93(){
  QAction *action = qobject_cast<QAction *>(sender());  
  int idx=0;
  if (action)
    idx=action->data().toInt();
  else return;
  if (idx>mole.asymm.size()) return;
  if (mole.knoepfe.at(idx).neighbors.size()!=1)return;//we need 1 non h neighbors
  int warmalAtome=0;
  for (int jj=0; jj<mole.asymm.size();jj++) if (mole.asymm.at(jj).an>=0)warmalAtome++;
  QStringList alab;
  for (int i =0; i<mole.asymm.size(); i++){
    alab.append(mole.asymm.at(i).Label);
  }
  QString nn;
  double nh= (mole.asymm.at(idx).an==6) ? 0.07 : 0;

  chgl->disSelection();
  MyAtom htest,qtest;
  if (editor->sfac.indexOf(0)==-1)addNewScatteringFactor(0);
  htest.an=0;
  htest.part=0;
  htest.resiNr=0;
  htest.hidden=0;
  htest.symmGroup=0;
  htest.sg=0;
  htest.scod=555;//the identity
  htest.auidx=-1;
  htest.uc.m12=htest.uc.m23=htest.uc.m13=0.0;
  htest.uc.m21=htest.uc.m32=htest.uc.m31=0.0;
  htest.uf.m12=htest.uf.m23=htest.uf.m13=0.0;
  htest.uf.m21=htest.uf.m32=htest.uf.m31=0.0;
  qtest=htest;
  qtest.an=-1;
  QTextDocument *document = editor->document();
  QTextCursor cursor = editor->textCursor();
  cursor.beginEditBlock ();
  double xh[8]={
    0.98,//1
    0.97,//2
    0.96,//3
    0.93,//4
    1.10,//15 B
    0.82,//8 O
    0.93,//9
    0.93// 16
  };
  V3 v=V3(0,0,0),w=V3(0,0,0),u=V3(0,0,0),a=V3(0,0,0);//,b=V3(0,0,0),c=V3(0,0,0);
  a = mole.showatoms.at(mole.knoepfe.at(idx).neighbors.at(0)).pos - mole.asymm.at(idx).pos;
  int j,k,l;
  a=Normalize(a);
  double jx,kx,lx,mx,my,mz;
  double val[24],merg[12],wink=0,t=0,mt=0;
  if (fxle->n5){
    for (int z=0; z<12;z++) merg[z]=0;
    for (int z=0; z<24; z++){
      wink=z*0.261799387799;
      w=Normalize(V3(0,0,1)%a);
      u=Normalize(w%a);
      v=(-(xh[6]-nh)*0.33333*a)+ mole.asymm.at(idx).pos+(xh[6]-nh)*0.942809041582*(sin(wink)*u+cos(wink)*w);
      qtest.pos=v;
      mole.kart2frac(v,v);
      jx=(v.x>0)?(v.x*fxle->n1+0.5):((1.0+v.x)*fxle->n1+0.5);    
      kx=(v.y>0)?(v.y*fxle->n2+0.5):((1.0+v.y)*fxle->n2+0.5);   
      lx=(v.z>0)?(v.z*fxle->n3+0.5):((1.0+v.z)*fxle->n3+0.5);   
      mx=jx-floor(jx);
      my=kx-floor(kx);
      mz=lx-floor(lx);
      j=((int)jx)%fxle->n1;//
      k=((int)kx)%fxle->n2;//
      l=((int)lx)%fxle->n3;//
      merg[z%12]+=val[z]=(
          (1-mx)*fxle->datfo_fc[(j+fxle->n1*(k+l*fxle->n2))%fxle->n5]+
          mx*fxle->datfo_fc[((j+1)+fxle->n1*(k+l*fxle->n2))%fxle->n5]+
          (1-my)*fxle->datfo_fc[(j+fxle->n1*(k+l*fxle->n2))%fxle->n5]+
          my*fxle->datfo_fc[(j+fxle->n1*((k+1)+l*fxle->n2))%fxle->n5]+
          (1-mz)*fxle->datfo_fc[(j+fxle->n1*(k+l*fxle->n2))%fxle->n5]+
          mz*fxle->datfo_fc[(j+fxle->n1*(k+(l+1)*fxle->n2))%fxle->n5])/3.0;
      qtest.peakHeight=val[z];
      qtest.frac=v;
      qtest.Label=QString("Q%1").arg(z+100);
      mole.pmin=qMin(mole.pmin, qtest.peakHeight);
      mole.pmax=qMax(mole.pmax, qtest.peakHeight);
      qpv->cutoff=0;//mole.pmin;
      qpv->setMin(mole.pmin);
      qpv->setMax(mole.pmax);
      mole.asymm.append(qtest);
    }
    for (int z=0; z<12;z++) {
      t =merg[(z+12)%12] ;
      double x = t - merg[(z+13)%12];
      double u = t - merg[(z+11)%12];
      if (fmin(x,u)<0) continue;
      double p=0.5*(u-x)/(u+x);
      t=t+0.25*(p*(u-x));
      mt=(mt>t)?mt:t;
      if (t<mt)continue;
      wink=((double) z + p )*0.261799387799; 

      /////////////////
    }
  }else{
    int zzz=0;
    int z=mole.knoepfe.at(mole.knoepfe.at(idx).neighbors.at(0)).neighbors.at(zzz++);
    while ((z==idx)&&(zzz<mole.knoepfe.at(mole.knoepfe.at(idx).neighbors.at(0)).neighbors.size()))
      z=mole.knoepfe.at(mole.knoepfe.at(idx).neighbors.at(0)).neighbors.at(zzz++);
    w=Normalize(V3(0,0,1)%a);
    u=Normalize(w%a);
    v=(-(xh[2]-nh)*0.33333*a)+ mole.asymm.at(idx).pos+(xh[2]-nh)*0.942809041582*(sin(wink)*u+cos(wink)*w);
    // if z == i then dieder() returns nan, because A in dieder gets (0,0,0)
    V3 increm = V3(0.0, 0.0, 0.0);
    if ( z == idx ) {
      increm = V3(0.00001, 0.00001, 0.00001);
    }
    wink=mole.dieder(mole.showatoms.at(mole.knoepfe.at(idx).neighbors.at(0)).pos+increm-mole.asymm.at(z).pos,
        mole.asymm.at(idx).pos-mole.showatoms.at(mole.knoepfe.at(idx).neighbors.at(0)).pos,
        v-mole.asymm.at(idx).pos)/180.0*M_PI;

  }

  v=(-(xh[6]-nh)*0.5*a)+ mole.asymm.at(idx).pos+(xh[6]-nh)*0.866025403784*(sin(wink)*u+cos(wink)*w);
  htest.Label=mole.asymm.at(idx).Label.section('_',0,0);
  htest.part=mole.asymm.at(idx).part;
  htest.resiNr=mole.asymm.at(idx).resiNr;
  htest.Label.replace(0,1,'H');
  int hindex=1;
  QString nnn=htest.Label;
  QString baslab=htest.Label;
  do {
    htest.Label=baslab;
    if (hindex) nnn=htest.Label.left(3).append(QString::number(hindex+9,36));
    if (nnn.size()>4) nnn=htest.Label.left(2).append(QString::number(hindex+9,36));
    if (htest.resiNr)
      nn=QString("%1_%2")//for shelxl same names in different parts are no problem but for platon so this should fix it.
        .arg(nnn)
        .arg((htest.resiNr)?QString::number(htest.resiNr):"");
    else nn=nnn;
    // qDebug()<<nn<<nnn<<(alab.contains(nn,Qt::CaseInsensitive));
    hindex++;
  }while(alab.contains(nn,Qt::CaseInsensitive));
  htest.Label=nnn;
  alab.append(nn);
  htest.isIso=true;
  htest.ufiso_org=QString("-1.2");
  double uIso = mole.ueq(mole.asymm.at(idx).uf)*1.2;
  htest.uf.m11 = htest.uf.m22 = htest.uf.m33 = uIso;
  htest.uf.m23 = uIso * mole.cell.cosra; 
  htest.uf.m13 = uIso * mole.cell.cosrb; 
  htest.uf.m12 = uIso * mole.cell.cosrg; 
  mole.Uf2Uo(htest.uf,htest.uc);
  htest.pos=v;
  mole.kart2frac(htest.pos,htest.frac);	
  htest.orginalLine=QString("%1  %2  %3 %4 %5 %6 %7")
    .arg(htest.Label)
    .arg(qMax(1,editor->sfac.indexOf(0)+1))
    .arg(htest.frac.x,9,'f',5)
    .arg(htest.frac.y,9,'f',5)
    .arg(htest.frac.z,9,'f',5)
    .arg(mole.asymm.at(idx).sof_org)
    .arg("-1.2");
  mole.asymm.append(htest);
  wink+=3.14159265359;
  v=(-(xh[6]-nh)*0.5*a)+ mole.asymm.at(idx).pos+(xh[6]-nh)*0.866025403784*(sin(wink)*u+cos(wink)*w);
  do {
    htest.Label=baslab;
    if (hindex) nnn=htest.Label.left(3).append(QString::number(hindex+9,36));
    if (nnn.size()>4) nnn=htest.Label.left(2).append(QString::number(hindex+9,36));
    if (htest.resiNr)
      nn=QString("%1_%2")//for shelxl same names in different parts are no problem but for platon so this should fix it.
        .arg(nnn)
        .arg((htest.resiNr)?QString::number(htest.resiNr):"");
    else nn=nnn;
    // qDebug()<<nn<<nnn<<(alab.contains(nn,Qt::CaseInsensitive));
    hindex++;
  }while(alab.contains(nn,Qt::CaseInsensitive));
  htest.Label=nnn;
  alab.append(nn);
  htest.pos=v;
  mole.kart2frac(htest.pos,htest.frac);	
  htest.orginalLine=QString("%1  %2  %3 %4 %5 %6 %7")
    .arg(htest.Label)
    .arg(qMax(1,editor->sfac.indexOf(0)+1))
    .arg(htest.frac.x,9,'f',5)
    .arg(htest.frac.y,9,'f',5)
    .arg(htest.frac.z,9,'f',5)
    .arg(mole.asymm.at(idx).sof_org)
    .arg("-1.2");
  mole.asymm.append(htest);

  QString label = mole.showatoms.at(idx).orginalLine.left(80).trimmed();
  //  int afixfuenf=(mole.showatoms.at(i).afix/10)?(mole.showatoms.at(i).afix/10)*10+5:0;
  cursor.movePosition(QTextCursor::Start);
  cursor = document->find(label,cursor);
  if (cursor.isNull()){
    cursor = editor->textCursor();
    cursor.movePosition(QTextCursor::Start);
    label.chop(10);
    cursor = document->find(label,cursor);
    if (cursor.isNull()) {
      cursor = editor->textCursor();
    }
  }
  cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
  cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
  while (cursor.selectedText().endsWith("=")) {
    cursor.movePosition(QTextCursor::Down,QTextCursor::KeepAnchor);
    cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
  }
  cursor.clearSelection();
  cursor.movePosition(QTextCursor::Down);
  cursor.insertText(QString("AFIX 93\n%1\n%2\nAFIX %3\n")
      .arg(mole.asymm.at(mole.asymm.size()-2).orginalLine)
      .arg(mole.asymm.at(mole.asymm.size()-1).orginalLine)
      .arg(mole.afix5(idx))
      );



  cursor.endEditBlock();
  int jetztAtome=0;
  for (int i=0; i<mole.asymm.size();i++) if (mole.asymm.at(i).an>=0)jetztAtome++;
  actionHFix->setDisabled(true);
  fuse();
  QString info=QString("<font color=\"green\"><b>%1</b> Hydrogen atoms added. <b>Please SAVE before GROW!</font>").arg(jetztAtome-warmalAtome);
  infoKanalNews(info); 
}//93

void Window::addH163(){
  QAction *action = qobject_cast<QAction *>(sender());
  int i=0;
  if (action)
    i=action->data().toInt();
  else return;
  if (i>mole.asymm.size()) return;
  if (mole.knoepfe.at(i).neighbors.size()!=1)return;//we need 1 non h neighbors
  int warmalAtome=0;
  for (int j=0; j<mole.asymm.size();j++) if (mole.asymm.at(j).an>=0)warmalAtome++;
  QStringList alab;
  for (int i =0; i<mole.asymm.size(); i++){
    alab.append(mole.asymm.at(i).Label);
  }
  QString nn;
  double nh= (mole.asymm.at(i).an==6) ? 0.07 : 0;

  chgl->disSelection();
  MyAtom htest,qtest;
  if (editor->sfac.indexOf(0)==-1)addNewScatteringFactor(0);
  htest.an=0;
  htest.part=0;
  htest.resiNr=0;
  htest.hidden=0;
  htest.symmGroup=0;
  htest.sg=0;
  htest.scod=555;//the identity
  htest.auidx=-1;
  htest.uc.m12=htest.uc.m23=htest.uc.m13=0.0;
  htest.uc.m21=htest.uc.m32=htest.uc.m31=0.0;
  htest.uf.m12=htest.uf.m23=htest.uf.m13=0.0;
  htest.uf.m21=htest.uf.m32=htest.uf.m31=0.0;
  qtest=htest;
  qtest.an=-1;
  QTextDocument *document = editor->document();
  QTextCursor cursor = editor->textCursor();
  cursor.beginEditBlock ();
  double xh[8]={
    0.98,//1
    0.97,//2
    0.96,//3
    0.93,//4
    1.10,//15 B
    0.82,//8 O
    0.93,//9
    0.93// 16
  };
  V3 v=V3(0,0,0),a=V3(0,0,0); 
  a = Normalize(mole.showatoms.at(mole.knoepfe.at(i).neighbors.at(0)).pos - mole.asymm.at(i).pos);
  v=(-(xh[7]-nh)*a)+ mole.asymm.at(i).pos;
  htest.Label=mole.asymm.at(i).Label.section('_',0,0);
  htest.part=mole.asymm.at(i).part;
  htest.resiNr=mole.asymm.at(i).resiNr;
  htest.Label.replace(0,1,'H');
  int hindex=0;
  QString nnn=htest.Label;
  do {
    if (hindex) nnn=htest.Label.left(3).append(QString::number(hindex+9,36));
    if (nnn.size()>4) nnn=htest.Label.left(2).append(QString::number(hindex+9,36));
    if (htest.resiNr)
      nn=QString("%1_%2")//for shelxl same names in different parts are no problem but for platon so this should fix it.
        .arg(nnn)
        .arg((htest.resiNr)?QString::number(htest.resiNr):"");
    else nn=nnn;
    // qDebug()<<nn<<nnn<<(alab.contains(nn,Qt::CaseInsensitive));
    hindex++;
  }while(alab.contains(nn,Qt::CaseInsensitive));
  htest.Label=nnn;
  alab.append(nn);
  htest.isIso=true;
  htest.ufiso_org=QString("-1.2");
  double uIso = mole.ueq(mole.asymm.at(i).uf)*1.2;
  htest.uf.m11 = htest.uf.m22 = htest.uf.m33 = uIso;
  htest.uf.m23 = uIso * mole.cell.cosra; 
  htest.uf.m13 = uIso * mole.cell.cosrb; 
  htest.uf.m12 = uIso * mole.cell.cosrg; 
  mole.Uf2Uo(htest.uf,htest.uc);
  htest.pos=v;
  mole.kart2frac(htest.pos,htest.frac);
  htest.orginalLine=QString("%1  %2  %3 %4 %5 %6 %7")
    .arg(htest.Label)
    .arg(qMax(1,editor->sfac.indexOf(0)+1))
    .arg(htest.frac.x,9,'f',5)
    .arg(htest.frac.y,9,'f',5)
    .arg(htest.frac.z,9,'f',5)
    .arg(mole.asymm.at(i).sof_org)
    .arg("-1.2");
  mole.asymm.append(htest);

  QString label = mole.showatoms.at(i).orginalLine.left(80).trimmed();
  //  int afixfuenf=(mole.showatoms.at(i).afix/10)?(mole.showatoms.at(i).afix/10)*10+5:0;
  cursor.movePosition(QTextCursor::Start);
  cursor = document->find(label,cursor);
  if (cursor.isNull()){
    cursor = editor->textCursor();
    cursor.movePosition(QTextCursor::Start);
    label.chop(10);
    cursor = document->find(label,cursor);
    if (cursor.isNull()) {
      cursor = editor->textCursor();
    }
  }
  cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
  cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
  while (cursor.selectedText().endsWith("=")) {
    cursor.movePosition(QTextCursor::Down,QTextCursor::KeepAnchor);
    cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
  }
  cursor.clearSelection();
  cursor.movePosition(QTextCursor::Down);
  cursor.insertText(QString("AFIX 163\n%1\nAFIX %2\n")
      .arg(mole.asymm.at(mole.asymm.size()-1).orginalLine)
      .arg(mole.afix5(i))
      );



  cursor.endEditBlock();
  int jetztAtome=0;
  for (int i=0; i<mole.asymm.size();i++) if (mole.asymm.at(i).an>=0)jetztAtome++;
  actionHFix->setDisabled(true);
  fuse();
  QString info=QString("<font color=\"green\"><b>%1</b> Hydrogen atoms added. <b>Please SAVE before GROW!</font>").arg(jetztAtome-warmalAtome);
  infoKanalNews(info); 

}//163

void Window::addMethyl(){//137
  QAction *action = qobject_cast<QAction *>(sender());
  int i=0;
  if (action)
    i=action->data().toInt();
  else return;
  if (i>mole.asymm.size()) return;
  int warmalAtome=0;
  for (int j=0; j<mole.asymm.size();j++) if (mole.asymm.at(j).an>=0)warmalAtome++;
  double nh= (mole.asymm.at(i).an==6) ? 0.07 : 0;
  QStringList alab;
  for (int i =0; i<mole.asymm.size(); i++){
    alab.append(mole.asymm.at(i).Label);
  }
  QString nn;
  chgl->disSelection();
  MyAtom htest,qtest;
  if (editor->sfac.indexOf(0)==-1)addNewScatteringFactor(0);
  htest.an=0;
  htest.part=0;
  htest.resiNr=0;
  htest.hidden=0;
  htest.symmGroup=0;
  htest.sg=0;
  htest.scod=555;//the identity
  htest.auidx=-1;
  htest.uc.m12=htest.uc.m23=htest.uc.m13=0.0;
  htest.uc.m21=htest.uc.m32=htest.uc.m31=0.0;
  htest.uf.m12=htest.uf.m23=htest.uf.m13=0.0;
  htest.uf.m21=htest.uf.m32=htest.uf.m31=0.0;
  qtest=htest;
  qtest.an=-1;
  QTextDocument *document = editor->document();
  QTextCursor cursor = editor->textCursor();
  cursor.beginEditBlock ();
  double xh[8]={
    0.98,//1
    0.97,//2
    0.96,//3
    0.93,//4
    1.10,//15 B
    0.82,//8 O
    0.93,//9
    0.93// 16
  };
  V3 v=V3(0,0,0),w=V3(0,0,0),u=V3(0,0,0) ,a=V3(0,0,0);//,b=V3(0,0,0),c=V3(0,0,0);
  a = mole.showatoms.at(mole.knoepfe.at(i).neighbors.at(0)).pos - mole.asymm.at(i).pos;
  int ji,ki,li;
  a=Normalize(a);
  double jx,kx,lx,mx,my,mz;
  double val[24],merg[8],wink=0,t=0,mt=0;
  for (int z=0; z<8;z++) merg[z]=0;
  if (fxle->n5){
    for (int z=0; z<24; z++){
      w=Normalize(V3(0,0,1)%a);
      u=Normalize(w%a);
      v=(-(xh[2]-nh)*0.33333*a)+ mole.asymm.at(i).pos+(xh[2]-nh)*0.942809041582*(sin(wink)*u+cos(wink)*w);
      qtest.pos=v;
      mole.kart2frac(v,v);
      int zplu=0;
      do {
        jx=((zplu+v.x)*fxle->n1+0.5);
        zplu++;
      }while (jx<0);
      zplu=0;
      do {
        kx=((zplu+v.y)*fxle->n2+0.5);
        zplu++;
      }while (kx<0);
      zplu=0;
      do {
        lx=((zplu+v.z)*fxle->n3+0.5);
        zplu++;
      }while (lx<0);
      mx=jx-floor(jx);
      my=kx-floor(kx);
      mz=lx-floor(lx);
      ji=((int)jx)%fxle->n1;//
      ki=((int)kx)%fxle->n2;//
      li=((int)lx)%fxle->n3;//
      merg[z%8]+=val[z]=(
          (1-mx)*fxle->datfo_fc[(ji+fxle->n1*(ki+li*fxle->n2))%fxle->n5]+
          mx*fxle->datfo_fc[((ji+1)+fxle->n1*(ki+li*fxle->n2))%fxle->n5]+
          (1-my)*fxle->datfo_fc[(ji+fxle->n1*(ki+li*fxle->n2))%fxle->n5]+
          my*fxle->datfo_fc[(ji+fxle->n1*((ki+1)+li*fxle->n2))%fxle->n5]+
          (1-mz)*fxle->datfo_fc[(ji+fxle->n1*(ki+li*fxle->n2))%fxle->n5]+
          mz*fxle->datfo_fc[(ji+fxle->n1*(ki+(li+1)*fxle->n2))%fxle->n5])/3.0;
      qtest.peakHeight=val[z];
      qtest.frac=v;
      qtest.Label=QString("Q%1").arg(z,-3);
      mole.pmin=qMin(mole.pmin, qtest.peakHeight);
      mole.pmax=qMax(mole.pmax, qtest.peakHeight);
      qpv->cutoff=0;//mole.pmin;
      qpv->setMin(mole.pmin);
      qpv->setMax(mole.pmax);
      mole.asymm.append(qtest);
      wink+=0.261799387799;
    }
    for (int z=0; z<8;z++) {
      t =merg[(z+8)%8] ;
      double x = t - merg[(z+9)%8];
      double u = t - merg[(z+7)%8];
      if (fmin(x,u)<0) continue;
      double p=0.5*(u-x)/(u+x);
      t=t+0.25*(p*(u-x));
      mt=(mt>t)?mt:t;
      if (t<mt)continue;
      wink=((double) z + p )*0.261799387799; 
    }
  }else{
    int zzz=0;
    int z=mole.knoepfe.at(mole.knoepfe.at(i).neighbors.at(0)).neighbors.at(zzz++);
    while ((z==i)&&(zzz<mole.knoepfe.at(mole.knoepfe.at(i).neighbors.at(0)).neighbors.size())) {
      z=mole.knoepfe.at(mole.knoepfe.at(i).neighbors.at(0)).neighbors.at(zzz++);
    }
    w=Normalize(V3(0,0,1)%a);
    u=Normalize(w%a);
    v=(-(xh[2]-nh)*0.33333*a)+ mole.asymm.at(i).pos+(xh[2]-nh)*0.942809041582*(sin(wink)*u+cos(wink)*w);
    // if z == i then dieder() returns nan, because A in dieder gets (0,0,0)
    V3 increm = V3(0.0, 0.0, 0.0);
    if ( z == i ) {
      increm = V3(0.00001, 0.00001, 0.00001);
    }
    wink=mole.dieder(mole.showatoms.at(mole.knoepfe.at(i).neighbors.at(0)).pos+increm-mole.asymm.at(z).pos,
        mole.asymm.at(i).pos-mole.showatoms.at(mole.knoepfe.at(i).neighbors.at(0)).pos,
        v-mole.asymm.at(i).pos)/180.0*M_PI;
  }
  v=(-(xh[2]-nh)*0.33333*a)+ mole.asymm.at(i).pos+(xh[2]-nh)*0.942809041582*(sin(wink)*u+cos(wink)*w);
  htest.Label=mole.asymm.at(i).Label.section('_',0,0);
  htest.part=mole.asymm.at(i).part;
  htest.resiNr=mole.asymm.at(i).resiNr;
  htest.Label.replace(0,1,'H');
  int hindex=1;
  QString nnn=htest.Label;
  QString ann=htest.Label;
  do {
    if (hindex) nnn=ann.left(3).append(QString::number(hindex+9,36));
    if (nnn.size()>4) nnn=ann.left(2).append(QString::number(hindex+9,36));
    if (htest.resiNr)
      nn=QString("%1_%2")//for shelxl same names in different parts are no problem but for platon so this should fix it.
        .arg(nnn)
        .arg((htest.resiNr)?QString::number(htest.resiNr):"");
    else nn=nnn;
    // qDebug()<<nn<<nnn<<(alab.contains(nn,Qt::CaseInsensitive));
    hindex++;
  }while(alab.contains(nn,Qt::CaseInsensitive));
  htest.Label=nnn;
  alab.append(nn);

  htest.isIso=true;
  htest.ufiso_org=QString("-1.5");
  double uIso = mole.ueq(mole.asymm.at(i).uf)*1.5;
  htest.uf.m11 = htest.uf.m22 = htest.uf.m33 = uIso;
  htest.uf.m23 = uIso * mole.cell.cosra; 
  htest.uf.m13 = uIso * mole.cell.cosrb; 
  htest.uf.m12 = uIso * mole.cell.cosrg; 
  mole.Uf2Uo(htest.uf,htest.uc);
  htest.pos=v;
  mole.kart2frac(htest.pos,htest.frac);	
  htest.orginalLine=QString("%1  %2  %3 %4 %5 %6 %7")
    .arg(htest.Label)
    .arg(qMax(1,editor->sfac.indexOf(0)+1))
    .arg(htest.frac.x,9,'f',5)
    .arg(htest.frac.y,9,'f',5)
    .arg(htest.frac.z,9,'f',5)
    .arg(mole.asymm.at(i).sof_org)
    .arg("-1.5");
  mole.asymm.append(htest);
  wink+=2.09439510239;
  v=(-(xh[2]-nh)*0.33333*a)+ mole.asymm.at(i).pos+(xh[2]-nh)*0.942809041582*(sin(wink)*u+cos(wink)*w);
  do {
    if (hindex) nnn=ann.left(3).append(QString::number(hindex+9,36));
    if (nnn.size()>4) nnn=ann.left(2).append(QString::number(hindex+9,36));
    if (htest.resiNr)
      nn=QString("%1_%2")//for shelxl same names in different parts are no problem but for platon so this should fix it.
        .arg(nnn)
        .arg((htest.resiNr)?QString::number(htest.resiNr):"");
    else nn=nnn;
    // qDebug()<<nn<<nnn<<(alab.contains(nn,Qt::CaseInsensitive));
    hindex++;
  }while(alab.contains(nn,Qt::CaseInsensitive));
  htest.Label=nnn;
  alab.append(nn);
  htest.pos=v;
  mole.kart2frac(htest.pos,htest.frac);	
  htest.orginalLine=QString("%1  %2  %3 %4 %5 %6 %7")
    .arg(htest.Label)
    .arg(qMax(1,editor->sfac.indexOf(0)+1))
    .arg(htest.frac.x,9,'f',5)
    .arg(htest.frac.y,9,'f',5)
    .arg(htest.frac.z,9,'f',5)
    .arg(mole.asymm.at(i).sof_org)
    .arg("-1.5");
  mole.asymm.append(htest);
  wink+=2.09439510239;
  v=(-(xh[2]-nh)*0.33333*a)+ mole.asymm.at(i).pos+(xh[2]-nh)*0.942809041582*(sin(wink)*u+cos(wink)*w);
  do {
    if (hindex) nnn=ann.left(3).append(QString::number(hindex+9,36));
    if (nnn.size()>4) nnn=ann.left(2).append(QString::number(hindex+9,36));
    if (htest.resiNr)
      nn=QString("%1_%2")//for shelxl same names in different parts are no problem but for platon so this should fix it.
        .arg(nnn)
        .arg((htest.resiNr)?QString::number(htest.resiNr):"");
    else nn=nnn;
    // qDebug()<<nn<<nnn<<(alab.contains(nn,Qt::CaseInsensitive));
    hindex++;
  }while(alab.contains(nn,Qt::CaseInsensitive));
  htest.Label=nnn;
  alab.append(nn);
  htest.pos=v;
  mole.kart2frac(htest.pos,htest.frac);	
  htest.orginalLine=QString("%1  %2  %3 %4 %5 %6 %7")
    .arg(htest.Label)
    .arg(qMax(1,editor->sfac.indexOf(0)+1))
    .arg(htest.frac.x,9,'f',5)
    .arg(htest.frac.y,9,'f',5)
    .arg(htest.frac.z,9,'f',5)
    .arg(mole.asymm.at(i).sof_org)
    .arg("-1.5");
  mole.asymm.append(htest);
  QString label = mole.showatoms.at(i).orginalLine.left(80).trimmed();
  //  int afixfuenf=(mole.showatoms.at(i).afix/10)?(mole.showatoms.at(i).afix/10)*10+5:0;
  cursor.movePosition(QTextCursor::Start);
  cursor = document->find(label,cursor);
  if (cursor.isNull()){
    cursor = editor->textCursor();
    cursor.movePosition(QTextCursor::Start);
    label.chop(10);
    cursor = document->find(label,cursor);
    if (cursor.isNull()) {
      cursor = editor->textCursor();
    }
  }
  cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
  cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
  while (cursor.selectedText().endsWith("=")) {
    cursor.movePosition(QTextCursor::Down,QTextCursor::KeepAnchor);
    cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
  }
  cursor.clearSelection();
  cursor.movePosition(QTextCursor::Down);
  cursor.insertText(QString("AFIX 137\n%1\n%2\n%3\nAFIX %4\n")
      .arg(mole.asymm.at(mole.asymm.size()-3).orginalLine)
      .arg(mole.asymm.at(mole.asymm.size()-2).orginalLine)
      .arg(mole.asymm.at(mole.asymm.size()-1).orginalLine)
      .arg(mole.afix5(i))
      );

  cursor.endEditBlock();
  int jetztAtome=0;
  for (int i=0; i<mole.asymm.size();i++) if (mole.asymm.at(i).an>=0)jetztAtome++;
  actionHFix->setDisabled(true);
  fuse();
  QString info=QString("<font color=\"green\"><b>%1</b> Hydrogen atoms added. <b>Please SAVE before GROW!</font>").arg(jetztAtome-warmalAtome);
  infoKanalNews(info); 
}


void Window::addHydroxyl(){//148
  QAction *action = qobject_cast<QAction *>(sender());
  int idx=0;
  if (action)
    idx=action->data().toInt();
  else return;
  if (idx>mole.asymm.size()) return;
  int warmalAtome=0;
  for (int j=0; j<mole.asymm.size();j++) if (mole.asymm.at(j).an>=0)warmalAtome++;

  QStringList alab;
  for (int i =0; i<mole.asymm.size(); i++){
    alab.append(mole.asymm.at(i).Label);
  }
  QString nn;
  chgl->disSelection();
  MyAtom htest,qtest;
  if (editor->sfac.indexOf(0)==-1)addNewScatteringFactor(0);
  htest.an=0;
  htest.part=0;
  htest.resiNr=0;
  htest.hidden=0;
  htest.symmGroup=0;
  htest.sg=0;
  htest.scod=555;//the identity
  htest.auidx=-1;
  htest.uc.m12=htest.uc.m23=htest.uc.m13=0.0;
  htest.uc.m21=htest.uc.m32=htest.uc.m31=0.0;
  htest.uf.m12=htest.uf.m23=htest.uf.m13=0.0;
  htest.uf.m21=htest.uf.m32=htest.uf.m31=0.0;
  qtest=htest;
  qtest.an=-1;
  QTextDocument *document = editor->document();
  QTextCursor cursor = editor->textCursor();
  cursor.beginEditBlock ();
  printf("editblock begins\n");
  double xh[8]={
    0.98,//1
    0.97,//2
    0.96,//3
    0.93,//4
    1.10,//15 B
    0.82,//8 O
    0.93,//9
    0.93// 16
  };
  //qDebug()<<mole.showatoms.at(mole.knoepfe.at(idx).neighbors.at(0)).Label<<mole.asymm.at(idx).Label;
  V3 v=V3(0,0,0),w=V3(0,0,0),u=V3(0,0,0) ,a=V3(0,0,0);//,b=V3(0,0,0),c=V3(0,0,0);
  a = mole.showatoms.at(mole.knoepfe.at(idx).neighbors.at(0)).pos - mole.asymm.at(idx).pos;
  int ji,ki,li;
  a=Normalize(a);
  double jx,kx,lx,mx,my,mz;
  double val[24],wink=0,t=0,mt=0;

  if (fxle->n5){
    for (int z=0; z<24; z++){
      w=Normalize(V3(0,0,1)%a);
      u=Normalize(w%a);
      v=(-(xh[5])*0.33333*a)+ mole.asymm.at(idx).pos+(xh[5])*0.942809041582*(sin(wink)*u+cos(wink)*w);
      qtest.pos=v;
      mole.kart2frac(v,v);
      int zplu=0;
      do {
        jx=((zplu+v.x)*fxle->n1+0.5);
        zplu++;
      }while (jx<0);
      zplu=0;
      do {
        kx=((zplu+v.y)*fxle->n2+0.5);
        zplu++;
      }while (kx<0);
      zplu=0;
      do {
        lx=((zplu+v.z)*fxle->n3+0.5);
        zplu++;
      }while (lx<0);
      mx=jx-floor(jx);
      my=kx-floor(kx);
      mz=lx-floor(lx);
      ji=((int)jx)%fxle->n1;//
      ki=((int)kx)%fxle->n2;//
      li=((int)lx)%fxle->n3;//
      val[z]=(
          (1-mx)*fxle->datfo_fc[(ji+fxle->n1*(ki+li*fxle->n2))%fxle->n5]+
          mx*fxle->datfo_fc[((ji+1)+fxle->n1*(ki+li*fxle->n2))%fxle->n5]+
          (1-my)*fxle->datfo_fc[(ji+fxle->n1*(ki+li*fxle->n2))%fxle->n5]+
          my*fxle->datfo_fc[(ji+fxle->n1*((ki+1)+li*fxle->n2))%fxle->n5]+
          (1-mz)*fxle->datfo_fc[(ji+fxle->n1*(ki+li*fxle->n2))%fxle->n5]+
          mz*fxle->datfo_fc[(ji+fxle->n1*(ki+(li+1)*fxle->n2))%fxle->n5])/3.0;
      qtest.peakHeight=val[z];
      qtest.frac=v;
      qtest.Label=QString("Q%1").arg(z,-3);
      mole.pmin=qMin(mole.pmin, qtest.peakHeight);
      mole.pmax=qMax(mole.pmax, qtest.peakHeight);
      qpv->cutoff=0;//mole.pmin;
      qpv->setMin(mole.pmin);
      qpv->setMax(mole.pmax);
      mole.asymm.append(qtest);
      wink+=0.261799387799;
    }
    for (int z=0; z<24;z++) {
      t =val[z%24] ;
      double x = t - val[(z+25)%24];
      double u = t - val[(z+23)%24];
      if (fmin(x,u)<0) continue;
      double p=0.5*(u-x)/(u+x);
      t=t+0.25*(p*(u-x));
      mt=(mt>t)?mt:t;
      if (t<mt)continue;
      wink=((double) z + p )*0.261799387799;
    }
  }else {qDebug()<<"Please enable Fourier maps!";cursor.endEditBlock(); return; }
  v=(-(xh[5])*0.33333*a)+ mole.asymm.at(idx).pos+(xh[5])*0.942809041582*(sin(wink)*u+cos(wink)*w);
  htest.Label=mole.asymm.at(idx).Label.section('_',0,0);
  htest.part=mole.asymm.at(idx).part;
  htest.resiNr=mole.asymm.at(idx).resiNr;
  htest.Label.replace(0,1,'H');
  int hindex=1;
  QString nnn=htest.Label;
  QString ann=htest.Label;
  do {
    if (hindex) nnn=ann.left(3).append(QString::number(hindex+9,36));
    if (nnn.size()>4) nnn=ann.left(2).append(QString::number(hindex+9,36));
    if (htest.resiNr)
      nn=QString("%1_%2")//for shelxl same names in different parts are no problem but for platon so this should fix it.
        .arg(nnn)
        .arg((htest.resiNr)?QString::number(htest.resiNr):"");
    else nn=nnn;
    // qDebug()<<nn<<nnn<<(alab.contains(nn,Qt::CaseInsensitive));
    hindex++;
  }while(alab.contains(nn,Qt::CaseInsensitive));
  htest.Label=nnn;
  alab.append(nn);

  htest.isIso=true;
  htest.ufiso_org=QString("-1.5");
  double uIso = mole.ueq(mole.asymm.at(idx).uf)*1.5;
  htest.uf.m11 = htest.uf.m22 = htest.uf.m33 = uIso;
  htest.uf.m23 = uIso * mole.cell.cosra;
  htest.uf.m13 = uIso * mole.cell.cosrb;
  htest.uf.m12 = uIso * mole.cell.cosrg;
  mole.Uf2Uo(htest.uf,htest.uc);
  htest.pos=v;
  mole.kart2frac(htest.pos,htest.frac);
  htest.orginalLine=QString("%1  %2  %3 %4 %5 %6 %7")
    .arg(htest.Label)
    .arg(qMax(1,editor->sfac.indexOf(0)+1))
    .arg(htest.frac.x,9,'f',5)
    .arg(htest.frac.y,9,'f',5)
    .arg(htest.frac.z,9,'f',5)
    .arg(mole.asymm.at(idx).sof_org)
    .arg("-1.5");
  mole.asymm.append(htest);
  QString label = mole.showatoms.at(idx).orginalLine.left(80).trimmed();
  //  int afixfuenf=(mole.showatoms.at(i).afix/10)?(mole.showatoms.at(i).afix/10)*10+5:0;
  cursor.movePosition(QTextCursor::Start);
  cursor = document->find(label,cursor);
  if (cursor.isNull()){
    cursor = editor->textCursor();
    cursor.movePosition(QTextCursor::Start);
    label.chop(10);
    cursor = document->find(label,cursor);
    if (cursor.isNull()) {
      cursor = editor->textCursor();
    }
  }
  cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
  cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
  while (cursor.selectedText().endsWith("=")) {
    cursor.movePosition(QTextCursor::Down,QTextCursor::KeepAnchor);
    cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
  }
  cursor.clearSelection();
  cursor.movePosition(QTextCursor::Down);
  cursor.insertText(QString("AFIX 148\n%1\nAFIX %2\n")
      .arg(mole.asymm.at(mole.asymm.size()-1).orginalLine)
      .arg(mole.afix5(idx))
      );
  printf("%d cursor will end edit block\n",cursor.isNull());
  cursor.endEditBlock();
  int jetztAtome=0;
  for (int i=0; i<mole.asymm.size();i++) if (mole.asymm.at(i).an>=0)jetztAtome++;
  actionHFix->setDisabled(true);
  fuse();
  QString info=QString("<font color=\"green\"><b>%1</b> Hydrogen atoms added. <b>Please SAVE before GROW!</font>").arg(jetztAtome-warmalAtome);
  infoKanalNews(info);
}




void Window::addHnonplanarAminR2(){
  //<! there is no afix for R-NH2 for the nonplanar case 
  //this trys to find similar to 23 the highest density in the terahedal cone 
  QAction *action = qobject_cast<QAction *>(sender());
  int i=0;
  if (action)
    i=action->data().toInt();
  else return;
  if (i>mole.asymm.size()) return;
  if (mole.knoepfe.at(i).neighbors.size()!=2)return;//we need 2 non h neighbors
  int warmalAtome=0;
  for (int j=0; j<mole.asymm.size();j++) if (mole.asymm.at(j).an>=0)warmalAtome++;
  QStringList alab;
  for (int i =0; i<mole.asymm.size(); i++){
    alab.append(mole.asymm.at(i).Label);
  }
  QString nn;
  double dist=0.9;//nh= (mole.asymm.at(i).an==6) ? 0.07 : 0;

  chgl->disSelection();
  MyAtom htest,qtest;
  if (editor->sfac.indexOf(0)==-1)addNewScatteringFactor(0);
  htest.an=0;
  htest.part=0;
  htest.resiNr=0;
  htest.hidden=0;
  htest.symmGroup=0;
  htest.sg=0;
  htest.scod=555;//the identity
  htest.auidx=-1;
  htest.uc.m12=htest.uc.m23=htest.uc.m13=0.0;
  htest.uc.m21=htest.uc.m32=htest.uc.m31=0.0;
  htest.uf.m12=htest.uf.m23=htest.uf.m13=0.0;
  htest.uf.m21=htest.uf.m32=htest.uf.m31=0.0;
  qtest=htest;
  qtest.an=-1;
  QTextDocument *document = editor->document();
  QTextCursor cursor = editor->textCursor();
  cursor.beginEditBlock ();
  V3 v=V3(0,0,0),w=V3(0,0,0),u=V3(0,0,0) ,a=V3(0,0,0),b=V3(0,0,0),c=V3(0,0,0);
  a = mole.showatoms.at(mole.knoepfe.at(i).neighbors.at(0)      ).pos - mole.asymm.at(i).pos;
  b = mole.showatoms.at(mole.knoepfe.at(i).neighbors.at(1)      ).pos - mole.asymm.at(i).pos;
  a = c = Normalize(a) ;
  c = c+ (b= Normalize(b));
  c = Normalize(c);

  w = Normalize(a);
  u = Normalize(b);
  double si=1.0376-0.0346*Norm(w-u);    //=1.91063323625-((acos(u*w)-1.91063323625)/5.0);//-1.91063323625 = 109.47 grad ; 3.7 empirischer Wert
  c = (-cos(si)*dist * c);
  v = sin(si)  *dist * Normalize(c%a);
  a = mole.asymm.at(i).pos + c + v;
  b = mole.asymm.at(i).pos + c - v;
  // test if pos a or b has the higher residual density 
  double densA=0.,densB=0.;
  if (fxle->n5){
    double jx,kx,lx,mx,my,mz;
    mole.kart2frac(a,v);
    int zplu=0,ji,ki,li;
    do {
      jx=((zplu+v.x)*fxle->n1+0.5);
      zplu++;
    }while (jx<0);
    zplu=0;
    do {
      kx=((zplu+v.y)*fxle->n2+0.5);
      zplu++;
    }while (kx<0);
    zplu=0;
    do {
      lx=((zplu+v.z)*fxle->n3+0.5);
      zplu++;
    }while (lx<0);
    mx=jx-floor(jx);
    my=kx-floor(kx);
    mz=lx-floor(lx);
    ji=((int)jx)%fxle->n1;//
    ki=((int)kx)%fxle->n2;//
    li=((int)lx)%fxle->n3;//
    densA=(
        (1-mx)*fxle->datfo_fc[(ji+fxle->n1*(ki+li*fxle->n2))%fxle->n5]+
        mx*fxle->datfo_fc[((ji+1)+fxle->n1*(ki+li*fxle->n2))%fxle->n5]+
        (1-my)*fxle->datfo_fc[(ji+fxle->n1*(ki+li*fxle->n2))%fxle->n5]+
        my*fxle->datfo_fc[(ji+fxle->n1*((ki+1)+li*fxle->n2))%fxle->n5]+
        (1-mz)*fxle->datfo_fc[(ji+fxle->n1*(ki+li*fxle->n2))%fxle->n5]+
        mz*fxle->datfo_fc[(ji+fxle->n1*(ki+(li+1)*fxle->n2))%fxle->n5]);

    mole.kart2frac(b,v);
    zplu=0;
    do {
      jx=((zplu+v.x)*fxle->n1+0.5);
      zplu++;
    }while (jx<0);
    zplu=0;
    do {
      kx=((zplu+v.y)*fxle->n2+0.5);
      zplu++;
    }while (kx<0);
    zplu=0;
    do {
      lx=((zplu+v.z)*fxle->n3+0.5);
      zplu++;
    }while (lx<0);
    mx=jx-floor(jx);
    my=kx-floor(kx);
    mz=lx-floor(lx);
    ji=((int)jx)%fxle->n1;//
    ki=((int)kx)%fxle->n2;//
    li=((int)lx)%fxle->n3;//
    densB=(
        (1-mx)*fxle->datfo_fc[(ji+fxle->n1*(ki+li*fxle->n2))%fxle->n5]+
        mx*fxle->datfo_fc[((ji+1)+fxle->n1*(ki+li*fxle->n2))%fxle->n5]+
        (1-my)*fxle->datfo_fc[(ji+fxle->n1*(ki+li*fxle->n2))%fxle->n5]+
        my*fxle->datfo_fc[(ji+fxle->n1*((ki+1)+li*fxle->n2))%fxle->n5]+
        (1-mz)*fxle->datfo_fc[(ji+fxle->n1*(ki+li*fxle->n2))%fxle->n5]+
        mz*fxle->datfo_fc[(ji+fxle->n1*(ki+(li+1)*fxle->n2))%fxle->n5]);
  }//n5
  c = c + mole.asymm.at(i).pos;

  htest.Label=mole.asymm.at(i).Label.section('_',0,0);
  htest.part=mole.asymm.at(i).part;
  htest.resiNr=mole.asymm.at(i).resiNr;
  htest.Label.replace(0,1,'H');
  int hindex=14;//N
  QString nnn=htest.Label;
  QString ann=nnn;
  if (densA>densB) {
    //HA
    do {
      if (hindex) nnn=ann.left(3).append(QString::number(hindex+9,36));
      if (nnn.size()>4) nnn=ann.left(2).append(QString::number(hindex+9,36));
      if (htest.resiNr)
        nn=QString("%1_%2")//for shelxl same names in different parts are no problem but for platon so this should fix it.
          .arg(nnn)
          .arg((htest.resiNr)?QString::number(htest.resiNr):"");
      else nn=nnn;
      hindex++;
    }while(alab.contains(nn,Qt::CaseInsensitive));
    htest.Label=nnn;
    alab.append(nn);
    htest.isIso=true;
    htest.ufiso_org=QString("-1.2");
    double uIso = mole.ueq(mole.asymm.at(i).uf)*1.2;
    htest.uf.m11 = htest.uf.m22 = htest.uf.m33 = uIso;
    htest.uf.m23 = uIso * mole.cell.cosra; 
    htest.uf.m13 = uIso * mole.cell.cosrb; 
    htest.uf.m12 = uIso * mole.cell.cosrg; 
    mole.Uf2Uo(htest.uf,htest.uc);
    htest.pos=a;
    mole.kart2frac(htest.pos,htest.frac);	
    htest.orginalLine=QString("%1  %2  %3 %4 %5 %6 %7")
      .arg(htest.Label)
      .arg(qMax(1,editor->sfac.indexOf(0)+1))
      .arg(htest.frac.x,9,'f',5)
      .arg(htest.frac.y,9,'f',5)
      .arg(htest.frac.z,9,'f',5)
      .arg(mole.asymm.at(i).sof_org)
      .arg("-1.2");
    mole.asymm.append(htest);
  } else {
    //HB
    do {
      if (hindex) nnn=ann.left(3).append(QString::number(hindex+9,36));
      if (nnn.size()>4) nnn=ann.left(2).append(QString::number(hindex+9,36));
      if (htest.resiNr)
        nn=QString("%1_%2")//for shelxl same names in different parts are no problem but for platon so this should fix it.
          .arg(nnn)
          .arg((htest.resiNr)?QString::number(htest.resiNr):"");
      else nn=nnn;
      hindex++;
    }while(alab.contains(nn,Qt::CaseInsensitive));
    htest.Label=nnn;
    alab.append(nn);
    htest.pos=b;
    mole.kart2frac(htest.pos,htest.frac);	
    htest.orginalLine=QString("%1  %2  %3 %4 %5 %6 %7")
      .arg(htest.Label)
      .arg(qMax(1,editor->sfac.indexOf(0)+1))
      .arg(htest.frac.x,9,'f',5)
      .arg(htest.frac.y,9,'f',5)
      .arg(htest.frac.z,9,'f',5)
      .arg(mole.asymm.at(i).sof_org)
      .arg("-1.2");
    mole.asymm.append(htest);
  }
  QString label = mole.showatoms.at(i).orginalLine.left(80).trimmed();
  cursor.movePosition(QTextCursor::Start);
  cursor = document->find(label,cursor);
  if (cursor.isNull()){
    cursor = editor->textCursor();
    cursor.movePosition(QTextCursor::Start);
    label.chop(10);
    cursor = document->find(label,cursor);
    if (cursor.isNull()) {
      cursor = editor->textCursor();
    }
  }
  cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
  cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
  while (cursor.selectedText().endsWith("=")) {
    cursor.movePosition(QTextCursor::Down,QTextCursor::KeepAnchor);
    cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
  }
  cursor.clearSelection();
  cursor.movePosition(QTextCursor::Down);
  cursor.insertText(QString("REM HFIX R2N-H\n%1\n") .arg(mole.asymm.last().orginalLine));
  //now comes some DFIX/DANG/SADI stuff
  cursor.movePosition(QTextCursor::Start,QTextCursor::MoveAnchor);
  cursor = document->find(QRegExp("^UNIT",Qt::CaseInsensitive),cursor);
  cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
  cursor.movePosition(QTextCursor::Down,QTextCursor::MoveAnchor);
  QString rns="";
  if (mole.asymm.at(i).resiNr!=0) rns=QString("_%1").arg(mole.asymm.at(i).resiNr);
  QString buffer = QString("DFIX%1 %2 %3 %4\n")
    .arg(rns)
    .arg(dist,0,'f',2)
    .arg(mole.asymm.at(i).Label.section('_',0,0))
    .arg(mole.asymm.last().Label);
  cursor.insertText(buffer);
  for (int z = 0; z < mole.knoepfe.at(i).neighbors.size(); z++){
    buffer.clear();
    double einsdrei=sqrt(Distance(mole.asymm.last().pos,mole.showatoms.at(mole.knoepfe.at(i).neighbors.at(z)).pos));//showatoms because this might be not in asymmeric unit
    QString LL=mole.showatoms.at(mole.knoepfe.at(i).neighbors.at(z)).Label.section('_',0,0),dollarN="";
    if (mole.showatoms.at(mole.knoepfe.at(i).neighbors.at(z)).symmGroup>0){
      int eq = document->toPlainText().count("EQIV", Qt::CaseInsensitive)+1;
      dollarN=QString("$%1").arg(eq);
      buffer = QString("EQIV %1 %2\n").arg(dollarN).arg(mole.symmcode2human(mole.showatoms.at(mole.knoepfe.at(i).neighbors.at(z)).sg));
      dollarN.prepend('_');
      LL=LL.section(QString::fromUtf8("»"),0,0);
    }
    buffer += QString("DANG%1 %2 %3%4 %5\n")
      .arg(rns)
      .arg(einsdrei,0,'f',2)
      .arg(LL)
      .arg(dollarN)
      .arg(mole.asymm.last().Label);
    cursor.insertText(buffer);

  }
  cursor.endEditBlock();
  int jetztAtome=0;
  for (int i=0; i<mole.asymm.size();i++) if (mole.asymm.at(i).an>=0)jetztAtome++;
  actionHFix->setDisabled(true);
  fuse();
  QString info=QString("<font color=\"green\"><b>%1</b> Hydrogen atoms added. <b>Please SAVE before GROW!</font>").arg(jetztAtome-warmalAtome);
  infoKanalNews(info); 
}

void Window::addHnonplanarAminR1(){
  //<! there is no afix for R-NH2 for the nonplanar case 
  //this trys to find similar to 137 the highest density in the terahedal cone 
  QAction *action = qobject_cast<QAction *>(sender());
  int i=0;
  if (action)
    i=action->data().toInt();
  else return;
  if (i>mole.asymm.size()) return;
  int warmalAtome=0;
  for (int j=0; j<mole.asymm.size();j++) if (mole.asymm.at(j).an>=0)warmalAtome++;

  chgl->disSelection();
  MyAtom htest,qtest;
  if (editor->sfac.indexOf(0)==-1)addNewScatteringFactor(0);
  QStringList alab;
  for (int i =0; i<mole.asymm.size(); i++){
    alab.append(mole.asymm.at(i).Label);
  }
  QString nn;
  htest.an=0;
  htest.part=0;
  htest.resiNr=0;
  htest.hidden=0;
  htest.symmGroup=0;
  htest.sg=0;
  htest.scod=555;//the identity
  htest.auidx=-1;
  htest.uc.m12=htest.uc.m23=htest.uc.m13=0.0;
  htest.uc.m21=htest.uc.m32=htest.uc.m31=0.0;
  htest.uf.m12=htest.uf.m23=htest.uf.m13=0.0;
  htest.uf.m21=htest.uf.m32=htest.uf.m31=0.0;
  qtest=htest;
  qtest.an=-1;
  QTextDocument *document = editor->document();
  QTextCursor cursor = editor->textCursor();
  cursor.beginEditBlock ();
  V3 v=V3(0,0,0),w=V3(0,0,0),u=V3(0,0,0) ,a=V3(0,0,0);//,b=V3(0,0,0),c=V3(0,0,0);
  a = mole.showatoms.at(mole.knoepfe.at(i).neighbors.at(0)).pos - mole.asymm.at(i).pos;
  int ji, ki, li, main[24], fi=0,az=0,bz=0;
  a=Normalize(a);
  double jx,kx,lx,mx,my,mz,dist=0.89;
  bool andersrum=false;
  double val[24],wink=0,t=0,mt=0.0,mava[24];
  if (fxle->n5){
    for (int z=0; z<24; z++){
      main[z] = -1;
      mava[z] = 0.0;
      w=Normalize(V3(0,0,1)%a);
      u=Normalize(w%a);
      v=(-dist*0.33333*a)+ mole.asymm.at(i).pos+dist*0.942809041582*(sin(wink)*u+cos(wink)*w);
      qtest.pos=v;
      mole.kart2frac(v,v);
      int zplu=0;
      do {
        jx=((zplu+v.x)*fxle->n1+0.5);
        zplu++;
      }while (jx<0);
      zplu=0;
      do {
        kx=((zplu+v.y)*fxle->n2+0.5);
        zplu++;
      }while (kx<0);
      zplu=0;
      do {
        lx=((zplu+v.z)*fxle->n3+0.5);
        zplu++;
      }while (lx<0);
      mx=jx-floor(jx);
      my=kx-floor(kx);
      mz=lx-floor(lx);
      ji=((int)jx)%fxle->n1;//
      ki=((int)kx)%fxle->n2;//
      li=((int)lx)%fxle->n3;//
      val[z]=(
          (1-mx)*fxle->datfo_fc[(ji+fxle->n1*(ki+li*fxle->n2))%fxle->n5]+
          mx*fxle->datfo_fc[((ji+1)+fxle->n1*(ki+li*fxle->n2))%fxle->n5]+
          (1-my)*fxle->datfo_fc[(ji+fxle->n1*(ki+li*fxle->n2))%fxle->n5]+
          my*fxle->datfo_fc[(ji+fxle->n1*((ki+1)+li*fxle->n2))%fxle->n5]+
          (1-mz)*fxle->datfo_fc[(ji+fxle->n1*(ki+li*fxle->n2))%fxle->n5]+
          mz*fxle->datfo_fc[(ji+fxle->n1*(ki+(li+1)*fxle->n2))%fxle->n5]);
      qtest.peakHeight=val[z];
      qtest.frac=v;
      qtest.Label=QString("Q%1").arg(z,-3);
      mole.pmin=qMin(mole.pmin, qtest.peakHeight);
      mole.pmax=qMax(mole.pmax, qtest.peakHeight);
      qpv->cutoff=0;//mole.pmin;
      qpv->setMin(mole.pmin);
      qpv->setMax(mole.pmax);
      mole.asymm.append(qtest);
      wink+=0.261799387799;
    }
    for (int z=0; z<24;z++) {
      t = val[(z+24)%24] ;
      double x = t - val[(z+25)%24];
      double u = t - val[(z+23)%24];
      if (fmin(x,u)<0.0) continue;
      double p=0.5*(u-x)/(u+x);
      t=t+0.25*(p*(u-x));
      mt=(mt>t)?mt:t;
      main[fi]=z;
      mava[fi]=t;
      fi++;
      if (t<mt)continue;
      az=z;
      wink=((double) z + p )*0.261799387799;
    }
    double m2t=0.0;
    for (int z=0; z<fi; z++){
      //printf("%d#%f ",main[z],mava[z]);
      if (main[z] != az) if (m2t < mava[z]) {bz = main[z]; m2t = mava[z];}
    }
    //printf("\n");
    andersrum=((((bz-az)+36)%24)<12);//decide on which side is the other H
    //printf("2nd->%d  andersrum %d %d %d\n", ((bz-az)+36)%24, andersrum,az,bz);
  }else{
    int zzz=0;
    int z=mole.knoepfe.at(mole.knoepfe.at(i).neighbors.at(0)).neighbors.at(zzz++);
    while ((z==i)&&(zzz<mole.knoepfe.at(mole.knoepfe.at(i).neighbors.at(0)).neighbors.size())) {
      z=mole.knoepfe.at(mole.knoepfe.at(i).neighbors.at(0)).neighbors.at(zzz++);
    }
    w=Normalize(V3(0,0,1)%a);
    u=Normalize(w%a);
    v=(-dist*0.33333*a)+ mole.asymm.at(i).pos+dist*0.942809041582*(sin(wink)*u+cos(wink)*w);
    V3 increm = V3(0.0, 0.0, 0.0);
    if ( z == i ) {
      increm = V3(0.00001, 0.00001, 0.00001);
    }
    wink=mole.dieder(mole.showatoms.at(mole.knoepfe.at(i).neighbors.at(0)).pos+increm-mole.asymm.at(z).pos,
        mole.asymm.at(i).pos-mole.showatoms.at(mole.knoepfe.at(i).neighbors.at(0)).pos,
        v-mole.asymm.at(i).pos)/180.0*M_PI;
  }
  v=(-dist*0.33333*a)+ mole.asymm.at(i).pos+dist*0.942809041582*(sin(wink)*u+cos(wink)*w);
  htest.Label=mole.asymm.at(i).Label.section('_',0,0);
  htest.part=mole.asymm.at(i).part;
  htest.resiNr=mole.asymm.at(i).resiNr;
  htest.Label.replace(0,1,'H');
  QString nnn=htest.Label;
  QString ann=nnn;
  int hindex=1;
  //HA
  do {
      if (hindex) nnn=ann.left(3).append(QString::number(hindex+9,36));
      if (nnn.size()>4) nnn=ann.left(2).append(QString::number(hindex+9,36));
      if (htest.resiNr)
        nn=QString("%1_%2")//for shelxl same names in different parts are no problem but for platon so this should fix it.
          .arg(nnn)
          .arg((htest.resiNr)?QString::number(htest.resiNr):"");
      else nn=nnn;
      hindex++;
  }while(alab.contains(nn,Qt::CaseInsensitive));
  htest.Label=nnn;
  htest.isIso=true;
  htest.ufiso_org=QString("-1.5");
  double uIso = mole.ueq(mole.asymm.at(i).uf)*1.5;
  htest.uf.m11 = htest.uf.m22 = htest.uf.m33 = uIso;
  htest.uf.m23 = uIso * mole.cell.cosra; 
  htest.uf.m13 = uIso * mole.cell.cosrb; 
  htest.uf.m12 = uIso * mole.cell.cosrg; 
  mole.Uf2Uo(htest.uf,htest.uc);
  htest.pos=v;
  mole.kart2frac(htest.pos,htest.frac);	
  htest.orginalLine=QString("%1  %2  %3 %4 %5 %6 %7")
    .arg(htest.Label)
    .arg(qMax(1,editor->sfac.indexOf(0)+1))
    .arg(htest.frac.x,9,'f',5)
    .arg(htest.frac.y,9,'f',5)
    .arg(htest.frac.z,9,'f',5)
    .arg(mole.asymm.at(i).sof_org)
    .arg("-1.5");
  mole.asymm.append(htest);
  wink+=2.09439510239;
  if (andersrum) wink+=2.09439510239;
  v=(-dist*0.33333*a)+ mole.asymm.at(i).pos+dist*0.942809041582*(sin(wink)*u+cos(wink)*w);
  //HB
  do {
      if (hindex) nnn=ann.left(3).append(QString::number(hindex+9,36));
      if (nnn.size()>4) nnn=ann.left(2).append(QString::number(hindex+9,36));
      if (htest.resiNr)
        nn=QString("%1_%2")//for shelxl same names in different parts are no problem but for platon so this should fix it.
          .arg(nnn)
          .arg((htest.resiNr)?QString::number(htest.resiNr):"");
      else nn=nnn;
      hindex++;
  }while(alab.contains(nn,Qt::CaseInsensitive));
  htest.Label=nnn;
  htest.pos=v;
  mole.kart2frac(htest.pos,htest.frac);	
  htest.orginalLine=QString("%1  %2  %3 %4 %5 %6 %7")
    .arg(htest.Label)
    .arg(qMax(1,editor->sfac.indexOf(0)+1))
    .arg(htest.frac.x,9,'f',5)
    .arg(htest.frac.y,9,'f',5)
    .arg(htest.frac.z,9,'f',5)
    .arg(mole.asymm.at(i).sof_org)
    .arg("-1.5");
  mole.asymm.append(htest);
  QString label = mole.showatoms.at(i).orginalLine.left(80).trimmed();
  cursor.movePosition(QTextCursor::Start);
  cursor = document->find(label,cursor);
  if (cursor.isNull()){
    cursor = editor->textCursor();
    cursor.movePosition(QTextCursor::Start);
    label.chop(10);
    cursor = document->find(label,cursor);
    if (cursor.isNull()) {
      cursor = editor->textCursor();
    }
  }
  cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
  cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
  while (cursor.selectedText().endsWith("=")) {
    cursor.movePosition(QTextCursor::Down,QTextCursor::KeepAnchor);
    cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
  }
  cursor.clearSelection();
  cursor.movePosition(QTextCursor::Down);
  cursor.insertText(QString("REM R-NH2 (non planar) FIX \n%1\n%2\n")
      .arg(mole.asymm.at(mole.asymm.size()-2).orginalLine)
      .arg(mole.asymm.at(mole.asymm.size()-1).orginalLine)
      );
  //now comes some DFIX/DANG/SADI stuff
  //
  cursor.movePosition(QTextCursor::Start,QTextCursor::MoveAnchor);
  cursor = document->find(QRegExp("^UNIT",Qt::CaseInsensitive),cursor);
  cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
  cursor.movePosition(QTextCursor::Down,QTextCursor::MoveAnchor);
  //printf("Resinr %d %d\n",mole.asymm.at(i).resiNr,(mole.asymm.at(i).resiNr!=0) );
  QString rns="";
  if (mole.asymm.at(i).resiNr!=0) rns=QString("_%1").arg(mole.asymm.at(i).resiNr);
  QString buffer = QString("DFIX%1 %2 %3 %4\n")
    .arg(rns)
    .arg(dist,0,'f',2)
    .arg(mole.asymm.at(i).Label.section('_',0,0))
    .arg(mole.asymm.at(mole.asymm.size()-2).Label);
  cursor.insertText(buffer);
  buffer = QString("DFIX%1 %2 %3 %4\n")
    .arg(rns)
    .arg(dist,0,'f',2)
    .arg(mole.asymm.at(i).Label.section('_',0,0))
    .arg(mole.asymm.at(mole.asymm.size()-1).Label);
  cursor.insertText(buffer);
  buffer = QString("DANG%1 %2 %3 %4! 1,3 dist H..H\n")
    .arg(rns)
    .arg(1.5)
    .arg(mole.asymm.at(mole.asymm.size()-2).Label)
    .arg(mole.asymm.at(mole.asymm.size()-1).Label);
  cursor.insertText(buffer);
  int nnb=mole.knoepfe.at(i).neighbors.at(0);
  rns="";
  if (mole.asymm.at(nnb).resiNr!=0) rns=QString("_%1").arg(mole.asymm.at(nnb).resiNr);

  buffer = QString("SADI%1 %2 %3 %4 %5\n")
    .arg(rns)
    .arg(mole.asymm.at(nnb).Label.section('_',0,0))
    .arg(mole.asymm.at(mole.asymm.size()-2).Label)
    .arg(mole.asymm.at(nnb).Label.section('_',0,0))
    .arg(mole.asymm.at(mole.asymm.size()-1).Label);

  buffer = QString("DANG%1 %2 %3 %4 %3 %5!\n")
    .arg(rns)
    .arg(2.0)
    .arg(mole.asymm.at(nnb).Label.section('_',0,0))
    .arg(mole.asymm.at(mole.asymm.size()-2).Label)
    .arg(mole.asymm.at(mole.asymm.size()-1).Label);

  cursor.insertText(buffer);

  //
  cursor.endEditBlock();
  int jetztAtome=0;
  for (int i=0; i<mole.asymm.size();i++) if (mole.asymm.at(i).an>=0)jetztAtome++;
  actionHFix->setDisabled(true);
  fuse();
  QString info=QString("<font color=\"green\"><b>%1</b> Hydrogen atoms added. <b>Please SAVE before GROW!</font>").arg(jetztAtome-warmalAtome);
  infoKanalNews(info); 
}

bool peakcomp(MyAtom &a1,MyAtom &a2){
  return (a1.peakHeight>a2.peakHeight);
}

void Window::addMoreQPeaks(){
  if (mole.asymm.isEmpty()) return;
  if (fxle->n5==0) return;

  for (int i=mole.asymm.size()-1; i>=0; i--){
    if (mole.asymm.at(i).an<0) mole.asymm.removeAt(i); 
  }
  MyAtom htest;
  htest.an=-1;
  htest.part=0;
  htest.resiNr=0;
  htest.hidden=0;
  htest.frac=V3(0,0,0);
  htest.pos=V3(0,0,0);
  htest.resiNr=0;
  htest.part=0;
  htest.style=1;
  htest.symmGroup=0;
  htest.sg=0;
  htest.scod=555;//the identity
  htest.auidx=-1;
  htest.uc.m12=htest.uc.m23=htest.uc.m13=0.0;
  htest.uc.m21=htest.uc.m32=htest.uc.m31=0.0;
  htest.uf.m12=htest.uf.m23=htest.uf.m13=0.0;
  htest.uf.m21=htest.uf.m32=htest.uf.m31=0.0;
  htest.uf.m11=0.05;
  htest.isIso=true;
  htest.uc.m11=htest.uc.m22=htest.uc.m33=htest.uf.m11;
  float x,y,z,u,v,w,p,q,r,t;
  int ipeak=0;
  mole.pmin=10000;
  mole.pmax=-10000;
  QList<MyAtom> peaks;
  for (int k=0;k<fxle->n3;k++){
    for (int j=0;j<fxle->n2;j++){
      for (int i=0;i<fxle->n1;i++){
          if (ipeak>MaxNumberOfPeaks) continue;
        t = fxle->datfo_fc[i+ fxle->n1*(j+k*fxle->n2)];
        x = t -  fxle->datfo_fc[((i+1)%fxle->n1) + fxle->n1*(j+k*fxle->n2)];
        y = t -  fxle->datfo_fc[i+ fxle->n1*(((j+1)%fxle->n2)+k*fxle->n2)];
        z = t -  fxle->datfo_fc[i+ fxle->n1*(j+((k+1)%fxle->n3)*fxle->n2)];
        u = t -  fxle->datfo_fc[((i+fxle->n1-1)%fxle->n1)+ fxle->n1*(j+k*fxle->n2)];
        v = t -  fxle->datfo_fc[i+ fxle->n1*(((j+fxle->n2-1)%fxle->n2)+k*fxle->n2)];
        w = t -  fxle->datfo_fc[i+ fxle->n1*(j+((k+fxle->n2-1)%fxle->n3)*fxle->n2)];
        if (fmin(x,fmin(y,fmin(z,fmin(u,fmin(v,w)))))<0) continue;
        p=0.5*(u-x)/(u+x);
        q=0.5*(v-y)/(v+y);
        r=0.5*(w-z)/(w+z);
        t=t+0.25*(p*(u-x)+q*(v-y)+r*(w-z));
        if (t<fabs(fxle->iso[1])*1.02) continue;
        htest.peakHeight=t;  
        htest.frac.x = ((double) i + p +0.5)/fxle->n1; 
        htest.frac.y = ((double) j + q +0.5)/fxle->n2;
        htest.frac.z = ((double) k + r +0.5)/fxle->n3;
        mole.frac2kart( htest.frac, htest.pos);
        if (!std_isfinite(htest.frac.x)||!std_isfinite(htest.frac.y)||!std_isfinite(htest.frac.z))continue;
        ipeak++;
        mole.pmin=qMin(mole.pmin, htest.peakHeight);
        mole.pmax=qMax(mole.pmax, htest.peakHeight);
        qpv->cutoff=0;//mole.pmin;
        qpv->setMin(mole.pmin);
        qpv->setMax(mole.pmax);
        htest.Label=QString("Q%1").arg(ipeak,3,36,QChar('0'));
        peaks.append(htest); 
      }
    }
  }
  if (chgl->neutrons){
      for (int k=0;k<fxle->n3;k++){
        for (int j=0;j<fxle->n2;j++){
          for (int i=0;i<fxle->n1;i++){
              if (ipeak>MaxNumberOfPeaks) continue;
            t = fxle->datfo_fc[i+ fxle->n1*(j+k*fxle->n2)];
            x = t -  fxle->datfo_fc[((i+1)%fxle->n1) + fxle->n1*(j+k*fxle->n2)];
            y = t -  fxle->datfo_fc[i+ fxle->n1*(((j+1)%fxle->n2)+k*fxle->n2)];
            z = t -  fxle->datfo_fc[i+ fxle->n1*(j+((k+1)%fxle->n3)*fxle->n2)];
            u = t -  fxle->datfo_fc[((i+fxle->n1-1)%fxle->n1)+ fxle->n1*(j+k*fxle->n2)];
            v = t -  fxle->datfo_fc[i+ fxle->n1*(((j+fxle->n2-1)%fxle->n2)+k*fxle->n2)];
            w = t -  fxle->datfo_fc[i+ fxle->n1*(j+((k+fxle->n2-1)%fxle->n3)*fxle->n2)];
            if (fmax(x,fmax(y,fmax(z,fmax(u,fmax(v,w)))))>0) continue;
            p=0.5*(u-x)/(u+x);
            q=0.5*(v-y)/(v+y);
            r=0.5*(w-z)/(w+z);
            t=t+0.25*(p*(u-x)+q*(v-y)+r*(w-z));
            if (t>-fabs(fxle->iso[1])*1.02) continue;
            htest.peakHeight=t;
            htest.frac.x = ((double) i + p +0.5)/fxle->n1;
            htest.frac.y = ((double) j + q +0.5)/fxle->n2;
            htest.frac.z = ((double) k + r +0.5)/fxle->n3;
            mole.frac2kart( htest.frac, htest.pos);
            if (!std_isfinite(htest.frac.x)||!std_isfinite(htest.frac.y)||!std_isfinite(htest.frac.z))continue;
            ipeak++;
            mole.pmin=qMin(mole.pmin, htest.peakHeight);
            mole.pmax=qMax(mole.pmax, htest.peakHeight);
            qpv->cutoff=0;//mole.pmin;
            qpv->setMin(mole.pmin);
            qpv->setMax(mole.pmax);
            htest.Label=QString("Q%1").arg(ipeak,3,36,QChar('0'));
            peaks.append(htest);
          }
        }
      }
  }

#if (QT_VERSION >= 0x050000)
  std::sort(peaks.begin(),peaks.end(),peakcomp );
#else
  qSort(peaks.begin(),peaks.end(),peakcomp );
#endif
  mole.asymm+=peaks;  
  mole.sdmcompleter();
  QList<MyAtom> duplicate;
  for (int i=0; i<mole.asymm.size(); i++){
    for (int j=i+1; j<mole.asymm.size(); j++){
      if ((mole.asymm.at(i).an>-1)||(mole.asymm.at(j).an>-1)) continue;
      if (Distance(mole.asymm.at(i).pos,mole.asymm.at(j).pos)<0.1) duplicate.append(mole.asymm.at(j));
    }
  }
  //printf("Duplicate size %d\n",duplicate.size());
  for (int i=0; i<duplicate.size();i++) {
    int rr=mole.asymm.indexOf(duplicate.at(i));
    if (rr<0) continue;
    mole.asymm.removeAt(rr);
  }
  QTextCursor cursor = editor->textCursor();
  cursor.beginEditBlock();
  editor->replace->setText("");
  editor->searchLE->setText("^Q\\S+\\s+1\\s+\\S+\\s+\\S+\\s+\\S+\\s+\\S+\\s+\\S+\\s+\\S+\\s*");
  editor->replaceAll();
  editor->searchLE->setText("");
  cursor.movePosition(QTextCursor::End);
  cursor.movePosition(QTextCursor::StartOfLine);
  ipeak=1;
  for (int i=0; i<mole.asymm.size(); i++){
    if (mole.asymm.at(i).an>-1) continue;
    mole.asymm[i].Label=QString("Q%1").arg(ipeak,3,36,QChar('0')).toUpper();
    ipeak++;
    mole.asymm[i].orginalLine=
      QString("%1 1 %2 %3 %4 %5 0.05 %6")
      .arg(mole.asymm.at(i).Label,-4)
      .arg(mole.asymm.at(i).frac.x,10,'f',6)
      .arg(mole.asymm.at(i).frac.y,10,'f',6)
      .arg(mole.asymm.at(i).frac.z,10,'f',6)
      .arg(mole.asymm[i].sof_org=(10+(1.0/mole.asymm.at(i).style)),9,'f',5)
      .arg(mole.asymm.at(i).peakHeight,9,'f',3)
      ;
    mole.asymm[i].sof=mole.asymm[i].sof_org-10;

    cursor.insertText(mole.asymm[i].orginalLine);
    cursor.insertText("\n");

  }
  cursor.endEditBlock();

  mole.showatoms.clear();
  for (int i=0; i<mole.asymm.size(); i++){
    mole.showatoms.append(mole.asymm.at(i));
  }
  ////
  bool growYes=chgl->fuse->isVisible ();
  bool fuseYes=chgl->grow->isVisible ();
  chgl->fuse->setVisible(true);
  chgl->grow->setVisible(false);
  mole.sdmcompleter();
  mole.showbonds = mole.connecting(mole.showatoms);

  chgl->mol->fuse();
  if (((!fuseYes)&&(growYes))||((!fuseYes)&&(!growYes))) chgl->mol->grow();
  else {
    chgl->fuse->setVisible(false);
    chgl->grow->setVisible(true);
  }
  infoKanalNews(mole.HumanSymmetry);
  chgl->murx=__LINE__;
  chgl->updateGL();
}

void Window::setShelxlPath(){
  QString s =
    QFileDialog::getOpenFileName(this, "Path to SHELXL executable", shelxlPath,QString(),nullptr,(useNativeDlg->isChecked())?noneopt:QFileDialog::DontUseNativeDialog);
  if (!s.isEmpty()){
    shelxlPath=s;
    mole.einstellung->beginGroup("Window");
    mole.einstellung->setValue("SHELXL-PATH",shelxlPath);
    mole.einstellung->endGroup();
    if (shxPath!=NULL) shxPath->setText(shelxlPath);
  }
}


void Window::setFFMPEGEXE(){
  mole.ffmpegexe= QFileDialog::getOpenFileName(this,"path to ffmpeg.exe","ffmpeg.exe","",nullptr,(useNativeDlg->isChecked())?noneopt:QFileDialog::DontUseNativeDialog);
  if (ffmpegedt!=NULL) ffmpegedt->setText(mole.ffmpegexe);
  mole.einstellung->beginGroup("Window");
  mole.einstellung->setValue("FFMPEG.EXE",mole.ffmpegexe);
  mole.einstellung->endGroup();

}

void Window::setMP4(){
  QString pth=dirName;
  pth.remove(QRegExp(".res$|.ins$",Qt::CaseInsensitive));
  QString s = QFileDialog::getSaveFileName(this,
      "save mp4 file",
      QString("%1.mp4").arg(pth),
      "Movie file (*.mp4)",nullptr,(useNativeDlg->isChecked())?noneopt:QFileDialog::DontUseNativeDialog);
  if (mp4file!=NULL) mp4file->setText(s);
}

void Window::updateOutput(){
  if (runffmpeg->pid()) {
    brs->show();
    QString s=brs->toPlainText();
    s.append(runffmpeg->readAllStandardOutput());
    s.append(runffmpeg->readAllStandardError());
    brs->setPlainText(s);
  }else{
    brs->show();
    QString s=brs->toPlainText();
    s.append(runffmpeg->readAllStandardOutput());
    s.append(runffmpeg->readAllStandardError());
    brs->setPlainText(s);
    QDir d=QDir::current();

    QStringList clips;
    clips.append("molisoclip*");
    clips  = d.entryList(clips);
    for (int i=0; i<clips.size();i++) QFile::remove(clips.at(i));
    QFile::remove("mcqwatermark.png");
    qint64 size = 0;
    QFile myFile(fffn);
    if (myFile.open(QIODevice::ReadOnly)){
      size = myFile.size();  //when file does open.
      myFile.close();
    }
    int kMGT=0;
    double siz=(double)size;
    while (siz>1024){
      siz/=1024;
      kMGT++;
    }
    QString byte="B";
    switch (kMGT){
      case 1: byte.prepend("k"); break;
      case 2: byte.prepend("M"); break;
      case 3: byte.prepend("G"); break;
      case 4: byte.prepend("T"); break;
    }
    QString fss=QString("%1 %2").arg(siz, 0, 'f', 2).arg(byte);

    ffl->setText(QString("finished! %1 has %2").arg(fffn).arg(fss));
    bar->hide();
    closeFF->show();
  }
}

void Window::makeRotMovi(){
  QDialog *tdlg = new QDialog(this);
  QGridLayout *l = new QGridLayout(tdlg);
  QDialogButtonBox *buttonBox = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
  connect(buttonBox, SIGNAL(accepted()), tdlg, SLOT(accept()));
  connect(buttonBox, SIGNAL(rejected()), tdlg, SLOT(reject()));
  ffmpegedt = new QLineEdit(mole.ffmpegexe);
  QPushButton *ffbrs = new QPushButton("Browse");
  connect(ffbrs,SIGNAL(pressed()),this,SLOT(setFFMPEGEXE()));
  QLabel *ffmpegtxt =new QLabel("Path to ffmpeg.exe <br>(You need ffmpeg.exe. You can get it from here <a href=\"https://ffmpeg.org/download.html\">https://ffmpeg.org/download.html</a> )");
  ffmpegtxt->setOpenExternalLinks(true);
  /* QRadioButton *hd720 = new QRadioButton("1280x720",tdlg);
     QRadioButton *hd1080 = new QRadioButton("1920x1080",tdlg);
     hd1080->setChecked(true);*/
  mp4file = new QLineEdit(QString("%1.mp4").arg(dirName));
  QPushButton *mp4brs = new QPushButton("Browse");
  connect(mp4brs,SIGNAL(pressed()),this,SLOT(setMP4()));
  QSpinBox *dura= new QSpinBox(tdlg);
  dura->setMinimum(5);
  dura->setMaximum(300);
  dura->setValue(10);
  dura->setSuffix("s");
  QSpinBox *fps= new QSpinBox(tdlg);
  fps->setMinimum(12);
  fps->setMaximum(60);
  fps->setValue(30);

  l->addWidget(ffmpegtxt,0,0,1,20);
  l->addWidget(ffmpegedt,1,0,1,18);
  l->addWidget(ffbrs,1,19,1,1);
  //l->addWidget(hd720,2,0,1,5);
  // l->addWidget(hd1080,2,6,1,5);
  l->addWidget(new QLabel("Duration"),3,0,1,1);
  l->addWidget(dura,3,1,1,1);
  l->addWidget(new QLabel("Frames per second (FPS)"),4,0,1,1);
  l->addWidget(fps,4,1,1,1);
  l->addWidget(new QLabel("mp4 file name"),5,0,1,1);
  l->addWidget(mp4file,5,1,1,18);
  l->addWidget(mp4brs,5,19,1,1);

  l->addWidget(buttonBox,20,0,1,20);
  if(tdlg->exec()==QDialog::Accepted) {
    if (mole.ffmpegexe.isEmpty()||mp4file->text().isEmpty()) return;
    QString fileName=mp4file->text();
    if (QFile::exists(fileName)) {
      QString n=fileName;
      QString re=QString("_%1_.mp4").arg(QDateTime::currentMSecsSinceEpoch (),0,36);
      n.replace(QRegExp(".mp4$"),re);
      QFile::rename(fileName,n);
    }
    int d,e,f;
    // bool hd=(hd720->isChecked()) ;
    int frameRate=fps->value();
    int frames = dura->value()*frameRate;
    d = chgl->width();
    e = chgl->height();
    //printf("%dx%d\n",d,e);
    //printf("!ungerade->%d %d\n",(d%2),d);
    if (d%2){
      chgl->setMinimumWidth(d+1);
      update();
      chgl->updateGL();
    }
    int wi = 0;
    int hi = 0;
    d = chgl->width();
    e = chgl->height();
    wi=d;
    hi=e;
    printf("%dx%d\n",d,e);
    //chgl->resize(wi,hi);
    f = chgl->myFont.pointSize ();
    //  h = chgl->MLegendFont.pointSize ();
    printf("%p\n",chgl);
    QDialog *q =new QDialog(this);
    q->setWindowTitle("Wait! Movie file creation in progress");
    bar = new QProgressBar(q);
    bar->setMinimum(0);
    bar->setMaximum(frames);
    QGridLayout *g= new QGridLayout(q);
    g->addWidget(bar,0,0);
    ffl=new QLabel(QString("Please wait until movie is created!! %1 frames will be created and joined to a mp4 movie file.").arg(frames));
    g->addWidget(ffl,1,0);
    brs=new QTextBrowser(q);
    QTextCharFormat fmt;
    brs->setFontFamily(FONTFAM);
    QPalette p = brs->palette();
    p.setBrush(QPalette::Active,QPalette::Base,QColor("#242424"));
    brs->setPalette (p );
    fmt.setFontFamily(FONTFAM);
    fmt.setBackground(QColor("#242424"));
    fmt.setForeground(QColor("#DDDD00"));
    fmt.setFontWeight(50);
    brs->setCurrentCharFormat(fmt);
    brs->setWordWrapMode(QTextOption::WordWrap);
    brs->setPlainText("====================\n Output of ffmpeg: \n====================\n\n");

    brs->hide();
    g->addWidget(brs,2,0);
    closeFF = new QPushButton("close", q);
    g->addWidget(closeFF,3,0);
    connect(closeFF,SIGNAL(released()),q,SLOT(close()));
    closeFF->hide();

    q->show();
    //double stepssi= 1.0/frames;
    //QPixmap   map;
    //printf("stepsize=%f frames %d\n",stepssi,frames);
    glReadBuffer(GL_FRONT);
    for (int i=0; i<frames; i++){
      ffl->setText(QString("Please wait until movie is created!! %1 of %2").arg(i).arg(frames));
      bar->setValue(i);
      char fname[255] ;
      //  statusBar()->showMessage(tr("create pic #%1 of %2").arg(i+1).arg(frames) );
      sprintf(fname, "molisoclip%04d.png", i);
      //chgl->noWaitLabel=true;
      //chgl->paparazi=true;
      //glGetDoublev(GL_MODELVIEW_MATRIX,chgl->MM);
      /*
         map = chgl->renderPixmap(wi,hi);
      //chgl->paparazi=false;
      map.save(fname);*/
      QImage mapi=chgl->grabFrameBuffer(false);
      int h = mapi.height();
      int w = mapi.width();
      mapi = mapi.scaled((w/2)*2,(h/2)*2);
      mapi.save(fname);
      chgl->rotY(18.0/(frames-1));
      //chgl->rotX(54.0/frames);
      //glRotated(360.0/frames,0.0,1.0,0.0);
      //glRotated(360/M_PI/frames,1.0,0.0,0.0);
      chgl->updateGL();
      //printf("%d/%d\n",i,frames);
      q->update();
      q->repaint();
    }
    if (!fileName.isEmpty()) {
      QPixmap watermark = (chgl->dipc.name() == QString("#008080"))?QIcon(":/xle-icons/IDEAL-text.png").pixmap(202, 76):
        QIcon(":/xle-icons/shelxle-text.png").pixmap(235, 91);
      watermark.save("mcqwatermark.png");
      int wawi=watermark.width()+3;
      int wahi=watermark.height()+3;
      QStringList al;
      al <<"-r"<< QString("%1").arg(frameRate)<< "-f"<< "image2"<< "-s"<< QString("%1x%2").arg(wi).arg(hi)//QString("%1").arg((hd)?"1280x720":"1920x1080")
        <<"-start_number"<< "0"<< "-i"<< "molisoclip%04d.png"<<
        "-i"<< "mcqwatermark.png"<< "-filter_complex"<< QString("[0:v][1:v] overlay=%1:%2").arg(wi-wawi).arg(hi-wahi)<<
        "-vframes"<< QString("%1").arg(frames)<< "-codec:v"<< "libx264" <<"-crf" <<"25"<< "-pix_fmt"<< "yuv420p"<< fileName;

      runffmpeg = new QProcess(this);
      QDir dn=QDir(QDir::current());
      runffmpeg->setWorkingDirectory(QDir::current().absolutePath());                           // updateXLput()
      connect(runffmpeg,SIGNAL(readyReadStandardOutput ()),this,SLOT(updateOutput()));
      connect(runffmpeg,SIGNAL(finished(int,QProcess::ExitStatus)),this,SLOT(updateOutput()));
      connect(runffmpeg,SIGNAL(error(QProcess::ProcessError)),this,SLOT(updateOutput()));

      runffmpeg->start(mole.ffmpegexe,al);
      fffn=fileName;
      updateOutput();

    }
    chgl->myFont.setPointSize(f);
    //chgl->MLegendFont.setPointSize(h);
    //chgl->_win_width=d;
    //chgl->_win_height=e;
    //chgl->noWaitLabel=chgl->quickRot->isChecked();
    //q->close();
    // filmFred = new TMovieThread(frames,wi,hi,d,e,f,h,chgl,fileName,hd720->isChecked());
    //connect(filmFred,SIGNAL(finished ()),q,SLOT(close()));
    // filmFred->start();
  }
}

void Window::savePovRay(){
  QString s1="",s2="",s3="";
  GLdouble  mv[16];
  glGetDoublev(GL_MODELVIEW_MATRIX, mv);

  QString povName = dirName, iniName,incName;
  povName.replace(QRegExp("(.ins)|(.res)",Qt::CaseInsensitive),".pov");
  QString fn=QFileDialog::getSaveFileName(this, tr("Export POV-Ray scene"), povName, tr("POV-Ray files (*.pov)"));
  if (fn.isEmpty()) return;
  savePovInc(fn);
  povName=fn;
  iniName=fn;
  iniName.replace(QRegExp("(.pov)",Qt::CaseInsensitive),".ini");
  incName=fn;
  incName.replace(QRegExp("(.pov)",Qt::CaseInsensitive),".inc");
  pngName=fn;
  pngName.replace(QRegExp("(.pov)",Qt::CaseInsensitive),".png");
  QFile f(fn);
  QString headerPOV;     // 1st part of PoV-Ray file
  QString visableAtoms;  // used to save ellipsoids of _un-selected_ atoms in _visable_ part of pov-file
  QString hiddenAtoms;   // used to save ellipsoids of _selected_ atoms in _hidden_ part of pov-file
  QString hydrogenAtoms; // used to save hydrogens data
  QString hiddenHAtoms;  // used to save hydrogens data of _selected_ atoms in _hidden_ part of pov-file
  QString qpeaks;        //Q peaks...
  QString unitCell;
  QString densityMaps;   //Fo and Fo-Fc map or the IDEAL BODD map.
  QString labels;
  QString bondsPOV;      // used for bonds in povray
  QString hidePOV;
  QString ringsPOV;
  QString voron;
  QString footerPOV;
  QString body;
  bool foundInSelected = false;
  GLdouble det=pow(mv[0]*mv[5]*mv[10] - mv[8]*mv[5]*mv[2] +  mv[1]*mv[6]*mv[8] - mv[9]*mv[6]*mv[0] + mv[2]*mv[4]*mv[9] - mv[10]*mv[4]*mv[1], 1.0/3.0);
  mv[0]/=det;  mv[1]/=det;  mv[2]/=det;  mv[4]/=det;  mv[5]/=det;  mv[6]/=det;  mv[8]/=det;  mv[9]/=det;  mv[10]/=det;
  Matrix rm = Matrix(mv[0], mv[1], mv[2], mv[4], mv[5], mv[6], mv[8], mv[9], mv[10]);
  Matrix irm = inverse(rm);
  // POV-Ray Header
  headerPOV.append(QString("/*\n    POV-Ray - 3.7  Scene Description File \n"));
  headerPOV.append(QString("Experimental POV-ray shelXLe-exporter by K.Radacki and C.B.Hubschle\n"));
  headerPOV.append(QString("This file is generated from: \n"));
  headerPOV.append(QString("%1 \n*/\n\n").arg(dirName));
  headerPOV.append(QString("#version 3.7;\n"));
  headerPOV.append(QString("global_settings{charset utf8}\n"));
  headerPOV.append(QString("#include \"transforms.inc\"\n"));
  headerPOV.append(QString("#include \"colors.inc\"\n"));
  headerPOV.append(QString("#include \"textures.inc\"\n"));
  //headerPOV.append(QString("#include \"metals.inc\"\n"));
  headerPOV.append(QString("#include \"shapes.inc\"\n"));
  headerPOV.append(QString("#include \"shapes2.inc\"\n"));
  headerPOV.append(QString("global_settings { assumed_gamma 1.2 ambient_light rgb < 1, 1, 1 > }\n"));

  headerPOV.append(QString("#declare InvMat = transform {matrix \n<%1, %2, %3,\n %4, %5, %6,\n %7, %8, %9,\n 0.0, 0.0, 0.0>};\n")
      .arg(irm.m11,9,'g',6)
      .arg(irm.m12,9,'g',6)
      .arg(irm.m13,9,'g',6)
      .arg(irm.m21,9,'g',6)
      .arg(irm.m22,9,'g',6)
      .arg(irm.m23,9,'g',6)
      .arg(irm.m31,9,'g',6)
      .arg(irm.m32,9,'g',6)
      .arg(irm.m33,9,'g',6));
  headerPOV.append(QString("#declare EyeDir = vtransform(<0,0,1>,InvMat);//This is for the labels. It moves them closer to You. change it to move all label.s\n"));
  headerPOV.append(QString("#declare CameraDistance    = %1;\n").arg((-mv[14]),0,'f',3));
  headerPOV.append(QString("#declare ViewAngle         = %1;\n").arg(chgl->viewAngle,0,'f',3));
  headerPOV.append(QString("#declare SCALE             = %1/(image_width/image_height);// scale factor L=%2 dim=%3\n\n").arg(chgl->L/3.4*det*29.0/(chgl->viewAngle)).arg(chgl->L).arg(mole.dimension()));
  headerPOV.append(QString("camera { perspective\n"));
  headerPOV.append(QString("  location  < 0, 0 , CameraDistance >\n"));
  headerPOV.append(QString("  right     < -image_width/image_height, 0, 0>\n"));
  headerPOV.append(QString("  look_at   < 0, 0 , 0 >\n"));
  headerPOV.append(QString("  angle     ViewAngle\n}\n\n"));//.arg(chgl->viewAngle,7,'f',1));
  headerPOV.append(QString("#declare DrawAromaticRings = true;   // You need to place Centroids in the center of each ring for this.\n"));
  headerPOV.append(QString("#declare DrawRoundCorners  = true;\n"));
  headerPOV.append(QString("#declare BW                = false;   // true = Black&White     false = Color\n"));
  headerPOV.append(QString("#declare NoADP4Selected    = true;   // true = Visible         false = Hidden\n"));
  headerPOV.append(QString("#declare Hiso              = false;   // true = Uiso            false = r=Bond_Radius*1.3*Prob\n"));
  headerPOV.append(QString("#declare DrawHydrogens     = true;   // true = Visible         false = Hidden\n"));
  headerPOV.append(QString("/* 'Hydrogens' here are all atoms with an isotropic ADP. Atoms with anisotropic ADP are considered to be non Hydrogen atoms.*/ \n"));
  headerPOV.append(QString("#declare DrawH_Bonds       = %1;   // true = Visible         false = Hidden\n").arg(togHBond->isChecked()?"true":"false"));
  headerPOV.append(QString("#declare DrawUnitCell      = %1;   // true = Visible         false = Hidden\n").arg(togUnit->isChecked()?"true":"false"));
  headerPOV.append(QString("#declare CellWidth         = 0.02;   // line width of unit cell\n"));
  headerPOV.append(QString("#declare DrawLegend        = %1;   // true = Visible         false = Hidden\n").arg(chgl->atomLegend->isChecked()?"true":"false"));
  headerPOV.append(QString("#declare DrawQPeaks        = true;   // true = Visible         false = Hidden\n"));
  headerPOV.append(QString("#declare DrawQPeaksBonds   = %1;   // connecting lines between Q-peaks\n").arg(chgl->qPeakBonds->isChecked()?"true":"false"));
  headerPOV.append(QString("#declare BGGradient        = %1;   // Background Gradient as in ShelXle!\n\n").arg(togBackGr->isChecked()?"true":"false"));
  headerPOV.append(QString("#declare QPeakRad          = %1;   // icosahedron size\n").arg(chgl->mol->qPeakRad * 2.0));
  headerPOV.append(QString("#declare DrawMaps          = %1;\n").arg((!chgl->fVertexes[0].isEmpty()||!chgl->fVertexes[1].isEmpty())?"true":"false"));
  headerPOV.append(QString("#declare DrawFo_Fc         = %1;\n").arg(chgl->fofcact->isChecked()?"true":"false"));
  headerPOV.append(QString("#declare DrawFobserved     = %1;\n").arg(chgl->foact->isChecked()?"true":"false"));
  headerPOV.append(QString("#declare DrawWireframeMaps = %1;\n").arg((!chgl->fillMap->isChecked())?"true":"false"));
  headerPOV.append(QString("#declare ForceWhiteBG      = false;\n"));
  headerPOV.append(QString("#declare TransparentBG     = true ;\n"));

  headerPOV.append(QString("#declare UniColorBonds     = %1;\n").arg((mole.bondColorStyle)?"true":"false"));
  headerPOV.append(QString("#declare NoShadows         = true;\n"));
  headerPOV.append(QString("#declare DrawLabels        = %1;\n").arg((togLabel->isChecked())?"true":"false"));

#if defined Q_WS_WIN || defined Q_OS_WIN
  headerPOV.append(QString("#declare atomfont = \"C:/Windows/Fonts/Arial.ttf\"//replace by any font path you like and works on your system\n"));//.arg(chgl->myFont.rawName()));
#elif defined Q_WS_MAC || defined Q_OS_MAC
  headerPOV.append(QString("#declare atomfont = \"/System/Library/Fonts/Supplemental/Arial.ttf\"//replace by any font path you like and works on your system\n"));
#else
  headerPOV.append(QString("#declare atomfont = \"/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf\"//replace by any font path you like and works on your system\n"));
#endif
  headerPOV.append(QString("//ADP probability\n"
        "//#declare Prob = 0.76;     // 10%\n"
        "//#declare Prob = 1.1932;   // 30%\n"
        "//#declare Prob = 1.3672;   // 40%\n"
        "#declare Prob = 1.5382;   // 50%\n"
        "//#declare Prob = 1.7164;   // 60%\n"
        "//#declare Prob = 1.9144;   // 70%\n"
        "//#declare Prob = 2.5;      // 90%\n"
        "\n"));
  headerPOV.append(QString("#declare CubeSize = 0.2;    // cube size for NPD-atom\n"));
  headerPOV.append(QString("#declare Origin = < 0,0,0>; // declare origin \n\n"));
  headerPOV.append(QString("#include \"%1\"//<-This contains additional declarations.\n\n").arg(incName));

  headerPOV.append(QString("#if (!TransparentBG)\n"));
  headerPOV.append(QString("#if (ForceWhiteBG)\n"));
  headerPOV.append(QString("background { color White}\n#else\n"));
  headerPOV.append(QString("#if (BW)\n    background { color rgb<  %1, %1, %1> }\n#else\n").arg(chgl->backGroundColor.valueF()));
  headerPOV.append(QString("background { color rgb<%1,%2,%3> }\n#end\n")
      .arg(chgl->backGroundColor.redF()  ,9,'f',5)
      .arg(chgl->backGroundColor.greenF(),9,'f',5)
      .arg(chgl->backGroundColor.blueF() ,9,'f',5));
  headerPOV.append(QString("//Gradient Background\n"));
  headerPOV.append(QString("#if (BGGradient)\n"));
  headerPOV.append(QString("#declare dis=CameraDistance/tan(radians(ViewAngle/2));\n"));
  headerPOV.append(QString("mesh {\n"));
  headerPOV.append(QString("triangle{ <-image_width,-image_height,-dis>,< image_width,-image_height,-dis>,<-image_width, image_height,-dis> uv_vectors <0,0>, <0,0>, <0,1>}\n"));
  headerPOV.append(QString("triangle{<-image_width, image_height,-dis>,< image_width, image_height,-dis>,< image_width,-image_height,-dis> uv_vectors <0,1>, <0,1>, <0,0>}\n"));
  headerPOV.append(QString("texture {uv_mapping   pigment {gradient <0,1,0>color_map {[0.0 color rgbt <1.0, 1.0, 1.0, 0.5>][1.0 color rgbt <0.3, 0.3, 0.3, 0.3>]}}finish { ambient 0.5 }}}\n"));
  headerPOV.append(QString("#end\n"));
  headerPOV.append(QString("#end //force white bg\n"));
  headerPOV.append(QString("#end //not transparent bg\n"));
  headerPOV.append(QString("light_source { <  -100.0 ,     100.0 , 100.0 >  color rgb<1.0,1.0,1.0> parallel}\n"
        "//================================================================================================================================================\n"));
  headerPOV.append(QString("#if (DrawLegend)\n"));
  headerPOV.append(QString("#declare ww=tan(radians(ViewAngle/2))*CameraDistance;\n"));
  headerPOV.append(QString("#declare hh=ww/image_width*image_height;\n"));
  //headerPOV.append(QString("#debug \"HALLOHALLO\\n\"\n"));
  //headerPOV.append(QString("#debug concat(\"Value is:\",str(ww,0,6),\"\\n\")\n"));
  densityMaps.append(QString("\n//Density Maps \n#if (DrawMaps)\n#if (DrawFo_Fc)\n"));
  if (!chgl->fVertexes[0].isEmpty()){
    densityMaps.append(QString("#if (DrawWireframeMaps)\n"));

    densityMaps.append(QString("union{\n"));
    for (int i=0; i<chgl->fVertexes[0].size();i+=9){
      if (Distance(
            V3( chgl->fVertexes[0].at(i+0), chgl->fVertexes[0].at(i+1), chgl->fVertexes[0].at(i+2)),
            V3( chgl->fVertexes[0].at(i+3), chgl->fVertexes[0].at(i+4), chgl->fVertexes[0].at(i+5) 
              ))>0.0001)
        densityMaps.append(QString("cylinder{<%1,%2,%3>,<%4,%5,%6>,%7 texture{diffPosCol}}\n")
            .arg(chgl->fVertexes[0].at(i+0)-chgl->altemitte.x,10,'g',6)
            .arg(chgl->fVertexes[0].at(i+1)-chgl->altemitte.y,10,'g',6)
            .arg(chgl->fVertexes[0].at(i+2)-chgl->altemitte.z,10,'g',6)
            .arg(chgl->fVertexes[0].at(i+3)-chgl->altemitte.x,10,'g',6)
            .arg(chgl->fVertexes[0].at(i+4)-chgl->altemitte.y,10,'g',6)
            .arg(chgl->fVertexes[0].at(i+5)-chgl->altemitte.z,10,'g',6)
            .arg(chgl->linwidth*0.01));
      if (Distance(
            V3( chgl->fVertexes[0].at(i+3), chgl->fVertexes[0].at(i+4), chgl->fVertexes[0].at(i+5)),
            V3( chgl->fVertexes[0].at(i+6), chgl->fVertexes[0].at(i+7), chgl->fVertexes[0].at(i+8) 
              ))>0.0001)
        densityMaps.append(QString("cylinder{<%1,%2,%3>,<%4,%5,%6>,%7 texture{diffPosCol}}\n")
            .arg(chgl->fVertexes[0].at(i+3)-chgl->altemitte.x,10,'g',6)
            .arg(chgl->fVertexes[0].at(i+4)-chgl->altemitte.y,10,'g',6)
            .arg(chgl->fVertexes[0].at(i+5)-chgl->altemitte.z,10,'g',6)
            .arg(chgl->fVertexes[0].at(i+6)-chgl->altemitte.x,10,'g',6)
            .arg(chgl->fVertexes[0].at(i+7)-chgl->altemitte.y,10,'g',6)
            .arg(chgl->fVertexes[0].at(i+8)-chgl->altemitte.z,10,'g',6)
            .arg(chgl->linwidth*0.01));
      if (Distance(
            V3( chgl->fVertexes[0].at(i+6), chgl->fVertexes[0].at(i+7), chgl->fVertexes[0].at(i+8)),
            V3( chgl->fVertexes[0].at(i+0), chgl->fVertexes[0].at(i+1), chgl->fVertexes[0].at(i+2) 
              ))>0.0001)
        densityMaps.append(QString("cylinder{<%1,%2,%3>,<%4,%5,%6>,%7 texture{diffPosCol}}\n")
            .arg(chgl->fVertexes[0].at(i+6)-chgl->altemitte.x,10,'g',6)
            .arg(chgl->fVertexes[0].at(i+7)-chgl->altemitte.y,10,'g',6)
            .arg(chgl->fVertexes[0].at(i+8)-chgl->altemitte.z,10,'g',6)
            .arg(chgl->fVertexes[0].at(i+0)-chgl->altemitte.x,10,'g',6)
            .arg(chgl->fVertexes[0].at(i+1)-chgl->altemitte.y,10,'g',6)
            .arg(chgl->fVertexes[0].at(i+2)-chgl->altemitte.z,10,'g',6)
            .arg(chgl->linwidth*0.01));
    }
    densityMaps.append(QString("}"));
    densityMaps.append(QString("#else\n"));
    densityMaps.append(QString("mesh {\n"));
    for (int i=0; i<chgl->fVertexes[0].size();i+=9){
      densityMaps.append(QString("smooth_triangle{\n<%1,%2,%3>,<%10,%11,%12>,\n<%4,%5,%6>,<%13,%14,%15>,\n<%7,%8,%9>,<%16,%17,%19>\n}\n")
          .arg(chgl->fVertexes[0].at(i+0)-chgl->altemitte.x,10,'g',6)
          .arg(chgl->fVertexes[0].at(i+1)-chgl->altemitte.y,10,'g',6)
          .arg(chgl->fVertexes[0].at(i+2)-chgl->altemitte.z,10,'g',6)
          .arg(chgl->fVertexes[0].at(i+3)-chgl->altemitte.x,10,'g',6)
          .arg(chgl->fVertexes[0].at(i+4)-chgl->altemitte.y,10,'g',6)
          .arg(chgl->fVertexes[0].at(i+5)-chgl->altemitte.z,10,'g',6)
          .arg(chgl->fVertexes[0].at(i+6)-chgl->altemitte.x,10,'g',6)
          .arg(chgl->fVertexes[0].at(i+7)-chgl->altemitte.y,10,'g',6)
          .arg(chgl->fVertexes[0].at(i+8)-chgl->altemitte.z,10,'g',6)
          .arg(chgl->fNormals[0].at(i+0),10,'g',6)
          .arg(chgl->fNormals[0].at(i+1),10,'g',6)
          .arg(chgl->fNormals[0].at(i+2),10,'g',6)
          .arg(chgl->fNormals[0].at(i+3),10,'g',6)
          .arg(chgl->fNormals[0].at(i+4),10,'g',6)
          .arg(chgl->fNormals[0].at(i+5),10,'g',6)
          .arg(chgl->fNormals[0].at(i+6),10,'g',6)
          .arg(chgl->fNormals[0].at(i+7),10,'g',6)
          .arg(chgl->fNormals[0].at(i+8),10,'g',6)
          );
    }
    densityMaps.append(QString("texture {diffPosCol}\n}\n"));  
    densityMaps.append(QString("#end\n"));
  }
  if (!chgl->fVertexes[1].isEmpty()){

    densityMaps.append(QString("#if (DrawWireframeMaps)\n"));

    densityMaps.append(QString("union{\n"));
    for (int i=0; i<chgl->fVertexes[1].size();i+=9){
      if (Distance(
            V3( chgl->fVertexes[1].at(i+0), chgl->fVertexes[1].at(i+1), chgl->fVertexes[1].at(i+2)),
            V3( chgl->fVertexes[1].at(i+3), chgl->fVertexes[1].at(i+4), chgl->fVertexes[1].at(i+5) 
              ))>0.0001)
        densityMaps.append(QString("cylinder{<%1,%2,%3>,<%4,%5,%6>,%7 texture{diffMinCol}}\n")
            .arg(chgl->fVertexes[1].at(i+0)-chgl->altemitte.x,10,'g',6)
            .arg(chgl->fVertexes[1].at(i+1)-chgl->altemitte.y,10,'g',6)
            .arg(chgl->fVertexes[1].at(i+2)-chgl->altemitte.z,10,'g',6)
            .arg(chgl->fVertexes[1].at(i+3)-chgl->altemitte.x,10,'g',6)
            .arg(chgl->fVertexes[1].at(i+4)-chgl->altemitte.y,10,'g',6)
            .arg(chgl->fVertexes[1].at(i+5)-chgl->altemitte.z,10,'g',6)
            .arg(chgl->linwidth*0.01)
            );
      if (Distance(
            V3( chgl->fVertexes[1].at(i+3), chgl->fVertexes[1].at(i+4), chgl->fVertexes[1].at(i+5)),
            V3( chgl->fVertexes[1].at(i+6), chgl->fVertexes[1].at(i+7), chgl->fVertexes[1].at(i+8) 
              ))>0.0001)
        densityMaps.append(QString("cylinder{<%1,%2,%3>,<%4,%5,%6>,%7 texture{diffMinCol}}\n")
            .arg(chgl->fVertexes[1].at(i+3)-chgl->altemitte.x,10,'g',6)
            .arg(chgl->fVertexes[1].at(i+4)-chgl->altemitte.y,10,'g',6)
            .arg(chgl->fVertexes[1].at(i+5)-chgl->altemitte.z,10,'g',6)
            .arg(chgl->fVertexes[1].at(i+6)-chgl->altemitte.x,10,'g',6)
            .arg(chgl->fVertexes[1].at(i+7)-chgl->altemitte.y,10,'g',6)
            .arg(chgl->fVertexes[1].at(i+8)-chgl->altemitte.z,10,'g',6)
            .arg(chgl->linwidth*0.01)
            );
      if (Distance(
            V3( chgl->fVertexes[1].at(i+6), chgl->fVertexes[1].at(i+7), chgl->fVertexes[1].at(i+8)),
            V3( chgl->fVertexes[1].at(i+0), chgl->fVertexes[1].at(i+1), chgl->fVertexes[1].at(i+2) 
              ))>0.0001)
        densityMaps.append(QString("cylinder{<%1,%2,%3>,<%4,%5,%6>,%7 texture{diffMinCol}}\n")
            .arg(chgl->fVertexes[1].at(i+6)-chgl->altemitte.x,10,'g',6)
            .arg(chgl->fVertexes[1].at(i+7)-chgl->altemitte.y,10,'g',6)
            .arg(chgl->fVertexes[1].at(i+8)-chgl->altemitte.z,10,'g',6)
            .arg(chgl->fVertexes[1].at(i+0)-chgl->altemitte.x,10,'g',6)
            .arg(chgl->fVertexes[1].at(i+1)-chgl->altemitte.y,10,'g',6)
            .arg(chgl->fVertexes[1].at(i+2)-chgl->altemitte.z,10,'g',6)
            .arg(chgl->linwidth*0.01)
            );
    }
    densityMaps.append(QString("}"));
    densityMaps.append(QString("#else\n"));
    densityMaps.append(QString("mesh{\n"));
    for (int i=0; i<chgl->fVertexes[1].size();i+=9){
      densityMaps.append(QString("smooth_triangle{\n<%1,%2,%3>,<%10,%11,%12>,\n<%4,%5,%6>,<%13,%14,%15>,\n<%7,%8,%9>,<%16,%17,%19>\n}\n")
          .arg(chgl->fVertexes[1].at(i+0)-chgl->altemitte.x,10,'g',6)
          .arg(chgl->fVertexes[1].at(i+1)-chgl->altemitte.y,10,'g',6)
          .arg(chgl->fVertexes[1].at(i+2)-chgl->altemitte.z,10,'g',6)
          .arg(chgl->fVertexes[1].at(i+3)-chgl->altemitte.x,10,'g',6)
          .arg(chgl->fVertexes[1].at(i+4)-chgl->altemitte.y,10,'g',6)
          .arg(chgl->fVertexes[1].at(i+5)-chgl->altemitte.z,10,'g',6)
          .arg(chgl->fVertexes[1].at(i+6)-chgl->altemitte.x,10,'g',6)
          .arg(chgl->fVertexes[1].at(i+7)-chgl->altemitte.y,10,'g',6)
          .arg(chgl->fVertexes[1].at(i+8)-chgl->altemitte.z,10,'g',6)
          .arg(chgl->fNormals[1].at(i+0),10,'g',6)
          .arg(chgl->fNormals[1].at(i+1),10,'g',6)
          .arg(chgl->fNormals[1].at(i+2),10,'g',6)
          .arg(chgl->fNormals[1].at(i+3),10,'g',6)
          .arg(chgl->fNormals[1].at(i+4),10,'g',6)
          .arg(chgl->fNormals[1].at(i+5),10,'g',6)
          .arg(chgl->fNormals[1].at(i+6),10,'g',6)
          .arg(chgl->fNormals[1].at(i+7),10,'g',6)
          .arg(chgl->fNormals[1].at(i+8),10,'g',6)
          );
    }
    densityMaps.append(QString("texture {diffMinCol}\n}\n"));
    densityMaps.append(QString("#end\n"));
  }
  if (!chgl->fVertexes[2].isEmpty()){
    densityMaps.append(QString("#end\n\n#if (DrawFobserved)\n"));
    densityMaps.append(QString("#if (DrawWireframeMaps)\n"));
    densityMaps.append(QString("union{\n"));
    for (int i=0; i<chgl->fVertexes[2].size();i+=9){
      if (Distance(
            V3( chgl->fVertexes[2].at(i+0), chgl->fVertexes[2].at(i+1), chgl->fVertexes[2].at(i+2)),
            V3( chgl->fVertexes[2].at(i+3), chgl->fVertexes[2].at(i+4), chgl->fVertexes[2].at(i+5) 
              ))>0.0001)
        densityMaps.append(QString("cylinder{<%1,%2,%3>,<%4,%5,%6>, %7 texture{FobsPosCol}}\n")
            .arg(chgl->fVertexes[2].at(i+0)-chgl->altemitte.x,10,'g',6)
            .arg(chgl->fVertexes[2].at(i+1)-chgl->altemitte.y,10,'g',6)
            .arg(chgl->fVertexes[2].at(i+2)-chgl->altemitte.z,10,'g',6)
            .arg(chgl->fVertexes[2].at(i+3)-chgl->altemitte.x,10,'g',6)
            .arg(chgl->fVertexes[2].at(i+4)-chgl->altemitte.y,10,'g',6)
            .arg(chgl->fVertexes[2].at(i+5)-chgl->altemitte.z,10,'g',6)
            .arg(chgl->linwidth*0.01)
            );
      if (Distance(
            V3( chgl->fVertexes[2].at(i+3), chgl->fVertexes[2].at(i+4), chgl->fVertexes[2].at(i+5)),
            V3( chgl->fVertexes[2].at(i+6), chgl->fVertexes[2].at(i+7), chgl->fVertexes[2].at(i+8) 
              ))>0.0001)
        densityMaps.append(QString("cylinder{<%1,%2,%3>,<%4,%5,%6>, %7 texture{FobsPosCol}}\n")
            .arg(chgl->fVertexes[2].at(i+3)-chgl->altemitte.x,10,'g',6)
            .arg(chgl->fVertexes[2].at(i+4)-chgl->altemitte.y,10,'g',6)
            .arg(chgl->fVertexes[2].at(i+5)-chgl->altemitte.z,10,'g',6)
            .arg(chgl->fVertexes[2].at(i+6)-chgl->altemitte.x,10,'g',6)
            .arg(chgl->fVertexes[2].at(i+7)-chgl->altemitte.y,10,'g',6)
            .arg(chgl->fVertexes[2].at(i+8)-chgl->altemitte.z,10,'g',6)
            .arg(chgl->linwidth*0.01)
            );
      if (Distance(
            V3( chgl->fVertexes[2].at(i+6), chgl->fVertexes[2].at(i+7), chgl->fVertexes[2].at(i+8)),
            V3( chgl->fVertexes[2].at(i+0), chgl->fVertexes[2].at(i+1), chgl->fVertexes[2].at(i+2) 
              ))>0.0001)
        densityMaps.append(QString("cylinder{<%1,%2,%3>,<%4,%5,%6>, %7 texture{FobsPosCol}}\n")
            .arg(chgl->fVertexes[2].at(i+6)-chgl->altemitte.x,10,'g',6)
            .arg(chgl->fVertexes[2].at(i+7)-chgl->altemitte.y,10,'g',6)
            .arg(chgl->fVertexes[2].at(i+8)-chgl->altemitte.z,10,'g',6)
            .arg(chgl->fVertexes[2].at(i+0)-chgl->altemitte.x,10,'g',6)
            .arg(chgl->fVertexes[2].at(i+1)-chgl->altemitte.y,10,'g',6)
            .arg(chgl->fVertexes[2].at(i+2)-chgl->altemitte.z,10,'g',6)
            .arg(chgl->linwidth*0.01)
            );
    }
    densityMaps.append(QString("}"));
    densityMaps.append(QString("#else\n"));
    densityMaps.append(QString("mesh{\n"));
    for (int i=0; i<chgl->fVertexes[2].size();i+=9){
      densityMaps.append(QString("smooth_triangle{\n<%1,%2,%3>,<%10,%11,%12>,\n<%4,%5,%6>,<%13,%14,%15>,\n<%7,%8,%9>,<%16,%17,%19>\n}\n")
          .arg(chgl->fVertexes[2].at(i+0)-chgl->altemitte.x,10,'g',6)
          .arg(chgl->fVertexes[2].at(i+1)-chgl->altemitte.y,10,'g',6)
          .arg(chgl->fVertexes[2].at(i+2)-chgl->altemitte.z,10,'g',6)
          .arg(chgl->fVertexes[2].at(i+3)-chgl->altemitte.x,10,'g',6)
          .arg(chgl->fVertexes[2].at(i+4)-chgl->altemitte.y,10,'g',6)
          .arg(chgl->fVertexes[2].at(i+5)-chgl->altemitte.z,10,'g',6)
          .arg(chgl->fVertexes[2].at(i+6)-chgl->altemitte.x,10,'g',6)
          .arg(chgl->fVertexes[2].at(i+7)-chgl->altemitte.y,10,'g',6)
          .arg(chgl->fVertexes[2].at(i+8)-chgl->altemitte.z,10,'g',6)
          .arg(chgl->fNormals[2].at(i+0),10,'g',6)
          .arg(chgl->fNormals[2].at(i+1),10,'g',6)
          .arg(chgl->fNormals[2].at(i+2),10,'g',6)
          .arg(chgl->fNormals[2].at(i+3),10,'g',6)
          .arg(chgl->fNormals[2].at(i+4),10,'g',6)
          .arg(chgl->fNormals[2].at(i+5),10,'g',6)
          .arg(chgl->fNormals[2].at(i+6),10,'g',6)
          .arg(chgl->fNormals[2].at(i+7),10,'g',6)
          .arg(chgl->fNormals[2].at(i+8),10,'g',6)
          );
    }
    densityMaps.append(QString("texture {FobsPosCol}\n}\n"));
    densityMaps.append(QString("#end\n"));
  }
  if (!chgl->fVertexes[3].isEmpty()){      
    densityMaps.append(QString("#if (DrawWireframeMaps)\n"));

    densityMaps.append(QString("union{\n"));
    for (int i=0; i<chgl->fVertexes[3].size();i+=9){
      if (Distance(
            V3( chgl->fVertexes[3].at(i+0), chgl->fVertexes[3].at(i+1), chgl->fVertexes[3].at(i+2)),
            V3( chgl->fVertexes[3].at(i+3), chgl->fVertexes[3].at(i+4), chgl->fVertexes[3].at(i+5) 
              ))>0.0001)
        densityMaps.append(QString("cylinder{<%1,%2,%3>,<%4,%5,%6>, %7 texture{FobsMinCol}}\n")
            .arg(chgl->fVertexes[3].at(i+0)-chgl->altemitte.x,10,'g',6)
            .arg(chgl->fVertexes[3].at(i+1)-chgl->altemitte.y,10,'g',6)
            .arg(chgl->fVertexes[3].at(i+2)-chgl->altemitte.z,10,'g',6)
            .arg(chgl->fVertexes[3].at(i+3)-chgl->altemitte.x,10,'g',6)
            .arg(chgl->fVertexes[3].at(i+4)-chgl->altemitte.y,10,'g',6)
            .arg(chgl->fVertexes[3].at(i+5)-chgl->altemitte.z,10,'g',6)
            .arg(chgl->linwidth*0.01)
            );
      if (Distance(
            V3( chgl->fVertexes[3].at(i+3), chgl->fVertexes[3].at(i+4), chgl->fVertexes[3].at(i+5)),
            V3( chgl->fVertexes[3].at(i+6), chgl->fVertexes[3].at(i+7), chgl->fVertexes[3].at(i+8) 
              ))>0.0001)
        densityMaps.append(QString("cylinder{<%1,%2,%3>,<%4,%5,%6>,%7 texture{FobsMinCol}}\n")
            .arg(chgl->fVertexes[3].at(i+3)-chgl->altemitte.x,10,'g',6)
            .arg(chgl->fVertexes[3].at(i+4)-chgl->altemitte.y,10,'g',6)
            .arg(chgl->fVertexes[3].at(i+5)-chgl->altemitte.z,10,'g',6)
            .arg(chgl->fVertexes[3].at(i+6)-chgl->altemitte.x,10,'g',6)
            .arg(chgl->fVertexes[3].at(i+7)-chgl->altemitte.y,10,'g',6)
            .arg(chgl->fVertexes[3].at(i+8)-chgl->altemitte.z,10,'g',6)
            .arg(chgl->linwidth*0.01)
            );
      if (Distance(
            V3( chgl->fVertexes[3].at(i+6), chgl->fVertexes[3].at(i+7), chgl->fVertexes[3].at(i+8)),
            V3( chgl->fVertexes[3].at(i+0), chgl->fVertexes[3].at(i+1), chgl->fVertexes[3].at(i+2) 
              ))>0.0001)
        densityMaps.append(QString("cylinder{<%1,%2,%3>,<%4,%5,%6>,%7 texture{FobsMinCol}}\n")
            .arg(chgl->fVertexes[3].at(i+6)-chgl->altemitte.x,10,'g',6)
            .arg(chgl->fVertexes[3].at(i+7)-chgl->altemitte.y,10,'g',6)
            .arg(chgl->fVertexes[3].at(i+8)-chgl->altemitte.z,10,'g',6)
            .arg(chgl->fVertexes[3].at(i+0)-chgl->altemitte.x,10,'g',6)
            .arg(chgl->fVertexes[3].at(i+1)-chgl->altemitte.y,10,'g',6)
            .arg(chgl->fVertexes[3].at(i+2)-chgl->altemitte.z,10,'g',6)
            .arg(chgl->linwidth*0.01)
            );
    }
    densityMaps.append(QString("}"));
    densityMaps.append(QString("#else\n"));
    densityMaps.append(QString("mesh{\n"));
    for (int i=0; i<chgl->fVertexes[3].size();i+=9){
      densityMaps.append(QString("smooth_triangle{\n<%1,%2,%3>,<%10,%11,%12>,\n<%4,%5,%6>,<%13,%14,%15>,\n<%7,%8,%9>,<%16,%17,%19>\n}\n")
          .arg(chgl->fVertexes[3].at(i+0)-chgl->altemitte.x,10,'g',6)
          .arg(chgl->fVertexes[3].at(i+1)-chgl->altemitte.y,10,'g',6)
          .arg(chgl->fVertexes[3].at(i+2)-chgl->altemitte.z,10,'g',6)
          .arg(chgl->fVertexes[3].at(i+3)-chgl->altemitte.x,10,'g',6)
          .arg(chgl->fVertexes[3].at(i+4)-chgl->altemitte.y,10,'g',6)
          .arg(chgl->fVertexes[3].at(i+5)-chgl->altemitte.z,10,'g',6)
          .arg(chgl->fVertexes[3].at(i+6)-chgl->altemitte.x,10,'g',6)
          .arg(chgl->fVertexes[3].at(i+7)-chgl->altemitte.y,10,'g',6)
          .arg(chgl->fVertexes[3].at(i+8)-chgl->altemitte.z,10,'g',6)
          .arg(chgl->fNormals[3].at(i+0),10,'g',6)
          .arg(chgl->fNormals[3].at(i+1),10,'g',6)
          .arg(chgl->fNormals[3].at(i+2),10,'g',6)
          .arg(chgl->fNormals[3].at(i+3),10,'g',6)
          .arg(chgl->fNormals[3].at(i+4),10,'g',6)
          .arg(chgl->fNormals[3].at(i+5),10,'g',6)
          .arg(chgl->fNormals[3].at(i+6),10,'g',6)
          .arg(chgl->fNormals[3].at(i+7),10,'g',6)
          .arg(chgl->fNormals[3].at(i+8),10,'g',6)
          );
    }
    densityMaps.append(QString("texture {FobsMinCol}\n}\n"));  
    densityMaps.append(QString("#end\n"));
  }
  densityMaps.append(QString("#end\n#end // maps\n\n"));
  if (!chgl->mol->vtriangles.isEmpty()){
    voron.append(QString("//voronoij polyherodron \n"));

    for (int k=0; k<editor->sfac.size();k++){
      voron.append(QString("#declare _%1_%2_ = texture{pigment{color rgbt< %3, %4, %5, %6>}}\n")
          .arg(mole.pse(editor->sfac.at(k)))
          .arg("a")

          .arg(mole.AtomColor[editor->sfac.at(k)].redF())
          .arg(mole.AtomColor[editor->sfac.at(k)].greenF())
          .arg(mole.AtomColor[editor->sfac.at(k)].blueF())
          .arg("0.97")
          );
      voron.append(QString("#declare _%1_%2_ = texture{pigment{color rgbt< %3, %4, %5, %6>}}\n")
          .arg(mole.pse(editor->sfac.at(k)))
          .arg("b")
          .arg(mole.AtomColor[editor->sfac.at(k)].redF())
          .arg(mole.AtomColor[editor->sfac.at(k)].greenF())
          .arg(mole.AtomColor[editor->sfac.at(k)].blueF())
          .arg("0.4")
          );
    }
    voron.append(QString("union{\n"));
    for (int ti=0; ti<mole.vtriangles.size(); ti++){
      voron.append(QString("cylinder {< %1, %2, %3 >,< %4, %5, %6>,0.01 texture{pigment{color rgbt< %7, %8, %9, 0.5>}}}\n")
          .arg(mole.vtriangles.at(ti).verts0.x-chgl->altemitte.x)
          .arg(mole.vtriangles.at(ti).verts0.y-chgl->altemitte.y)
          .arg(mole.vtriangles.at(ti).verts0.z-chgl->altemitte.z)
          .arg(mole.vtriangles.at(ti).verts1.x-chgl->altemitte.x)
          .arg(mole.vtriangles.at(ti).verts1.y-chgl->altemitte.y)
          .arg(mole.vtriangles.at(ti).verts1.z-chgl->altemitte.z)
          .arg(mole.AtomColor[mole.vtriangles.at(ti).acol].redF())
          .arg(mole.AtomColor[mole.vtriangles.at(ti).acol].greenF())
          .arg(mole.AtomColor[mole.vtriangles.at(ti).acol].blueF())
          );
    }
    voron.append(QString("}\nmesh{\n"));
    for (int ti=0; ti<mole.vtriangles.size(); ti++){
      voron.append(QString("triangle{< %1, %2, %3>,< %4, %5, %6>,< %7, %8, %9>\n")
          .arg(mole.vtriangles.at(ti).mid.x-chgl->altemitte.x)
          .arg(mole.vtriangles.at(ti).mid.y-chgl->altemitte.y)
          .arg(mole.vtriangles.at(ti).mid.z-chgl->altemitte.z)
          .arg(mole.vtriangles.at(ti).verts0.x-chgl->altemitte.x)
          .arg(mole.vtriangles.at(ti).verts0.y-chgl->altemitte.y)
          .arg(mole.vtriangles.at(ti).verts0.z-chgl->altemitte.z)
          .arg(mole.vtriangles.at(ti).verts1.x-chgl->altemitte.x)
          .arg(mole.vtriangles.at(ti).verts1.y-chgl->altemitte.y)
          .arg(mole.vtriangles.at(ti).verts1.z-chgl->altemitte.z)
          );
      voron.append(QString("texture { _%1_%2_ }}\n").arg(mole.pse(mole.vtriangles.at(ti).acol)).arg((mole.vtriangles.at(ti).intra)?"a":"b"));
    }
    voron.append(QString("} //voronoij\n"));
  }
  body.clear();
  for (int i=0,j=0; i<mole.legendAtoms.size();i++){
    if (mole.legendAtoms.at(i).hidden) continue;
    if (mole.legendAtoms.at(i).an<0){
      body.append(QString("#if (BW)\nqpeak(<-ww/1.025,-hh/1.25+%1*hh/18,0>,QPeakRad*4*ViewAngle/29.0,0.6,0.6,0.6,%1)\n"
            "#else\nqpeak(<-ww/1.025,-hh/1.08+%2*hh/18,0>,QPeakRad*4*ViewAngle/29.0,0.9,0.5,0.0,%1)\n#end\n")
          .arg(mole.legendAtoms.at(i).an)
          .arg(j)
          );//
    }else{
      if (chgl->mol->AtomStyle[mole.legendAtoms.at(i).an]&ATOM_STYLE_NOADP) {
        body.append(QString("  object{\n"));
        body.append(QString("    sphere{ Origin, 1 texture {  finish { Shiny } pigment {color Color_%1 } } }\n").arg(mole.pse(mole.legendAtoms.at(i).an)));
        body.append(QString("    scale< H_Radius*Prob, H_Radius*Prob, H_Radius*Prob>*4*ViewAngle/29.0 \n"));
      }else{
        V3 ev=V3(0,0,0); // Eigen Vectors
        double *arr=mole.jacobi(mole.legendAtoms.at(i).uc,ev);
        if ((ev.x>0)&&(ev.y>0)&&(ev.z>0)){
          body.append(QString("#declare  U11 =  %1 ;\n").arg(sqrt(ev.x),10,'f',6));
          body.append(QString("#declare  U22 =  %1 ;\n").arg(sqrt(ev.y),10,'f',6));
          body.append(QString("#declare  U33 =  %1 ;\n").arg(sqrt(ev.z),10,'f',6));
          body.append(QString("object{\n  union{\n"));
          body.append(QString("    sphere{Origin, 1               texture {  finish { Shiny } pigment {color Color_%1 transmit %2} } }\n")
              .arg(mole.pse(mole.legendAtoms.at(i).an)).arg((chgl->mol->AtomStyle[mole.legendAtoms.at(i).an]&ATOM_STYLE_SOLID)?"0.0":"0.8"));

          body.append(QString("    sphere{Origin, 1 scale<1,1,0.2>  texture {  finish { Shiny } pigment {color Color_%1 } } }\n").arg(mole.pse(mole.legendAtoms.at(i).an)));
          body.append(QString("    sphere{Origin, 1 scale<0.2,1,1>  texture {  finish { Shiny } pigment {color Color_%1 } } }\n").arg(mole.pse(mole.legendAtoms.at(i).an)));
          body.append(QString("    sphere{Origin, 1 scale<1,0.2,1>  texture {  finish { Shiny } pigment {color Color_%1 } } }\n").arg(mole.pse(mole.legendAtoms.at(i).an)));
          body.append(QString("    torus{ 1 .06                 texture {  finish { Shiny } pigment {color Equator_%1 } } }\n").arg(mole.pse(mole.legendAtoms.at(i).an)));
          body.append(QString("    torus{ 1 .06 rotate< 90,0,0> texture {  finish { Shiny } pigment {color Equator_%1 } } }\n").arg(mole.pse(mole.legendAtoms.at(i).an)));
          body.append(QString("    torus{ 1 .06 rotate< 0,0,90> texture {  finish { Shiny } pigment {color Equator_%1 } } }\n").arg(mole.pse(mole.legendAtoms.at(i).an)));
          body.append(QString("    scale< U11*Prob, U22*Prob, U33*Prob>*4*ViewAngle/29.0\n  }\n"));
          body.append(QString("    Axis_Rotate_Trans( < %1 , %2 , %3 >, %4 ) \n")
              .arg(arr[1],10,'f',6)
              .arg(arr[2],10,'f',6)
              .arg(arr[3],10,'f',6)
              .arg(arr[0],10,'f',6));
        }
      }
      body.append(QString("    translate <-ww/1.025,-hh/1.08+%1*hh/18,0>\nno_shadow\n}\n\n").arg(j));
    }
    body.append(QString("llabel(\"%1\",<-ww/1.06,-hh/1.06+%2*hh/18,0>,Black,0.35*4*ViewAngle/29.0)\n").arg(mole.pse(mole.legendAtoms.at(i).an)).arg(j));
    j++;
  }
  headerPOV.append(body);

  headerPOV.append(QString("#end //DrawLegend\n"));
  headerPOV.append(QString("// ====================================\n"));
  headerPOV.append(QString("// __Declarations of atoms coordinates \n"));
  for (int i=0; i< mole.showatoms.size(); i++){
    if (mole.showatoms.at(i).hidden) continue;
    if ((mole.nopm1)&&(mole.showatoms.at(i).symmGroup)&&(mole.showatoms.at(i).part<-0)) continue; // ignore hidden parts (-1)
    else {
      s1=QString("AtomPos%1").arg(i);
      headerPOV.append(QString("#declare  %1 = < %2 , %3 , %4 >;//%5\n")
          .arg(s1)
          .arg(mole.showatoms.at(i).pos.x-chgl->altemitte.x,10,'f',6) //use the actual rotation center
          .arg(mole.showatoms.at(i).pos.y-chgl->altemitte.y,10,'f',6)
          .arg(mole.showatoms.at(i).pos.z-chgl->altemitte.z,10,'f',6)
          .arg(mole.showatoms.at(i).Label));
    }}
  headerPOV.append(QString("// ____________________________________ end of atom coordinates\n\n\n\n"));

  headerPOV.append(QString("// ====================================\n"));
  headerPOV.append(QString("// __START union of objects\n"));
  headerPOV.append(QString("union {\n\n"));

  headerPOV.append(QString("// ====================================\n"));
  headerPOV.append(QString("// Spheres for nicely overlapping bonds\n"));
  headerPOV.append(QString("  #if(DrawRoundCorners)\n"));
  body.clear(); // we will use body as temporary buffer for hydrogen atoms spheres
  body.append(QString("\n    #if(DrawHydrogens)\n"));

  for (int i=0; i< mole.showatoms.size(); i++){   // read Uij into matrix form
    if (mole.showatoms.at(i).an<0) continue;//only real atoms here
    if (mole.showatoms.at(i).hidden) continue;
    if ((mole.nopm1)&&(mole.showatoms.at(i).symmGroup)&&(mole.showatoms.at(i).part<-0)) continue; // ignore hidden parts (-1)
    s1=QString("AtomPos%1").arg(i);
    if (mole.showatoms.at(i).an==0)
      body.append(QString("sphere { %1 , HBond_Radius texture {Bond_Texture}}//%2\n").arg(s1)
          .arg(mole.showatoms.at(i).Label));
    else
      headerPOV.append(QString("    sphere { %1 , Bond_Radius texture {Bond_Texture}}//%2\n").arg(s1)
          .arg(mole.showatoms.at(i).Label));
  }
  headerPOV.append(body);
  headerPOV.append(QString("    #end // End of atomic spheres for hydrogens\n"));
  headerPOV.append(QString("  #end // End of atomic spheres\n"));
  headerPOV.append(QString("// ____________________________________ end of corners\n\n\n\n"));

  headerPOV.append(QString("// ====================================\n"));
  headerPOV.append(QString("// __Declarations of atoms and their Uij\n\n"));

  hiddenAtoms.append(QString("\n\n// ====================================\n"));
  hiddenAtoms.append(QString("// Put in this IF-END loop atoms that shouldn't be drawn.\n"));
  hiddenAtoms.append(QString("#if(!NoADP4Selected)\n"));

  hydrogenAtoms.append(QString("\n\n// ====================================\n"));
  hydrogenAtoms.append(QString("// __Declarations of hydrogen atoms and their Uiso\n\n"));
  hydrogenAtoms.append(QString("#if(DrawHydrogens)\n"));
  hiddenHAtoms.append(QString("// __Declarations of hydrogen atoms and their Uiso\n"));
  hiddenHAtoms.append(QString("\n#  if(DrawHydrogens)\n"));

  for (int i=0; i< mole.showatoms.size(); i++){   // read Uij into matrix form
    if (mole.showatoms.at(i).an<0) continue;//only real atoms here
    if (mole.showatoms.at(i).hidden) continue;
    if ((mole.nopm1)&&(mole.showatoms.at(i).symmGroup)&&(mole.showatoms.at(i).part<-0)) continue; // ignore hidden parts (-1)
    if (mole.showatoms.at(i).isIso) {//Wow this is stupid all iso atoms are Hydrogens? If Hydrogens are anisotropic (neutrons, SHADE etc.) they are not Hydrogens????)
      s1=QString("AtomPos%1").arg(i);
      body.clear(); // we will use body as temporary buffer for hydrogen atoms
      body.append(QString("  #if (Hiso) #declare  H_Radius =  %1 ; #end\n").arg(sqrt(mole.showatoms.at(i).uf.m11),10,'f',6));
      body.append(QString("  object{\n"));
      if ((chgl->highlightParts->isChecked())&&(mole.showatoms.at(i).part!=0)){
          if ((mole.showatoms.at(i).part<0)&&(mole.showatoms.at(i).symmGroup))
            body.append(QString("    sphere{ Origin, 1 texture {  finish { Shiny } pigment {color Color_%1 blue 1.0 transmit 0.7} } }\n").arg(mole.pse(mole.showatoms.at(i).an)));
          else
            body.append(QString("    sphere{ Origin, 1 texture {  finish { Shiny } pigment {color ptcol%1 } } }\n")
                        .arg((mole.showatoms.at(i).part>0)?QString("%1").arg(mole.showatoms.at(i).part):
                        (mole.showatoms.at(i).part<-3)?"mX":QString("m%1").arg(-mole.showatoms.at(i).part))
                        );
      } else{
      if ((mole.showatoms.at(i).part<0)&&(mole.showatoms.at(i).symmGroup))
        body.append(QString("    sphere{ Origin, 1 texture {  finish { Shiny } pigment {color Color_%1 blue 1.0 transmit 0.7} } }\n").arg(mole.pse(mole.showatoms.at(i).an)));
      else
        body.append(QString("    sphere{ Origin, 1 texture {  finish { Shiny } pigment {color Color_%1 } } }\n").arg(mole.pse(mole.showatoms.at(i).an)));
      }
      body.append(QString("    scale< H_Radius*Prob, H_Radius*Prob, H_Radius*Prob> \n"));
      body.append(QString("  translate %1//%2\n  }\n\n").arg(s1)
          .arg(mole.showatoms.at(i).Label));
      foundInSelected=false;
      for (int j = 0; j <chgl->mol->selectedatoms.size();j++)if (chgl->mol->selectedatoms.at(j).style==i) {foundInSelected=true;break;}
      if (foundInSelected){hiddenHAtoms.append(body);}
      else {hydrogenAtoms.append(body);}
    } // end of Hs
    else {
      body.clear(); // we will use body as temporary buffer
      V3 ev=V3(0,0,0); // Eigen Vectors
      double *arr=mole.jacobi(mole.showatoms.at(i).uc,ev);
      if ((ev.x>0)&&(ev.y>0)&&(ev.z>0)){

        body.append(QString("#declare  U11 =  %1 ;\n").arg(sqrt(ev.x),10,'f',6));
        body.append(QString("#declare  U22 =  %1 ;\n").arg(sqrt(ev.y),10,'f',6));
        body.append(QString("#declare  U33 =  %1 ;\n").arg(sqrt(ev.z),10,'f',6));
        body.append(QString("object{\n  union{\n"));
        if ((chgl->highlightParts->isChecked())&&(mole.showatoms.at(i).part!=0)){
            if ((mole.showatoms.at(i).part<0)&&(mole.showatoms.at(i).symmGroup)){
                body.append(QString("    sphere{ Origin, 1.1 texture {  finish { Shiny } pigment {color Color_%1 blue 1.0 transmit 0.7} } }\n")
                            .arg(mole.pse(mole.showatoms.at(i).an)));
            }else{
                body.append(QString("    sphere{ Origin, 1.1 texture {  finish { Shiny } pigment {color ptcol%1} } }\n")
                            .arg((mole.showatoms.at(i).part>0)?QString("%1").arg(mole.showatoms.at(i).part):
                            (mole.showatoms.at(i).part<-3)?"mX":QString("m%1").arg(-mole.showatoms.at(i).part))
                        );
            }
        }
        if ((mole.showatoms.at(i).part<0)&&(mole.showatoms.at(i).symmGroup)){
            body.append(QString("    sphere{ Origin, 1               texture {  finish { Shiny } pigment {color Color_%1 blue 1.0 transmit 0.7} } }\n")
                        .arg(mole.pse(mole.showatoms.at(i).an))
                        );
            body.append(QString("    sphere{Origin, 1 scale<1,1,0.2>  texture {  finish { Shiny } pigment {color Color_%1 blue 1.0 transmit 0.7} } }\n").arg(mole.pse(mole.showatoms.at(i).an)));
            body.append(QString("    sphere{Origin, 1 scale<0.2,1,1>  texture {  finish { Shiny } pigment {color Color_%1 blue 1.0 transmit 0.7} } }\n").arg(mole.pse(mole.showatoms.at(i).an)));
            body.append(QString("    sphere{Origin, 1 scale<1,0.2,1>  texture {  finish { Shiny } pigment {color Color_%1 blue 1.0 transmit 0.7} } }\n").arg(mole.pse(mole.showatoms.at(i).an)));
            body.append(QString("    torus{ 1 .06                 texture {  finish { Shiny } pigment {color Equator_%1 blue 1.0 transmit 0.7} } }\n").arg(mole.pse(mole.showatoms.at(i).an)));
            body.append(QString("    torus{ 1 .06 rotate< 90,0,0> texture {  finish { Shiny } pigment {color Equator_%1 blue 1.0 transmit 0.7} } }\n").arg(mole.pse(mole.showatoms.at(i).an)));
            body.append(QString("    torus{ 1 .06 rotate< 0,0,90> texture {  finish { Shiny } pigment {color Equator_%1 blue 1.0 transmit 0.7} } }\n").arg(mole.pse(mole.showatoms.at(i).an)));

        }else{
        body.append(QString("    sphere{ Origin, 1               texture {  finish { Shiny } pigment {color Color_%1 transmit %2} } }\n")
            .arg(mole.pse(mole.showatoms.at(i).an)).arg((chgl->mol->AtomStyle[mole.showatoms.at(i).an]&ATOM_STYLE_SOLID)?"0.0":"0.3"));
        body.append(QString("    sphere{Origin, 1 scale<1,1,0.2>  texture {  finish { Shiny } pigment {color Color_%1 } } }\n").arg(mole.pse(mole.showatoms.at(i).an)));
        body.append(QString("    sphere{Origin, 1 scale<0.2,1,1>  texture {  finish { Shiny } pigment {color Color_%1 } } }\n").arg(mole.pse(mole.showatoms.at(i).an)));
        body.append(QString("    sphere{Origin, 1 scale<1,0.2,1>  texture {  finish { Shiny } pigment {color Color_%1 } } }\n").arg(mole.pse(mole.showatoms.at(i).an)));
        body.append(QString("    torus{ 1 .06                 texture {  finish { Shiny } pigment {color Equator_%1 } } }\n").arg(mole.pse(mole.showatoms.at(i).an)));
        body.append(QString("    torus{ 1 .06 rotate< 90,0,0> texture {  finish { Shiny } pigment {color Equator_%1 } } }\n").arg(mole.pse(mole.showatoms.at(i).an)));
        body.append(QString("    torus{ 1 .06 rotate< 0,0,90> texture {  finish { Shiny } pigment {color Equator_%1 } } }\n").arg(mole.pse(mole.showatoms.at(i).an)));
        }
        body.append(QString("    scale< U11*Prob, U22*Prob, U33*Prob>\n  }\n"));
        body.append(QString("    Axis_Rotate_Trans( < %1 , %2 , %3 >, %4 ) \n")
            .arg(arr[1],10,'f',6)
            .arg(arr[2],10,'f',6)
            .arg(arr[3],10,'f',6)
            .arg(arr[0],10,'f',6));
      }
      else {
        body.append(QString("object{\n  union{\n"));
        body.append(QString("DrawCube(CubeSize,Color_%1,Equator_%1)}\n").arg(mole.pse(mole.showatoms.at(i).an)));
      }
      s1=QString("AtomPos%1").arg(i);
      body.append(QString("  translate %1//%2\n}\n\n").arg(s1)
          .arg(mole.showatoms.at(i).Label));

      foundInSelected=false;
      for (int j = 0; j <chgl->mol->selectedatoms.size();j++)if (chgl->mol->selectedatoms.at(j).style==i) {foundInSelected=true;break;}
      if (foundInSelected){hiddenAtoms.append(body);}
      else {visableAtoms.append(body);}
    } // end of non-H
  } // end of lopp over all atoms for Uij computation

  hydrogenAtoms.append(QString("  #end // closing hydrogen atoms loop\n"));
  hiddenHAtoms.append(QString("  #end // closing hidden hydrogen atoms loop\n"));
  hiddenAtoms.append(hiddenHAtoms);
  hiddenAtoms.append(QString("#end // ____________________________________ end of hidden atoms\n\n"));

  hidePOV.append(QString("// ====================================\n"));
  hidePOV.append(QString("// Place in this IF-END loop atoms that shouldn't be drawn.\n"));
  hidePOV.append(QString("#if(NoADP4Selected)\n\n"));
  hidePOV.append(hiddenAtoms);
  hidePOV.append(QString("#end\n"));
  hidePOV.append(QString("// ____________________________________ end of hidden atoms\n\n\n\n"));

  qpeaks.append(QString("// ====================================\n"));
  qpeaks.append(QString("// Q-Peaks show up here\n"));
  qpeaks.append(QString("#if (DrawQPeaks)\n"));
  for (int i=0; i< mole.showatoms.size(); i++){   // read Uij into matrix form
    if (mole.showatoms.at(i).an>=0) continue;//only non real atoms here
    if (mole.showatoms.at(i).hidden) continue;
    s1=QString("AtomPos%1").arg(i);
    QColor qcol=chgl->farbverlaufQC(chgl->mol->showatoms.at(i).peakHeight,chgl->mol->pmin,chgl->mol->pmax);
    if (mole.showatoms.at(i).an==-42){
      if (mole.beloColorByDefden) qcol=chgl->farbverlaufQC(chgl->mol->showatoms.at(i).sof,mole.lmin,mole.lmax);
      else qcol=mole.beloColor;
    }
    double grey=(chgl->mol->showatoms.at(i).peakHeight-chgl->mol->pmin)/(chgl->mol->pmax-chgl->mol->pmin);
    qpeaks.append(QString("#if (BW)//%7\nqpeak(%1,QPeakRad,%5,%5,%5,%6)\n#else\nqpeak(%1,QPeakRad,%2,%3,%4,%6)\n#end\n")
        .arg(s1)
        .arg(qcol.redF())
        .arg(qcol.greenF())
        .arg(qcol.blueF())
        .arg(grey,5,'f',4)
        .arg(mole.showatoms.at(i).an)
        .arg(mole.showatoms.at(i).Label)
        );//
  }
  qpeaks.append(QString("#if (DrawQPeaksBonds)\n"));
  for (int i=0; i<chgl->mol->lbonds.size();i++){
    if (mole.lbonds.at(i).ato1->hidden) continue;
    if (mole.lbonds.at(i).ato2->hidden) continue;
    s1=QString("AtomPos%1").arg(mole.lbonds.at(i).a1);
    s2=QString("AtomPos%1").arg(mole.lbonds.at(i).a2);
    qpeaks.append(QString("qbond(%1,%2)//%3==%4\n").arg(s1).arg(s2).arg(mole.lbonds.at(i).ato1->Label).arg(mole.lbonds.at(i).ato2->Label));
  }
  qpeaks.append(QString("#end\n"));
  qpeaks.append(QString("#end\n\n"));
  // BONDS
  bondsPOV.append(QString("\n\n"));
  bondsPOV.append(QString("// ====================================\n"));
  bondsPOV.append(QString("// __Bonds\n"));

  body.clear(); // we will use body as temporary buffer for bonds to hydrogen atoms
  body.append(QString("\n#if(DrawHydrogens)\n"));

  for (int i =0; i<mole.showbonds.size();i++){
    if (mole.showbonds.at(i).ato1->hidden) continue;
    if (mole.showbonds.at(i).ato2->hidden) continue;
    if ((mole.nopm1)&&(mole.showbonds.at(i).ato1->symmGroup)&&(mole.showbonds.at(i).ato1->part<0))continue; // ignore hidden parts (-1)
    if ((mole.nopm1)&&(mole.showbonds.at(i).ato2->symmGroup)&&(mole.showbonds.at(i).ato2->part<0))continue; // ignore hidden parts (-1)
    s1=QString("AtomPos%1").arg(mole.showbonds.at(i).a1);
    s2=QString("AtomPos%1").arg(mole.showbonds.at(i).a2);
    if ((chgl->mol->AtomStyle[chgl->mol->showbonds.at(i).ato1->an]&ATOM_STYLE_METAL)||(chgl->mol->AtomStyle[chgl->mol->showbonds.at(i).ato2->an]&ATOM_STYLE_METAL)){
      if ((mole.showbonds.at(i).ato1->an == 0)||(mole.showbonds.at(i).ato2->an == 0))
        body.append(QString("  DrawDashBond2( %1, %2, HBond_Radius,Dash_Length, Bond_Texture,Color_%3,Color_%4)//%5==%6\n").arg(s1).arg(s2)
            .arg(mole.pse(mole.showbonds.at(i).ato2->an))
            .arg(mole.pse(mole.showbonds.at(i).ato1->an)).arg(mole.showbonds.at(i).ato1->Label).arg(mole.showbonds.at(i).ato2->Label));
      else
        bondsPOV.append(QString("DrawDashBond2( %1, %2, Bond_Radius,Dash_Length, Bond_Texture,Color_%3,Color_%4)//%5==%6\n").arg(s1).arg(s2)
            .arg(mole.pse(mole.showbonds.at(i).ato2->an))
            .arg(mole.pse(mole.showbonds.at(i).ato1->an)).arg(mole.showbonds.at(i).ato1->Label).arg(mole.showbonds.at(i).ato2->Label));
    }else{
        if ((chgl->highlightParts->isChecked())&&(mole.showbonds.at(i).ato1->part!=0))
        bondsPOV.append(QString("DrawBond( %1, %2, Bond_Radius, Bond_Texture,ptcol%3,ptcol%4,%7)//%5==%6\n")
                        .arg(s1)
                        .arg(s2)
                        .arg((mole.showbonds.at(i).ato1->part>0)?QString("%1").arg(mole.showbonds.at(i).ato1->part):
                        (mole.showbonds.at(i).ato1->part<-3)?"mX":QString("m%1").arg(-mole.showbonds.at(i).ato1->part))
                        .arg((mole.showbonds.at(i).ato2->part>0)?QString("%1").arg(mole.showbonds.at(i).ato2->part):
                        (mole.showbonds.at(i).ato2->part<-3)?"mX":QString("m%1").arg(-mole.showbonds.at(i).ato2->part))
                        .arg(mole.showbonds.at(i).ato1->Label).arg(mole.showbonds.at(i).ato2->Label)
                        .arg((mole.showbonds.at(i).ato1->part<0)&&(mole.showbonds.at(i).ato1->symmGroup)));

      else{
      if ((mole.showbonds.at(i).ato1->an == 0)||(mole.showbonds.at(i).ato2->an == 0))
        body.append(QString("  DrawBond( %1, %2, HBond_Radius, Bond_Texture,Color_%3,Color_%4,%7)//%5==%6\n").arg(s1).arg(s2).arg(mole.pse(mole.showbonds.at(i).ato1->an)).arg(mole.pse(mole.showbonds.at(i).ato2->an))
                    .arg(mole.showbonds.at(i).ato1->Label).arg(mole.showbonds.at(i).ato2->Label)
                    .arg((mole.showbonds.at(i).ato1->part<0)&&(mole.showbonds.at(i).ato1->symmGroup))
                    );
      else
        bondsPOV.append(QString("DrawBond( %1, %2, Bond_Radius, Bond_Texture,Color_%3,Color_%4,%7)//%5==%6\n").arg(s1).arg(s2).arg(mole.pse(mole.showbonds.at(i).ato1->an)).arg(mole.pse(mole.showbonds.at(i).ato2->an))
                        .arg(mole.showbonds.at(i).ato1->Label).arg(mole.showbonds.at(i).ato2->Label)
                        .arg((mole.showbonds.at(i).ato1->part<0)&&(mole.showbonds.at(i).ato1->symmGroup)));
        }
    }
  }
  body.append(QString("\n#if(DrawH_Bonds)\n"));
  //qDebug()<<chgl->mol->theH_Bonds.size();
  for (int i =0; i<chgl->mol->theH_Bonds.size();i++){
    if (mole.theH_Bonds.at(i).ato1->hidden) continue;
    if (mole.theH_Bonds.at(i).ato2->hidden) continue;
    if ((mole.nopm1)&&(mole.theH_Bonds.at(i).ato1->symmGroup)&&(mole.theH_Bonds.at(i).ato1->part<0))continue; // ignore hidden parts (-1)
    if ((mole.nopm1)&&(mole.theH_Bonds.at(i).ato2->symmGroup)&&(mole.theH_Bonds.at(i).ato2->part<0))continue; // ignore hidden parts (-1)
    s1=QString("AtomPos%1").arg(mole.theH_Bonds.at(i).a1);
    s2=QString("AtomPos%1").arg(mole.theH_Bonds.at(i).a2);
    body.append(QString("  DrawDashBond( %1, %2, HBond_Radius, Dash_Length*0.5, HBond_Texture)\n").arg(s1).arg(s2));

  }
  body.append(QString("#end // End of DrawH_Bonds\n"));
  body.append(QString("#end // End of bonds to hydrogen atoms\n"));
  bondsPOV.append(body);
  bondsPOV.append(QString("//------\n"));

  bondsPOV.append(QString("\n//DrawDashBond( Ct02 , Hf1  , Dash_Radius, Dash_Length, texture { Bond_Texture } )\n"));
  bondsPOV.append(QString("// ____________________________________ end of bonds\n\n\n\n"));

  ringsPOV.append(QString("// ====================================\n"));
  ringsPOV.append(QString("#if (DrawAromaticRings)\n"));
  ringsPOV.append(QString("/*\n"));
  ringsPOV.append(QString(" DrawRing - Example of usage\n"));
  ringsPOV.append(QString(" 1st declare new centroid; summation is over coordinates of all ring atoms\n"));
  ringsPOV.append(QString(" Divisor should be the same as count of atoms\n"));
  ringsPOV.append(QString(" The atoms C1 and N2, used in macro, should be neighbours in the ring.\n\n"));
  ringsPOV.append(QString(" #declare CtNew1=(C1+N2+C3+C4+N5)/5;\n"));
  ringsPOV.append(QString(" DrawRing(C1,N2,CtNew1)\n\n"));
  ringsPOV.append(QString("*/\n"));

  //    int nonMetal[10], countNonMetal;
  QList<int> nonMetals;
  for (int i=0; i< mole.showatoms.size(); i++){   // scan visble for Cnt
    if (mole.showatoms.at(i).hidden) continue;
    if ((mole.nopm1)&&(mole.showatoms.at(i).symmGroup)&&(mole.showatoms.at(i).part<-0)) continue; // ignore hidden parts (-1)
    if (mole.showatoms.at(i).an==-66) {//Cnt
      nonMetals.clear();
      for (int j=0; j< mole.showatoms.size(); j++){
        if ((i==j) || (mole.showatoms.at(j).an<1)) continue;   // ignore Q, Cnt and H
        if (mole.AtomStyle[mole.showatoms.at(j).an]&ATOM_STYLE_METAL) continue;
        if ((mole.nopm1)&&(mole.showatoms.at(j).symmGroup)&&(mole.showatoms.at(j).part<-0)) continue; // ignore hidden parts (-1)
        double d = sqrt(Distance(mole.showatoms.at(i).pos,mole.showatoms.at(j).pos));
        double soll=(70+mole.Kovalenz_Radien[mole.showatoms.at(j).an])*0.012;
        if (d<soll) nonMetals.append(j);
      }
      if (nonMetals.size()>1) { for (int j=0; j<nonMetals.size(); j++){
        for (int k=j+1; k<nonMetals.size(); k++){
          double d = sqrt(Distance(mole.showatoms.at(nonMetals.at(j)).pos,mole.showatoms.at(nonMetals.at(k)).pos));
          double soll=(mole.Kovalenz_Radien[mole.showatoms.at(nonMetals.at(j)).an]+mole.Kovalenz_Radien[mole.showatoms.at(nonMetals.at(k)).an])*0.012;
          if (d<soll){                
            s3=QString("AtomPos%1").arg(i);
            s2=QString("AtomPos%1").arg(nonMetals.at(j));
            s1=QString("AtomPos%1").arg(nonMetals.at(k));
            ringsPOV.append(QString(" DrawRing(%1,%2,%3)\n").arg(s1,10).arg(s2,10).arg(s3,10));
            goto endLoop;
          }
        }
      }}
endLoop:;
    }
  }
  ringsPOV.append(QString("#end\n"));
  ringsPOV.append(QString("// ____________________________________ end of rings\n\n\n\n"));
  nonMetals.clear();
  labels.append("//Labels\n#if (DrawLabels)\n");
  for (int i=0; i<mole.showatoms.size(); i++){
    if (mole.showatoms.at(i).hidden) continue;
    if ((mole.nopm1)&&(mole.showatoms.at(i).symmGroup)&&(mole.showatoms.at(i).part<-0)) continue; // ignore hidden parts (-1)
    if (mole.showatoms.at(i).an<0) continue;
    s2=mole.showatoms.at(i).Label;
    if (chgl->shortLabels->isChecked()) {
      s2=s2.section("_",0,0);
      s2=s2.section(QString::fromUtf8("»"),0,0);
    }
    s2=s2.replace("\\","\\\\");
    s2=s2.replace("\"","\\\"");
    s1=QString("AtomPos%1").arg(i);
    labels.append(QString("label(\"%1\",%2,Black,0.35)\n").arg(s2).arg(s1));
  }
  labels.append("#end //DrawLabels\n\n");


  /*!draw a unit cell box
   *
   * */
  V3 uz0f,uz1f,uz2f,uz3f,uz4f,uz5f,uz6f,uz7f;
  V3 uz0k,uz1k,uz2k,uz3k,uz4k,uz5k,uz6k,uz7k;
  uz0f.x=0.0;  uz0f.y=0.0;  uz0f.z=0.0;
  uz1f.x=1.0;  uz1f.y=0.0;  uz1f.z=0.0;
  uz2f.x=0.0;  uz2f.y=1.0;  uz2f.z=0.0;
  uz3f.x=0.0;  uz3f.y=0.0;  uz3f.z=1.0;
  uz4f.x=1.0;  uz4f.y=1.0;  uz4f.z=0.0;
  uz5f.x=1.0;  uz5f.y=0.0;  uz5f.z=1.0;
  uz6f.x=0.0;  uz6f.y=1.0;  uz6f.z=1.0;
  uz7f.x=1.0;  uz7f.y=1.0;  uz7f.z=1.0;
  mole.frac2kart(uz0f,uz0k);
  mole.frac2kart(uz1f,uz1k);
  mole.frac2kart(uz2f,uz2k);
  mole.frac2kart(uz3f,uz3k);
  mole.frac2kart(uz4f,uz4k);
  mole.frac2kart(uz5f,uz5k);
  mole.frac2kart(uz6f,uz6k);
  mole.frac2kart(uz7f,uz7k);
  uz0k = uz0k - chgl->altemitte;
  uz1k = uz1k - chgl->altemitte;
  uz2k = uz2k - chgl->altemitte;
  uz3k = uz3k - chgl->altemitte;
  uz4k = uz4k - chgl->altemitte;
  uz5k = uz5k - chgl->altemitte;
  uz6k = uz6k - chgl->altemitte;
  uz7k = uz7k - chgl->altemitte;
  unitCell.append(QString("#if (DrawUnitCell)\n"));
  unitCell.append(QString("union{\n"));
  unitCell.append(QString("cylinder{<%1,%2,%3>,<%4,%5,%6>,CellWidth texture{pigment{color Red}}}\n")
      .arg(uz0k.x)
      .arg(uz0k.y)
      .arg(uz0k.z)
      .arg(uz1k.x)
      .arg(uz1k.y)
      .arg(uz1k.z));
  unitCell.append(QString("cylinder{<%1,%2,%3>,<%4,%5,%6>,CellWidth texture{pigment{color Green}}}\n")
      .arg(uz0k.x)
      .arg(uz0k.y)
      .arg(uz0k.z)
      .arg(uz2k.x)
      .arg(uz2k.y)
      .arg(uz2k.z));
  unitCell.append(QString("cylinder{<%1,%2,%3>,<%4,%5,%6>,CellWidth texture{pigment{color Blue}}}\n")
      .arg(uz0k.x)
      .arg(uz0k.y)
      .arg(uz0k.z)
      .arg(uz3k.x)
      .arg(uz3k.y)
      .arg(uz3k.z));
  unitCell.append(QString("cylinder{<%1,%2,%3>,<%4,%5,%6>,CellWidth texture{pigment{color LightSteelBlue}}}\n")
      .arg(uz4k.x)
      .arg(uz4k.y)
      .arg(uz4k.z)
      .arg(uz1k.x)
      .arg(uz1k.y)
      .arg(uz1k.z));
  unitCell.append(QString("cylinder{<%1,%2,%3>,<%4,%5,%6>,CellWidth texture{pigment{color LightSteelBlue}}}\n")
      .arg(uz5k.x)
      .arg(uz5k.y)
      .arg(uz5k.z)
      .arg(uz1k.x)
      .arg(uz1k.y)
      .arg(uz1k.z));
  unitCell.append(QString("cylinder{<%1,%2,%3>,<%4,%5,%6>,CellWidth texture{pigment{color LightSteelBlue}}}\n")
      .arg(uz2k.x)
      .arg(uz2k.y)
      .arg(uz2k.z)
      .arg(uz4k.x)
      .arg(uz4k.y)
      .arg(uz4k.z));
  unitCell.append(QString("cylinder{<%1,%2,%3>,<%4,%5,%6>,CellWidth texture{pigment{color LightSteelBlue}}}\n")
      .arg(uz2k.x)
      .arg(uz2k.y)
      .arg(uz2k.z)
      .arg(uz6k.x)
      .arg(uz6k.y)
      .arg(uz6k.z));
  unitCell.append(QString("cylinder{<%1,%2,%3>,<%4,%5,%6>,CellWidth texture{pigment{color LightSteelBlue}}}\n")
      .arg(uz3k.x)
      .arg(uz3k.y)
      .arg(uz3k.z)
      .arg(uz5k.x)
      .arg(uz5k.y)
      .arg(uz5k.z));
  unitCell.append(QString("cylinder{<%1,%2,%3>,<%4,%5,%6>,CellWidth texture{pigment{color LightSteelBlue}}}\n")
      .arg(uz3k.x)
      .arg(uz3k.y)
      .arg(uz3k.z)
      .arg(uz6k.x)
      .arg(uz6k.y)
      .arg(uz6k.z));
  unitCell.append(QString("cylinder{<%1,%2,%3>,<%4,%5,%6>,CellWidth texture{pigment{color LightSteelBlue}}}\n")
      .arg(uz4k.x)
      .arg(uz4k.y)
      .arg(uz4k.z)
      .arg(uz7k.x)
      .arg(uz7k.y)
      .arg(uz7k.z));
  unitCell.append(QString("cylinder{<%1,%2,%3>,<%4,%5,%6>,CellWidth texture{pigment{color LightSteelBlue}}}\n")
      .arg(uz5k.x)
      .arg(uz5k.y)
      .arg(uz5k.z)
      .arg(uz7k.x)
      .arg(uz7k.y)
      .arg(uz7k.z));
  unitCell.append(QString("cylinder{<%1,%2,%3>,<%4,%5,%6>,CellWidth texture{pigment{color LightSteelBlue}}}\n")
      .arg(uz6k.x)
      .arg(uz6k.y)
      .arg(uz6k.z)
      .arg(uz7k.x)
      .arg(uz7k.y)
      .arg(uz7k.z));
  unitCell.append(QString("}\n#end //DrawUnitCell\n\n"));
  footerPOV.append(QString("transform {\n"));
  footerPOV.append(QString("scale<3.5*ViewAngle/29,3.5*ViewAngle/29,3.5*ViewAngle/29>\n"));
  footerPOV.append(QString("scale<SCALE,SCALE,SCALE>\n"));
  footerPOV.append(QString("  matrix <\n"));
  footerPOV.append(QString("  %1, %2, %3, \n").arg(mv[0],9,'f',6).arg(mv[1],9,'f',6).arg(mv[2],9,'f',6));
  footerPOV.append(QString("  %1, %2, %3, \n").arg(mv[4],9,'f',6).arg(mv[5],9,'f',6).arg(mv[6],9,'f',6));
  footerPOV.append(QString("  %1, %2, %3, \n").arg(mv[8],9,'f',6).arg(mv[9],9,'f',6).arg(mv[10],9,'f',6));
  footerPOV.append(QString("  %1, %2, %3\n").arg(0.0,9,'f',6).arg(0.0,9,'f',6).arg(0.0,9,'f',6));
  footerPOV.append(QString("  >\n"));
  footerPOV.append(QString("// You can adapt geometry by applying \n"));
  footerPOV.append(QString("// translation and rotations (in deg).\n"));
  footerPOV.append(QString("// It's easier to use separate rotation for each axis.\n"));
  footerPOV.append(QString("  translate <    %1,   %2,    0.0000 >\n").arg(mv[12]/10,7,'f',4).arg(mv[13]/10,7,'f',4));
  footerPOV.append(QString("  rotate    <     1.0000,    0.0000,    0.0000 >  //     Y\n"));
  footerPOV.append(QString("  rotate    <     0.0000,    1.0000,    0.0000 >  //     |_______X\n"));
  footerPOV.append(QString("  rotate    <     0.0000,    0.0000,    1.0000 >  //    /\n"));
  footerPOV.append(QString("                                                  //   Z\n"));
  footerPOV.append(QString(" }\n"));
  footerPOV.append(QString("#if (NoShadows)\nno_shadow\n#end\n} // __END union of objects\n\n"));

  bool success = f.open(QIODevice::WriteOnly|QIODevice::Text);
  if (success){
    f.write(headerPOV.toUtf8());
    f.write(visableAtoms.toUtf8());
    f.write(hydrogenAtoms.toUtf8());
    f.write(hiddenAtoms.toUtf8());
    f.write(qpeaks.toUtf8());
    f.write(bondsPOV.toUtf8());
    f.write(ringsPOV.toUtf8());
    f.write(unitCell.toUtf8());
    f.write(densityMaps.toUtf8());
    f.write(voron.toUtf8());
    f.write(labels.toUtf8());
    f.write(footerPOV.toUtf8());
    f.close();
    QFile ini(iniName);
    ini.open(QIODevice::WriteOnly|QIODevice::Text);
    body.clear();
    body.append(QString("Input_File_Name='%1';\nWidth=%2;\nHeight=%3;\nAntialias=on;\nAntialias_Threshold=0.3;\nOutput_File_Type=N;\nOutput_Alpha=on;\nOutput_File_Name='%4';\n\n")
        .arg(povName)
        .arg(int(chgl->width()*scalePic+0.5))
        .arg(int(chgl->height()*scalePic+0.5))
        .arg(pngName)
        );
    ini.write(body.toUtf8());
    ini.close();
    QString PovRayExe = QString();
    QSettings *povset = new QSettings( QSettings::IniFormat, QSettings::UserScope ,PROGRAM_NAME,mole.mynewnameis );
    povset->beginGroup("PovRay");
    PovRayExe = povset->value("PovRayExe","").toString();
    povset->endGroup();
    if ((PovRayExe.isEmpty())||(!QFileInfo(PovRayExe).isExecutable())) {
      PovRayExe.clear();
    }
    QString fn2;
    if (PovRayExe.isEmpty()){
      fn2=QFileDialog::getOpenFileName(this, tr("PovRay EXEcutable"), "povray","",nullptr,(useNativeDlg->isChecked())?noneopt:QFileDialog::DontUseNativeDialog  );
      if (fn2.isEmpty()) return;
    }
    if ((!fn2.isEmpty())&&(QFileInfo(fn2).isExecutable())) {
      povset->beginGroup("PovRay");
      povset->setValue("PovRayExe", fn2);
      PovRayExe = fn2;
      povset->endGroup();
    }//executable
    //run povray
    QString dn=dirName.section('/',0,-2);
#if defined Q_WS_WIN || defined Q_OS_WIN
    QStringList al=QString(QString("/EDIT*%1*/EDIT*%2*/RENDER*%2").arg(fn).arg(iniName)).split("*");//i think * should not be alowed in path names
    //qDebug()<<al;
#else
    QStringList al=QString(QString("+I%1*%2").arg(fn).arg(iniName)).split("*");

#endif
    extraProc = new QProcess(this);
#if (defined Q_WS_WIN || defined Q_OS_WIN)
#if (QT_VERSION >= 0x050700)
    extraProc->setProgram(PovRayExe);
    extraProc->setArguments(al);
    extraProc->setWorkingDirectory(dn);
    extraProc->setCreateProcessArgumentsModifier([] (QProcess::CreateProcessArguments *args) {args->flags &= ~CREATE_NO_WINDOW;});
    extraProc->startDetached();
#else
    extraProc->startDetached(PovRayExe,al,dn);
#endif
#else
    //not windows we need to parse the output of povray
    //qDebug()<<PovRayExe<<al<<dn;
    extraIndex = -21;
    extraProc->setWorkingDirectory(dn);                           // updateXLput()
    connect(extraProc,SIGNAL(readyReadStandardOutput ()),this,SLOT(updateExtraOutput()));
    connect(extraProc,SIGNAL(finished(int,QProcess::ExitStatus)),this,SLOT(updateExtraOutput()));
    connect(extraProc,SIGNAL(error(QProcess::ProcessError)),this,SLOT(updateExtraOutput())); 
#if (QT_VERSION >= 0x040600)
    QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
    extraProc->setProcessEnvironment(env);//Thanks to Dr. Pavlo Solntsev!! 
#else
    QStringList env = QProcess::systemEnvironment();
    extraProc->setEnvironment(env);
#endif
    //extraProc->startDetached(,al,dn);
    extraProc->start(PovRayExe,al);
    extraOutPut->setReadOnly(false);
    extraOutPut->setText(QString("Running POVRAY ...\n"));
    extraOutput->show();
    updateExtraOutput();
#endif

  }//success

}

void Window::savePovInc(QString povName){
  // Generates additional incremenmt file with color and other parameters

  //  QString iniName = "atoms.inc";
  //  QString fn=QFileDialog::getSaveFileName(this, tr("Export POV-Ray inc"), iniName, tr("POV-Ray inc (*.inc)"));

  QString incName = povName.section('.',0,-2);
  incName.append(".inc");

  //QString fn=QFileDialog::getSaveFileName(this, tr("Export POV-Ray inc"), iniName, tr("POV-Ray inc (*.inc)"));
  //if (fn.isEmpty()) return;

  QFile f(incName);
  QString body;
  body.append("#declare Triacontaeder=\n"
      "object {\n"
      "#local A=1.0;\n"
      "#local B=0.0;\n"
      "#local C=(sqrt(5.0)+1.0)/2.0;//1.618034\n"
      "#local D=C-1.0;//0.618034\n"
      "mesh2 {\n"
      "   vertex_vectors {\n"
      "     32,\n"
      "< B, -C,  A>, \n"
      "<-A,  B,  C>,<  A,  B,  C>,<  B,  D,  C>,\n"
      "< B, -D,  C>,<  A,  A,  A>,<  A, -A,  A>,\n"
      "< C,  B,  D>,<  C,  B, -D>,<  C,  A,  B>,\n"
      "< C, -A,  B>,< -C,  B,  D>,< -C,  A,  B>,\n"
      "<-C,  B, -D>,< -C, -A,  B>,<  A,  A, -A>,\n"
      "< D,  C,  B>,< -A,  A,  A>,< -D,  C,  B>,\n"
      "<-A,  A, -A>,<  B,  C, -A>,<  B,  C,  A>,\n"
      "<-A, -A, -A>,< -D, -C,  B>,<  D, -C,  B>,\n"
      "< A, -A, -A>,<  B, -C, -A>,<  B,  D, -C>,\n"
      "< A,  B, -C>,< -A, -A,  A>,<  B, -D, -C>,\n"
      "<-A,  B, -C>\n"
      "   }\n"
      "   face_indices {\n"
      "      60,\n"
      "  <  2,   3,   4>, <  2,   5,   3>, <  2,   4,   6>,\n"
      "  <  2,   7,   5>, <  2,   6,   7>, <  7,   8,   9>,\n"
      "  <  7,  10,   8>, < 11,  12,  13>, < 11,  13,  14>,\n"
      "  <  9,  15,  16>, <  9,   8,  15>, <  3,   1,   4>,\n"
      "  <  3,  17,   1>, < 18,  19,  12>, < 18,  20,  19>,\n"
      "  < 12,  19,  13>, <  3,  21,  17>, < 14,  22,  23>,\n"
      "  < 14,  13,  22>, < 24,  25,  10>, < 24,  26,  25>,\n"
      "  < 10,  25,   8>, < 15,  27,  20>, < 15,  28,  27>,\n"
      "  < 20,  27,  19>, <  1,  29,   4>, < 22,  30,  26>,\n"
      "  < 22,  31,  30>, <  1,  17,  11>, < 26,  30,  25>,\n"
      "  <  1,  11,  29>, < 25,  30,  28>, < 28,  30,  27>,\n"
      "  < 27,  30,  31>, <  4,   0,   6>, <  5,   9,  16>,\n"
      "  <  5,  16,  21>, < 21,  16,  18>, < 21,  18,  17>,\n"
      "  < 29,  14,  23>, < 29,  23,   0>, <  0,  23,  24>,\n"
      "  <  0,  24,   6>, < 16,  20,  18>, < 23,  26,  24>,\n"
      "  < 16,  15,  20>, <  3,   5,  21>, < 23,  22,  26>,\n"
      "  <  8,  28,  15>, <  8,  25,  28>, < 13,  19,  31>,\n"
      "  < 13,  31,  22>, < 19,  27,  31>, <  4,  29,   0>,\n"
      "  <  5,   7,   9>, < 17,  12,  11>, < 17,  18,  12>,\n"
      "  < 29,  11,  14>, <  6,  10,   7>, <  6,  24,  10>\n"
      "   }\n"
      "}//mesh\n"
      "};\n\n");
  body.append(QString("#macro DrawBond(at1,at2,rad,textur,t1,t2,ghost)\n"));
  body.append(QString("#if (ghost)\n"));
  body.append(QString("#local bc = (at1 + at2) * 0.5;\ncylinder {at1 bc rad texture { pigment{t1 blue 1.0 transmit 0.7} } }\ncylinder {at2 bc rad texture { pigment{t2  blue 1.0 transmit 0.7} } }\n"));
  body.append(QString("#else\n"));
  body.append(QString("#if (UniColorBonds)\n"));
  body.append(QString("    cylinder {at1 at2 rad texture { textur } }\n"));
  body.append(QString("#else\n"));
  body.append(QString("#local bc = (at1 + at2) * 0.5;\ncylinder {at1 bc rad texture { pigment{t1} } }\ncylinder {at2 bc rad texture { pigment{t2} } }\n"));
  body.append(QString("#end\n"));
  body.append(QString("#end\n"));
  body.append(QString("#end\n\n"));
  body.append(QString("#macro qbond(at1,at2)\n"));
  body.append(QString("    cylinder {at1 at2 0.005 texture { pigment{ color Color_Cnt} } }\n"));
  body.append(QString("##end\n\n"));
  body.append(QString("#macro qpeak(pos, r, cr, cg, cb, an)\n"));
  body.append(QString("object{\n"));
  body.append(QString("#local rf =1;\n"));
  body.append(QString("#switch (an)\n#case(-1)\nIcosahedron\nqpeakTexture(cr, cg, cb)\n#break\n#case(-42)\n"
        "Triacontaeder\nqpeakTexture(cr, cg, cb)\n#local rf =%1;\n"
        "#break\n#case(-66)\nDodecahedron\ntexture {pigment{ color Color_Cnt}}\n#local rf =1.25;\n\n#end\n").arg(0.5*mole.beloRad/mole.qPeakRad,0,'f',3));
  body.append(QString("scale <1, 1, 1> * r *rf \n"));
  body.append(QString("translate pos\n"));
  body.append(QString("}\n"));
  body.append(QString("#end\n\n"));
  body.append(QString("#macro DrawDashBond(at1,ct1,RadiusDash,LengthDash,TextureDash)\n"));
  body.append(QString("    #local L=VDist(at1,ct1);\n"));
  body.append(QString("    #local IL = L / LengthDash;\n"));
  body.append(QString("    #local strip = (ct1 - at1)/IL;\n"));
  body.append(QString("    #local i=0;\n"));
  body.append(QString("    #local tempXYZ=ct1;\n"));
  body.append(QString("    #while (i<IL )\n"));
  body.append(QString("        #local tempXYZ2=tempXYZ-strip;\n"));
  body.append(QString("        cylinder { tempXYZ tempXYZ2 RadiusDash texture { TextureDash } }\n"));
  body.append(QString("        #local tempXYZ=tempXYZ2-strip;\n"));
  body.append(QString("        #local i=i+2;\n"));
  body.append(QString("    #end\n"));
  body.append(QString("#end\n\n"));

  body.append(QString("#macro DrawDashBond2(at1,ct1,RadiusDash,LengthDash,T0,T1,T2)\n"));
  body.append(QString("    #local L=VDist(at1,ct1);\n"));
  body.append(QString("    #local IL = L / LengthDash;\n"));
  body.append(QString("    #local strip = (ct1 - at1)/IL;\n"));
  body.append(QString("    #local i=0;\n"));
  body.append(QString("    #local tempXYZ=ct1;\n"));
  body.append(QString("    #while (i<IL )\n"));
  body.append(QString("        #local tempXYZ2=tempXYZ-strip;\n"));
  body.append(QString("        #if (UniColorBonds)\n"
        "          cylinder { tempXYZ tempXYZ2 RadiusDash texture { T0 } }\n"
        "        #else\n"
        "          #if (i<IL/2)\n"
        "            cylinder { tempXYZ tempXYZ2 RadiusDash texture { pigment{T1} } }\n"
        "          #else\n"
        "            cylinder { tempXYZ tempXYZ2 RadiusDash texture { pigment{T2} } }\n"
        "          #end //IL/2\n"
        "        #end //unicolor\n"));
  body.append(QString("        #local tempXYZ=tempXYZ2-strip;\n"));
  body.append(QString("        #local i=i+2;\n"));
  body.append(QString("    #end\n"));
  body.append(QString("#end\n\n"));
  body.append(QString("#macro DrawArrow(at1,at2,rad,textur)\n"));
  body.append(QString("  #local SpaceBeforeAt2 = 0.2; // arrow should end before ellipsoide\n"));
  body.append(QString("  #local ArrowConeLength = rad*4;\n"));
  body.append(QString("  #local ArrowConeRadius = rad*2;\n"));
  body.append(QString("  #local ArrowVector = (at2 - at1);\n"));
  body.append(QString("  #local ShaftMeetsHead = at2 - vnormalize (ArrowVector) * (ArrowConeLength+SpaceBeforeAt2);\n"));
  body.append(QString("  #local ArrowPoint = at2 - vnormalize (ArrowVector) * SpaceBeforeAt2;\n"));
  body.append(QString("  cylinder {at1 ShaftMeetsHead radiu texture { textur } }\n"));
  body.append(QString("  cone {ShaftMeetsHead, ArrowConeRadius, ArrowPoint, 0 texture { textur } }\n"));
  body.append(QString("#end\n\n"));
  body.append(QString("#macro DrawArrowC(at1,at2,rad,colou)\n"));
  body.append(QString("  #local SpaceBeforeAt2 = 0.2; // arrow should end before ellipsoide\n"));
  body.append(QString("  #local ArrowConeLength = rad*4;\n"));
  body.append(QString("  #local ArrowConeRadius = rad*2;\n"));
  body.append(QString("  #local ArrowVector = (at2 - at1);\n"));
  body.append(QString("  #local ShaftMeetsHead = at2 - vnormalize (ArrowVector) * (ArrowConeLength+SpaceBeforeAt2);\n"));
  body.append(QString("  #local ArrowPoint = at2 - vnormalize (ArrowVector) * SpaceBeforeAt2;\n"));
  body.append(QString("  cylinder {at1 ShaftMeetsHead rad texture { pigment {color colou} finish { Shiny } } }\n"));
  body.append(QString("  cone {ShaftMeetsHead, ArrowConeRadius, ArrowPoint, 0 texture { pigment {color colou} finish { Shiny } } }\n"));
  body.append(QString("#end\n\n"));
  body.append(QString("#macro DrawRing(at1,at2,Ct)\n"));
  body.append(QString("#declare    w = vcross((at1-Ct),(at2-Ct));\n"));
  body.append(QString("#declare RadiusBig = vlength((at1+at2)/2 - Ct);\n"));
  body.append(QString("object {\n"));
  body.append(QString("      torus\n"));
  body.append(QString("        {        RadiusBig*.75, Dash_Radius\n"));
  body.append(QString("        texture { Bond_Texture  }\n"));
  body.append(QString("        }\n"));
  body.append(QString("      Reorient_Trans(<0, 1, 0>,w)\n"));
  body.append(QString("      translate Ct\n"));
  body.append(QString("      }\n"));
  body.append(QString("#end\n\n"));
  body.append(QString("#macro DrawCube(cL,colorCube,colorEdge)\n"));
  body.append(QString(" #local edgeR=cL/10;\n"));
  body.append(QString("   box{ <-cL,-cL,-cL>,<cL,cL,cL>  texture {  finish { Shiny } pigment {color colorCube } } }\n"));
  body.append(QString("   cylinder{ <-cL,-cL,-cL> < cL,-cL,-cL> edgeR texture {  finish { Shiny } pigment {color colorEdge } } }\n"));
  body.append(QString("   cylinder{ <-cL,-cL,-cL> <-cL, cL,-cL> edgeR texture {  finish { Shiny } pigment {color colorEdge } } }\n"));
  body.append(QString("   cylinder{ <-cL,-cL,-cL> <-cL,-cL, cL> edgeR texture {  finish { Shiny } pigment {color colorEdge } } }\n"));
  body.append(QString("   cylinder{ < cL, cL, cL> < cL, cL,-cL> edgeR texture {  finish { Shiny } pigment {color colorEdge } } }\n"));
  body.append(QString("   cylinder{ < cL, cL, cL> <-cL, cL, cL> edgeR texture {  finish { Shiny } pigment {color colorEdge } } }\n"));
  body.append(QString("   cylinder{ < cL, cL, cL> < cL,-cL, cL> edgeR texture {  finish { Shiny } pigment {color colorEdge } } }\n"));
  body.append(QString("   cylinder{ <-cL, cL, cL> <-cL, cL,-cL> edgeR texture {  finish { Shiny } pigment {color colorEdge } } }\n"));
  body.append(QString("   cylinder{ <-cL, cL, cL> <-cL,-cL, cL> edgeR texture {  finish { Shiny } pigment {color colorEdge } } }\n"));
  body.append(QString("   cylinder{ < cL,-cL, cL> < cL,-cL,-cL> edgeR texture {  finish { Shiny } pigment {color colorEdge } } }\n"));
  body.append(QString("   cylinder{ < cL,-cL, cL> <-cL,-cL, cL> edgeR texture {  finish { Shiny } pigment {color colorEdge } } }\n"));
  body.append(QString("   cylinder{ < cL, cL,-cL> < cL,-cL,-cL> edgeR texture {  finish { Shiny } pigment {color colorEdge } } }\n"));
  body.append(QString("   cylinder{ < cL, cL,-cL> <-cL, cL,-cL> edgeR texture {  finish { Shiny } pigment {color colorEdge } } }\n"));
  body.append(QString("#end\n\n"));
  body.append(QString("#declare Molekel_GrayLt       = color red 0.70 green 0.70 blue 0.70;\n"));
  body.append(QString("#declare Molekel_Red          = color red 0.70 green 0.00 blue 0.00;\n"));
  body.append(QString("#declare Molekel_Green        = color red 0.00 green 0.40 blue 0.00;\n"));
  body.append(QString("#declare Molekel_Blue         = color red 0.00 green 0.00 blue 0.60;\n"));
  body.append(QString("#declare Molekel_Yellow       = color red 0.80 green 0.80 blue 0.00;\n"));
  body.append(QString("#declare Molekel_Violet       = color red 0.60 green 0.00 blue 0.60;\n"));
  body.append(QString("#declare Molekel_GrayDk       = color red 0.25 green 0.25 blue 0.25;\n"));
  body.append(QString("#declare Molekel_BrownDk      = color red 0.30 green 0.20 blue 0.10;\n"));
  body.append(QString("#declare Molekel_BrownLt      = color red 0.45 green 0.40 blue 0.25;\n"));
  body.append(QString("#declare Lightblue            = color red 0.56 green 0.56 blue 1.00;\n"));
  body.append(QString("#declare DeepPink             = color red 1.00 green 0.08 blue 0.58;\n\n"));
  body.append(QString("#macro qpeakTexture(r, g, b)\n"));
  body.append(QString("	texture{\n"));
  body.append(QString("		pigment{\n"));
  body.append(QString("			color <r, g, b>\n"));
  body.append(QString("			filter 0.25\n"));
  body.append(QString("			transmit 0.25}\n"));
  body.append(QString("		finish{\n"));
  body.append(QString("			specular 0.6\n"));
  body.append(QString("			phong 0.2\n"));
  body.append(QString("			phong_size 80}\n}\n"));
  body.append(QString("	interior_texture{\n"));
  body.append(QString("		pigment{\n"));
  body.append(QString("			color <r, g, b>\n"));
  body.append(QString("			filter 0.666\n"));
  body.append(QString("			transmit 0.475\n"));
  body.append(QString("		}\n"));
  body.append(QString("		finish{\n"));
  body.append(QString("			specular 0\n"));
  body.append(QString("		}\n"));
  body.append(QString("	}\n"));
  body.append(QString("#end\n\n"));
  body.append(QString("#if (BW)\n"));
  body.append(QString("#declare diffPosCol = texture{ pigment{ color rgbt<%1,%2,%3,%4>}finish { diffuse 1.0 ambient 0.5 specular 0.3  }};\n")
      .arg(0.8)
      .arg(0.8)
      .arg(0.8)
      .arg(1.0-chgl->lintrans));
  body.append(QString("#declare diffMinCol = texture{ pigment{ color rgbt<%1,%2,%3,%4>}finish { diffuse 1.0 ambient 0.5 specular 0.3  }};\n")
      .arg(0.2)
      .arg(0.2)
      .arg(0.2)
      .arg(1.0-chgl->lintrans));
  body.append(QString("#declare FobsPosCol = texture{ pigment{ color rgbt<%1,%2,%3,%4>}finish { diffuse 1.0 ambient 0.5 specular 0.3  }};\n")
      .arg(0.4)
      .arg(0.4)
      .arg(0.4)
      .arg(1.0-chgl->lintrans));
  body.append(QString("#declare FobsMinCol = texture{ pigment{ color rgbt<%1,%2,%3,%4>}finish { diffuse 1.0 ambient 0.5 specular 0.3  }};\n")
      .arg(0.6)
      .arg(0.6)
      .arg(0.6)
      .arg(1.0-chgl->lintrans));
  body.append(QString("#else\n"));
  body.append(QString("#declare diffPosCol = texture{ pigment{ color rgbt<%1,%2,%3,%4>}finish { diffuse 1.0 ambient 0.5 specular 0.3  }};\n")
      .arg(chgl->dipc.redF())
      .arg(chgl->dipc.greenF())
      .arg(chgl->dipc.blueF())
      .arg(1.0-chgl->lintrans));
  body.append(QString("#declare diffMinCol = texture{ pigment{ color rgbt<%1,%2,%3,%4>}finish { diffuse 1.0 ambient 0.5 specular 0.3  }};\n")
      .arg(chgl->dimc.redF())
      .arg(chgl->dimc.greenF())
      .arg(chgl->dimc.blueF())
      .arg(1.0-chgl->lintrans));
  body.append(QString("#declare FobsPosCol = texture{ pigment{ color rgbt<%1,%2,%3,%4>}finish { diffuse 1.0 ambient 0.5 specular 0.3  }};\n")
      .arg(chgl->fopc.redF())
      .arg(chgl->fopc.greenF())
      .arg(chgl->fopc.blueF())
      .arg(1.0-chgl->lintrans));
  body.append(QString("#declare FobsMinCol = texture{ pigment{ color rgbt<%1,%2,%3,%4>}finish { diffuse 1.0 ambient 0.5 specular 0.3  }};\n")
      .arg(chgl->fomc.redF())
      .arg(chgl->fomc.greenF())
      .arg(chgl->fomc.blueF())
      .arg(1.0-chgl->lintrans));
  body.append(QString("#end\n"));
  body.append(QString("#declare Bond_Texture     = texture {\n"));
  body.append(QString("#if (BW)\npigment {color rgb<%1,%1,%1>}\n#else\n").arg(chgl->mol->bondColor.valueF()));
  body.append(QString("pigment {color rgb<%1, %2, %3>}\n#end\n").arg(chgl->mol->bondColor.redF()).arg(chgl->mol->bondColor.greenF()).arg(chgl->mol->bondColor.blueF()));
  body.append(QString("finish { diffuse 1.0 ambient 0.5 specular 1.0  } }\n\n"));
  body.append(QString("#declare HBond_Texture    = texture {\n"));
  body.append(QString("pigment {\n#if (BW)\ncolor rgb<0.7, 0.7, 0.7>\n#else\ncolor rgb<1, 1, 0>\n#end\n}\n"));
  body.append(QString("finish { diffuse 1.0 ambient 0.5 specular 1.0  } }\n\n"));
  QColor pcolor;

  body.append(QString("#declare Bond_Radius      = %1;\n").arg(mole.bondStrength));
  body.append(QString("#declare H_Radius         = Bond_Radius*1.3;\n"));
  body.append(QString("#declare Dash_Radius      = 0.6 * Bond_Radius;\n"));
  body.append(QString("#declare Dash_Length      = 0.14;\n"));
  body.append(QString("#declare HBond_Radius     = 0.6 * Bond_Radius;\n\n"));
  body.append(QString("#macro label(lab,pos,col,scal)\n"));
  body.append(QString("text{ttf atomfont lab 0.01, 0.0 texture{pigment{color col}finish{ambient 1.0}}\n"));
  body.append(QString("scale scal\ntransform InvMat\ntranslate pos\ntranslate EyeDir\nno_shadow\n}\n#end\n\n"));
  body.append(QString("#macro llabel(lab,pos,col,scal)\n"));
  body.append(QString("text{ttf atomfont lab 0.01, 0.0 texture{pigment{color col}finish{ambient 1.0}}\n"));
  body.append(QString("scale scal\ntranslate pos\nno_shadow\n}\n#end\n\n"));
  body.append(QString("#if(BW)   // _________________________________ set here colors for B&W modus\n"));
  //body.append(QString("#declare Color_Ct      = color rgb<%1,%1,%1>;\n"));
  //body.append(QString("#declare Equator_Ct    = color Gray05;\n"));
  for (int pt=1; pt<100; pt++){


  switch (pt){
    case 1: pcolor=QColor("lightskyblue");break;
    case 2: pcolor=QColor("darkgoldenrod");break;
    case 3: pcolor=Qt::green;break;
    case 4: pcolor=Qt::yellow;break;
    case 5: pcolor=QColor("orange");break;
    case 6: pcolor=Qt::black;break;
    case 7: pcolor=QColor("lightsalmon");break;
    case 8: pcolor=QColor("lightseagreen");break;

    default: pcolor=QColor::colorNames().at(qMin(pt,QColor::colorNames().size()-1));

  }
  pcolor.setAlpha(140);
  body.append(QString("#declare ptcol%1 = color rgbt<%2, %3, %4, %5>;\n")
              .arg(pt)
              .arg(pcolor.valueF())
              .arg(pcolor.valueF())
              .arg(pcolor.valueF())
              .arg(1.0-pcolor.alphaF())
              );
  }
  pcolor=QColor("aquamarine");
  pcolor.setAlpha(140);
  body.append(QString("#declare ptcolm1 = color rgbt<%1, %2, %3, %4>;\n")
              .arg(pcolor.valueF())
              .arg(pcolor.valueF())
              .arg(pcolor.valueF())
              .arg(1.0-pcolor.alphaF())
              );

  pcolor=QColor("olive");pcolor.setAlpha(140);
  body.append(QString("#declare ptcolm2 = color rgbt<%1, %2, %3, %4>;\n")
              .arg(pcolor.valueF())
              .arg(pcolor.valueF())
              .arg(pcolor.valueF())
              .arg(1.0-pcolor.alphaF())
              );

  pcolor=QColor("bisque");pcolor.setAlpha(140);
  body.append(QString("#declare ptcolm3 = color rgbt<%1, %2, %3, %4>;\n")
              .arg(pcolor.valueF())
              .arg(pcolor.valueF())
              .arg(pcolor.valueF())
              .arg(1.0-pcolor.alphaF())
              );
  pcolor=Qt::magenta;pcolor.setAlpha(140);
  body.append(QString("#declare ptcolmX = color rgbt<%1, %2, %3, %4>;\n")
              .arg(pcolor.valueF())
              .arg(pcolor.valueF())
              .arg(pcolor.valueF())
              .arg(1.0-pcolor.alphaF())
              );
  pcolor=QColor("fuchsia");
  pcolor.setAlpha(200);
  body.append(QString("#declare ptcol666 = color rgbt<%1, %2, %3, %4>;\n")
              .arg(pcolor.valueF())
              .arg(pcolor.valueF())
              .arg(pcolor.valueF())
              .arg(1.0-pcolor.alphaF())
              );
  for (int i=0; i<103; i++){
    body.append(QString("#declare Color_%2       = color rgb<%1,%1,%1>;\n").arg(chgl->mol->AtomColor[i].valueF()).arg(chgl->mol->pse(i)));
    body.append(QString("#declare Equator_%2     = color rgb<%1,%1,%1>;;\n").arg((chgl->mol->AtomStyle[i]&ATOM_STYLE_RINGS)
          ?((chgl->mol->AtomStyle[i]&ATOM_STYLE_WHITERING)? 0.95 : 0.05)
          :chgl->mol->AtomColor[i].valueF()).arg(chgl->mol->pse(i)));//ATOM_STYLE_WHITERING//ATOM_STYLE_RINGS
  }
  body.append(QString("#declare Color_Q       = color rgbt<0.5,0.5,0.5,0.5>;\n"));
  body.append(QString("#declare Color_Cnt     = color rgbt<0.2,0.2,0.2,0.5>;\n"));
  body.append(QString("#else   // _________________________________ set here colors for Color modus\n"));
  for (int pt=1; pt<100; pt++){


  switch (pt){
    case 1: pcolor=QColor("lightskyblue");break;
    case 2: pcolor=QColor("darkgoldenrod");break;
    case 3: pcolor=Qt::green;break;
    case 4: pcolor=Qt::yellow;break;
    case 5: pcolor=QColor("orange");break;
    case 6: pcolor=Qt::black;break;
    case 7: pcolor=QColor("lightsalmon");break;
    case 8: pcolor=QColor("lightseagreen");break;

    default: if (pt>0)
               pcolor=QColor::colorNames().at(qMin(pt,QColor::colorNames().size()-1));
             else pcolor=Qt::magenta;
  }
  pcolor.setAlpha(140);
  body.append(QString("#declare ptcol%1 = color rgbt<%2, %3, %4, %5>;\n")
              .arg(pt)
              .arg(pcolor.redF())
              .arg(pcolor.greenF())
              .arg(pcolor.blueF())
              .arg(1.0-pcolor.alphaF())
              );
  }
  pcolor=QColor("aquamarine");
  pcolor.setAlpha(140);
  body.append(QString("#declare ptcolm1 = color rgbt<%1, %2, %3, %4>;\n")
              .arg(pcolor.redF())
              .arg(pcolor.greenF())
              .arg(pcolor.blueF())
              .arg(1.0-pcolor.alphaF())
              );

  pcolor=QColor("olive");pcolor.setAlpha(140);
  body.append(QString("#declare ptcolm2 = color rgbt<%1, %2, %3, %4>;\n")
              .arg(pcolor.redF())
              .arg(pcolor.greenF())
              .arg(pcolor.blueF())
              .arg(1.0-pcolor.alphaF())
              );

  pcolor=QColor("bisque");pcolor.setAlpha(140);
  body.append(QString("#declare ptcolm3 = color rgbt<%1, %2, %3, %4>;\n")
              .arg(pcolor.redF())
              .arg(pcolor.greenF())
              .arg(pcolor.blueF())
              .arg(1.0-pcolor.alphaF())
              );
  pcolor=Qt::magenta;pcolor.setAlpha(140);
  body.append(QString("#declare ptcolmX = color rgbt<%1, %2, %3, %4>;\n")
              .arg(pcolor.redF())
              .arg(pcolor.greenF())
              .arg(pcolor.blueF())
              .arg(1.0-pcolor.alphaF())
              );
  pcolor=QColor("fuchsia");
  pcolor.setAlpha(200);
  body.append(QString("#declare ptcol666 = color rgbt<%1, %2, %3, %4>;\n")
              .arg(pcolor.redF())
              .arg(pcolor.greenF())
              .arg(pcolor.blueF())
              .arg(1.0-pcolor.alphaF())
              );
  for (int i=0; i<103; i++){
    body.append(QString("#declare Color_%1       = color rgb<%2,%3,%4>;\n").arg(chgl->mol->pse(i))
        .arg(chgl->mol->AtomColor[i].redF())
        .arg(chgl->mol->AtomColor[i].greenF())
        .arg(chgl->mol->AtomColor[i].blueF()));
    body.append(QString("#declare Equator_%2     = color rgb<%1,%1,%1>;;\n").arg((chgl->mol->AtomStyle[i]&ATOM_STYLE_RINGS)
          ?((chgl->mol->AtomStyle[i]&ATOM_STYLE_WHITERING)? 0.95 : 0.05)
          :chgl->mol->AtomColor[i].valueF()).arg(chgl->mol->pse(i)));//ATOM_STYLE_WHITERING//ATOM_STYLE_RINGS
  }
  body.append(QString("#declare Color_Q       = color rgbt<1.0,0.5,0.0,0.5>;\n"));
  body.append(QString("#declare Color_Cnt     = color Brown;\n"));
  //body.append(QString("#declare Color_Ct      = color Gray95;\n"));
  //body.append(QString("#declare Equator_Ct    = color Gray05;\n"));
  body.append(QString("#end    // _________________________________ end of Color modus\n"));

  bool success = f.open(QIODevice::WriteOnly|QIODevice::Text);
  if (success){
    f.write(body.toUtf8());
    f.close();
  }
}

void Window::saveScene(){
  glGetDoublev(GL_MODELVIEW_MATRIX,chgl->MM);

  QList<QByteArray> supo = QImageWriter::supportedImageFormats ();
  QString formats;
  saveName = dirName;
  saveName.replace(dirName.size()-4,4,".png");
  QString selectedFilter="png-file (*.png)";
  for (int i=0; i<supo.size(); i++){
    if ((!QString(supo.at(i)).contains("ps",Qt::CaseInsensitive)) &&
        (!QString(supo.at(i)).contains(QRegExp("[A-Z]"))))
      formats+=QString("%1-file (*.%1)%2").arg(QString(supo.at(i))).arg(((i+1)<supo.size())?";;":"");
  }
  int
    a = int(chgl->width()*scalePic+0.5),
      b = int(chgl->height()*scalePic+0.5),
      c = int(chgl->myFont.pointSize ()*scalePic+0.5),
      d = chgl->width(),
      e = chgl->height(),
      f = chgl->myFont.pointSize ();
  QString fileName = QFileDialog::getSaveFileName(this,QString("Save a screen shot with %1 x %2 pixels").arg(a).arg(b), saveName,formats,&selectedFilter);
  if (!fileName.isEmpty()){
    QString endung=selectedFilter.section('*',1,1).section(')',0,0);
    if (!fileName.endsWith(endung)) fileName.append(endung);
    chgl->noWaitLabel=true;
    chgl->exporting=true;
    chgl->myFont.setPointSize(c);
    mole.saveProg=mole.g_Program;
    QPixmap   map;

    if (!mole.useShaders||scalePic!=1.0) map= chgl->renderPixmap(a,b);
    if ((mole.useShaders&&scalePic==1.0)||map.isNull ()){
      if (QGLFramebufferObject::hasOpenGLFramebufferObjects()) {
        QImage mapi=chgl->grabFrameBuffer(false);
        //printf("hasOpenGLFramebufferObjects\n");
        mapi.save(fileName);
      }else{
        QPixmap pixmap = QPixmap::grabWindow( chgl->winId() );
        pixmap.save(fileName);
      }
    }else map.save(fileName);
    mole.g_Program=mole.saveProg;
    if(!separateLabelFile->isChecked()) {
      QPixmap fmap = QPixmap(fileName);
      QPainter *paint = new QPainter(&fmap);
      paint->setPen(QPen(chgl->labelColor));
      paint->setFont(chgl->myFont);
      for (int n=0; n<chgl->LabelZ.size(); n++){
        if ((!(mole.AtomStyle[chgl->LabelZ.at(n).an]&ATOM_STYLE_NOLABEL)))
          paint->drawText(chgl->LabelZ.at(n).x,chgl->LabelZ.at(n).y,chgl->LabelZ.at(n).l);
      }
      paint->end();
      fmap.save(fileName);
    }
    else{
      QPixmap fmap = QPixmap(a,b);
      fmap.fill(QColor(128,128,128,0));
      QPainter *paint = new QPainter(&fmap);
      paint->setPen(QPen(chgl->labelColor));
      paint->setFont(chgl->myFont);
      for (int n=0; n<chgl->LabelZ.size(); n++){
        if ((!(mole.AtomStyle[chgl->LabelZ.at(n).an]&ATOM_STYLE_NOLABEL)))
          paint->drawText(chgl->LabelZ.at(n).x,chgl->LabelZ.at(n).y,chgl->LabelZ.at(n).l);
      }
      paint->end();
      QString fn2=fileName;
      fn2.insert(fileName.lastIndexOf("."),"_labels");
      fmap.save(fn2);
    }
    saveName=fileName;
    chgl->exporting=false;
  }
  chgl->myFont.setPointSize(f);
  chgl->ww=d;
  chgl->wh=e;
  chgl->noWaitLabel=false;
}

void Window::infoKanalNews(const QString& s){
  QString alt = infoKanal->toHtml();
  //  printf("\n\n\n%s\n\n\n",(const char *)alt.toLocal8Bit());
  alt.remove(QRegExp("ERROR [^!]*!"));
  alt.remove(QRegExp("<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:large; color:#ff0000;\"><br /></span></p>",
        Qt::CaseInsensitive,QRegExp::FixedString));
  alt.remove(QRegExp("<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:large; color:#ff0000;\"></span></p>"
        ,Qt::CaseInsensitive,QRegExp::FixedString));
  alt.append(s);
  infoKanal->setHtml(alt);
  QTextCursor c = infoKanal->textCursor();
  c.movePosition(QTextCursor::End);
  infoKanal->setTextCursor(c);
  infoKanal->ensureCursorVisible();
  if (chgl->toggleDockWidgets->isChecked()) return;
  if ( enterRenameMode->isChecked()) return;
  dock->show();
  dock->raise();
}

void Window::shx_editor(QString filename){
  if (otherOpenFiles){
    editor->clear();
    editor->document()->disconnect();
    actionUndo->disconnect();
    actionRedo->disconnect();
    actionCut->disconnect();
    actionCopy->disconnect();
    actionPaste->disconnect();
  }
  altursize=0;
  QFile shxf(filename);
  if (shxf.open(QIODevice::ReadOnly|QIODevice::Text)){
    actionCut->setEnabled(false);
    actionCopy->setEnabled(false);
    QString s=shxf.readAll().replace('\0','~');
    s=s.replace(QRegExp("[ \t]+\n")," \n");// printf("remove non used spaces\n");
    editor->setPlainText(s);
    actionSave->setEnabled(false);
    actionHFix->setDisabled(false);
    setWindowModified(editor->document()->isModified());
    editor->highlighter->setDocument(editor->document());
    connect(editor->document(), SIGNAL(modificationChanged(bool)),
        actionSave, SLOT(setEnabled(bool)));
    connect(editor->document(), SIGNAL(modificationChanged(bool)),
        actionHFix, SLOT(setDisabled(bool)));
    connect(editor->document(), SIGNAL(modificationChanged(bool)),
        this, SLOT(setWindowModified(bool)));
    connect(editor->document(), SIGNAL(undoAvailable(bool)),
        actionUndo, SLOT(setEnabled(bool)));
    connect(editor->document(), SIGNAL(undoCommandAdded ()),
        this, SLOT(wasRename()));
    connect(editor->document(), SIGNAL(undoCommandAdded()),this,SLOT(wasDelete()));
    connect(editor->document(), SIGNAL(redoAvailable(bool)),
        actionRedo, SLOT(setEnabled(bool)));
    connect(actionUndo, SIGNAL(triggered()), editor, SLOT(undo()));
    connect(actionUndo,SIGNAL(triggered()),this,SLOT(undoRename()));
    connect(actionRedo, SIGNAL(triggered()), editor, SLOT(redo()));
    connect(actionRedo, SIGNAL(triggered()),this, SLOT(redoRename()));
    connect(actionCut, SIGNAL(triggered()), editor, SLOT(cut()));
    connect(actionCopy, SIGNAL(triggered()), editor, SLOT(copy()));
    connect(actionPaste, SIGNAL(triggered()), editor, SLOT(paste()));
    connect(editor, SIGNAL(copyAvailable(bool)), actionCut, SLOT(setEnabled(bool)));
    connect(editor, SIGNAL(copyAvailable(bool)), actionCopy, SLOT(setEnabled(bool)));
    shxf.close();    
    shxEditorDock->setWindowTitle(title);
    shxEditorDock->show();
    shxEditorDock->raise();
    actionSearch->setEnabled(true);
    actionNext->setEnabled(true);
    actionPrev->setEnabled(true);
    otherOpenFiles=true;
    editor->fv=fvar;
    QTextCursor c1=editor->textCursor();
    c1.movePosition(QTextCursor::End,QTextCursor::MoveAnchor);
    int maxPos=c1.position();
    c1.movePosition(QTextCursor::Start,QTextCursor::MoveAnchor);
    int pos1=0;
    mole.einstellung->beginGroup("Cursor");
    if (mole.einstellung->contains("lastCursorHash"))
      myHash=mole.einstellung->value("lastCursorHash").toHash();
    //qDebug()<<myHash;
    pos1=myHash.value(dirName).toInt();
    mole.einstellung->endGroup();
    if ((myHash.contains(dirName))&&(pos1<=maxPos)&&(pos1>=0))
      c1.setPosition(pos1,QTextCursor::MoveAnchor);
    if (!c1.isNull()) editor->setTextCursor(c1);
    editor->centerCursor();
    if (focusSet) editor->setFocus(Qt::OtherFocusReason);
    if (!title.contains("!!Empty!!"))infoKanalNews(fvarinfo);
  }
  //printf("shx_edit\n");
  chgl->pause=false;
//  printf("%d\n",__LINE__);
  if (title.contains("!!Empty!!")) infoKanalNews("<font size=+2 color=red>No atoms in file!</font>");
}

bool Window::fileSave(bool spell, bool loadafter){
  if (spell) {
    spellCheck();
  }
  if (FehlerTeufel) {
    QMessageBox::warning(0,"Syntax-errors", "Syntax-errors were found in the file please correct them before saving! (Saving more frequently might reduce errors caused by this GUI)",QMessageBox::Ok,QMessageBox::Ok);
    return false;
  }
  QFile f(dirName);

  if ((chgl->rotze!=-1)&&(chgl->rotze<mole.asymm.size())) {
      popel = mole.asymm.at(chgl->rotze).orginalLine.left(80).trimmed();
  } else {
      popel = "";
      //printf("%d %d!\n", chgl->rotze, mole.asymm.size());
      chgl->rotze=-1;
  }

  f.open(QIODevice::ReadOnly|QIODevice::Text);
  QString alterScheis=f.readAll();
  QFileInfo fi(f);
  f.close();
  QTextCursor c=editor->textCursor();
  if (!c.isNull()){
    myHash[dirName]=c.position();
    mole.einstellung->beginGroup("Cursor");
    mole.einstellung->setValue("lastCursorHash", myHash );
    mole.einstellung->endGroup();
  }
  bool success = f.open(QIODevice::WriteOnly|QIODevice::Text);
  if (success){
    f.write(editor->toPlainText().toLatin1());
    f.close();
    QString dn=dirName.section('/',0,-2),
            argument=dirName.section('/',-1);
    QDir work=QDir(QString("%1/%2saves/").arg(dn).arg(PROGRAM_NAME));
    if (!work.exists ( QString("%1/%2saves/").arg(dn).arg(PROGRAM_NAME))) work.mkdir (QString("%1/%2saves/").arg(dn).arg(PROGRAM_NAME));
    QString saveHistName=QString("%1/%2saves/SAVEHIST").arg(dn).arg(PROGRAM_NAME);
    QFile sahi(saveHistName);
    sahi.open(QIODevice::Append|QIODevice::Text);
    sahi.write(QString("Entry|@|%1|@|%2|@|\n").arg(fi.lastModified().toString(Qt::ISODate)).arg(argument).toLatin1());
    sahi.write(alterScheis.toLatin1());
    editor->document()->setModified(false);
    if (loadafter) {
      loadFile(dirName);
    }
  }
  else
    infoKanalNews(QString("<font color=\"red\">%1 could not be opened for writing!</font>").arg(f.fileName()));
  return success;
}

bool Window::fileSaveAs(){
  spellCheck();
  if (FehlerTeufel) {
    QMessageBox::warning(0,"Syntax-errors", "Syntax-errors were found in the file please correct them before saving! (Saving more frequently might reduce errors caused by this GUI)",QMessageBox::Ok,QMessageBox::Ok);
    return false;
  }
  QString fn=QFileDialog::getSaveFileName(this, tr("Save As ..."), dirName, tr("SHELX-files (*.res *.ins)"));
  if (fn.isEmpty()) return false;
  QFile f(fn);
  bool success = f.open(QIODevice::WriteOnly|QIODevice::Text);
  if (success){
    f.write(editor->toPlainText().toLatin1());
    f.close();
    editor->document()->setModified(false);
    loadFile(dirName=fn);
  }
  return success;
}

void Window::unique(){
  if (mole.asymm.isEmpty()) return;
  mole.enviSDM(2.5);
  if (mole.maxmols()==0)sdm();
  QSet<int> molecules;
  QList<int> flags;
  for (int i=0; i<mole.asymm.size(); i++) if (molecules.contains(mole.asymm.at(i).molindex)){
    flags.append(-1);
  }else {
    molecules.insert(mole.asymm.at(i).molindex);
    flags.append(1);
  }
  int finished=1;
  do{
    finished=1;
    for (int i=0; i<mole.envi_sdm.size(); i++){
      if ((flags.at(mole.envi_sdm.at(i).a1)*flags.at(mole.envi_sdm.at(i).a2)==-1)&&
          ( mole.asymm.at(mole.envi_sdm.at(i).a1).molindex==mole.asymm.at(mole.envi_sdm.at(i).a2).molindex ))  {
        if ((mole.asymm[mole.envi_sdm.at(i).a1].an<0)||(mole.asymm[mole.envi_sdm.at(i).a2].an<0))continue;
        if (flags.at(mole.envi_sdm.at(i).a1)==1)continue;
        if ((mole.envi_sdm.at(i).sn==0)&&(mole.envi_sdm.at(i).floorD==V3(0,0,0))) {
          flags[mole.envi_sdm.at(i).a1]=1;
          //          flags[mole.envi_sdm.at(i).a2]=1;
          finished=0;
          break;
        }
        mole.asymm[mole.envi_sdm.at(i).a1].frac = 
          mole.cell.symmops.at(mole.envi_sdm.at(i).sn) * 
          mole.asymm[mole.envi_sdm.at(i).a1].frac + 
          mole.cell.trans.at(mole.envi_sdm.at(i).sn) - 
          mole.envi_sdm.at(i).floorD;
        flags[mole.envi_sdm.at(i).a1]=1;
        //        flags[mole.envi_sdm.at(i).a2]=1;
        mole.frac2kart(mole.asymm[mole.envi_sdm.at(i).a1].frac, mole.asymm[mole.envi_sdm.at(i).a1].pos);
        finished=0;

        mole.enviSDM(2.5);
        break;
      }
    }
  }while (!finished);
  mole.showatoms.clear();
  mole.showbonds.clear();
  chgl->mol->showatoms.clear();
  chgl->mol->showbonds.clear();
  chgl->mol->selectedatoms.clear();
  for (int o=0; o<mole.asymm.size();o++){
    mole.showatoms.append(mole.asymm[o]);
  }
  mole.sdmcompleter();
  mole.showbonds =
    mole.connecting(mole.showatoms);
  chgl->setMolecule(&mole);
  chgl->mol->selectedatoms.clear();
  chgl->murx=__LINE__;

  QTextDocument *document = editor->document();
  QTextCursor cursor = editor->textCursor();
  cursor.beginEditBlock ();

  for (int i=0; i<mole.asymm.size();i++){
    cursor.movePosition(QTextCursor::Start);
    QString label=mole.asymm.at(i).orginalLine.left(80).trimmed();
    cursor = document->find(label ,cursor);  

    if (cursor.isNull()){
      cursor = editor->textCursor();    
      cursor.movePosition(QTextCursor::Start);
      label.chop(10);
      cursor = document->find(label,cursor);
      if (cursor.isNull()) {
        cursor = editor->textCursor();
      }
    }
    QString vorherig,neues;
    cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
    cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
    while (cursor.selectedText().endsWith("=")) {
      cursor.movePosition(QTextCursor::Down,QTextCursor::KeepAnchor);
      cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);  
    }
    neues = vorherig= cursor.selectedText();
    QStringList sl = vorherig.split(QRegExp("\\s+"));
    sl.removeOne("=");
    if (sl.size()>=7)
      neues=QString("%1  %2  %3 %4 %5 %6 %7 ")
        .arg(mole.asymm.at(i).Label.section('_',0,0),-4)
        .arg(qMax(1,editor->sfac.indexOf(mole.asymm.at(i).an)+1))
        .arg(mole.asymm.at(i).frac.x,10,'f',6)
        .arg(mole.asymm.at(i).frac.y,10,'f',6)
        .arg(mole.asymm.at(i).frac.z,10,'f',6)
        .arg(mole.asymm.at(i).sof_org,9,'f',5)
        .arg((mole.asymm.at(i).isIso)?mole.asymm.at(i).ufiso_org:QString("%1").arg(mole.asymm.at(i).uf.m11,9,'f',5));
    mole.asymm[i].orginalLine=neues;
    if (mole.asymm.at(i).an<0) {
      neues.append(QString("%1 ")
          .arg(mole.asymm.at(i).peakHeight,9,'f',2));
    } else
      if (!mole.asymm.at(i).isIso){
        neues.append(QString("%1 =\n    %2 %3 %4 %5")
            .arg(mole.asymm.at(i).uf.m22,9,'f',5)
            .arg(mole.asymm.at(i).uf.m33,9,'f',5)
            .arg(mole.asymm.at(i).uf.m23,9,'f',5)
            .arg(mole.asymm.at(i).uf.m13,9,'f',5)
            .arg(mole.asymm.at(i).uf.m12,9,'f',5));
      } 
    cursor.deleteChar();
    cursor.insertText(neues);

  }//i
  cursor.endEditBlock ();
  molecules.clear();
  flags.clear();
  mole.envi_sdm.clear();
  bool growYes=chgl->fuse->isVisible ();
  chgl->mol->fuse();
  if (growYes) chgl->mol->grow();
  chgl->pause=false;
//  printf("%d\n",__LINE__);

}

void Window::editorIsVisible(bool vis){editor->uCanSeeMe=vis;}//isVisible is also true if widget is stacked behind an other

void Window::outputIsVisible(bool vis){xlPutor->uCanSeeMe=vis;}

void Window::hideToolz(bool b){

  editToolBar->setVisible(!b);
  refineToolBar->setVisible(!b);
  bottomToolBar->setVisible(!b);
  fito->setVisible(!b);
  vito->setVisible(!b);
  update();
}

void Window::updateLC(){
  QTextCursor tc = editor->textCursor();
  int l,c;
  l=tc.blockNumber()+1;
  c=tc.columnNumber()+1; 
  lineColumn->setText(QString("Line: <b>%1</b> | Col: <b>%2</b>").arg(l,5).arg(c,5));
  editor->update();
  lineColumn->update();
}

void Window::paintEvent(QPaintEvent *){
  static int ap=0;
  if (chgl->stereo_mode==1){ 
    int p=geometry().y()+chgl->y();
    //    chgl->minus=(p%2)?-1:1;
    chgl->minus=(p%2)?1:-1;
    if (p!=ap) chgl->updateGL();
    ap=p;
  }
}

void Window::moveEvent(QMoveEvent *) {
  static int ap=0;
  if (chgl->stereo_mode==1){ 
    int p=geometry().y()+chgl->y();
    chgl->minus=(p%2)?-1:1;
    if (p!=ap) chgl->updateGL();
    ap=p;
  }
}

void Window::styleDialog(){
  EacDlg *eac = new EacDlg(chgl->mol);
  eac->exec();
  //printf("hi%d\n",__LINE__);
  mole.showbonds = mole.connecting(mole.showatoms);//das ist notwendig weil es in eac ebenfalls aufgerufen wird und dort lbonds ueberschreibt.

  chgl->murx=__LINE__;
  chgl->setFocus(Qt::OtherFocusReason);
  chgl->show();
  chgl->raise();
  chgl->updateGL();
  delete eac;
}

void Window::effuenf(){
  chgl->murx=__LINE__;
  chgl->setFocus(Qt::OtherFocusReason);
  chgl->show();
  chgl->raise();
  chgl->updateGL();
}

void Window::selectInStructure(const QString &info){
  chgl->mol->selectedatoms.clear();
  for (int i=0; i<chgl->mol->showatoms.size(); i++){
    if (chgl->mol->showatoms.at(i).orginalLine.size()<30) continue;
    if (info.contains(chgl->mol->showatoms.at(i).orginalLine,Qt::CaseInsensitive)){
      chgl->mol->selectedatoms.append(chgl->mol->showatoms[i]);
      chgl->mol->selectedatoms.last().style=i;
    }
  }
  chgl->updateBondActions();
  chgl->updateGL();
  update();
  chgl->updateGL();
}

void Window::findInStructure(const QString &info){
  int index=-1;
  for (int i=0; i<chgl->mol->showatoms.size(); i++){
    if (chgl->mol->showatoms.at(i).orginalLine.contains(info,Qt::CaseInsensitive)) {index=i;break;}
    if (info.contains(chgl->mol->showatoms.at(i).orginalLine,Qt::CaseInsensitive)) {index=i;break;}
  }
  if (index!=-1){
    chgl->rotze=index;
    chgl->rCenter->show();
    chgl->mol->selectedatoms.clear();
    chgl->mol->selectedatoms.append(chgl->mol->showatoms[index]);
    chgl->mol->selectedatoms.last().style=index;
    chgl->updateBondActions();
    chgl->updateGL();
    update();
    chgl->updateGL();
  }
}

void Window::openIncludeFile(const QString &info){
  QString dn=dirName.section('/',0,-2);
  IncludeEditor *ie = new IncludeEditor(info,dn,this);
  ie->exec();
}

void Window::jumpToAtom(int index){
  if ((chgl->inRenameMode)&&(enterRenameMode->isChecked())) {
    renameThisAtom(index);
    return;
  }
  if (chgl->inRenameMode) renamUpdate(false);
  QString label = mole.showatoms.at(index).orginalLine.left(80).trimmed();
  //  qDebug()<<index<<mole.showatoms.at(index).Label<<label;
  QTextDocument *document = editor->document();
  QTextCursor cursor = editor->textCursor();
  cursor.movePosition(QTextCursor::Start);
  cursor = document->find(label,cursor);
  if (cursor.isNull()){
    cursor = editor->textCursor();    
    cursor.movePosition(QTextCursor::Start);
    label.chop(10);
    cursor = document->find(label,cursor);
    if (cursor.isNull()) cursor = editor->textCursor();
    cursor.movePosition(QTextCursor::Start);
    label = mole.showatoms.at(index).orginalLine.left(80).simplified();
    cursor = document->find(label,cursor);
    if (cursor.isNull()) cursor = editor->textCursor();
  }
  cursor.movePosition(QTextCursor::StartOfLine);
  editor->setTextCursor(cursor);
  editor->centerCursor();
  cursor.clearSelection();
  editor->setTextCursor(cursor);
  editor->setFocus();
  if (chgl->toggleDockWidgets->isChecked()) return;
  shxEditorDock->show();
}

void Window::rufmode(){

  mole.einstellung->beginGroup("Labeling");
  mole.einstellung->setValue("AutoUnused",rufModeBox->isChecked());
  mole.einstellung->endGroup();
  bool inuse=isLabelInUse();
  if ((inuse)&&(rufModeBox->isChecked())&&((labelIndex==-1)||(indexIncr->isChecked()))){
    if (sufixBox->currentIndex()<0) sufixBox->setCurrentIndex(0);
    while (isLabelInUse()){
      //      qDebug()<<"zz"<<labelIndex;
      sufixBox->setCurrentIndex((sufixBox->count()>sufixBox->currentIndex()+1)?sufixBox->currentIndex()+1:sufixBox->currentIndex());
      updateLabel();
    }
    inuse=isLabelInUse();
  }else
    if ((rufModeBox->isChecked())){
      if (nowaste) labelIndex=1;
      while (isLabelInUse()) {
        labelIndex++;
        if (labelIndex>999) {
          labelIndex=00;
          sufixBox->setCurrentIndex((sufixBox->count()>sufixBox->currentIndex()+1)?sufixBox->currentIndex()+1:sufixBox->currentIndex());
          updateLabel();
        }
      }
      inuse=isLabelInUse(); 
      indexSpin->setValue(labelIndex); 
    }
  updateLabel();
}

void Window::changeElemetofLabel(const QString &pse){
  labelPSE=pse;
  bool inuse=isLabelInUse();
  if ((inuse)&&(rufModeBox->isChecked())&&((labelIndex==-1)||(indexIncr->isChecked()))){
    if (sufixBox->currentIndex()<0) sufixBox->setCurrentIndex(0);
    while (isLabelInUse()){
      sufixBox->setCurrentIndex((sufixBox->count()>sufixBox->currentIndex()+1)?sufixBox->currentIndex()+1:sufixBox->currentIndex());
      updateLabel();
    }
    inuse=isLabelInUse();
  }else
    if ((rufModeBox->isChecked())){
      if (!nextLabel.contains("any"))labelIndex=1;
      while (isLabelInUse()) {
        labelIndex++;
        if (labelIndex>999) {
          labelIndex=00;
          sufixBox->setCurrentIndex((sufixBox->count()>sufixBox->currentIndex()+1)?sufixBox->currentIndex()+1:sufixBox->currentIndex());
          updateLabel();
        }
      }
      inuse=isLabelInUse(); 
      indexSpin->setValue(labelIndex); 
    }
  if ((nextLabel.contains("any"))){
    QString altLabel="";
    for (int i=1; i<109; i++){
      if (pserbt[i]->isVisible()) {
        if (labelIndex<0) altLabel+=QString("%1%2").arg(pserbt[i]->text()).arg(labelSuffix);
        else altLabel+=QString("%1%2%3").arg(pserbt[i]->text()).arg(labelIndex).arg(labelSuffix);
        altLabel.append(", ");
      }
    }
    altLabel.remove(QRegExp(", $"));
    int lakoma = altLabel.lastIndexOf(", ");
    if (lakoma>1) altLabel.replace(lakoma,2," or ");
    nextNameL->setText(QString("Next Label is:<br> <font size=\"+1\" color=\"%2\">%1</font>")
        .arg(altLabel)
        .arg("blue"));
  } else {
    nextNameL->setText(QString("Next Label is:<br> <font size=\"+1\" color=\"%2\">%1</font>%3")
        .arg(nextLabel)
        .arg((inuse)?"red":"green")
        .arg((inuse)?"<font size=\"-19\"><br>Label is already in use. You may change ResidueNr or Part.</font>":""));
  }
  update();
}

void Window::changeIndexofLabel(int i){
  labelIndex=i;
  bool inuse=isLabelInUse();
  if ((inuse)&&(rufModeBox->isChecked())&&((labelIndex==-1)||(indexIncr->isChecked()))){
    if (sufixBox->currentIndex()<0) sufixBox->setCurrentIndex(0);
    while (isLabelInUse()){
      sufixBox->setCurrentIndex((sufixBox->count()>sufixBox->currentIndex()+1)?sufixBox->currentIndex()+1:sufixBox->currentIndex());
      updateLabel();
    }
    inuse=isLabelInUse();
  }else
    if ((rufModeBox->isChecked())){
      if (!nextLabel.contains("any"))labelIndex=1;
      while (isLabelInUse()) {
        labelIndex++;
        if (labelIndex>999) {
          labelIndex=00;
          sufixBox->setCurrentIndex((sufixBox->count()>sufixBox->currentIndex()+1)?sufixBox->currentIndex()+1:sufixBox->currentIndex());
          updateLabel();
        }
      }
      inuse=isLabelInUse(); 
      indexSpin->setValue(labelIndex); 
    }


  if ((nextLabel.contains("any"))){
    QString altLabel="";
    for (int i=1; i<109; i++){
      if (pserbt[i]->isVisible()) {
        if (labelIndex<0) altLabel+=QString("%1%2").arg(pserbt[i]->text()).arg(labelSuffix);
        else altLabel+=QString("%1%2%3").arg(pserbt[i]->text()).arg(labelIndex).arg(labelSuffix);
        altLabel.append(", ");
      }
    }
    altLabel.remove(QRegExp(", $"));
    int lakoma = altLabel.lastIndexOf(", ");
    if (lakoma>1) altLabel.replace(lakoma,2," or ");
    nextNameL->setText(QString("Next Label is:<br> <font size=\"+1\" color=\"%2\">%1</font>")
        .arg(altLabel)
        .arg("blue"));
  } else {
    nextNameL->setText(QString("Next Label is:<br> <font size=\"+1\" color=\"%2\">%1</font>%3")
        .arg(nextLabel)
        .arg((inuse)?"red":"green")
        .arg((inuse)?"<font size=\"-19\"><br>Label is already in use. You may change ResidueNr or Part.</font>":""));
  }
  update();
}

void Window::changeSuffixofLabel(const QString &fix){
  labelSuffix=fix;
  bool inuse=isLabelInUse();
  if ((inuse)&&(rufModeBox->isChecked())&&((labelIndex==-1)||(indexIncr->isChecked()))){
    if (sufixBox->currentIndex()<0) sufixBox->setCurrentIndex(0);
    while (isLabelInUse()){
      sufixBox->setCurrentIndex((sufixBox->count()>sufixBox->currentIndex()+1)?sufixBox->currentIndex()+1:sufixBox->currentIndex());
      updateLabel();
    }
    inuse=isLabelInUse();
  }else if((inuse)&&(rufModeBox->isChecked())&&(labelIndex!=-1)){
    updateLabel();
    inuse=isLabelInUse();
  }
  if ((nextLabel.contains("any"))){
    QString altLabel="";
    for (int i=1; i<109; i++){
      if (pserbt[i]->isVisible()) {
        if (labelIndex<0) altLabel+=QString("%1%2").arg(pserbt[i]->text()).arg(labelSuffix);
        else altLabel+=QString("%1%2%3").arg(pserbt[i]->text()).arg(labelIndex).arg(labelSuffix);
        altLabel.append(", ");
      }
    }
    altLabel.remove(QRegExp(", $"));
    int lakoma = altLabel.lastIndexOf(", ");
    if (lakoma>1) altLabel.replace(lakoma,2," or ");
    nextNameL->setText(QString("Next Label is:<br> <font size=\"+1\" color=\"%2\">%1</font>")
        .arg(altLabel)
        .arg("blue"));
  } else {
    nextNameL->setText(QString("Next Label is:<br> <font size=\"+1\" color=\"%2\">%1</font>%3")
        .arg(nextLabel)
        .arg((inuse)?"red":"green")
        .arg((inuse)?"<font size=\"-19\"><br>Label is already in use. You may change ResidueNr or Part.</font>":""));
  }
  update();
}

void Window::updateLabel(){
  indexSpin->setValue(labelIndex);
  //  if ((rufModeBox->isChecked())&&(!nextLabel.contains("any"))) labelIndex=1;
  bool inuse=isLabelInUse();
  if ((inuse)&&(rufModeBox->isChecked())){
    while (isLabelInUse()) {
      labelIndex++;
      if (labelIndex>999) {
        labelIndex=00;
        sufixBox->setCurrentIndex((sufixBox->count()>sufixBox->currentIndex()+1)?sufixBox->currentIndex()+1:sufixBox->currentIndex());
        updateLabel();
      }
    }
    inuse=isLabelInUse(); 
    indexSpin->setValue(labelIndex); 
  }
  if ((nextLabel.contains("any"))){
    QString altLabel="";
    for (int i=1; i<109; i++){
      if (pserbt[i]->isVisible()) {
        if (labelIndex<0) altLabel+=QString("%1%2").arg(pserbt[i]->text()).arg(labelSuffix);
        else altLabel+=QString("%1%2%3").arg(pserbt[i]->text()).arg(labelIndex).arg(labelSuffix);
        altLabel.append(", ");
      }
    }
    altLabel.remove(QRegExp(", $"));
    int lakoma = altLabel.lastIndexOf(", ");
    if (lakoma>1) altLabel.replace(lakoma,2," or ");
    nextNameL->setText(QString("Next Label is:<br> <font size=\"+1\" color=\"%2\">%1</font>")
        .arg(altLabel)
        .arg("blue"));
  } else {
    nextNameL->setText(QString("Next Label is:<br> <font size=\"+1\" color=\"%2\">%1</font>%3")
        .arg(nextLabel)
        .arg((inuse)?"red":"green")
        .arg((inuse)?"<font size=\"-19\"><br>Label is already in use. You may change ResidueNr or Part.</font>":""));

  }
  bool x=false;

  for (int i=0; i<mole.asymm.size(); i++){
    if (mole.asymm.at(i).Label!=mole.showatoms.at(i).Label){
      //printf("!!%s %s\n",mole.asymm.at(i).Label.toStdString().c_str(),mole.showatoms.at(i).Label.toStdString().c_str());
      mole.showatoms[i].Label=mole.asymm.at(i).Label;
      x=true;
    }
  }
  if (x){
    chgl->updateLabelTextures();
    //printf("update!!1elf\n");
  }
  update();


}

int Window::duplicates(){
  int was=0;
  mole.duplicateAtoms.clear();
  if (search4duplicates->isChecked()){
    for (int i =0; i<mole.asymm.size(); i++){
      if (mole.asymm.at(i).an<0) continue;//Q peaks don't have to be uniq!
      for (int j =i+1; j<mole.asymm.size(); j++){
        if (mole.asymm.at(j).an<0) continue;//Q peaks don't have to be uniq!
        if ((mole.asymm.at(i).part==mole.asymm.at(j).part)&&
            (mole.asymm.at(i).resiNr==mole.asymm.at(j).resiNr)&&
            (mole.asymm.at(i).Label==mole.asymm.at(j).Label)){
          mole.duplicateAtoms.append(mole.asymm.at(i));
          mole.duplicateAtoms.last().part=666;
          mole.duplicateAtoms.append(mole.asymm.at(j));
          mole.duplicateAtoms.last().part=666;
          was|=(mole.asymm.at(i).an==0)?1:2;
        }
      }
    }
  }
  editor->highlighter->highlightDupl(mole.duplicateAtoms);
  chgl->updateGL();
  return was;
}

bool Window::isLabelInUse(){
  QStringList alab;
  for (int i =0; i<mole.asymm.size(); i++){
    alab.append(mole.asymm.at(i).Label);
  }
  QString nn;
  //wenn rufMode dann labelIndex auf 1 setzen und hochzaehlen bis (alab.contains(nn,Qt::CaseInsensitive)) false
  // sollte (labelIndex<0) sein dann suffix auf A und hochzaehlen
  if (labelIndex<0) nextLabel=QString("%1%2").arg(labelPSE).arg(labelSuffix);
  else nextLabel=QString("%1%2%3").arg(labelPSE).arg(labelIndex).arg(labelSuffix);
  if (!nextLabel.startsWith("any")) nextLabel=nextLabel.left(4);
  if ((partSpin->value()!=0)||(resiNrSpin->value()!=0)){
    nn=QString("%1_%3%4")
      .arg(nextLabel)
      .arg((resiNrSpin->value())?QString::number(resiNrSpin->value()):"")
      .arg((partSpin->value())?QString::number((partSpin->value()<0)?
            36+partSpin->value():
            partSpin->value()+9,36):"");

  }else
    nn=nextLabel;
  return (alab.contains(nn,Qt::CaseInsensitive));
}

void Window::renameThisAtom(){
  QAction *action = qobject_cast<QAction *>(sender());
  int index=0;
  if (action)
    index=action->data().toInt();
  else return;
  if (index>mole.asymm.size()) return;
  QRegExp num=QRegExp("\\d+");
  if (mole.asymm.at(index).Label.contains(num)) {
    int p=mole.asymm.at(index).an;
    labelPSE=mole.pse(p);

    labelIndex=mole.asymm.at(index).Label.section(QRegExp("\\D+"),0,0,QString::SectionSkipEmpty).toInt();
    labelSuffix=mole.asymm.at(index).Label.section(num,1,1);
    labelSuffix.remove(QRegExp("[^A-Za-z']+"));
  }
  else{
    int p=mole.asymm.at(index).an;
    labelPSE=mole.pse(p);
    labelIndex=-1;
    labelSuffix=mole.asymm.at(index).Label;
    labelSuffix.remove(0,labelPSE.size());
    labelSuffix.remove(QRegExp("[^A-Za-z']+"));
  }

  partSpin->setValue(mole.asymm.at(index).part);
  resiNrSpin->setValue(mole.asymm.at(index).resiNr);
  resiResiClass->setText(mole.asymm.at(index).ResiClass);
  pserbt[mole.asymm.at(index).an+1]->setChecked(true);

  renamUpdate(true);
  updateLabel();

}

void Window::rename2ThisAtom(int index){
  //printf("2\n");
  if (index>mole.asymm.size()) return;
  QRegExp num=QRegExp("\\d+");
  int p=mole.asymm.at(index).an;
  bool rmo= rufModeBox->isChecked(), iix=indexIncr->isChecked();
  rufModeBox->setChecked(false);
  sufixBox->setCurrentIndex(0);
  labelPSE=mole.pse(p);
  //sufixBox->setCurrentIndex(1);
  if (mole.asymm.at(index).Label.contains(num)) {

    labelIndex=mole.asymm.at(index).Label.section(QRegExp("\\D+"),0,0,QString::SectionSkipEmpty).toInt();
    labelSuffix=mole.asymm.at(index).Label.section(num,1,1);
    labelSuffix.remove(QRegExp("[^A-Za-z']+"));
  }
  else{
    labelIndex=-1;
    labelSuffix=mole.asymm.at(index).Label;
    labelSuffix.remove(0,labelPSE.size());
    labelSuffix.remove(QRegExp("[^A-Za-z']+"));
  }
  labelPSE="H";

  partSpin->setValue(mole.asymm.at(index).part);
  resiNrSpin->setValue(mole.asymm.at(index).resiNr);
  resiResiClass->setText(mole.asymm.at(index).ResiClass);
  pserbt[1]->setChecked(true);//H
  updateLabel();

  indexIncr->setChecked(true);
  rufModeBox->setChecked(true);
  renamUpdate(false);
  updateLabel();
  rufModeBox->setChecked(rmo);
  indexIncr->setChecked(iix);

}


void Window::renameRNchanged(int ii){
  QMap<int,QString> resNrClass;
  for (int i=0; i<editor->resiFinder->count(); i++){
    QString resil=editor->resiFinder->itemText(i).toUpper();
    resil.remove(QRegExp("^RESI"));//remove resi at the beginning resi could be also a (STUPID) resi class
    QString resinr=resil;
    resil.remove(QRegExp("\\b\\d+\\b"));//remove the number which separated (e.g. not like CCF3)
    resinr.remove(resil.trimmed());//the rest should be the number
    int rn=resinr.trimmed().toInt();
    resNrClass[rn]=resil.trimmed();
  }

  if ((rufModeBox->isChecked())&&(!nextLabel.contains("any"))) labelIndex=1;
  if (!ii) {
    resiResiClass->setEnabled(false);
    resiResiClass->setText("");
    resiResiClassCB->setEnabled(false);
  }
  else {
    resiResiClassCB->setEnabled(!resNrClass.contains(ii));
    resiResiClass->setDisabled(resNrClass.contains(ii));  
    resiResiClass->setText(resNrClass[ii]);
  }
  updateLabel();

}


void Window::incResiNr(){
  int rnmax=-1;
  for (int i=0; i<editor->resiFinder->count(); i++){
    QString resil=editor->resiFinder->itemText(i).toUpper();
    resil.remove(QRegExp("^RESI"));//remove resi at the beginning resi could be also a (STUPID) resi class
    QString resinr=resil;
    resil.remove(QRegExp("\\b\\d+\\b"));//remove the number which separated (e.g. not like CCF3)
    resinr.remove(resil.trimmed());//the rest should be the number
    int rn=resinr.trimmed().toInt();
    rnmax=(rn>rnmax)?rn:rnmax;
  }
  int rnr = resiNrSpin->value()+1;
  rnr = (rnr>rnmax+1)?rnmax+1:rnr;
  resiNrSpin->setValue(rnr);
  updateLabel();

}

void Window::decResiNr(){
  int rnr = resiNrSpin->value()-1;
  rnr = (rnr<0)? 0: rnr;
  resiNrSpin->setValue(rnr);
  updateLabel();

}

void Window::redoRename(){
  if (gehtMichAn2.size()&&(0!=gehtMichAn2.takeLast())){//redoDeleteAtoms
    deletedAtom.clear();
    for (int i=0; i<restoredAtom.size();i++)deletedAtom.append(restoredAtom.at(i));
    for (int i=0; i<restoredAtom.size();i++){
      mole.asymm.removeAt(mole.asymm.indexOf(restoredAtom.at(i)));
    }
    restoredAtom.clear();
    chgl->disSelection();
    if (chgl->fuse->isVisible())chgl->mol->grow();
    else  chgl->mol->fuse();

    switch (duplicates()){
      case 1:infoKanalNews("<font color=orange >Some hydrogen atoms have identical names please check.</font>");break;
      case 2:infoKanalNews("<font color=red >Some non-hydrogen atoms have identical names. YOU HAVE TO CHECK BEFORE REFINING!</font>");break;
      case 3:infoKanalNews("<font color=red >Some atoms have identical names. YOU HAVE TO CHECK BEFORE REFINING!</font>");break;
    }
    chgl->murx=__LINE__;
    chgl->updateGL();
    gehtMichAn.takeLast();
    return;
  }
  if (gehtMichAn.size()&&(0==gehtMichAn.takeLast()))return;
  MyAtom renamed;
  int renamindex;
  if (redoAtom.isEmpty()) return;
  renamindex = redoAtomIndex.takeLast();
  if (renamindex==-1){
    do {
      renamed = redoAtom.takeLast();
      undoAtom.append(renamed);
      mole.asymm.append(renamed);
      undoAtomIndex.append(renamindex);
    } while ((redoAtomIndex.size())&&(-1==(renamindex = redoAtomIndex.takeLast())));
  }else {

    renamed = redoAtom.takeLast();
    undoAtom.append(mole.asymm[renamindex]);
    undoAtomIndex.append(renamindex);

    mole.asymm[renamindex]=renamed;
  }
  updateLabel();
  chgl->disSelection();
  if (chgl->fuse->isVisible())chgl->mol->grow();
  else  chgl->mol->fuse();

  switch (duplicates()){
    case 1:infoKanalNews("<font color=orange >Some hydrogen atoms have identical names please check.</font>");break;
    case 2:infoKanalNews("<font color=red >Some non-hydrogen atoms have identical names. YOU HAVE TO CHECK BEFORE REFINING!</font>");break;
    case 3:infoKanalNews("<font color=red >Some atoms have identical names. YOU HAVE TO CHECK BEFORE REFINING!</font>");break;
  }chgl->murx=__LINE__;
  chgl->updateGL();
}

void Window::wasDelete(){
  static int changeDel=0;
  if (changeDel!=(deletedAtom.size()+restoredAtom.size())) gehtMichAn2.append(1);
  else gehtMichAn2.append(0);
  changeDel=deletedAtom.size()+restoredAtom.size();
}

void Window::wasRename(){
  if (altursize!=(redoAtom.size()+undoAtom.size()))gehtMichAn.append(1);
  else gehtMichAn.append(0);
  altursize=(redoAtom.size()+undoAtom.size());
}

void Window::undoRename(){
  int angang=0;
  if (gehtMichAn2.size()&&(0!=(angang=gehtMichAn2.takeLast()))){//undoDeleteAtoms
    restoredAtom.clear();
    for (int i=0; i<deletedAtom.size();i++)restoredAtom.append(deletedAtom.at(i));
    for (int i=0; i<deletedAtom.size();i++){
      mole.asymm.append(deletedAtom.at(i));
    }
    deletedAtom.clear();
    chgl->disSelection();
    if (chgl->fuse->isVisible())chgl->mol->grow();
    else  chgl->mol->fuse();

    switch (duplicates()){
      case 1:infoKanalNews("<font color=orange >Some hydrogen atoms have identical names please check.</font>");break;
      case 2:infoKanalNews("<font color=red >Some non-hydrogen atoms have identical names. YOU HAVE TO CHECK BEFORE REFINING!</font>");break;
      case 3:infoKanalNews("<font color=red >Some atoms have identical names. YOU HAVE TO CHECK BEFORE REFINING!</font>");break;
    } chgl->murx=__LINE__;
    chgl->updateGL();
    gehtMichAn.takeLast();
    gehtMichAn2.append(1);
    return;
  }
  angang=0;
  if (gehtMichAn.size()&&(0==(angang=gehtMichAn.takeLast()))){
    return;
  }
  if (angang>1){

    for (int i = 2; i<angang; i++ ){
      redoAtom.append(mole.asymm.takeLast());
      redoAtomIndex.append(-1);

    }

    updateLabel();
    chgl->disSelection();
    if (chgl->fuse->isVisible())chgl->mol->grow();
    else  chgl->mol->fuse();

    switch (duplicates()){
      case 1:infoKanalNews("<font color=orange >Some hydrogen atoms have identical names please check.</font>");break;
      case 2:infoKanalNews("<font color=red >Some non-hydrogen atoms have identical names. YOU HAVE TO CHECK BEFORE REFINING!</font>");break;
      case 3:infoKanalNews("<font color=red >Some atoms have identical names. YOU HAVE TO CHECK BEFORE REFINING!</font>");break;
    }chgl->murx=__LINE__;
    chgl->updateGL();

    return;
  }
  MyAtom renamed;
  int renamindex;
  if (undoAtom.isEmpty()) return;
  renamed = undoAtom.takeLast();
  renamindex = undoAtomIndex.takeLast();
  if (renamindex<0)redoAtom.append(renamed);
  else redoAtom.append(mole.asymm[renamindex]);
  redoAtomIndex.append(renamindex);

  mole.asymm[renamindex]=renamed;
  updateLabel();
  chgl->disSelection();
  if (chgl->fuse->isVisible())chgl->mol->grow();
  else  chgl->mol->fuse();

  switch (duplicates()){
    case 1:infoKanalNews("<font color=orange >Some hydrogen atoms have identical names please check.</font>");break;
    case 2:infoKanalNews("<font color=red >Some non-hydrogen atoms have identical names. YOU HAVE TO CHECK BEFORE REFINING!</font>");break;
    case 3:infoKanalNews("<font color=red >Some atoms have identical names. YOU HAVE TO CHECK BEFORE REFINING!</font>");break;
  }chgl->murx=__LINE__;
  chgl->updateGL();
}


void Window::renameThisAtom(int index){
  //  QTime rzeit;
  //  rzeit.start();
  if ((index<0)||index>=mole.asymm.size()){
    if ((index>=0)&&(mole.showatoms.at(index).Label.startsWith('Q'))){
      MyAtom ato(mole.showatoms.at(index));
      ato.Label=ato.Label.remove("'");
      ato.symmGroup=0;
      ato.sg=0;
      ato.scod=555;//the identity
      ato.auidx=index;

      int nindex=mole.asymm.indexOf(ato);
      if (nindex!=-1 ){
        //        mole.asymm.append(mole.asymm[nindex]);
        mole.asymm[nindex].frac=mole.showatoms.at(index).frac;
        mole.asymm[nindex].pos=mole.showatoms.at(index).pos;
        double uEQ=0.05;//mole.ueq(mole.asymm.at(i).uf);
        mole.asymm[nindex].uf.m11= mole.asymm[nindex].uc.m11= mole.asymm[nindex].uc.m22= mole.asymm[nindex].uc.m33=uEQ;
        mole.asymm[nindex].isIso=true;
        mole.asymm[nindex].uf.m33=uEQ;
        mole.asymm[nindex].uf.m12= mole.asymm[nindex].uf.m21= mole.asymm[nindex].uf.m13= mole.asymm[nindex].uf.m31=
          mole.asymm[nindex].uf.m23= mole.asymm[nindex].uf.m32= mole.asymm[nindex].uc.m21= mole.asymm[nindex].uc.m12=
          mole.asymm[nindex].uc.m13= mole.asymm[nindex].uc.m31= mole.asymm[nindex].uc.m32= mole.asymm[nindex].uc.m23=0.0;
        index=nindex;
      }else return;
    }
    else{
      QMessageBox::information(0,"information","The Atom you have clicked is not present in the file (yet) and can't be renamed by this program!<br>You can try 'move ... here' in the context menu of this atom. ");
      return;
    }
  }
  chgl->pause=true;
 // printf("PAUSE!\n");
  bool warnicht=false;
  static int previousHorse=-1;
  static int previousJokey=-1;
  CEnvironment respar;
  QString insertSuchString;
  for (int i=0; i<mole.asymm.size();i++){
      if (mole.asymm.at(i).resiNr!=resiNrSpin->value()) continue;
      if (mole.asymm.at(i).part!=partSpin->value()) continue;
      if (i!=index) respar.append(mole.asymm[i]);
  }

  MyAtom testat=mole.asymm[index];
  testat.Label=nextLabel;
  testat.Label.replace("any",mole.pse((mole.asymm.at(index).an)<0?1:mole.asymm.at(index).an));
  testat.Label=testat.Label.left(4);
  testat.ResiClass = resiResiClass->text();
  testat.resiNr=resiNrSpin->value();
  testat.part=partSpin->value();
  testat.an=mole.getOZ(labelPSE);
  if (testat.an<0) {
    testat.an=5;
  }
  //respar.append(testat);
  insertSuchString = editor->sortLabelList(respar,testat);

  respar.clear();


  QString nlab = nextLabel ;
  //b= nlab.contains("any");
  //QString nsn = nlab.replace("any",mole.pse(mole.asymm.at(index).an));
  bool ridingH = false;

  if (insertSuchString.startsWith('Q')) insertSuchString="HKLF";
  //printf("seek to: %s\n",insertSuchString.toStdString().c_str());
  if ((mole.getOZ(labelPSE)==0)&&(mole.asymm.at(index).an==-1)){
    int dahin2=-1;
    //double dd=0.0;
    for (int isd=0; isd<mole.sdm.size(); isd++){//sdm is sorted in that way that the smalest
      if (mole.sdm.at(isd).d>1.3) continue;
      if ((mole.sdm.at(isd).a1==index)&&(mole.asymm.at(mole.sdm.at(isd).a2).an>0)) {
        //      dd=mole.sdm.at(isd).d;
        dahin2=mole.sdm.at(isd).a2;
        break;
      } //qDebug()<<isd<<'a'<<mole.asymm.at(mole.sdm.at(isd).a2).Label<<mole.sdm.at(isd).d;
      if ((mole.sdm.at(isd).a2==index)&&(mole.asymm.at(mole.sdm.at(isd).a1).an>0)) {
        //      dd=mole.sdm.at(isd).d;
        dahin2=mole.sdm.at(isd).a1;
        break;
      } //qDebug()<<isd<<'b'<<mole.asymm.at(mole.sdm.at(isd).a1).Label<<mole.sdm.at(isd).d;
    }
    //qDebug()<<insertSuchString<<dahin2<<index<<dd<<mole.asymm.at(dahin2).orginalLine.left(80).trimmed();;a
    if (dahin2==-1)insertSuchString="HKLF";
    else{
      if (!enterRenameMode->isChecked()) {
        nowaste=false;
        rename2ThisAtom(dahin2);
        nowaste=true;
      }
      ridingH=true;
      //int orderer=0;
      if (previousHorse==dahin2){
          insertSuchString=mole.asymm.at(previousJokey).orginalLine.left(80).trimmed();
          //printf("second or later H here %d %d\n",previousJokey,dahin2);
      }else{
          insertSuchString=mole.asymm.at(dahin2).orginalLine.left(80).trimmed();
      }
      previousHorse=dahin2;
      previousJokey=index;
     // insertSuchString=mole.asymm.at(dahin2).orginalLine.left(80).trimmed();
    }

  }
  //qDebug()<<"suche nach: "<<insertSuchString;
  QString label = mole.showatoms.at(index).orginalLine.left(80).trimmed();
  //  printf("2 => %d ms\n", rzeit.elapsed());  rzeit.restart();
  QTextDocument *document = editor->document();
  QTextCursor cursor = editor->textCursor();
  cursor.beginEditBlock ();
  //insert missing afix 0 at end
  cursor.movePosition(QTextCursor::Start);
  cursor = document->find("HKLF",cursor);
  cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
  cursor.movePosition(QTextCursor::Up,QTextCursor::KeepAnchor);
  if (editor->parenthesis.at(cursor.blockNumber())){
    cursor.select(QTextCursor::WordUnderCursor);
    if ((cursor.selectedText().contains("RESI",Qt::CaseInsensitive))||(cursor.selectedText().contains("PART",Qt::CaseInsensitive)))
      cursor.movePosition(QTextCursor::Up,QTextCursor::KeepAnchor);
    cursor.select(QTextCursor::WordUnderCursor);
    if ((cursor.selectedText().contains("RESI",Qt::CaseInsensitive))||(cursor.selectedText().contains("PART",Qt::CaseInsensitive)))
      cursor.movePosition(QTextCursor::Up,QTextCursor::KeepAnchor);
    cursor.movePosition(QTextCursor::Down,QTextCursor::MoveAnchor);
    cursor.clearSelection();
    cursor.insertText("AFIX 0 ! chuebsch want to keep this here!!\nREM #####\n");
    editor->updateAfix();
  }
  //insert missing afix 0 at End!

  cursor.movePosition(QTextCursor::Start);
  cursor = document->find(label,cursor);
  if (cursor.isNull()){
    cursor = editor->textCursor();
    cursor.movePosition(QTextCursor::Start);
    label.chop(10);
    cursor = document->find(label,cursor);
    if (cursor.isNull()) {
      cursor = editor->textCursor();
      warnicht=true;
    }
  }
  if (editor->parenthesis.at(cursor.blockNumber())){
    QMessageBox::information(0,"information",QString("ATOM %1 is in a AFIX construct and can't be renamed by this program!").arg(label.section(' ',0,0)));
    cursor.endEditBlock ();
    editor->setTextCursor(cursor);
    // printf("qpeakbug? %d\n",__LINE__);
    chgl->pause=false;
 //   printf("%d\n",__LINE__);
    return;
  }
  if (warnicht) {
    QMessageBox::information(0,"information","The Atom you have clicked is not present in the file (yet) and can't be renamed by this program!");
    cursor.endEditBlock ();
    editor->setTextCursor(cursor);
    chgl->pause=false;
//    printf("%d\n",__LINE__);
    return;//hier muss eingefuegt werden: verhalten bei objecten die noch nicht in der datei stehen
  }
  QString vorherig,neues;
  cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
  cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
  QString otxt= cursor.selectedText();
  while (cursor.selectedText().endsWith("=")) {
    cursor.movePosition(QTextCursor::Down,QTextCursor::KeepAnchor);
    cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
  }
  while (editor->parenthesis.at(cursor.blockNumber()+1)){
    cursor.movePosition(QTextCursor::Down,QTextCursor::KeepAnchor);
    cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
  }
  neues = vorherig= cursor.selectedText();
  //qDebug()<<otxt<<neues;
  if (tieType->itemData(tieType->currentIndex()).toInt()){
    QString asof=neues.section(QRegExp("\\s+"),5,5,QString::SectionSkipEmpty);
    asof.prepend(" ");
    int fnj=tieFVNr->value();
    QString nsof=(fnj!=1)?QString(" %1").arg(tieType->itemData(tieType->currentIndex()).toInt()*(fabs(fmod(mole.asymm.at(index).sof_org,10))+(10*fnj)),7,'f',5):
      QString(" %1").arg(fabs(fmod(mole.asymm.at(index).sof_org,10)*tieFix->value()+10),7,'f',5);
    ;
    //    qDebug()<<asof<<nsof;
    neues.replace(asof,nsof);
    otxt.replace(asof,nsof);
    mole.asymm[index].sof_org=nsof.toDouble();
  }
  QString oldSfac=neues.section(QRegExp("\\s+"),1,1,QString::SectionSkipEmpty);
  int ii=editor->sfac.indexOf(mole.getOZ(labelPSE));
  QString nl=QString("%1     ").arg(nextLabel,-4,' ');
  nl=nl.replace("any",mole.pse(editor->sfac.at(oldSfac.toInt()-1))).left(4);
  if (ii<0) {
    nl=nl.replace("any",mole.pse(editor->sfac.at(oldSfac.toInt()-1))).left(4);
    ii=oldSfac.toInt()-1;
  }
  else{
    neues.replace(QRegExp(QString("\\s%1\\s").arg(oldSfac)),QString(" %1 ").arg((ii+1)));
    otxt.replace(QRegExp(QString("\\s%1\\s").arg(oldSfac)),QString(" %1 ").arg((ii+1)));
  }
  nl=nl.left(4);
  neues.replace(0,4,nl);
  otxt.replace(0,4,nl);
  //  printf("3 => %d ms\n", rzeit.elapsed());  rzeit.restart();
  undoAtom.append(mole.asymm[index]);
  undoAtomIndex.append(index);
  //  printf("3' => %d ms\n", rzeit.elapsed());  rzeit.restart();
  QString ol=mole.asymm[index].Label.section('_',0,0);
  QString oldH=ol;
  oldH.replace(QRegExp(QString("^%1").arg(mole.pse(mole.asymm[index].an)),Qt::CaseInsensitive),"H");
  mole.asymm[index].Label=nextLabel;
  mole.asymm[index].Label.replace("any",mole.pse(editor->sfac.at(oldSfac.toInt()-1)));
  mole.asymm[index].Label=mole.asymm[index].Label.left(4);
  if (mole.asymm[index].an<0) {
    otxt=neues=
      QString("%1 %2 %3 %4 %5 %6 %7 \n")
      .arg(mole.asymm[index].Label,-5)
      .arg(ii+1)
      .arg(mole.asymm.at(index).frac.x,9,'f',5)
      .arg(mole.asymm.at(index).frac.y,9,'f',5)
      .arg(mole.asymm.at(index).frac.z,9,'f',5)
      .arg(mole.asymm.at(index).sof_org,9,'f',5)
            .arg((ridingH)?"-1.5":"0.05");
  }
  mole.asymm[index].an=mole.getOZ(labelPSE);
  if (mole.asymm[index].an<0) {
    mole.asymm[index].an=editor->sfac.at(oldSfac.toInt()-1);
  }
  QString newH=mole.asymm[index].Label;
  newH.replace(QRegExp(QString("^%1").arg(mole.pse(mole.asymm.at(index).an)),Qt::CaseInsensitive),"H");
  newH=newH.left(3);
  neues.replace(oldH,newH);

  //printf("altes H='%s' neues H='%s' %s %s\n",oldH.toStdString().c_str(),newH.toStdString().c_str(),mole.asymm[index].Label.toStdString().c_str(),mole.pse(mole.asymm.at(index).an).toStdString().c_str());
  mole.asymm[index].orginalLine=otxt.left(80).section('=',0);
  //  printf(":%s:\n",mole.asymm[index].orginalLine.toStdString().c_str());
  //  qDebug()<<"aa"<<mole.asymm[index].orginalLine;
  mole.asymm[index].ResiClass = resiResiClass->text();  
  mole.asymm[index].resiNr=resiNrSpin->value();
  mole.asymm[index].part=partSpin->value();
  cursor.deleteChar();

  //cursor.deleteChar();//...this seems to cause errors but those emty lines are so ugly!
  //cursor.insertText(QString(" %1 has been renamed to %2. SHELXL ignores this line.").arg(ol).arg(mole.asymm[index].Label));
  QTextCursor wc = cursor; 
  if ((partSpin->value()!=0)||(resiNrSpin->value()!=0)){
    mole.asymm[index].Label=QString("%1_%3%4")
      .arg(nextLabel)
      .arg((resiNrSpin->value())?QString::number(resiNrSpin->value()):"")
      .arg((partSpin->value())?QString::number((partSpin->value()<0)?
            36+partSpin->value():
            partSpin->value()+9,36):"");
    mole.asymm[index].Label.replace("any",mole.pse(editor->sfac.at(oldSfac.toInt()-1)));

  }
  cursor = editor->textCursor();    
  cursor.movePosition(QTextCursor::Start);
  editor->updateAfix();
  cursor = document->find(insertSuchString,cursor);
  if (cursor.isNull()){
    cursor = wc; //alte schreibposition setzen (wir haben atom nicht gefunden weil wir es gerade geloescht haben....   
    cursor.movePosition(QTextCursor::Down);
    //printf("%s not found %d\n",insertSuchString.toStdString().c_str(),wc.position());
  }
  else if(insertSuchString!="HKLF"){
    cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
    cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
    while (cursor.selectedText().endsWith("=")) {
      cursor.movePosition(QTextCursor::Down,QTextCursor::KeepAnchor);
      cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);  
    }
    while (editor->parenthesis.at(cursor.blockNumber()+1)){
      cursor.movePosition(QTextCursor::Down,QTextCursor::KeepAnchor);
      cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);  
    }
    cursor.movePosition(QTextCursor::Down); //10.09.2020 do i need this really?=>yes
    //printf("%s found %d\n",insertSuchString.toStdString().c_str(),cursor.position());
  }
  cursor.clearSelection ();
  cursor.movePosition(QTextCursor::StartOfLine);
  if ((insertSuchString=="HKLF")&&(mole.asymm[index].resiNr)) cursor.insertText(QString("RESI %1 %2\n")
      .arg(mole.asymm[index].resiNr)
      .arg(mole.asymm[index].ResiClass));
  if ((insertSuchString=="HKLF")&&(mole.asymm[index].part)) cursor.insertText(QString("PART %1 \n")
      .arg(mole.asymm[index].part)
      //		  .arg((tieType->itemData(tieType->currentIndex()).toInt())?
      //			  QString::number((tieType->itemData(tieType->currentIndex()).toInt()*(10*tieFVNr->value()+1))):"")
      );
  cursor.insertText(neues);
  if (!neues.endsWith("\n")) cursor.insertText("\n");
  if ((insertSuchString=="HKLF")&&(mole.asymm[index].part)) cursor.insertText("PART 0\n");
  if ((insertSuchString=="HKLF")&&(mole.asymm[index].resiNr)) cursor.insertText("RESI 0\n");
  if ((tieType->itemData(tieType->currentIndex()).toInt())&&(mole.asymm[index].part)&&(fvar.size()<tieFVNr->value())){
    //  !!!Neue Freie Variable anlegen!!!
    cursor.movePosition(QTextCursor::End);	
    cursor = document->find("FVAR",cursor,QTextDocument::FindBackward);
    cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
    cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
    while (cursor.selectedText().endsWith("=")) {
      cursor.movePosition(QTextCursor::Down,QTextCursor::KeepAnchor);
      cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);  
    }
    QString fvstr = cursor.selectedText().trimmed();
    fvstr.append(" 0.666 ");
    fvar.append(0.667);
    cursor.deleteChar();
    fvstr = DSRGui::textWrap(fvstr, "\nFVAR ");
    cursor.insertText(fvstr);
    updateTieFreeVar();
    // !!!!
  }
  //qDebug()<<"redi";
  // printf("3! => %d ms\n", rzeit.elapsed());  rzeit.restart();
  chgl->murx=__LINE__;


  cursor.movePosition(QTextCursor::Start);
  int apo,po=cursor.position();
  apo=po;
  do {
    cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
    cursor.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
    if (cursor.selectedText().isEmpty()) {
      cursor.deleteChar();
    }
    //cursor.deleteChar();
    cursor.setPosition(cursor.position(), QTextCursor::MoveAnchor);
    cursor.movePosition(QTextCursor::Down,QTextCursor::MoveAnchor);
    apo=po;
    po=cursor.position();
  }
  while (!cursor.isNull()&&(po!=apo));

  //  printf("3!a => %d ms\n", rzeit.elapsed());  rzeit.restart();
  cursor.endEditBlock ();
  //  printf("3!b => %d ms\n", rzeit.elapsed());  rzeit.restart();
  if ((!indexIncr->isChecked())&&(labelIndex!=-1)) labelIndex++;
  else {
    if (sufixBox->currentIndex()<0) sufixBox->setCurrentIndex(0);
    sufixBox->setCurrentIndex((sufixBox->count()>sufixBox->currentIndex()+1)?sufixBox->currentIndex()+1:sufixBox->currentIndex());
  }
  updateLabel();

  // printf("3!0 => %d ms\n", rzeit.elapsed());  rzeit.restart();
  chgl->disSelection();
  chgl->updateGL();
  //  printf("3!1 => %d ms\n", rzeit.elapsed());  rzeit.restart();
  //  printf("Qpeak-Crash %d  %d\n",__LINE__,mole.showatoms.size());
  if (chgl->fuse->isVisible())chgl->mol->grow();
  else  chgl->mol->fuse();
  //  printf("Qpeak-Crash %d  %d\n",__LINE__,mole.showatoms.size());

  //  printf("3!2 => %d ms\n", rzeit.elapsed());  rzeit.restart();
  switch (duplicates()){
    case 1:infoKanalNews("<font color=orange >Some hydrogen atoms have identical names please check.</font>");break;
    case 2:infoKanalNews("<font color=red >Some non-hydrogen atoms have identical names. YOU HAVE TO CHECK BEFORE REFINING!</font>");break;
    case 3:infoKanalNews("<font color=red >Some atoms have identical names. YOU HAVE TO CHECK BEFORE REFINING!</font>");break;
  } 
  chgl->murx=__LINE__;
  editor->setTextCursor(cursor);
  /* 
     QFile dump("dkcrash.res");
     dump.open(QIODevice::WriteOnly|QIODevice::Text);
     dump.write( editor->toPlainText().toLatin1());
     dump.close();
     */
  //fileSave(false,true);

  //chgl->setRotationCenter(index);
  // printf("4# => %d ms\n", rzeit.elapsed());  rzeit.restart();

//  printf("PAUSE? %d\n",chgl->pause);
  chgl->updateLabelTextures();
  chgl->pause=false;
//  printf("%d\n",__LINE__);

 // printf("NO PAUSE!\n");
  chgl->updateGL();
  printf("NO PAUSE!!\n");
  //sdm();
  // exportCoordinates();
  //printf("Qpeak-Crash %d \n",__LINE__);
  // printf("5 => %d ms\n", rzeit.elapsed());  rzeit.restart();
}

void Window::changeResiPart(){  
  if (chgl->mol->selectedatoms.isEmpty()) return;
  chgl->pause=true;
  CEnvironment todos = chgl->mol->selectedatoms;
  changeElemetofLabel("any");
  pserbt[0]->setChecked(true);
  QRegExp num=QRegExp("\\d+");
  int unusedpart=0;
  for (int i=0; i<mole.asymm.size();i++){
    unusedpart=qMax(mole.asymm.at(i).part,unusedpart);
  }
  unusedpart++;
  partSpin->setValue(unusedpart);
  tieType->setCurrentIndex(1);
  tieFVNr->setValue(fvar.size()+1);
  updateTieFreeVar(); 
  QDialog *groupReNaMo= new QDialog(this);
  groupReNaMo->setLayout(rnla);
  indexL->hide();
  indexSpin->hide();
  sufixL->hide();
  nextNameL->hide();
  sufixBox->hide();
  QString text=nliL->text();
  nliL->setText("Change RESI or PART of selected atoms.<br><> 0 value leaves current values unchaged.");
  rufModeBox->hide();
  indexIncr->hide();
  willpse->hide();
  qsa->hide();
  connect(buttonBoxRN, SIGNAL(accepted()), groupReNaMo, SLOT(accept()));
  connect(buttonBoxRN, SIGNAL(rejected()), groupReNaMo, SLOT(reject()));
  buttonBoxRN->show();
  int  result=groupReNaMo->exec();
  renameBox->setLayout(rnla);
  nliL->setText(text);
  indexL->show();
  indexSpin->show();
  sufixL->show();
  sufixBox->show();
  nextNameL->show();
  rufModeBox->show();
  indexIncr->show();
  willpse->show();
  qsa->show();
  buttonBoxRN->hide();
  buttonBoxRN->disconnect();
  int rn= resiNrSpin->value();
  int pn= partSpin->value();
  if (result==QDialog::Accepted)
    for (int i=0; i<todos.size();i++){
      if (todos.at(i).symmGroup) continue;
      if (todos.at(i).Label.contains(QString::fromUtf8("»")))continue;
      if ((todos.at(i).an<0)) continue;
      if ((todos.at(i).afix>0)&&(todos.at(i).an==0)) continue;

      int das=todos.at(i).style;
      //    qDebug()<<"##==>>"<<i<<das<<todos.size()<<mole.asymm.at(das).Label;

      labelIndex=mole.asymm.at(das).Label.section(QRegExp("\\D+"),0,0,QString::SectionSkipEmpty).toInt();
      labelSuffix=mole.asymm.at(das).Label.section(num,1,1);
      labelSuffix.remove(QRegExp("[^A-Za-z']+"));
      if (pn==0) partSpin->setValue(mole.asymm.at(das).part);
      if (rn==0){
        resiNrSpin->setValue(mole.asymm.at(das).resiNr);
        resiResiClass->setText(mole.asymm.at(das).ResiClass);
      }
      renamUpdate(false);
      updateLabel();
      renameThisAtom(das);
    }
  chgl->pause=false;
  //printf("%d\n",__LINE__);
  chgl->updateGL();
}

bool Window::restraintsOrConstraints(){
    bool corr = (editor->toPlainText().contains("AFIX")) ;
    corr=(corr)||(editor->toPlainText().contains("BIND")) ;
    corr=(corr)||(editor->toPlainText().contains("CHIV")) ;
    corr=(corr)||(editor->toPlainText().contains("DANG")) ;
    corr=(corr)||(editor->toPlainText().contains("DFIX")) ;
    corr=(corr)||(editor->toPlainText().contains("EADP")) ;
    corr=(corr)||(editor->toPlainText().contains("EXYZ")) ;
    corr=(corr)||(editor->toPlainText().contains("FRAG")) ;
    corr=(corr)||(editor->toPlainText().contains("FEND")) ;
    corr=(corr)||(editor->toPlainText().contains("FREE")) ;
    corr=(corr)||(editor->toPlainText().contains("HFIX")) ;
    corr=(corr)||(editor->toPlainText().contains("MPLA")) ;
    corr=(corr)||(editor->toPlainText().contains("SADI")) ;
    corr=(corr)||(editor->toPlainText().contains("SAME")) ;
    corr=(corr)||(editor->toPlainText().contains("FLAT")) ;
    if (corr){
        QTextCursor cursor = editor->textCursor();
        cursor.setPosition(0);
        editor->setTextCursor(cursor);
        editor->searchLE->setText("(AFIX)|(BIND)|(CHIV)|(DANG)|(DFIX)|(EADP)|(EXYZ)|(FRAG)|(FEND)|(FREE)|(FLAT)|(HFIX)|(MPLA)|(SADI)|(SAME)");
        editor->wholeLine->setChecked(true);
        editor->findNext();
        editor->showSearch();
    }
    return corr;
}

void Window::aula(){//!< Auto Labeling

  if (mole.asymm.isEmpty())return;
  bool hasafix = (editor->toPlainText().contains("AFIX")) ;
  bool hasrest = restraintsOrConstraints();
  bool hash=false;
  bool useResis;
  for (int i=0;i<mole.asymm.size();i++){if (mole.asymm.at(i).an==0) {hash=true; break;}}
  QPushButton *okmitresi=nullptr,*okohneresi=nullptr;
  QMessageBox mb(QMessageBox::NoIcon,
     "Automatic Labeling",
    QString(
      "<img src=\":/xle-icons/aula.svg\"><p><h3>AuLa <u>Au</u>tomatic <u>La</u>beling</h3> It will probably never give you satisfying results, but hopefully consitent ones."
      "<p>Please use this feature before adding Hydrogen atoms and %3restraints or constraints%4."
      "<p>%1 It will complain about any atom that is in a AFIX environment.%2"
      "<p>When finished it will sort and save the file automatically. Please be a little patient."
      "<p>First it searches for rings in each molecule or fragment. Rings may consist only of nonmetals. "
      "In each molecule it starts numbering in the ring that if most distant away from the molecules center of mass."
      "If possible, it annulate other rings to the first one. It then adds side chains and the side chains of these until no atoms are left in the molecule."
      "When there are no rings in the molecule it starts at the end of the chain that is most distant from molecules center of mass. "
      "Center of mass here means just the geometrical average position. %5")
                 .arg((hasafix)?"<font color=red><b>":"")
                 .arg((hasafix)?"</b></font>":"")
                 .arg((hasrest)?"<font color=red><b>":"")
                 .arg((hasrest)?"</b></font>":"")
                 .arg((hasrest)?"<p><h3><font color=red> Please remove all Hydrogen atoms and constraints/restraints first and come back here later.</font></h3> "
                                "You should not have any of these instructions in your file:<br> <b>AFIX BIND CHIV DANG DFIX EADP EXYZ FLAT FRAG FEND FREE HFIX MPLA SADI SAME</b> "
                              :"<p><h3>Click on one of the AutoLabel buttons below to run the auto labeling procedure now. </h3>")
                 ,
     (QMessageBox::Cancel ));
  if (hash){
    QPushButton *killh = mb.addButton("remove Hydrogen atoms now",QMessageBox::ActionRole);
    connect(killh,SIGNAL(clicked()),this,SLOT(deleteAllH()));
  }
  if (!hasrest){
      okmitresi = mb.addButton("AutoLabel with RESIdues",QMessageBox::AcceptRole);
      okohneresi= mb.addButton("AutoLabel without RESIdues",QMessageBox::AcceptRole);
  }
  mb.exec();
  bool ok=false;
  if (mb.clickedButton()==nullptr)return;
  if (mb.clickedButton()==okmitresi){useResis=true;ok=true;}
  if (mb.clickedButton()==okohneresi){useResis=false;ok=true;}
  if (!ok)return;
  chgl->pause=true;
  QList<int> chain;
  sdm();
  printf("TEST\n========Au=La=====================================================================\n");
  printf(
      "        .-\"-~-\"-.\n"
      "       /.-\"-.-\"-.\\\n"
      "       ||((o|o))||\n"
      "       )\\__/V\\__/(\n"
      "      / ~ -...- ~ \\\n"
      "     |\\` ~. ~ .~ `/|\n"
      "     | `~ - ^ - ~` |\n"
      "     | ;  '  :  .  |\n"
      "      \\ . : '  ; '/\n"
      "       '.   ; ' .'\n"
      "        `uu---uu`\n");
  mole.inventNewLabels(chain);
  bool saveruf = rufModeBox->isChecked();
  editor->document()->setUndoRedoEnabled(false);
  rufModeBox->setChecked(true);
  if (chain.isEmpty()){
    chgl->pause=false;
    chgl->updateGL();
    return;
  }
  printf("{");
  for (int i=0; i<chain.size(); i++){
    int das = chain.at(i);
    printf("%s--",mole.asymm.at(das).Label.toStdString().c_str());
    //labelIndex=mole.asymm.at(das).Label.section(QRegExp("\\D+"),0,0,QString::SectionSkipEmpty).toInt();
    labelSuffix="";
    partSpin->setValue(mole.asymm.at(das).part);  
    if (useResis) {
        resiNrSpin->setValue(mole.asymm.at(das).molindex);
        resiResiClass->setText(QString("M%1").arg(mole.asymm.at(das).molindex,3,10,QLatin1Char('0')));
    }else resiNrSpin->setValue(0);
    labelPSE=mole.pse(mole.asymm.at(das).an);
    labelSuffix="";
    renamUpdate(false);
    renameThisAtom(das);
  }
  printf("}\n");
  printf("{");
  for (int i=0; i<chain.size(); i++){
    int das = chain.at(i);
    printf("%s~",mole.asymm.at(das).Label.toStdString().c_str());
  } 
  printf("}\n");
  int posibile=0;
  for (int i=0; i<mole.asymm.size(); i++) if (mole.asymm.at(i).an>=0) posibile++;
  QMessageBox mb2(QMessageBox::Information,
      "Automatic Labeling",QString("<h4>Labeled %1 atoms out of %2 atoms in the asymmetic unit.</h4>").arg(chain.size()).arg(posibile));
  mb2.exec();
  rufModeBox->setChecked(saveruf);
  editor->document()->setUndoRedoEnabled(true);
  editor->sortAtoms();
  maybeSave2();
  chgl->pause=false;
  sdm();
  chgl->updateGL();
}

void Window::changeElement(){
  QAction *action = qobject_cast<QAction *>(sender());
  int index=0;
  if (action)
    index=action->data().toInt();
  else return;
  if (index>editor->sfac.size()) return;
  if ((chgl->ImeanThisAtom>mole.asymm.size())||(chgl->ImeanThisAtom<0)) return;
  int das=chgl->ImeanThisAtom;
  bool alterMichi=rufModeBox->isChecked();
  rufModeBox->setChecked(true);
  //   printf("new Element of %s is %s\n",mole.asymm.at(das).Label.toStdString().c_str(),mole.pse(editor->sfac.at(index)).toStdString().c_str());
  QRegExp num=QRegExp("\\d+");
  if (mole.asymm.at(das).Label.contains(num)) {
    int p=editor->sfac.at(index);
    labelPSE=mole.pse(p);

    labelIndex=mole.asymm.at(das).Label.section(QRegExp("\\D+"),0,0,QString::SectionSkipEmpty).toInt();
    labelSuffix=mole.asymm.at(das).Label.section(num,1,1);
    labelSuffix.remove(QRegExp("[^A-Za-z']+"));
  }
  else{
    int p=editor->sfac.at(index);
    labelPSE=mole.pse(p);
    labelIndex=-1;
    labelSuffix=mole.asymm.at(das).Label;
    labelSuffix.remove(0,labelPSE.size());
    labelSuffix.remove(QRegExp("[^A-Za-z']+"));
  }

  partSpin->setValue(mole.asymm.at(das).part);
  resiNrSpin->setValue(mole.asymm.at(das).resiNr);
  resiResiClass->setText(mole.asymm.at(das).ResiClass);
  pserbt[editor->sfac.at(index)+1]->setChecked(true);

  renamUpdate(false);
  updateLabel();
  renameThisAtom(das);
  rufModeBox->setChecked(alterMichi);
}

void Window::zoomin(){
  chgl->zoom(0.1);
  chgl->updateGL();
} 

void Window::zoomout(){
  chgl->zoom(-0.1);
  chgl->updateGL();
}

void Window::calculator() {
  calcmenu = new Calculator(mole.cell.wave,this);
}

void Window::create_DSRGui() {
  // Only starts DSRGui instance if not already started:
  if (dsr == NULL) {
    dsr = new DSRGui(&mole, shelxlPath, this);
    connect(dsr, SIGNAL(closed()), this, SLOT(dsrClosed()) );
    QList<QAction *> acs = helpMenu->actions();
    bool oneisenough=true;
    for (int i = 0; i < acs.size(); ++i){
        if (acs.at(i)->text()=="About DSR Plugin") {oneisenough=false;break;}
    }
    if (oneisenough) helpMenu->addAction("About DSR Plugin", dsr, SLOT(aboutDSR()));
  }
  // Go out of rename mode.
  renamUpdate(false);
  if (!dsr->isActiveWindow()){
    dsr->raise();
    dsr->activateWindow();
    renamUpdate(false);
  }
}

void Window::dsrClosed() {
  dsr = NULL;
}

void Window::insertDSRLine(QString dsrline, int position, QVector<int> previousLine){
  // Insert the DSR command line at the position below the FVAR line,
  // or if not present, the first atom.
  // If also a previous DSR line is present (previousLine > 0), the previous line will be deleted.
  foreach (int lineNum, previousLine) {
    if (lineNum > 0) {
      QTextCursor cursor = editor->textCursor();
      cursor.setPosition(0);
      cursor.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, lineNum);
      editor->setTextCursor(cursor);
      cursor.insertText("REM ");
    }
  }
  QTextCursor cursor = editor->textCursor();
  cursor.setPosition(0);
  cursor.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, position+1);
  editor->setTextCursor(cursor);
  cursor.insertText(dsrline);
  cursor.insertText("\n");
  fileSave(true, false);
}

void Window::rotl(){
  emit movedByUser();
  chgl->rotY(0.1);
  chgl->updateGL();

}   

void Window::rotr(){
  emit movedByUser();
  chgl->rotY(-0.1);
  chgl->updateGL();
}   

void Window::rotu(){
  emit movedByUser();
  chgl->rotX(0.1);
  chgl->updateGL();
}   

void Window::rotd(){
  emit movedByUser();
  chgl->rotX(-0.1);
  chgl->updateGL();
} 

void Window::updateStatusBar(const QString& s) {
  statusBar()->showMessage(s);
  emit pipeStatus(s);
  update();

}



double Window::getNumber(double v, const QList<double> fv,int idx,int &fixFlag){
  double av=qAbs(v),res=0.0,var=1.0;
  int m=0;
  while ((-10*m+av) > 5){m++;}
  if (m>1) m=qMin(m,fv.size());
  if (m>1) var=fv.at(m-1);
  if (!m) res=v;
  else if (v>0) res=(av-(10*m))*var;
  else res=(av-(10*m))*(1.0-var);
  fvarCntr[m]++;
  if (m>0) fixFlag|=1<<idx; else if (fixFlag&1<<idx) fixFlag-=1<<idx;
  // printf("idx: %d shift %d  flag %d  m%d\n", idx,1<<idx,fixFlag,m);
  return res;
}

double Window::getNumber(double v, const QList<double> fv, double uiso){
  double av=qAbs(v),res=0.0,var=1.0;
  if ((v<-0.5)&& (v>-5.0)) return res = av * uiso ;
  int m=0;
  while ((-10*m+av) > 5){m++;}
  if (m>1) m=qMin(m,fv.size());
  if (m>1) var=fv.at(m-1);
  if (!m) return v;
  else if (v>=0) res=(av-(10*m))*var;
  else res=(av-(10*m))*(1.0-var);
  fvarCntr[m]++;
  return res;
}

int Window::isacommand(QString command){
  QStringList keywords;
  keywords << 
    "ACTA"<<//0
    "AFIX"<<//1
    "MPLA"<<//2
    "ANIS"<<//3
    "BASF"<<//4
    "BIND"<<//5
    "BLOC"<<//6
    "BOND"<<//7 AGS4 to MPLA
    "BUMP"<<//8
    "CELL"<<//9 
    "CGLS"<<//10
    "CHIV"<<//11
    "CONF"<<//12
    "CONN"<<//13
    "DAMP"<<//14
    "DANG"<<//15
    "DEFS"<<//16
    "DELU"<<//17
    "DFIX"<<//18
    "DISP"<<//19
    "EADP"<<//20
    "EGEN"<<//21
    "END" <<//22
    "EQIV"<<//23
    "ESEL"<<//24
    "EXTI"<<//25
    "EXYZ"<<//26
    "FEND"<<//27
    "FLAT"<<//28
    "FMAP"<<//29
    "FRAG"<<//30
    "FREE"<<//31
    "FVAR"<<//32
    "GRID"<<//33
    "HFIX"<<//34
    "HKLF"<<//35
    "HOPE"<<//36
    "HTAB"<<//37
    "INIT"<<//38
    "ISOR"<<//39
    "LAST"<<//40
    "LATT"<<//41
    "LAUE"<<//42
    "LIST"<<//43
    "L.S."<<//44
    "MERG"<<//45
    "MOLE"<<//46
    "MORE"<<//47
    "MOVE"<<//48
    "NCSY"<<//49
    "OMIT"<<//50
    "PART"<<//51
    "PATT"<<//52
    "PHAN"<<//53
    "PHAS"<<//54
    "PLAN"<<//55
    "PSEE"<<//56
    "REM"<< //57
    "RESI"<<//58
    "RTAB"<<//59
    "SADI"<<//60
    "SAME"<<//61
    "SFAC"<<//62
    "SHEL"<<//63
    "SIMU"<<//64
    "SIZE"<<//65
    "SPEC"<<//66
    "SPIN"<<//67
    "STIR"<<//68
    "SUMP"<<//69
    "SWAT"<<//70
    "SYMM"<<//71
    "TEMP"<<//72
    "TEXP"<<//73
    "TIME"<<//74
    "TITL"<<//75
    "TREF"<<//76
    "TWIN"<<//77
    "UNIT"<<//78
    "VECT"<<//79
    "WPDB"<<//80
    "WGHT"<<//81
    "ZERR"<<//82
    "XNPD"<<//83
    "REST"<<//84
    "CHAN"<<//85
    "RIGU"<<//86
    "FLAP"<<//87
    "RNUM"<<//88
    "SOCC"<<//89
    "PRIG"<<//90
    "WIGL"<<//91
    "RANG"<<//92
    "TANG"<<//93
    "ADDA"<<//94
    "STAG"<<//95
    "ATOM"<<//96PDB dummy commands ...
    "HETA"<<//97
    "SCAL"<<//98
    "ABIN"<<//99
    "ANSC"<<//100
    "ANSR"<<//101
    "NOTR"<<//102
    "NEUT"<<//103
    "TWST"<<//104
    "BEDE"<<//105
    "LONE"//106<<
    ;//
  QString c=command;
  c=c.toUpper();
  c.remove(QRegExp("_\\S*"));
  if (c.startsWith("+")) return 666;//file inclusion
  return keywords.indexOf(c);
}

void Window::clearStructure(){
  chgl->showHidden();
  machPlatz=false;
  chgl->neutrons=false;
  infoKanal->clear();
  shxEditorDock->show();
  wghtAct->setEnabled(false);
  qPeakDock->hide();

  chgl->pause=true;
  enterRenameMode->setVisible(true);
  chgl->qPeakBonds->setVisible(false);
  chgl->shpm1->setVisible(false);
  chgl->hideBeLo->setVisible(false);
  belocube->setVisible(false);
  mole.cell.symmops.clear();
  mole.cell.trans.clear();
  mole.asymm.clear();
  mole.sdm.clear();
  mole.showbonds.clear();
  mole.showatoms.clear();
  mole.selectedatoms.clear();
  mole.lbonds.clear();

  mole.envi_sdm.clear();
  mole.contact.clear();
  mole.envi_sdm.clear();
  mole.contact.clear();
  mole.symmopsEQIV.clear();
  mole.labelEQIV.clear();
  mole.transEQIV.clear();
  mole.freeatoms.clear();
  mole.bindatoms.clear();
  for (int i=0; i<mole.knoepfe.size();i++) mole.knoepfe[i].neighbors.clear();
  mole.knoepfe.clear();
  mole.showbonds.clear();
  mole.selectedatoms.clear();
  //chgl->rotCenter();
  chgl->updateBondActions();
  mole.showatoms.clear();
  update();
  chgl->updateGL();

}

bool Window::quickReLoad(QString fn, QString &content){
  //return false;
  // reasons for return false:
  // CELL differs +
  // filename differs +
  // LATT differs +
  // SYMM differs +
  // asymm.size is different -
  bool xit=(fn==oldFileName);
  oldFileName=fn;
  if (!xit) return false;
  QRegExp sep=QRegExp("\\s+");
  // Disabled SkipEmptyParts because otherwise i is not in sync with the line number!
  QStringList lines = content.split(QRegExp("[\\r\\n]")); //,skipEmptyParts);
  {//cell
    int idx =lines.indexOf(QRegExp("^CELL.*$"));
    //printf("IDX %d\n",idx);
    double wave = lines.at(idx).section(sep,1,1).toDouble();
    double a = lines.at(idx).section(sep,2,2).toDouble();
    double b = lines.at(idx).section(sep,3,3).toDouble();
    double c = lines.at(idx).section(sep,4,4).toDouble();
    double al= lines.at(idx).section(sep,5,5).toDouble();
    double be = lines.at(idx).section(sep,6,6).toDouble();
    double ga = lines.at(idx).section(sep,7,7).toDouble();
    double diff=
      fabs(mole.cell.a-a)+
      fabs(mole.cell.b-b)+
      fabs(mole.cell.c-c)+
      fabs(mole.cell.al-al)+
      fabs(mole.cell.be-be)+
      fabs(mole.cell.ga-ga)+
      fabs(mole.cell.wave-wave);
    printf("cell differs %g\n",diff);
    if (diff>0.00001) {
        printf("cell differs too much!\n");
      lines.clear();
      return false;
    }
  }
  {//latt
    int idx =lines.indexOf(QRegExp("^LATT.*$"));
    //printf("IDX %d\n",idx);
    int thisLattice=lines.at(idx).section(sep,1,1).toInt();
    if (mole.latt!=thisLattice){
      lines.clear();
      return false;
    }

  }
  int minp=1,maxp=0;  
  bool qbeforehkl=false,hklf=false;
  mole.pmin=10000;
  mole.pmax=-10000;
  mole.lmin=10000;
  mole.lmax=-10000;
  qPeakDock->hide();

  mole.symmopsEQIV.clear();
  mole.labelEQIV.clear();
  mole.transEQIV.clear();
  mole.freeatoms.clear();
  mole.bindatoms.clear();
  editor->sfac.clear();
  fvar.clear();
  firstAtomLine = 0;
  ls_cycls = 0;
  editor->fvMinLine = 0; // otherwise it does not recognize a moving fvar line
  MyAtom newAtom;
  newAtom.part=0;
  newAtom.resiNr=0;
  newAtom.hidden=0;
  newAtom.symmGroup=0;
  newAtom.sg=0;
  newAtom.scod=555;//the identity
  newAtom.sof=0;
  newAtom.sof_org=0;
  newAtom.screenX=0;
  newAtom.screenY=0;
  newAtom.afix=0;
  int part=0,afix=0;
  double part_fvar=11.0;
  double uiso=0.05;
  int qpeaks=0;
  int afixparent=0;
  Scatt s(&mole);
  //printf("after scatt\n");
  QStringList bedeRloneLY;
  CEnvironment quickAtoms;
  bool fragIgnore=false;
  for (int i=0; i<lines.size(); i++){
    if (lines.at(i).startsWith(" ")) continue;
    if (!lines.at(i).isEmpty()){
      newAtom.orginalLine=lines.at(i).section("=",0,0);
      lines[i].remove("=");
      int cmd=isacommand(lines.at(i).section(sep,0,0));
      //qDebug()<<cmd<<lines.at(i);
      QString resiSpez=lines.at(i).section(sep,0,0).section('_',1,1);
      if (cmd==30) fragIgnore=true;
      if (cmd==27) fragIgnore=false;
      if (!fragIgnore)
        switch (cmd) {
          case 1: //AFIX
            afix=lines.at(i).section(sep,1,1).toInt();
            // For later
            //afix_fvar = lines.at(i).section(sep,3,3).toInt();
            newAtom.afix=afix;           
            break;
          case 5: {//bind
                    if (!lines.at(i).section(sep,1,2).contains(QRegExp("[A-Za-z]"))){
                      int pn01=0,pn02=0;
                      bool ok1,ok2;
                      pn01=lines.at(i).section(sep,1,1).toInt(&ok1);
                      pn02=lines.at(i).section(sep,2,2).toInt(&ok2);
                      if ((ok1)&&(ok2)) mole.bindPart[pn01]=pn02;
                      if ((ok1)&&(ok2)) mole.bindPart[pn02]=pn01;
                    }
                    if (notRefine) break;
                    MyBind aa;
                    aa.Lab1=lines.at(i).section(sep,1,1).toUpper();
                    aa.Lab2=lines.at(i).section(sep,2,2).toUpper();
                    mole.bindatoms.append(aa);
                  }
                  break;
          case 9: { //CELL
                  }
                  break;
          case 10: { // L.S.
                     ls_cycls = lines.at(i).section(sep, 1, 1).toInt();
                   }
                   break;
          case 19:{//DISP
                    QStringList tok = lines.at(i).split(sep,skipEmptyParts);
                    s.setDISP(tok);
                  }
                  break;

          case 23:{ //EQIV
                    mole.decodeSymmCardEQIV(lines.at(i));
                  }
                  break;
          case 25:{//EXTI
                    mole.exti=lines.at(i).section(sep,1,1).toDouble();
                  }
                  break;
          case 31:{//free
                    MyBind aa;
                    aa.Lab1=lines.at(i).section(sep,1,1).toUpper();
                    aa.Lab2=lines.at(i).section(sep,2,2).toUpper();
                    mole.freeatoms.append(aa);
                  }
                  break;
          case 32:{ //FVAR
                    editor->fvMinLine=i;
                    QStringList tok = lines.at(i).split(sep,skipEmptyParts);
                    for (int ifv=1; ifv<tok.size();ifv++){
                      fvar.append(tok.at(ifv).toDouble());
                    }
                    if (!fvar.isEmpty()) {
                      mole.osf=fvar.at(0);
                    }
                  }
                  break;
          case 35: //HKLF
                  {
                    hklf=true;
                    QStringList tok = lines.at(i).split(sep,skipEmptyParts);
                    if (tok.size()>1)mole.hklf=tok.at(1).toInt();
                    if (tok.size()>2)mole.hklScale=tok.at(2).toDouble();
                    if (tok.size()>11){
                      mole.hklMat.m11=tok.at(3).toDouble();
                      mole.hklMat.m12=tok.at(4).toDouble();
                      mole.hklMat.m13=tok.at(5).toDouble();
                      mole.hklMat.m21=tok.at(6).toDouble();
                      mole.hklMat.m22=tok.at(7).toDouble();
                      mole.hklMat.m23=tok.at(8).toDouble();
                      mole.hklMat.m31=tok.at(9).toDouble();
                      mole.hklMat.m32=tok.at(10).toDouble();
                      mole.hklMat.m33=tok.at(11).toDouble();

                    }
                    if (tok.size()>12)mole.hklSigmaScale=tok.at(12).toDouble();
                    /*printf("HKLF N=%d s:%g \n%g %g %g\n%g %g %g\n%g %g %g\nsm: %g \n",mole.hklf,mole.hklScale ,
                      mole.hklMat.m11,mole.hklMat.m12,mole.hklMat.m13,
                      mole.hklMat.m21,mole.hklMat.m22,mole.hklMat.m23,
                      mole.hklMat.m31,mole.hklMat.m32,mole.hklMat.m33,
                      mole.hklSigmaScale);
                    // */

                  }
                  break;
          case 41: { //LATT
                     break;
                   }
          case 44: { // CGLS
                     ls_cycls = lines.at(i).section(sep, 1, 1).toInt();
                   }
                   break;
          case 50://OMIT
                   {
                     QStringList tok = lines.at(i).split(sep,skipEmptyParts);
                     QRegExp num=QRegExp("$[A-Za-z]");
                     if ((tok.size()==3)&&(!tok.at(1).contains(num))&&(!tok.at(2).contains(num))){
                       //hklOmitSig,hklOmit2th,hklShellLow,hklShellHig
                       mole.hklOmitSig=tok.at(1).toDouble();
                       mole.hklOmit2th=tok.at(2).toDouble();
                       mole.hklShellHig=0.5*mole.cell.wave/sin(mole.hklOmit2th/360.0*M_PI);
                     }
                   }
                   break;
          case 51: { //PART n sof
                     part = lines.at(i).section(sep,1,1).toInt();
                     // part_fvar stores sof (and fvar) to decide during atom parsing
                     part_fvar = lines.at(i).section(sep, 2, 2).toDouble();
                     minp=(minp<part)?minp:part;
                     maxp=(maxp>part)?maxp:part;
                   }
                   break;
          case 58: {//RESI
                     if (lines.at(i).section(sep,1,1).indexOf(QRegExp("^[0-9]+"))!=-1) {
                       newAtom.resiNr=lines.at(i).section(sep,1,1).toInt();
                       newAtom.ResiClass=lines.at(i).section(sep,2,2);
                     } else {
                       newAtom.resiNr=lines.at(i).section(sep,2,2).toInt();
                       newAtom.ResiClass=lines.at(i).section(sep,1,1);
                     }
                     break;
                   }
          case 62: { //SFAC
                     QStringList tok = lines.at(i).split(sep,skipEmptyParts);
                     if ((tok.size()>4)&&(!tok.at(2).contains(QRegExp("[A-Za-z]")))) {
                       s.setSCAT(tok);
                       if ((tok.at(2).toDouble()==0)&&((tok.at(3).toDouble()==1))) {
                         chgl->neutrons=true;
                       }
                       editor->sfac.append(mole.getOZ(tok.at(1)));
                       if (editor->sfac.last()>-2) {
                         pserbt[editor->sfac.last()+1]->show();
                       }
                       sfacBox->setFixedSize((editor->sfac.size()+1)*52,70);
                     } else {
                       for (int isf=1; isf<tok.size();isf++) {
                         editor->sfac.append(mole.getOZ(tok.at(isf)));
                         pserbt[editor->sfac.last()+1]->show();
                         sfacBox->setFixedSize((editor->sfac.size()+1)*52,70);
                       }
                     }
                   }
                   break;
          case 63:{//shel
                    //hklOmitSig,hklOmit2th,hklShellLow,hklShellHig
                    QStringList tok = lines.at(i).split(sep,skipEmptyParts);
                    if (tok.size()>2){
                      mole.hklShellLow=tok.at(1).toDouble();
                      mole.hklShellHig=tok.at(2).toDouble();
                      // qDebug()<<mole.hklShellLow<<mole.hklShellHig;
                    }
                  }break;
          case 69:{ //SUMP
                    QStringList forml= lines.at(i).split(sep);
                    int fvix=4;
                    while (forml.size()>fvix){
                      int m=forml.at(fvix).toInt();
                      fvarCntr[m]++;
                      fvix+=2;
                    }
                  }
                  break;
          case 70:{//SWAT g[0] U[2]
                    mole.swat=0.0;
                    mole.exti=2.0;
                    QStringList tok = lines.at(i).split(sep,skipEmptyParts);
                    if (tok.size()>1) mole.swat=tok.at(1).toDouble();
                    if (tok.size()>2) mole.exti=tok.at(2).toDouble();
                  }
                  break;

          case 71: {// SYMM
                     if (mole.symmCard2Code(lines.at(i).section(" ",1,130)).isEmpty()){
                       lines.clear();
                       return false;                     
                     }
                     break;
                   }
          case 75: {// TITL
                     title = QString ("'%1'@ %2")
                       .arg(lines.at(i).section(" ",1,30).simplified())
                       .arg(fn.section('/', -1));
                     mole.titl=lines.at(i).section(" ",1,-1).simplified();
                     break;
                   }
          case 78: {// UNIT
                     editor->unitAlt = lines.at(i) ;	
                     break;
                   }
          case 81: {// WGHT 
                     wghtAct->setEnabled(true);
                     break;
                   }
          case 82: {// ZERR
                     mole.cell.Z= lines.at(i);
                     break;
                   }
          case 103: {// NEUT 
                      //	qDebug()<<"Neutrons!";

                      chgl->neutrons=true;
                      break; 
                    }
          case 105:// BEDE
          case 106:{// LONE
                     bedeRloneLY.append(lines.at(i));
                     chgl->hideBeLo->setVisible(true);
                     belocube->setVisible(true);
                     break;
                   }
          case -1:{//an atom or an error!
                    newAtom.isIso=false;
                    newAtom.ufiso_org=""; 
                    if (firstAtomLine == 0) {
                      firstAtomLine = i;
                    }
                    if ((newAtom.afix>170)&&((newAtom.afix<180))) break;
                    QStringList tok = lines.at(i).split(sep,skipEmptyParts);
                    newAtom.part=part;
                    if (newAtom.resiNr<0){
                      newAtom.resiNr=0;
                      newAtom.ResiClass="";
                    }
                    if (tok.size()==7){
                      // We have an isotropic atom!
                      if ((newAtom.part!=0)||(newAtom.resiNr!=0)){
                        newAtom.Label=QString("%1_%3%4")
                          .arg(tok.at(0))
                          .arg((newAtom.resiNr)?QString::number(newAtom.resiNr):"")
                          .arg((newAtom.part)?QString::number((newAtom.part<0)?
                                36+newAtom.part:
                                newAtom.part+9,36):"");
                      } else {
                        newAtom.Label=tok.at(0);
                      }
                      int fac=tok.at(1).toInt()-1;
                      newAtom.fixFlag=0;

                      newAtom.an=((fac<0)||(fac>=editor->sfac.size()))?-2:editor->sfac.at(fac);
                      newAtom.frac.x = getNumber(tok.at(2).toDouble(),fvar,0,newAtom.fixFlag);
                      newAtom.frac.y = getNumber(tok.at(3).toDouble(),fvar,1,newAtom.fixFlag);
                      newAtom.frac.z = getNumber(tok.at(4).toDouble(),fvar,2,newAtom.fixFlag);
                      if (qAbs(part_fvar) > 11.0 ){
                        // fvar is defined for entire part:
                        newAtom.sof = getNumber(part_fvar, fvar, 3, newAtom.fixFlag);
                        newAtom.sof_org = part_fvar;
                      } else {
                        // fvar is defined at each atom:
                        newAtom.sof = getNumber(tok.at(5).toDouble(), fvar, 3, newAtom.fixFlag);
                        newAtom.sof_org = tok.at(5).toDouble();
                      }
                      newAtom.isIso=true;
                      double uIso = getNumber(tok.at(6).toDouble(),fvar,uiso);
                      newAtom.uf.m11 = newAtom.uf.m22 = newAtom.uf.m33 = uIso;
                      newAtom.uf.m32 = newAtom.uf.m23 = uIso * mole.cell.cosra; 
                      newAtom.uf.m31 = newAtom.uf.m13 = uIso * mole.cell.cosrb;
                      newAtom.uf.m21 = newAtom.uf.m12 = uIso * mole.cell.cosrg;
                      mole.Uf2Uo(newAtom.uf, newAtom.uc);
                      newAtom.ufiso_org=tok.at(6);
                      newAtom.peakHeight=-666;
                      if (newAtom.an==-66) newAtom.peakHeight=9999.99;
                      newAtom.afixParent=-1;
                      if (newAtom.an>0) afixparent=quickAtoms.size();
                      else newAtom.afixParent=afixparent;
                      quickAtoms.append(newAtom);
                    }
                    if (tok.size()==8) {
                      // We have a q-peak!
                      newAtom.Label=tok.at(0);
                      if (newAtom.Label.startsWith('Q',Qt::CaseInsensitive)) {
                        newAtom.an=-1;
                        newAtom.resiNr=-1;
                        newAtom.ResiClass="Q-Peak";
                        qpeaks++;
                        if (!hklf) qbeforehkl=true;
                      } else {
                        int fac=tok.at(1).toInt()-1;
                        newAtom.an=((fac<0)||(fac>=editor->sfac.size()))?-2:editor->sfac.at(fac);
                        //isoat++;
                      }
                      newAtom.fixFlag=0;
                      newAtom.frac.x = tok.at(2).toDouble();
                      newAtom.frac.y = tok.at(3).toDouble();
                      newAtom.frac.z = tok.at(4).toDouble();
                      if (qAbs(part_fvar) > 11.0 ){
                        // fvar is defined for entire part:
                        newAtom.sof = getNumber(part_fvar, fvar, 3, newAtom.fixFlag);
                        newAtom.sof_org = part_fvar;
                      } else {
                        // fvar is defined at each atom:
                        newAtom.sof = getNumber(tok.at(5).toDouble(), fvar, 3, newAtom.fixFlag);
                        newAtom.sof_org = tok.at(5).toDouble();
                      }
                      newAtom.isIso=true;
                      double uIso = getNumber(tok.at(6).toDouble(),fvar,uiso);
                      newAtom.uf.m11 = newAtom.uf.m22 = newAtom.uf.m33 = uIso;
                      newAtom.uf.m32 = newAtom.uf.m23 = uIso * mole.cell.cosra;
                      newAtom.uf.m31 = newAtom.uf.m13 = uIso * mole.cell.cosrb; 
                      newAtom.uf.m21 = newAtom.uf.m12 = uIso * mole.cell.cosrg; 
                      newAtom.ufiso_org=tok.at(6); 
                      newAtom.peakHeight=tok.at(7).toDouble();
                      //printf("##%d %f\n",qpeaks,newAtom.peakHeight);
                      if(newAtom.an==-1){
                        mole.pmin=qMin(mole.pmin, newAtom.peakHeight);
                        mole.pmax=qMax(mole.pmax, newAtom.peakHeight);
                      }
                      chgl->qPeakBonds->setVisible(true);

                      showQPeakLegend->setVisible(true);
                      newAtom.afixParent=-1;
                      quickAtoms.append(newAtom);

                    }
                    if (tok.size()==12){
                      // We have an ellipsoid atom!
                      if ((newAtom.part!=0)||(newAtom.resiNr!=0)){
                        newAtom.Label=QString("%1_%3%4")
                          .arg(tok.at(0))
                          .arg((newAtom.resiNr)?QString::number(newAtom.resiNr):"")
                          .arg((newAtom.part)?QString::number((newAtom.part<0)?
                                36+newAtom.part:
                                newAtom.part+9,36):"");
                      }else newAtom.Label=tok.at(0);
                      int fac=tok.at(1).toInt()-1;
                      newAtom.an=((fac<0)||(fac>=editor->sfac.size()))?-2:editor->sfac.at(fac);
                      newAtom.frac.x = getNumber(tok.at(2).toDouble(),fvar,0,newAtom.fixFlag);
                      newAtom.frac.y = getNumber(tok.at(3).toDouble(),fvar,1,newAtom.fixFlag);
                      newAtom.frac.z = getNumber(tok.at(4).toDouble(),fvar,2,newAtom.fixFlag);
                      if (qAbs(part_fvar) > 11.0 ){
                        // fvar is defined for entire part:
                        newAtom.sof = getNumber(part_fvar, fvar, 3, newAtom.fixFlag);
                        newAtom.sof_org = part_fvar;
                      } else {
                        // fvar is defined at each atom:
                        newAtom.sof = getNumber(tok.at(5).toDouble(), fvar, 3, newAtom.fixFlag);
                        newAtom.sof_org = tok.at(5).toDouble();
                      }
                      newAtom.uf.m11 = getNumber(tok.at(6).toDouble(),fvar,4,newAtom.fixFlag);
                      newAtom.uf.m22 = getNumber(tok.at(7).toDouble(),fvar,5,newAtom.fixFlag);
                      newAtom.uf.m33 = getNumber(tok.at(8).toDouble(),fvar,6,newAtom.fixFlag);
                      newAtom.uf.m32 = newAtom.uf.m23 = getNumber(tok.at(9).toDouble(),fvar,7,newAtom.fixFlag);
                      newAtom.uf.m31 = newAtom.uf.m13 = getNumber(tok.at(10).toDouble(),fvar,8,newAtom.fixFlag);
                      newAtom.uf.m21 = newAtom.uf.m12 = getNumber(tok.at(11).toDouble(),fvar,9,newAtom.fixFlag);
                      newAtom.peakHeight=-666;
                      uiso=mole.ueq(newAtom.uf);
                      if (newAtom.an>0) afixparent=quickAtoms.size();
                      newAtom.afixParent=-1;
                      quickAtoms.append(newAtom);
                      //adpat++;
                    }
                  }
                  break;
        }


    }

  }
  int lnrr=0;
  CEnvironment belo;
  printf("belo: %d\n",bedeRloneLY.size());
  for (int bl=0; bl<bedeRloneLY.size(); bl++){
    int ignore=0;
    QStringList tok = bedeRloneLY.at(bl).split(sep,skipEmptyParts);
    printf("belo: %s\n",tok.at(0).toStdString().c_str());
    if ((tok.at(0).endsWith("BEDE",Qt::CaseInsensitive))&&(tok.size()>6)){
      lnrr=belo.size();
      QString aton1=tok.at(1),aton2=tok.at(2);  
      double rad = getNumber(tok.at(3).toDouble(),fvar,0,ignore);
      double a   = getNumber(tok.at(4).toDouble(),fvar,0,ignore);
      double b1  = getNumber(tok.at(5).toDouble(),fvar,0,ignore);
      double b2  = getNumber(tok.at(6).toDouble(),fvar,0,ignore);
      newAtom.an=-42;
      newAtom.symmGroup=0; 
      newAtom.sg=0;
      newAtom.scod=555;//the identity
      newAtom.auidx=-1;
      int an1=-1,an2=-2;
      for (int bl1=0; bl1<mole.asymm.size(); bl1++)
        for (int bl2=0; bl2<mole.asymm.size(); bl2++){
          if ((mole.asymm.at(bl1).an<0)||(mole.asymm.at(bl2).an<0)) continue;
          double soll=-1,d= sqrt(Distance(mole.asymm.at(bl1).pos,mole.asymm.at(bl2).pos));
          if ((mole.asymm.at(bl1).an==0)&&(mole.asymm.at(bl2).an==0)) continue;
          if ((mole.asymm.at(bl1).an>-1)&&(mole.asymm.at(bl2).an>-1)&&
              ((!mole.asymm.at(bl1).part)||(!mole.asymm.at(bl2).part)||(mole.asymm.at(bl1).part==mole.asymm.at(bl2).part)))
            soll=(mole.Kovalenz_Radien[mole.asymm.at(bl1).an]+ mole.Kovalenz_Radien[mole.asymm.at(bl2).an])*0.012;
          else
            soll=-1;
          if ((d>0.1)&&(d<soll)) {
            an1=-1;
            an2=-2;
            if (aton1[0]=='$') an1=mole.getOZ(aton1);
            if (aton2[0]=='$') an2=mole.getOZ(aton2);
            if (((an1>=0)&&(mole.asymm.at(bl1).an==an1))||(aton1==mole.asymm.at(bl1).Label.section('_',0,0)))
              if (((an2>=0)&&(mole.asymm.at(bl2).an==an2))||(aton2==mole.asymm.at(bl2).Label.section('_',0,0))){
                V3 pos = mole.asymm.at(bl1).pos+Normalize(mole.asymm.at(bl2).pos-mole.asymm.at(bl1).pos)*rad;
                newAtom.pos=pos;
                mole.kart2frac(pos,pos);
                newAtom.Label=QString("L%1").arg(++lnrr);
                newAtom.frac=pos;
                newAtom.peakHeight=b1;
                newAtom.sof=a;                
                newAtom.auidx=-1;
                newAtom.uf=mole.u2b(mole.asymm.at(bl1).uf);//posible problem if U is not anisotrop 
                belo.append(newAtom);
                pos=mole.asymm.at(bl1).frac;
                newAtom.Label=QString("L%1").arg(++lnrr);
                newAtom.frac=mole.asymm.at(bl1).frac;
                mole.frac2kart(newAtom.frac,newAtom.pos);
                newAtom.sof=-a;
                newAtom.peakHeight=b2;
                belo.append(newAtom);

                mole.lmin=qMin(mole.lmin,-a);
                mole.lmax=qMax(mole.lmax, a);

              } 
          }
        }

    }else
      if (tok.at(0).endsWith("LONE",Qt::CaseInsensitive)){
        belo.append(lonesome(bedeRloneLY.at(bl),belo.size()+1));
      }
  }
  if (!belo.isEmpty()) {
    for (int bl=0; bl<belo.size(); bl++){
      belo[bl].orginalLine=QString("%1    2 %2 %3 %4").arg(belo.at(bl).Label.section('_',0,0),-4)
        .arg(belo.at(bl).frac.x,10,'f',5)
        .arg(belo.at(bl).frac.y,10,'f',5)
        .arg(belo.at(bl).frac.z,10,'f',5);
    }
    quickAtoms.append(belo);
  }
  printf("qck %d au %d\n",quickAtoms.size(),mole.asymm.size());
  for (int i=0;i<quickAtoms.size();i++){ 
    mole.Uf2Uo(quickAtoms.at(i).uf,quickAtoms[i].uc);
    mole.frac2kart(quickAtoms.at(i).frac,quickAtoms[i].pos);
  }
  if (quickAtoms.size()>mole.asymm.size()){
    int osiz=mole.asymm.size();
    for (int k=osiz;k<quickAtoms.size();k++){
      mole.showatoms.insert(k,quickAtoms[k]);
    }
  }
  printf("qck %d au %d\n",quickAtoms.size(),mole.asymm.size());
  if (quickAtoms.size()<mole.asymm.size()){
    mole.asymm.clear();
    quickAtoms.clear();
    printf("number of atoms differs too much!\n");
    lines.clear();
    return false;
  }
  mole.asymm.clear();
  for (int i=0; i<quickAtoms.size(); i++){
    mole.asymm.append(quickAtoms[i]);
  }
  //mole.asymm=quickAtoms;
  printf("X-\n");
  for (int i=0; i<mole.showatoms.size(); i++){
    int idx=0;
    if ((mole.showatoms.at(i).auidx<0)||(mole.showatoms.at(i).auidx>quickAtoms.size())){
        idx=i;
        printf("AU:%s=%s %d=%d %f %f %f %f %f %f\n",mole.showatoms.at(i).Label.toStdString().c_str(),quickAtoms.at(idx).Label.toStdString().c_str(),
               mole.showatoms.at(i).scod,quickAtoms.at(i).scod,
               mole.showatoms.at(i).pos.x,mole.showatoms.at(i).pos.y,mole.showatoms.at(i).pos.z,
               quickAtoms.at(i).pos.x,quickAtoms.at(i).pos.y,quickAtoms.at(i).pos.z
               );
    }
    else idx=mole.showatoms.at(i).auidx;
    if (idx>=quickAtoms.size()) continue;
    //printf("quickAtoms %s %d %d %d %d %s\n",mole.showatoms.at(i).Label.toStdString().c_str(),i,idx,quickAtoms.size(),mole.showatoms.size(),quickAtoms.at(idx).Label.toStdString().c_str());
    V3 actpos = mole.applySymCode(quickAtoms.at(idx).frac,mole.showatoms.at(i).scod);
    //printf("#%-4d %d %d %d %d %g\n",i,mole.showatoms.at(i).symmGroup,mole.showatoms.at(i).sg,mole.showatoms.at(i).scod,mole.showatoms.at(i).hidden,Distance(actpos,mole.showatoms.at(i).frac));
    mole.showatoms[i].frac = actpos;
    mole.showatoms[i].isIso = quickAtoms.at(idx).isIso;
    if (mole.showatoms.at(i).scod==555){
        mole.showatoms[i].orginalLine = quickAtoms.at(idx).orginalLine;
        mole.showatoms[i].Label = quickAtoms.at(idx).Label;
    }
    //printf("tick %d scod%d %d %d\n",__LINE__,mole.showatoms.at(i).scod,i,idx);
    ///printf("%f %f\n",mole.showatoms[i].peakHeight , quickAtoms.at(idx).peakHeight);
    if (quickAtoms[idx].an>=0){
      mole.USymCode(quickAtoms[idx].uf,mole.showatoms.at(i).scod,mole.showatoms[i].uf);
      //printf("tick %d\n",__LINE__);
      mole.Uf2Uo(mole.showatoms[i].uf,mole.showatoms[i].uc);
    }
    mole.showatoms[i].peakHeight = quickAtoms.at(idx).peakHeight;
    //printf("tick %d\n",__LINE__);
    mole.showatoms[i].part = quickAtoms.at(idx).part;
    mole.showatoms[i].an = quickAtoms.at(idx).an;
    //printf("tick %d\n",__LINE__);
    mole.showatoms[i].resiNr= quickAtoms.at(idx).resiNr;
    //printf("tick %d\n",__LINE__);
    mole.showatoms[i].auidx = idx;
    //printf("tick %d\n",__LINE__);
    mole.showatoms[i].sof = quickAtoms.at(idx).sof;
    //printf("tick %d\n",__LINE__);
    mole.showatoms[i].sof_org = quickAtoms.at(idx).sof_org;
    //printf("tick %d\n",__LINE__);
    mole.showatoms[i].screenX = quickAtoms.at(idx).screenX;
    //printf("tick %d\n",__LINE__);
    mole.showatoms[i].screenY = quickAtoms.at(idx).screenY;
    //printf("tick %d\n",__LINE__);
    mole.showatoms[i].afix = quickAtoms.at(idx).afix;
    //printf("tick %d\n",__LINE__);
    mole.frac2kart(actpos,mole.showatoms[i].pos);
    //printf("tick %d\n",__LINE__);
  }
  printf("x\n");

  chgl->shpm1->setVisible(false);
  chgl->highlightParts->setVisible(false);
  if (minp<0) {
    chgl->shpm1->setVisible(true);
    chgl->highlightParts->setVisible(true);
  }
  if (maxp>0) chgl->highlightParts->setVisible(true);
  mole.qbeforehkl=qbeforehkl;
  actionUniq->setDisabled(mole.qbeforehkl);
  QString info;
  for (int ifv=0; ifv<fvar.size();ifv++){
    if (ifv==0) {
      info.append("OSF: ");
      info.append(QString("<font color=red>%1</font>").arg(fvar.at(ifv)));
    }
    else {
      info.append(QString("FVAR<font color=blue>%1</font>: ").arg(ifv+1));
      if (fvarCntr.value(ifv+1)<1)info.append(QString("<font color=red>%1</font>(Never Used!)").arg(fvar.at(ifv)));
      else info.append(QString("<font color=red>%1</font>(used %2 time%3.)").arg(fvar.at(ifv))
          .arg(fvarCntr.value(ifv+1)).arg((fvarCntr.value(ifv+1)>1)?"s":""));
    }
    if ((ifv+1)<fvar.size()) info.append(", ");
    info.append("<br>");
  }
  fvarinfo=QString("<b>Free variables:</b> %1").arg(info);  
  qpv->setMin(mole.pmin);
  qpv->setMax(mole.pmax);
  printf("%f %f\n",mole.pmin,mole.pmax);

  qpv->update();
  for (int i=0; i<mole.showatoms.size(); i++){
      if (mole.showatoms.at(i).an!=-1) continue;
      if (mole.showatoms.at(i).peakHeight>mole.pmax) {printf("remove q %d %d %s %f %f max\n",i,mole.showatoms.at(i).an,mole.showatoms.at(i).Label.toStdString().c_str(),mole.showatoms.at(i).peakHeight,mole.pmax); mole.showatoms.removeAt(i); i--; i=(i<0)?0:i;}
  }
  for (int i=0; i<mole.showatoms.size(); i++){
      if (mole.showatoms.at(i).an!=-1) continue;
      if (mole.showatoms.at(i).peakHeight<mole.pmin) {printf("remove q %d %d %s %f %f min\n",i,mole.showatoms.at(i).an,mole.showatoms.at(i).Label.toStdString().c_str(),mole.showatoms.at(i).peakHeight,mole.pmin); mole.showatoms.removeAt(i); i--; i=(i<0)?0:i;}
  }
  updateStatusBar("finding bonds...");
  mole.showbonds.clear(); 
  mole.showbonds = mole.connecting(mole.showatoms);
  if (qpeaks) qPeakDock->show();
  QTime zeit; zeit.start();
  //printf("MAPS?\n");
  fxle->resDir=QDir(fn);
  fxle->fouName=(fxle->MYFCF)?s.myfcf(fn):"";
  if (fxle->fouName.isEmpty()){
    fxle->fouName=fn;
    fxle->fouName.chop(4);
    fxle->fouName.append(".fcf");
  }

  if  ((fxle->doMaps->isChecked())&& (!fxle->loadFouAndPerform(fxle->fouName.toLocal8Bit()))) {
    if (fxle->doMaps->isChecked()) infoKanalNews(QString("<font color=red>Error while loading %1!</font><br>").arg(fxle->fouName));

  //printf("%d\n",__LINE__);
    fxle->killmaps();
  //printf("%d\n",__LINE__);
    fxle->n1=fxle->n2=fxle->n3=fxle->n5=0;
  }
  if (fxle->doMaps->isChecked()){
    fxle->mapcontrol->setVisible(true);
  }
  fxle->doMaps->show();
  //printf("MAPS!\n");
  QString listName=fn;
  listName.replace(QRegExp(".ins$"),".lst");
  listName.replace(QRegExp(".res$"),".lst");
  QFile lstf(listName);
  if (lstf.open(QIODevice::ReadOnly|QIODevice::Text)){
    QString liste=QString(lstf.readAll());
    while (liste.contains(QRegExp("\n\\s+REM"))) liste=liste.replace(QRegExp("\n\\s+REM[^\n]*\n",Qt::CaseInsensitive),"\n");
    if (liste.contains("Flack x parameter =")){
      QString flackS=liste.section("Flack x parameter =",1).section('\n',0,0);
      double flackX=flackS.split(QRegExp("\\s+"),skipEmptyParts).first().toDouble();
      double flackXesd=flackS.split(QRegExp("\\s+"),skipEmptyParts).last().toDouble();
      infoKanalNews(QString("SHELXL-list file reports <b>Flack</b> x parameter:<b> %1 &plusmn; %2</b>").arg(flackX).arg(flackXesd)); 
    }
    //Flack x =
    if (liste.contains("Flack x =")) {
      QString flackS=liste.section("\n Flack x = ",1).section('\n',0,1);
      QString flackX = "";
      // prevent crash from empty flackS:
      if (flackS.split(QRegExp("\\s+"),skipEmptyParts).length() > 0) {
        flackX=flackS.split(QRegExp("\\s+"),skipEmptyParts).first();
      }
      QString parsonsZ=flackS.section('\n',1,1);
      if (parsonsZ.isEmpty() && !flackX.isEmpty()) {
        infoKanalNews(QString("SHELXL-list file reports <b>Flack</b> x parameter:<b> %1 </b>").arg(flackX)); 
      }
      if (!parsonsZ.isEmpty() && !flackX.isEmpty()) {
        parsonsZ=parsonsZ.split(QRegExp("\\s+"),skipEmptyParts).first();
        infoKanalNews(QString("SHELXL-list file reports <br><b>Flack</b> x parameter:<b> %1 </b><br><b>Parsons</b> parameter:<b>  %2</b>")
            .arg(flackX).arg(parsonsZ));
      }
    }
    lstf.close();
  }
  QMap<int,double> unit;
  for (int i=0; i<mole.asymm.size(); i++){
    if (mole.asymm.at(i).an>=0) unit[mole.asymm.at(i).an]+= mole.asymm.at(i).sof * mole.cell.symmops.size();
  }
  editor->unitNeu="UNIT";
  for (int i = 0; i < editor->sfac.size() ; i++){
    if (unit.value(editor->sfac.at(i))>9999)
      editor->unitNeu.append(QString(" %1").arg((int)unit.value(editor->sfac.at(i)))); else
        editor->unitNeu.append(QString(" %1").arg(unit.value(editor->sfac.at(i)),0,'g'));
    if (editor->unitNeu.split('\n').last().size()>76) editor->unitNeu.append("=\n    ");
  }
  //printf("EX %d\n",__LINE__);
  //return false;
  return true;
}

void Window::load_sheldrick(QString fileName, QString &inhalt){
  //! Parses the SHELX res/ins file into data structures.
  if (quickReLoadButton->isChecked())if (quickReLoad(fileName, inhalt)) return;// if quickreload works then here is nothing to do
  //printf("%d\n",__LINE__);
  fxle->killmaps();
  //printf("%d\n",__LINE__);
  fxle->n5=0;
  mole.newstructure();
  chgl->showHidden();
  machPlatz=false;
  chgl->neutrons=false;
  static QString maidenName="";
  infoKanal->clear();
  shxEditorDock->show();
  wghtAct->setEnabled(false);
  QString problem;
  qPeakDock->hide();
  chgl->pause=true;
  int minp=1,maxp=0;
  bool qbeforehkl=false,hklf=false;
  enterRenameMode->setVisible(true);
  chgl->qPeakBonds->setVisible(false);
  chgl->shpm1->setVisible(false);
  chgl->hideBeLo->setVisible(false);
  belocube->setVisible(false);
  mole.cell.symmops.clear();
  mole.cell.trans.clear();
  mole.asymm.clear();
  mole.sdm.clear();
  mole.showbonds.clear();
  mole.showatoms.clear();
  mole.selectedatoms.clear();

  mole.lbonds.clear();
  mole.envi_sdm.clear();
  mole.contact.clear();
  mole.envi_sdm.clear();
  mole.contact.clear();
  mole.symmopsEQIV.clear();
  mole.labelEQIV.clear();
  mole.transEQIV.clear();
  mole.freeatoms.clear();
  mole.bindatoms.clear();
  for (int i=0; i<mole.knoepfe.size();i++) mole.knoepfe[i].neighbors.clear();
  mole.knoepfe.clear();
  mole.showbonds.clear();
  mole.selectedatoms.clear();
  chgl->updateBondActions();
  mole.showatoms.clear();
  V3 nl(0,0,0);
  QStringList bedeRloneLY;
  mole.cell.trans.append(nl);
  mole.cell.symmops.append(Matrix(1,0,0, 0,1,0, 0,0,1));
  mole.pmin=10000;
  mole.pmax=-10000;
  mole.lmin=10000;
  mole.lmax=-10000;
  firstAtomLine = 0;
  ls_cycls = 0;
  editor->fvMinLine = 0; // otherwise it does not recognize a moving fvar line
  MyAtom newAtom;
  newAtom.part=0;
  newAtom.resiNr=0;
  newAtom.hidden=0;
  newAtom.symmGroup=0;
  newAtom.sg=0;
  newAtom.scod=555;//the identity
  newAtom.auidx=-1;
  newAtom.sof=0;
  newAtom.sof_org=0;
  newAtom.screenX=0;
  newAtom.screenY=0;
  newAtom.afix=0;
  bool virg=true;
  if (maidenName!=fileName) {
    labelIndex=1;
    nextLabel="C1";
    labelPSE="C";
    pserbt[6]->setChecked(true);
    renamDock->hide();
    updateLabel();
  }else{
    virg=false;
  }
  maidenName=fileName;
  int part=0,afix=0;
  double part_fvar=11.0;
  double uiso=0.05;
  int lattice=1;
  int isoat=0,adpat=0,qpeaks=0;
  int afixparent=0;
  mole.exti=-666.0;
  mole.swat=-666.0;
  editor->sfac.clear();
  fvar.clear();
  chgl->sfacMenu->clear();
  MyAtom xda;
  xda.symmGroup=0;
  xda.sg=0;
  xda.scod=555;//the identity
  xda.auidx=-1;
  xda.hidden=0;
  xda.part=0;
  xda.Label="H";
  xda.pos.x=-2.75;
  xda.pos.y=-6.8;
  xda.pos.z=0;
  xda.an=5;
  xda.peakHeight=0.02;
  xda.uc=Matrix(
      0.01773,-0.00303, 0.00266,
      -0.00303, 0.01456, 0.00172,
      0.00266, 0.00172, 0.01110);
  mole.legendAtoms.clear();
  //
  mole.osf=0.0;
  mole.hklScale=mole.hklSigmaScale=1.0;
  mole.hklMat=Matrix(1,0,0,0,1,0,0,0,1);
  mole.hklOmitSig=-2;
  mole.hklOmit2th=180.0;
  mole.hklShellLow=99999.0;
  mole.hklShellHig=0.0;
  fvarCntr.clear();
  mole.transEQIV.clear();
  mole.symmopsEQIV.clear();
  mole.labelEQIV.clear();
  mole.freeatoms.clear();
  mole.bindatoms.clear();
  mole.envi_sdm.clear();
  mole.bindPart.clear();
  Scatt s(&mole);
  chgl->labs.clear();
  chgl->enviPositions.clear();
  for (int i=1; i<109; i++) pserbt[i]->hide();
  if (notRefine) lattice=-1;
  QRegExp sep=QRegExp("\\s+");
  // Disabled SkipEmptyParts because otherwise i is not in sync with the line number!
  QStringList lines = inhalt.split(QRegExp("[\\r\\n]")); //,skipEmptyParts);
  bool fragIgnore=false;
  for (int i=0; i<lines.size(); i++){
    if (lines.at(i).startsWith(" ")) continue;
    if (!lines.at(i).isEmpty()){
      newAtom.orginalLine=lines.at(i).section("=",0,0);
      lines[i].remove("=");
      int cmd=isacommand(lines.at(i).section(sep,0,0));
      //qDebug()<<cmd<<lines.at(i);
      QString resiSpez=lines.at(i).section(sep,0,0).section('_',1,1);
      if (cmd==30) fragIgnore=true;
      if (cmd==27) fragIgnore=false;
      if (!fragIgnore)
        switch (cmd) {
          case 1: //AFIX
            afix=lines.at(i).section(sep,1,1).toInt();
            // For later
            //afix_fvar = lines.at(i).section(sep,3,3).toInt();
            newAtom.afix=afix;           
            break;
          case 5: {//bind
                    if (!lines.at(i).section(sep,1,2).contains(QRegExp("[A-Za-z]"))){
                      int pn01=0,pn02=0;
                      bool ok1,ok2;
                      pn01=lines.at(i).section(sep,1,1).toInt(&ok1);
                      pn02=lines.at(i).section(sep,2,2).toInt(&ok2);
                      if ((ok1)&&(ok2)) mole.bindPart[pn01]=pn02;
                      if ((ok1)&&(ok2)) mole.bindPart[pn02]=pn01;
                    }
                    if (notRefine) break;
                    MyBind aa;
                    aa.Lab1=lines.at(i).section(sep,1,1).toUpper();
                    aa.Lab2=lines.at(i).section(sep,2,2).toUpper();
                    mole.bindatoms.append(aa);
                  }
                  break;
          case 9: { //CELL
                    mole.cell.wave = lines.at(i).section(sep,1,1).toDouble();
                    mole.cell.a = lines.at(i).section(sep,2,2).toDouble();
                    mole.cell.b = lines.at(i).section(sep,3,3).toDouble();
                    mole.cell.c = lines.at(i).section(sep,4,4).toDouble();
                    mole.cell.al= lines.at(i).section(sep,5,5).toDouble();
                    mole.cell.be = lines.at(i).section(sep,6,6).toDouble();
                    mole.cell.ga = lines.at(i).section(sep,7,7).toDouble();
                    mole.cellSetup();
                  }
                  break;
          case 10: { // L.S.
                     ls_cycls = lines.at(i).section(sep, 1, 1).toInt();
                   }
                   break;
          case 19:{//DISP
                    QStringList tok = lines.at(i).split(sep,skipEmptyParts);
                    s.setDISP(tok);
                  }
                  break;

          case 23:{ //EQIV
                    mole.decodeSymmCardEQIV(lines.at(i));
                  }
                  break;
          case 25:{//EXTI
                    mole.exti=lines.at(i).section(sep,1,1).toDouble();
                  }
                  break;
          case 31:{//free
                    MyBind aa;
                    aa.Lab1=lines.at(i).section(sep,1,1).toUpper();
                    aa.Lab2=lines.at(i).section(sep,2,2).toUpper();
                    mole.freeatoms.append(aa);
                  }
                  break;
          case 32:{ //FVAR
                    editor->fvMinLine=i;
                    QStringList tok = lines.at(i).split(sep,skipEmptyParts);
                    for (int ifv=1; ifv<tok.size();ifv++){
                      fvar.append(tok.at(ifv).toDouble());
                    }
                    if (!fvar.isEmpty()) {
                      mole.osf=fvar.at(0);
                    }
                  }
                  break;
          case 35: //HKLF
                  {
                    hklf=true;
                    QStringList tok = lines.at(i).split(sep,skipEmptyParts);
                    if (tok.size()>1)mole.hklf=tok.at(1).toInt();
                    if (tok.size()>2)mole.hklScale=tok.at(2).toDouble();
                    if (tok.size()>11){
                      mole.hklMat.m11=tok.at(3).toDouble();
                      mole.hklMat.m12=tok.at(4).toDouble();
                      mole.hklMat.m13=tok.at(5).toDouble();
                      mole.hklMat.m21=tok.at(6).toDouble();
                      mole.hklMat.m22=tok.at(7).toDouble();
                      mole.hklMat.m23=tok.at(8).toDouble();
                      mole.hklMat.m31=tok.at(9).toDouble();
                      mole.hklMat.m32=tok.at(10).toDouble();
                      mole.hklMat.m33=tok.at(11).toDouble();

                    }
                    if (tok.size()>12)mole.hklSigmaScale=tok.at(12).toDouble();
                   /* printf("HKLF N=%d s:%g \n%g %g %g\n%g %g %g\n%g %g %g\nsm: %g \n",mole.hklf,mole.hklScale ,
                        mole.hklMat.m11,mole.hklMat.m12,mole.hklMat.m13,
                        mole.hklMat.m21,mole.hklMat.m22,mole.hklMat.m23,
                        mole.hklMat.m31,mole.hklMat.m32,mole.hklMat.m33,
                        mole.hklSigmaScale);*/

                  }
                  break;
          case 41: { //LATT
                     lattice=lines.at(i).section(sep,1,1).toInt();
                     break;
                   }
          case 44: { // CGLS
                     ls_cycls = lines.at(i).section(sep, 1, 1).toInt();
                   }
                   break;
          case 50://OMIT
                   {
                     QStringList tok = lines.at(i).split(sep,skipEmptyParts);
                     QRegExp num=QRegExp("$[A-Za-z]");
                     if ((tok.size()==3)&&(!tok.at(1).contains(num))&&(!tok.at(2).contains(num))){
                       //hklOmitSig,hklOmit2th,hklShellLow,hklShellHig
                       mole.hklOmitSig=tok.at(1).toDouble();
                       mole.hklOmit2th=tok.at(2).toDouble();
                       mole.hklShellHig=0.5*mole.cell.wave/sin(mole.hklOmit2th/360.0*M_PI);
                     }
                   }
                   break;
          case 51: { //PART n sof
                     part = lines.at(i).section(sep,1,1).toInt();
                     // part_fvar stores sof (and fvar) to decide during atom parsing
                     part_fvar = lines.at(i).section(sep, 2, 2).toDouble();
                     minp=(minp<part)?minp:part;
                     maxp=(maxp>part)?maxp:part;
                   }
                   break;
          case 58: {//RESI
                     if (lines.at(i).section(sep,1,1).indexOf(QRegExp("^[0-9]+"))!=-1) {
                       newAtom.resiNr=lines.at(i).section(sep,1,1).toInt();
                       newAtom.ResiClass=lines.at(i).section(sep,2,2);
                     } else {
                       newAtom.resiNr=lines.at(i).section(sep,2,2).toInt();
                       newAtom.ResiClass=lines.at(i).section(sep,1,1);
                     }
                     break;
                   }
          case 62: { //SFAC
                     QStringList tok = lines.at(i).split(sep,skipEmptyParts);
                     if ((tok.size()>4)&&(!tok.at(2).contains(QRegExp("[A-Za-z]")))) {
                       s.setSCAT(tok);
                       if ((tok.at(2).toDouble()==0)&&((tok.at(3).toDouble()==1))) {
                         chgl->neutrons=true;
                       }
                       editor->sfac.append(mole.getOZ(tok.at(1)));
                       if (editor->sfac.last()>-2) {
                         pserbt[editor->sfac.last()+1]->show();
                       }
                       if ((virg)&&(editor->sfac.last()==5)) {
                         pserbt[editor->sfac.last()+1]->setChecked(true);
                       }
                       sfacBox->setFixedSize((editor->sfac.size()+1)*52,70);
                     } else {
                       for (int isf=1; isf<tok.size();isf++) {
                         editor->sfac.append(mole.getOZ(tok.at(isf)));
                         pserbt[editor->sfac.last()+1]->show();
                         if ((virg)&&(editor->sfac.last()==5)) {
                           pserbt[editor->sfac.last()+1]->setChecked(true);
                         }
                         sfacBox->setFixedSize((editor->sfac.size()+1)*52,70);
                       }
                     }
                   }
                   break;
          case 63:{//shel
                    //hklOmitSig,hklOmit2th,hklShellLow,hklShellHig
                    QStringList tok = lines.at(i).split(sep,skipEmptyParts);
                    if (tok.size()>2){
                      mole.hklShellLow=tok.at(1).toDouble();
                      mole.hklShellHig=tok.at(2).toDouble();
                      // qDebug()<<mole.hklShellLow<<mole.hklShellHig;
                    }
                  }break;
          case 69:{ //SUMP
                    QStringList forml= lines.at(i).split(sep);
                    int fvix=4;
                    while (forml.size()>fvix){
                      int m=forml.at(fvix).toInt();
                      fvarCntr[m]++;
                      fvix+=2;
                    }
                  }
                  break;
          case 70:{
                    //SWAT g[0] U[2]
                    mole.swat=0.0;
                    mole.exti=2.0;
                    QStringList tok = lines.at(i).split(sep,skipEmptyParts);
                    if (tok.size()>1) mole.swat=tok.at(1).toDouble();
                    if (tok.size()>2) mole.exti=tok.at(2).toDouble();
                  }
                  break;

          case 71: {// SYMM
                     mole.decodeSymmCard(lines.at(i).section(" ",1,130));
                     break;
                   }
          case 75: {// TITL
                     title = QString ("'%1'@ %2")
                       .arg(lines.at(i).section(" ",1,30).simplified())
                       .arg(fileName.section('/', -1));
                     mole.titl=lines.at(i).section(" ",1,-1).simplified();
                     break;
                   }
          case 78: {// UNIT
                     editor->unitAlt = lines.at(i) ;	
                     mole.applyLatticeCentro(lattice);

                     break;
                   }
          case 81: {// WGHT 
                     wghtAct->setEnabled(true);
                     break;
                   }
          case 82: {// ZERR
                     mole.cell.Z= lines.at(i);
                     break;
                   }
          case 103: {// NEUT 
                      //	qDebug()<<"Neutrons!";

                      chgl->neutrons=true;
                      break; 
                    }
          case 105:// BEDE
          case 106:{// LONE
                     bedeRloneLY.append(lines.at(i));
                     chgl->hideBeLo->setVisible(true);
                     belocube->setVisible(true);
                     break;
                   }
          case -1:{//an atom or an error!
                    newAtom.isIso=false;
                    newAtom.ufiso_org=""; 
                    if (firstAtomLine == 0) {
                      firstAtomLine = i;
                    }
                    if ((newAtom.afix>170)&&((newAtom.afix<180))) break;
                    QStringList tok = lines.at(i).split(sep,skipEmptyParts);
                    newAtom.part=part;
                    if (newAtom.resiNr<0){
                      newAtom.resiNr=0;
                      newAtom.ResiClass="";
                    }
                    if (tok.size()==7){
                      // We have an isotropic atom!
                      if ((newAtom.part!=0)||(newAtom.resiNr!=0)){
                        newAtom.Label=QString("%1_%3%4")
                          .arg(tok.at(0))
                          .arg((newAtom.resiNr)?QString::number(newAtom.resiNr):"")
                          .arg((newAtom.part)?QString::number((newAtom.part<0)?
                                36+newAtom.part:
                                newAtom.part+9,36):"");
                      } else {
                        newAtom.Label=tok.at(0);
                      }
                      int fac=tok.at(1).toInt()-1;
                      newAtom.fixFlag=0;

                      newAtom.an=((fac<0)||(fac>=editor->sfac.size()))?-2:editor->sfac.at(fac);
                      newAtom.frac.x = getNumber(tok.at(2).toDouble(),fvar,0,newAtom.fixFlag);
                      newAtom.frac.y = getNumber(tok.at(3).toDouble(),fvar,1,newAtom.fixFlag);
                      newAtom.frac.z = getNumber(tok.at(4).toDouble(),fvar,2,newAtom.fixFlag);
                      if (qAbs(part_fvar) > 11.0 ){
                        // fvar is defined for entire part:
                        newAtom.sof = getNumber(part_fvar, fvar, 3, newAtom.fixFlag);
                        newAtom.sof_org = part_fvar;
                      } else {
                        // fvar is defined at each atom:
                        newAtom.sof = getNumber(tok.at(5).toDouble(), fvar, 3, newAtom.fixFlag);
                        newAtom.sof_org = tok.at(5).toDouble();
                      }
                      newAtom.isIso=true;
                      double uIso = getNumber(tok.at(6).toDouble(),fvar,uiso);
                      newAtom.uf.m11 = newAtom.uf.m22 = newAtom.uf.m33 = uIso;
                      newAtom.uf.m32 = newAtom.uf.m23 = uIso * mole.cell.cosra; 
                      newAtom.uf.m31 = newAtom.uf.m13 = uIso * mole.cell.cosrb;
                      newAtom.uf.m21 = newAtom.uf.m12 = uIso * mole.cell.cosrg;
                      mole.Uf2Uo(newAtom.uf, newAtom.uc);
                      newAtom.ufiso_org=tok.at(6);
                      /*printf("Uiso%g uiso%g %g %g %g\n",uIso,uiso,mole.cell.cosra,mole.cell.cosrb,mole.cell.cosrg);
                        printf("%s org=%s iso=%d\n a%9.6f b%9.6f c%9.6f  %9.6f %9.6f %9.6f\n d%9.6f e%9.6f f%9.6f  %9.6f %9.6f %9.6f\n g%9.6f h%9.6f i%9.6f  %9.6f %9.6f %9.6f\n\n",
                        newAtom.Label.toStdString().c_str(),
                        newAtom.ufiso_org.toStdString().c_str(),
                        newAtom.isIso,
                        newAtom.uf.m11,newAtom.uf.m12,newAtom.uf.m13,  newAtom.uc.m11,newAtom.uc.m12,newAtom.uc.m13,
                        newAtom.uf.m21,newAtom.uf.m22,newAtom.uf.m23,  newAtom.uc.m21,newAtom.uc.m22,newAtom.uc.m23,
                        newAtom.uf.m31,newAtom.uf.m32,newAtom.uf.m33,  newAtom.uc.m31,newAtom.uc.m32,newAtom.uc.m33);*/
                      //qDebug()<< newAtom.ufiso_org<< uIso<<newAtom.uc.m11<<newAtom.uc.m22<<newAtom.uc.m33<<newAtom.uc.m23<<newAtom.uc.m13<<newAtom.uc.m12;
                      newAtom.peakHeight=-666;
                      if (newAtom.an==-66) newAtom.peakHeight=9999.99;
                      newAtom.afixParent=-1;
                      if (newAtom.an>0) afixparent=mole.asymm.size();
                      else newAtom.afixParent=afixparent;
                      mole.asymm.append(newAtom);
                      isoat++;
                    }
                    if (tok.size()==8) {
                      // We have a q-peak!
                      newAtom.Label=tok.at(0);
                      if (newAtom.Label.startsWith('Q',Qt::CaseInsensitive)) {
                        newAtom.an=-1;
                        newAtom.resiNr=-1;
                        newAtom.ResiClass="Q-Peak";
                        qpeaks++;
                      } else {
                        int fac=tok.at(1).toInt()-1;
                        newAtom.an=((fac<0)||(fac>=editor->sfac.size()))?-2:editor->sfac.at(fac);
                        isoat++;
                      }
                      newAtom.fixFlag=0;
                      newAtom.frac.x = tok.at(2).toDouble();
                      newAtom.frac.y = tok.at(3).toDouble();
                      newAtom.frac.z = tok.at(4).toDouble();
                      if (qAbs(part_fvar) > 11.0 ){
                        // fvar is defined for entire part:
                        newAtom.sof = getNumber(part_fvar, fvar, 3, newAtom.fixFlag);
                        newAtom.sof_org = part_fvar;
                      } else {
                        // fvar is defined at each atom:
                        newAtom.sof = getNumber(tok.at(5).toDouble(), fvar, 3, newAtom.fixFlag);
                        newAtom.sof_org = tok.at(5).toDouble();
                      }
                      newAtom.isIso=true;
                      double uIso = getNumber(tok.at(6).toDouble(),fvar,uiso);
                      newAtom.uf.m11 = newAtom.uf.m22 = newAtom.uf.m33 = uIso;
                      newAtom.uf.m32 = newAtom.uf.m23 = uIso * mole.cell.cosra;
                      newAtom.uf.m31 = newAtom.uf.m13 = uIso * mole.cell.cosrb; 
                      newAtom.uf.m21 = newAtom.uf.m12 = uIso * mole.cell.cosrg; 
                      newAtom.ufiso_org=tok.at(6); 
                      //newAtom.uf.m11= getNumber(tok.at(6).toDouble(), fvar, uiso);
                      //newAtom.isIso=true;
                      //newAtom.uf.m33= tok.at(6).toDouble();
                      newAtom.peakHeight=tok.at(7).toDouble();
                      if (!hklf) qbeforehkl=true;
                      if(newAtom.an==-1){
                        mole.pmin=qMin(mole.pmin, newAtom.peakHeight);
                        mole.pmax=qMax(mole.pmax, newAtom.peakHeight);
                      }
                      chgl->qPeakBonds->setVisible(true);

                      showQPeakLegend->setVisible(true);
                      newAtom.afixParent=-1;
                      mole.asymm.append(newAtom);

                    }
                    if (tok.size()==12){
                      // We have an ellipsoid atom!
                      if ((newAtom.part!=0)||(newAtom.resiNr!=0)){
                        newAtom.Label=QString("%1_%3%4")
                          .arg(tok.at(0))
                          .arg((newAtom.resiNr)?QString::number(newAtom.resiNr):"")
                          .arg((newAtom.part)?QString::number((newAtom.part<0)?
                                36+newAtom.part:
                                newAtom.part+9,36):"");
                      }else newAtom.Label=tok.at(0);
                      int fac=tok.at(1).toInt()-1;
                      newAtom.an=((fac<0)||(fac>=editor->sfac.size()))?-2:editor->sfac.at(fac);
                      newAtom.frac.x = getNumber(tok.at(2).toDouble(),fvar,0,newAtom.fixFlag);
                      newAtom.frac.y = getNumber(tok.at(3).toDouble(),fvar,1,newAtom.fixFlag);
                      newAtom.frac.z = getNumber(tok.at(4).toDouble(),fvar,2,newAtom.fixFlag);
                      if (qAbs(part_fvar) > 11.0 ){
                        // fvar is defined for entire part:
                        newAtom.sof = getNumber(part_fvar, fvar, 3, newAtom.fixFlag);
                        newAtom.sof_org = part_fvar;
                      } else {
                        // fvar is defined at each atom:
                        newAtom.sof = getNumber(tok.at(5).toDouble(), fvar, 3, newAtom.fixFlag);
                        newAtom.sof_org = tok.at(5).toDouble();
                      }
                      newAtom.uf.m11 = getNumber(tok.at(6).toDouble(),fvar,4,newAtom.fixFlag);
                      newAtom.uf.m22 = getNumber(tok.at(7).toDouble(),fvar,5,newAtom.fixFlag);
                      newAtom.uf.m33 = getNumber(tok.at(8).toDouble(),fvar,6,newAtom.fixFlag);
                      newAtom.uf.m32 = newAtom.uf.m23 = getNumber(tok.at(9).toDouble(),fvar,7,newAtom.fixFlag);
                      newAtom.uf.m31 = newAtom.uf.m13 = getNumber(tok.at(10).toDouble(),fvar,8,newAtom.fixFlag);
                      newAtom.uf.m21 = newAtom.uf.m12 = getNumber(tok.at(11).toDouble(),fvar,9,newAtom.fixFlag);
                      newAtom.peakHeight=-666;
                      uiso=mole.ueq(newAtom.uf);
                      if (newAtom.an>0) afixparent=mole.asymm.size();
                      newAtom.afixParent=-1;
                      mole.asymm.append(newAtom);
                      adpat++;
                    }
                  }
                  break;
        }


    }

  }
  mole.qboMax=1.67;
  if (minp<0) {
    chgl->shpm1->setVisible(true);
    chgl->highlightParts->setVisible(true);
  }
  if (maxp>0) chgl->highlightParts->setVisible(true);
  mole.qbeforehkl=qbeforehkl;  
  actionUniq->setDisabled(mole.qbeforehkl); 
  if (!popel.isEmpty()){
      for (int i=0;i<mole.asymm.size();i++){
        if (mole.asymm.at(i).orginalLine.contains(popel)){
            printf("HATSCHI %d => %d! (%s)\n",chgl->rotze,i,popel.toStdString().c_str());
              chgl->rotze=i;
        }
    }
  }
  for (int i=0;i<mole.asymm.size();i++){ 
    mole.Uf2Uo(mole.asymm.at(i).uf,mole.asymm[i].uc);
    mole.frac2kart(mole.asymm.at(i).frac,mole.asymm[i].pos);
    mole.showatoms.append(mole.asymm.at(i));
  }
  //printf("Average U equivalent (only positive definite counted): %f\n",mole.averageUeq());
  if (mole.asymm.size()){
    updateStatusBar("analysing structure...");

    if ((!notRefine)&&(mole.asymm.size()<chgl->SDM_Limit)) mole.packer(mole.sdmcompleter());
    infoKanalNews(mole.Fragments);
    bool growYes=chgl->fuse->isVisible ();
    bool fuseYes=chgl->grow->isVisible ();
    chgl->fuse->setVisible(true);
    chgl->grow->setVisible(false);
    mole.loadSettings();
    updateStatusBar("finding bonds...");

    mole.showbonds = mole.connecting(mole.showatoms);
    int lnrr=0;
    CEnvironment belo;
    //printf("belo: %d\n",bedeRloneLY.size());
    for (int bl=0; bl<bedeRloneLY.size(); bl++){
      int ignore=0;
      QStringList tok = bedeRloneLY.at(bl).split(sep,skipEmptyParts);      
      if ((tok.at(0).endsWith("BEDE",Qt::CaseInsensitive))&&(tok.size()>6)){
        lnrr=belo.size();
        QString aton1=tok.at(1),aton2=tok.at(2);
        double rad = getNumber(tok.at(3).toDouble(),fvar,0,ignore);
        double a   = getNumber(tok.at(4).toDouble(),fvar,0,ignore);
        double b1  = getNumber(tok.at(5).toDouble(),fvar,0,ignore);
        double b2  = getNumber(tok.at(6).toDouble(),fvar,0,ignore);
        newAtom.an=-42;
        newAtom.symmGroup=0; 
        newAtom.sg=0;
        newAtom.scod=555;//the identity
        newAtom.auidx=-1;
        int an1=-1,an2=-2;
        for (int bl1=0; bl1<mole.asymm.size(); bl1++)
          for (int bl2=0; bl2<mole.asymm.size(); bl2++){
            if ((mole.asymm.at(bl1).an<0)||(mole.asymm.at(bl2).an<0)) continue;
            double soll=-1,d= sqrt(Distance(mole.asymm.at(bl1).pos,mole.asymm.at(bl2).pos));
            if ((mole.asymm.at(bl1).an==0)&&(mole.asymm.at(bl2).an==0)) continue;
            if ((mole.asymm.at(bl1).an>-1)&&(mole.asymm.at(bl2).an>-1)&&
                ((!mole.asymm.at(bl1).part)||(!mole.asymm.at(bl2).part)||(mole.asymm.at(bl1).part==mole.asymm.at(bl2).part)))
              soll=(mole.Kovalenz_Radien[mole.asymm.at(bl1).an]+ mole.Kovalenz_Radien[mole.asymm.at(bl2).an])*0.012;
            else
              soll=-1;
            if ((d>0.1)&&(d<soll)) {
              an1=-1;
              an2=-2;
              if (aton1[0]=='$') an1=mole.getOZ(aton1);
              if (aton2[0]=='$') an2=mole.getOZ(aton2);
              if (((an1>=0)&&(mole.asymm.at(bl1).an==an1))||(aton1==mole.asymm.at(bl1).Label))
                if (((an2>=0)&&(mole.asymm.at(bl2).an==an2))||(aton2==mole.asymm.at(bl2).Label)){
                  V3 pos = mole.asymm.at(bl1).pos+Normalize(mole.asymm.at(bl2).pos-mole.asymm.at(bl1).pos)*rad;
                  newAtom.pos=pos;
                  mole.kart2frac(pos,pos);
                  newAtom.Label=QString("L%1").arg(++lnrr);
                  newAtom.frac=pos;                  
                  newAtom.auidx=-1;
                  newAtom.peakHeight=b1;
                  newAtom.sof=a;
                  newAtom.uf=mole.u2b(mole.asymm.at(bl1).uf);//possible problem if U is not anisotrop
                  belo.append(newAtom);
                  pos=mole.asymm.at(bl1).frac;
                  newAtom.Label=QString("L%1").arg(++lnrr);
                  newAtom.frac=mole.asymm.at(bl1).frac;
                  mole.frac2kart(newAtom.frac,newAtom.pos);
                  newAtom.sof=-a;
                  newAtom.peakHeight=b2;
                  belo.append(newAtom);

                  mole.lmin=qMin(mole.lmin,-a);
                  mole.lmax=qMax(mole.lmax, a);

                } 
            }
          }

      }else
        if (tok.at(0).endsWith("LONE",Qt::CaseInsensitive)){
          belo.append(lonesome(bedeRloneLY.at(bl),belo.size()+1));
        }
    }
    if (!belo.isEmpty()) {
      for (int bl=0; bl<belo.size(); bl++){
        belo[bl].orginalLine=QString("%1    2 %2 %3 %4").arg(belo.at(bl).Label.section('_',0,0),-4)
          .arg(belo.at(bl).frac.x,10,'f',5)
          .arg(belo.at(bl).frac.y,10,'f',5)
          .arg(belo.at(bl).frac.z,10,'f',5);
      }
      mole.asymm.append(belo);
    }
    QString info;
    for (int ifv=0; ifv<fvar.size();ifv++){
      if (ifv==0) {
        info.append("OSF: ");
        info.append(QString("<font color=red>%1</font>").arg(fvar.at(ifv)));
      }
      else {
        info.append(QString("FVAR<font color=blue>%1</font>: ").arg(ifv+1));
        if (fvarCntr.value(ifv+1)<1)info.append(QString("<font color=red>%1</font>(Never Used!)").arg(fvar.at(ifv)));
        else info.append(QString("<font color=red>%1</font>(used %2 time%3.)").arg(fvar.at(ifv))
            .arg(fvarCntr.value(ifv+1)).arg((fvarCntr.value(ifv+1)>1)?"s":""));
      }
      if ((ifv+1)<fvar.size()) info.append(", ");
      info.append("<br>");
    }
    fvarinfo=QString("<b>Free variables:</b> %1").arg(info);

    chgl->setMolecule(&mole);
    chgl->mol->fuse();
    if ((!notRefine)&&(mole.asymm.size()<chgl->SDM_Limit)) {
      if (((!fuseYes)&&(growYes))||(((!fuseYes)&&(!growYes))&&(!startFused))) chgl->mol->grow();
      else {
        chgl->fuse->setVisible(false);
        chgl->grow->setVisible(true);
      }
    }
    else {
      if ((mole.asymm.size()>chgl->SDM_Limit)&&(chgl->dratpause==80))
        chgl->dratpause=300;
      chgl->fuse->setVisible(false);
      chgl->grow->setVisible(false);   

    }
    infoKanalNews(mole.HumanSymmetry);
    updateStatusBar("drawing display lists...");

    chgl->rehide();
    updateStatusBar("");
  }
  chgl->pause=false;
  //  printf("%d\n",__LINE__);
  chgl->updateGL();


  urs=V3(0,0,0);int gt=0;
  for (int i=0; i<mole.showatoms.size();i++)
    if (mole.showatoms.at(i).an>-1) {urs+=mole.showatoms.at(i).frac;gt++;}
  urs*=1.0/gt;
  urs=V3(1,1,1)-1.0*urs;
  mole.frac2kart(urs,urs);
  mode=0;
  qpv->cutoff=0;//qMin(0.0,mole.pmin);
  qpv->setMin(mole.pmin);
  qpv->setMax(mole.pmax);
  if (qpeaks) qPeakDock->show();

  QTime zeit; zeit.start();
  //printf("MAPS?\n");
  fxle->resDir=QDir(fileName);
  fxle->fouName=(fxle->MYFCF)?s.myfcf(fileName):"";
  if (fxle->fouName.isEmpty()){
    fxle->fouName=fileName;
    fxle->fouName.chop(4);
    fxle->fouName.append(".fcf");
  }

  if  ((fxle->doMaps->isChecked())&& (!fxle->loadFouAndPerform(fxle->fouName.toLocal8Bit()))) {
    if (fxle->doMaps->isChecked()) infoKanalNews(QString("<font color=red>Error while loading %1!</font><br>").arg(fxle->fouName));

  //printf("%d\n",__LINE__);
    fxle->killmaps();
  //printf("%d\n",__LINE__);
    fxle->n1=fxle->n2=fxle->n3=fxle->n5=0;
  }
  if (fxle->doMaps->isChecked()){
    fxle->mapcontrol->setVisible(true);
  }
  fxle->doMaps->show();
  //printf("MAPS!\n");
  QMap<int,double> unit;
  for (int i=0; i<mole.asymm.size(); i++){
    if (mole.asymm.at(i).an>=0) unit[mole.asymm.at(i).an]+= mole.asymm.at(i).sof * mole.cell.symmops.size();
  }
  editor->unitNeu="UNIT";
  for (int i = 0; i < editor->sfac.size() ; i++){
    if (unit.value(editor->sfac.at(i))>9999)
      editor->unitNeu.append(QString(" %1").arg((int)unit.value(editor->sfac.at(i)))); else
        editor->unitNeu.append(QString(" %1").arg(unit.value(editor->sfac.at(i)),0,'g'));
    if (editor->unitNeu.split('\n').last().size()>76) editor->unitNeu.append("=\n    ");
  }
  chgl->toggleDockWidgets->setVisible(true);
  astdlg->setDisabled(false);
  toggDocWid(false);
  sinaAct->setVisible(adpat!=0);
  if (!mole.asymm.size()) title.append("!!Empty!!");

  refineAct->setVisible(!notRefine);
  refineAct->setEnabled(!notRefine);

  refineActAnis->setVisible(!notRefine);
  refineActAnis->setEnabled(!notRefine);

  refineActActa->setVisible(!notRefine);
  refineActActa->setEnabled(!notRefine);
  for (int k=0; k<editor->sfac.size();k++){
    xda.an = editor->sfac.at(k);
    xda.Label = mole.pse(editor->sfac.at(k));
    mole.legendAtoms.append(xda);
    if (editor->sfac.at(k)<0) continue;
    QAction *a = chgl->sfacMenu->addAction(mole.pse(editor->sfac.at(k)),this,SLOT(changeElement()));
    a->setData(k);
  }
  if (qpeaks){
    xda.an = -1;
    xda.Label = "Q";
    xda.peakHeight = mole.pmax-0.01;
    mole.legendAtoms.append(xda);
    xda.pos.y += 0.5;
  }
  if (chgl->hideBeLo->isVisible()){
    xda.an = -42;
    xda.Label = "BELO";
    xda.peakHeight = mole.lmax-0.01;
    mole.legendAtoms.append(xda);
    xda.pos.y += 0.5;
  }
  int td=0;
  if (!notRefine) switch (td=duplicates()){
    case 1:infoKanalNews("<font color=orange >Some hydrogen atoms have identical names please check.</font>");break;
    case 2:infoKanalNews("<font color=red >Some non-hydrogen atoms have identical names. YOU HAVE TO CHECK BEFORE REFINING!</font>");break;
    case 3:infoKanalNews("<font color=red >Some atoms have identical names. YOU HAVE TO CHECK BEFORE REFINING!</font>");break;
  }
  QString listName=fileName;
  listName.replace(QRegExp(".ins$"),".lst");
  listName.replace(QRegExp(".res$"),".lst");
  QFile lstf(listName);
  if (lstf.open(QIODevice::ReadOnly|QIODevice::Text)){
    QString liste=QString(lstf.readAll());
    while (liste.contains(QRegExp("\n\\s+REM"))) liste=liste.replace(QRegExp("\n\\s+REM[^\n]*\n",Qt::CaseInsensitive),"\n");
    if (liste.contains("Flack x parameter =")){
      QString flackS=liste.section("Flack x parameter =",1).section('\n',0,0);
      double flackX=flackS.split(QRegExp("\\s+"),skipEmptyParts).first().toDouble();
      double flackXesd=flackS.split(QRegExp("\\s+"),skipEmptyParts).last().toDouble();
      infoKanalNews(QString("SHELXL-list file reports <b>Flack</b> x parameter:<b> %1 &plusmn; %2</b>").arg(flackX).arg(flackXesd)); 
    }
    //Flack x =
    if (liste.contains("Flack x =")) {
      QString flackS=liste.section("\n Flack x = ",1).section('\n',0,1);
      QString flackX = "";
      // prevent crash from empty flackS:
      if (flackS.split(QRegExp("\\s+"),skipEmptyParts).length() > 0) {
        flackX=flackS.split(QRegExp("\\s+"),skipEmptyParts).first();
      }
      QString parsonsZ=flackS.section('\n',1,1);
      if (parsonsZ.isEmpty() && !flackX.isEmpty()) {
        infoKanalNews(QString("SHELXL-list file reports <b>Flack</b> x parameter:<b> %1 </b>").arg(flackX)); 
      }
      if (!parsonsZ.isEmpty() && !flackX.isEmpty()) {
        parsonsZ=parsonsZ.split(QRegExp("\\s+"),skipEmptyParts).first();
        infoKanalNews(QString("SHELXL-list file reports <br><b>Flack</b> x parameter:<b> %1 </b><br><b>Parsons</b> parameter:<b>  %2</b>")
            .arg(flackX).arg(parsonsZ));
      }
    }
    lstf.close();
  }
  QString fcfname = fileName;
  fcfname.replace(QRegExp(".res$|.ins$",Qt::CaseInsensitive),".fcf");
  fvused->setText(QString("%1 FVARs defined").arg(fvar.count()));

  fcvsfoAct->setEnabled(QFile::exists(fcfname));
  chgl->showHidden();  
  update();
  chgl->updateGL();
  //return title;
}//shelx


#include "ideal_defden.h"
void Window::beloWriteCube(){
  //printf("bWC belo?%d\n",fxle->isBelo);
  if (fxle->isBelo) return;
  fxle->isBelo=true;  
  chgl->fofcact->setVisible(true);
  chgl->fofcact->setChecked(true);
  IdealDefdenGenerator *idealDefGen = new IdealDefdenGenerator(chgl, fxle, this);
  connect(idealDefGen, SIGNAL(finished()), fxle, SLOT(controlMap()));
  connect(idealDefGen, SIGNAL(message(const QString&)), this, SLOT(updateStatusBar(const QString&)));
  connect(idealDefGen, SIGNAL(finished()), idealDefGen, SLOT(deleteLater()));
  idealDefGen->start();
  chgl->updateGL();
}

void Window::configBeLos(){
  QColor c = mole.beloColor;
  QDialog *belodlg = new QDialog(this);
  QGridLayout *lo = new QGridLayout(belodlg);
  QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel,Qt::Horizontal,belodlg);
  connect(bb, SIGNAL(accepted()), belodlg, SLOT(accept()));
  connect(bb, SIGNAL(rejected()), belodlg, SLOT(reject()));
  QDoubleSpinBox *beloRadSpin = new QDoubleSpinBox(belodlg);
  beloRadSpin->setMinimum(0.01);
  beloRadSpin->setMaximum(0.2);
  beloRadSpin->setValue(mole.beloRad);
  beloRadSpin->setSingleStep(0.01);
  QCheckBox *beloLabel = new QCheckBox("Show BEDE LONE Labels",belodlg);
  beloLabel->setChecked(mole.beloLabels); 
  beloColorButton = new QPushButton("BEDE LONE objects color",belodlg);
  beloColorButton->setStyleSheet(QString(
        "QPushButton {"
        "border: 1px solid #000000;"
        "border-radius: 9px;"
        "color: %4;"
        "background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 %1, stop: 0.5 %3, stop: 1 %2);"
        "}"
        "QPushButton:hover {"
        "background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 %2, stop: 0.5 %1, stop: 1 %2);"
        "}"
        "QPushButton:flat {"
        "    border: none; /* no border for a flat push button */"
        "}"
        )
      .arg(mole.beloColor.name())
      .arg(mole.beloColor.darker(200).name())
      .arg(mole.beloColor.lighter(200).name())
      .arg((mole.beloColor.value()<90)?"#ffffff":"#000000"));
  connect(beloColorButton, SIGNAL(pressed()), this, SLOT(colorButtonDialog()));
  QCheckBox *beloColorByDefdenBx = new QCheckBox("Use deformation density based color scheme",belodlg);
  beloColorByDefdenBx->setChecked(mole.beloColorByDefden);
  lo->addWidget(beloColorByDefdenBx,0,0,1,10);
  lo->addWidget(beloColorButton,1,0,1,10);
  lo->addWidget(new QLabel("BEDE LONE objects size:",belodlg),2,0,1,1);
  lo->addWidget(beloRadSpin,2,1,1,1);
  lo->addWidget(beloLabel,3,0,1,1);
  lo->addWidget(bb,10,0,1,10);
  if (belodlg->exec()==QDialog::Accepted){
    mole.beloRad=beloRadSpin->value();
    mole.beloColorByDefden = beloColorByDefdenBx->isChecked();
    mole.beloLabels = beloLabel->isChecked();
    chgl->murx=12942;
    chgl->updateGL();
    mole.einstellung->beginGroup("IDEAL");
    mole.einstellung->setValue("beloRad", mole.beloRad);
    mole.einstellung->setValue("beloColor", mole.beloColor);
    mole.einstellung->setValue("beloColorByDefden", mole.beloColorByDefden); 
    mole.einstellung->setValue("beloLabels", mole.beloLabels);
    mole.einstellung->endGroup();
  }else{
    mole.beloColor=c;
  }
  belodlg->deleteLater();

}

void Window::colorButtonDialog(){
  QColor bgcolor;
  bgcolor=QColorDialog::getColor(mole.beloColor, this);
  if (bgcolor.isValid()) {
    beloColorButton->setStyleSheet(QString(
          "QPushButton {"
          "border: 1px solid #000000;"
          "border-radius: 9px;"
          "color: %4;"
          "background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 %1, stop: 0.5 %3, stop: 1 %2);"
          "}"
          "QPushButton:hover {"
          "background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 %2, stop: 0.5 %1, stop: 1 %2);"
          "}"
          "QPushButton:flat {"
          "    border: none; /* no border for a flat push button */"
          "}"
          )
        .arg(bgcolor.name())
        .arg(bgcolor.darker(200).name())
        .arg(bgcolor.lighter(200).name())
        .arg((bgcolor.value()<90)?"#ffffff":"#000000"));
    mole.beloColor=bgcolor;
  }
}

CEnvironment Window::lonesome(QString s, int stnum){
  const QRegExp sep=QRegExp("\\s+");
  const QRegExp num=QRegExp("^\\d+");
  const QRegExp alp=QRegExp("^[\\$A-Za-z]+");
  QStringList tok=s.split(sep,skipEmptyParts);
  int m=0,j=0,k=0,ll=stnum;;
  MyAtom horse;
  //static CEnvironment l;
  CEnvironment l;
  l.clear();
  MyAtom at;
  at.an=-42;
  at.auidx=-1;
  at.scod=555;
  int ignore=0;
  while (!tok.at(j).contains(num)) {j++;}
  m=tok.at(j).toInt();
  k=j;
  QString such;
  j=1;
  while ((!tok.at(j).contains(alp))) {j++;if (j>=tok.size()) break;}
  if (j==tok.size()) {
    qDebug()<<"oh-oh!";
    return l;//big problem
  }
  such=tok.at(j);
  //j=qMax(j,k)+1;
  j = k + 1;
  while (tok.at(j).contains(alp)) {j++;}
  double a   = getNumber(tok.at(j).toDouble(),fvar,0,ignore);
  j++;
  while (tok.at(j).contains(alp)) {j++;}
  double b1  = getNumber(tok.at(j).toDouble(),fvar,0,ignore);
  j++;
  while (tok.at(j).contains(alp)) {j++;}
  double b2  = getNumber(tok.at(j).toDouble(),fvar,0,ignore);
  bool general=true;
//    qDebug()<<s<<such<<j<<tok.size()<<k<<'m'<<m<<'a'<<a<<"b1"<<b1<<"b2"<<b2;

  for (int i=0; i<mole.asymm.size(); i++){
    if (such==mole.asymm.at(i).Label) {
      general=false;
      horse=mole.asymm[i];
      break;}
  }
  if (general){

    QString such2=such;
    such2.remove('$'); 
    // qDebug()<<such<<such2;
    int an1= mole.getOZ(such2);
    int jjj=stnum;
    for (int recurs=0; recurs<mole.asymm.size();recurs++){
      if (mole.asymm.at(recurs).an==an1){
        QString s2=s;
        s2=s2.replace(such,mole.asymm.at(recurs).Label);
        // qDebug()<<l.size()<<s2;
        CEnvironment lrec;
        lrec=lonesome(s2, jjj);//recursion!
        jjj+=lrec.size();
        for (int dii=0; dii<lrec.size();dii++) {
          //          qDebug()<<dii <<lrec.at(dii).Label;
          l.append(lrec[dii]);
        }
        // qDebug()<<l.size()<<jjj<<lrec.size();;
      }
    }
    //    for (int dii=0; dii<l.size();dii++) { qDebug()<<"return "<<dii <<l.at(dii).Label; }
    return l;

  }else{
    switch (m) {
      case 1:{
               MyAtom n1,n2,n3;
               j=0;
               double d,soll=0;
               for (;j<mole.asymm.size();j++) {
                 if (mole.asymm.at(j).an<0) continue;
                 soll=(mole.Kovalenz_Radien[horse.an]+ mole.Kovalenz_Radien[mole.asymm.at(j).an])*0.012;
                 d= sqrt(Distance(horse.pos,mole.asymm.at(j).pos));
                 if ((d>0.1)&&(d<soll)){
                   n1=mole.asymm[j];
                   j++;
                   break;
                 }
               }
               for (;j<mole.asymm.size();j++) {
                 if (mole.asymm.at(j).an<0) continue;
                 soll=(mole.Kovalenz_Radien[horse.an]+ mole.Kovalenz_Radien[mole.asymm.at(j).an])*0.012;
                 d= sqrt(Distance(horse.pos,mole.asymm.at(j).pos));
                 if ((d>0.1)&&(d<soll)){
                   n2=mole.asymm[j];
                   j++;
                   break;
                 }
               }
               for (;j<mole.asymm.size();j++) {
                 if (mole.asymm.at(j).an<0) continue;
                 soll=(mole.Kovalenz_Radien[horse.an]+ mole.Kovalenz_Radien[mole.asymm.at(j).an])*0.012;
                 d= sqrt(Distance(horse.pos,mole.asymm.at(j).pos));
                 if ((d>0.1)&&(d<soll)){
                   n3=mole.asymm[j];
                   j++;
                   break;
                 }
               }
               V3 va= Normalize(n1.pos-horse.pos);
               V3 vb= Normalize(n2.pos-horse.pos);
               V3 vc= Normalize(n3.pos-horse.pos);
               V3 trisect=Normalize(va+vb+vc);
               double rad=tok.last().toDouble();
               if (rad<0) {
                 rad=-rad;
               }
               at.pos=horse.pos-(trisect*rad);
               at.uf=mole.u2b(horse.uf);//possible problem if U is not anisotrop
               mole.kart2frac(at.pos,at.frac);
               at.peakHeight=b1;
               at.sof=a;               
               at.auidx=-1;
               at.Label=QString("L%1").arg(ll++);
               l.append(at);
               at.pos=horse.pos;
               at.frac=horse.frac;
               at.peakHeight=b2;
               at.sof=-a*l.size();
               at.Label=QString("L%1").arg(ll++);
               l.append(at);
               //qDebug()<<n1.Label<<n2.Label;
               if (tok.size()>7) {
                 QString s2=s;
                 s2.remove(horse.Label);
                 //qDebug()<<s2<<ll;

                 l.append(lonesome(s2,ll));
               }
             }
             break;
      case 2:{
               MyAtom n1,n2;
               j=0;
               double d,soll=0;
               for (;j<mole.asymm.size();j++) {
                 if (mole.asymm.at(j).an<0) continue;
                 soll=(mole.Kovalenz_Radien[horse.an]+ mole.Kovalenz_Radien[mole.asymm.at(j).an])*0.012;
                 d= sqrt(Distance(horse.pos,mole.asymm.at(j).pos));
                 if ((d>0.1)&&(d<soll)){
                   n1=mole.asymm[j];
                   j++;
                   break;
                 }
               }
               for (;j<mole.asymm.size();j++) {
                 if (mole.asymm.at(j).an<0) continue;
                 soll=(mole.Kovalenz_Radien[horse.an]+ mole.Kovalenz_Radien[mole.asymm.at(j).an])*0.012;
                 d= sqrt(Distance(horse.pos,mole.asymm.at(j).pos));
                 if ((d>0.1)&&(d<soll)){
                   n2=mole.asymm[j];
                   j++;
                   break;
                 }
               }
               V3 va= Normalize(n1.pos-horse.pos);
               V3 vb= Normalize(n2.pos-horse.pos);
               V3 bisect=Normalize(va+vb);
               V3 ax=Normalize(vb%va);//LLLL
               double phi=tok.last().toDouble();
               double rad=tok.at(tok.size()-2).toDouble();
               //qDebug()<<phi<<rad;
               //qDebug()<<va.x<<va.y<<va.z;
               //qDebug()<<vb.x<<vb.y<<vb.z;
               phi*=M_PI/360.0;//we want /2 !
               V3 c=-cos(phi)*bisect;
               if (rad<0) {
                 c=-1.0*c;
                 rad=-rad;
               }
               V3 v=sin(phi)*ax;
               at.pos=horse.pos+(c+v)*rad;
               at.uf=mole.u2b(horse.uf);//possible problem if U is not anisotrop
               mole.kart2frac(at.pos,at.frac);
               at.peakHeight=b1;
               at.sof=a;
               at.auidx=-1;
               at.Label=QString("L%1").arg(ll++);
               l.append(at);
               at.pos=horse.pos+(c-v)*rad;
               mole.kart2frac(at.pos,at.frac);
               at.Label=QString("L%1").arg(ll++);
               l.append(at);
               at.pos=horse.pos;
               at.frac=horse.frac;
               at.peakHeight=b2;
               at.sof=-a*l.size();
               at.Label=QString("L%1").arg(ll++);
               l.append(at);
               //qDebug()<<n1.Label<<n2.Label;
               if (tok.size()>8) {
                 QString s2=s;
                 s2.remove(horse.Label);
                 //qDebug()<<s2<<ll;

                 l.append(lonesome(s2,ll));
               }
             }
             break;

      case 4:{
               MyAtom n1,n2;
               j=0;
               double d,soll=0;
               for (;j<mole.asymm.size();j++) {
                 if (mole.asymm.at(j).an<0) continue;
                 soll=(mole.Kovalenz_Radien[horse.an]+ mole.Kovalenz_Radien[mole.asymm.at(j).an])*0.012;
                 d= sqrt(Distance(horse.pos,mole.asymm.at(j).pos));
                 if ((d>0.1)&&(d<soll)){
                   n1=mole.asymm[j];
                   j++;
                   break;
                 }
               }
               for (;j<mole.asymm.size();j++) {
                 if (mole.asymm.at(j).an<0) continue;
                 soll=(mole.Kovalenz_Radien[horse.an]+ mole.Kovalenz_Radien[mole.asymm.at(j).an])*0.012;
                 d= sqrt(Distance(horse.pos,mole.asymm.at(j).pos));
                 if ((d>0.1)&&(d<soll)){
                   n2=mole.asymm[j];
                   j++;
                   break;
                 }
               }
               V3 va= Normalize(n1.pos-horse.pos);
               V3 vb= Normalize(n2.pos-horse.pos);
               V3 bisect=Normalize(va+vb);
               //V3 ax=Normalize(vb%va);//LLLL
               double rad=tok.last().toDouble();
               at.pos=horse.pos-bisect*rad;
               at.uf=mole.u2b(horse.uf);//possible problem if U is not anisotrop
               mole.kart2frac(at.pos,at.frac);
               at.peakHeight=b1;
               at.sof=a;
               at.Label=QString("L%1").arg(ll++);
               l.append(at);
               at.pos=horse.pos;
               at.frac=horse.frac;
               at.peakHeight=b2;
               at.sof=-a;
               at.Label=QString("L%1").arg(ll++);
               l.append(at);
               //qDebug()<<n1.Label<<n2.Label;
               if (tok.size()>7) {
                 QString s2=s;
                 s2.remove(horse.Label);
                 //qDebug()<<s2<<ll;

                 l.append(lonesome(s2,ll));
               }
             }
             break;
      case 6:{
               MyAtom n1,n2;
               j=0;
               double d,soll=0;
               for (;j<mole.asymm.size();j++) {
                 if (mole.asymm.at(j).an<0) continue;
                 soll=(mole.Kovalenz_Radien[horse.an]+ mole.Kovalenz_Radien[mole.asymm.at(j).an])*0.012;
                 d= sqrt(Distance(horse.pos,mole.asymm.at(j).pos));
                 if ((d>0.1)&&(d<soll)){
                   n1=mole.asymm[j];
                   j++;
                   break;
                 }
               }
               for (;j<mole.asymm.size();j++) {
                 if (mole.asymm.at(j).an<0) continue;
                 soll=(mole.Kovalenz_Radien[horse.an]+ mole.Kovalenz_Radien[mole.asymm.at(j).an])*0.012;
                 d= sqrt(Distance(horse.pos,mole.asymm.at(j).pos));
                 if ((d>0.1)&&(d<soll)){
                   n2=mole.asymm[j];
                   j++;
                   break;
                 }
               }
               V3 va= Normalize(n1.pos-horse.pos);
               V3 vb= Normalize(n2.pos-horse.pos);
               V3 ax=Normalize(vb%va);//LLLL
               double rad=tok.last().toDouble();
               //qDebug()<<phi<<rad;
               //qDebug()<<va.x<<va.y<<va.z;
               //qDebug()<<vb.x<<vb.y<<vb.z;
               if (rad<0) {
                 rad=-rad;
               }
               at.pos=horse.pos+(ax)*rad;
               at.uf=mole.u2b(horse.uf);//possible problem if U is not anisotrop
               mole.kart2frac(at.pos,at.frac);
               at.peakHeight=b1;
               at.sof=a;
               at.Label=QString("L%1").arg(ll++);
               l.append(at);
               at.pos=horse.pos-(ax)*rad;
               mole.kart2frac(at.pos,at.frac);
               at.Label=QString("L%1").arg(ll++);
               l.append(at);
               at.pos=horse.pos;
               at.frac=horse.frac;
               at.peakHeight=b2;
               at.sof=-a*l.size();
               at.Label=QString("L%1").arg(ll++);
               l.append(at);
               //qDebug()<<"m=6!"<<s<<n1.Label<<n2.Label<<at.Label;
               //qDebug()<<tok<<tok.size();
               if (tok.size()>7) {
                 QString s2=s;
                 s2.remove(horse.Label);
                 //qDebug()<<s2<<ll;

                 l.append(lonesome(s2,ll));
               }
             }
             break;
      case 7:{
               MyAtom n1,n2;
               j=0;
               double d,soll=0,d2;
               for (;j<mole.asymm.size();j++) {
                 if (mole.asymm.at(j).an<0) continue;
                 soll=(mole.Kovalenz_Radien[horse.an]+ mole.Kovalenz_Radien[mole.asymm.at(j).an])*0.012;
                 d= sqrt(Distance(horse.pos,mole.asymm.at(j).pos));
                 if ((d>0.1)&&(d<soll)){
                   n1=mole.asymm[j];
                   j++;
                   break;
                 }
               }
               for (j=0;j<mole.asymm.size();j++) {
                 if (mole.asymm.at(j).an<0) continue;
                 soll=(mole.Kovalenz_Radien[n1.an]+ mole.Kovalenz_Radien[mole.asymm.at(j).an])*0.012;
                 d= sqrt(Distance(n1.pos,mole.asymm.at(j).pos));
                 d2= sqrt(Distance(horse.pos,mole.asymm.at(j).pos));
                 if ((d2>1.1)&&(d>0.1)&&(d<soll)){
                   n2=mole.asymm[j];
                   j++;
                   break;
                 }
               }
               V3 va= Normalize(n1.pos-horse.pos);
               V3 vb= Normalize(n2.pos-n1.pos);
               V3 ax=Normalize(vb%va);//LLLL
               double phi=tok.last().toDouble();
               double rad=tok.at(tok.size()-2).toDouble();
               //qDebug()<<phi<<rad;
               //qDebug()<<va.x<<va.y<<va.z;
               //qDebug()<<vb.x<<vb.y<<vb.z;
               phi*=M_PI/360.0;//we want /2 !
               V3 c=-cos(phi)*va;
               if (rad<0) {
                 c=-1.0*c;
                 rad=-rad;
               }
               V3 v=sin(phi)*ax;
               at.pos=horse.pos+(c+v)*rad;
               at.uf=mole.u2b(horse.uf);//possible problem if U is not anisotrop
               mole.kart2frac(at.pos,at.frac);
               at.peakHeight=b1;
               at.sof=a;
               at.Label=QString("L%1").arg(ll++);
               l.append(at);
               at.pos=horse.pos+(c-v)*rad;
               mole.kart2frac(at.pos,at.frac);
               at.Label=QString("L%1").arg(ll++);
               l.append(at);
               at.pos=horse.pos;
               at.frac=horse.frac;
               at.peakHeight=b2;
               at.sof=-a*l.size();
               at.Label=QString("L%1").arg(ll++);
               l.append(at);
               //             qDebug()<<n1.Label<<n2.Label<<tok.size();
               if (tok.size()>8) {
                 QString s2=s;
                 s2.remove(horse.Label);
                 //qDebug()<<s2<<ll;

                 l.append(lonesome(s2,ll));
               }
             }
             break;
      case 9:{
               MyAtom n1,n2;
               j=0;
               double d,soll=0,d2;
               for (;j<mole.asymm.size();j++) {
                 if (mole.asymm.at(j).an<0) continue;
                 soll=(mole.Kovalenz_Radien[horse.an]+ mole.Kovalenz_Radien[mole.asymm.at(j).an])*0.012;
                 d= sqrt(Distance(horse.pos,mole.asymm.at(j).pos));
                 if ((d>0.1)&&(d<soll)){
                   n1=mole.asymm[j];
                   j++;
                   break;
                 }
               }
               for (j=0;j<mole.asymm.size();j++) {
                 if (mole.asymm.at(j).an<0) continue;
                 soll=(mole.Kovalenz_Radien[n1.an]+ mole.Kovalenz_Radien[mole.asymm.at(j).an])*0.012;
                 d= sqrt(Distance(n1.pos,mole.asymm.at(j).pos));
                 d2= sqrt(Distance(horse.pos,mole.asymm.at(j).pos));
                 if ((d2>1.1)&&(d>0.1)&&(d<soll)){
                   n2=mole.asymm[j];
                   j++;
                   break;
                 }
               }
               V3 va= Normalize(n1.pos-horse.pos);
               V3 vb= Normalize(n2.pos-n1.pos);
               V3 ax1=Normalize(vb%va);//LLLL
               V3 ax=Normalize(va%ax1);//LLLL
               double phi=tok.last().toDouble();
               double rad=tok.at(tok.size()-2).toDouble();
               //qDebug()<<phi<<rad;
               //qDebug()<<va.x<<va.y<<va.z;
               //qDebug()<<vb.x<<vb.y<<vb.z;
               phi*=M_PI/360.0;//we want /2 !
               V3 c=-cos(phi)*va;
               if (rad<0) {
                 c=-1.0*c;
                 rad=-rad;
               }
               V3 v=sin(phi)*ax;
               at.pos=horse.pos+(c+v)*rad;
               at.uf=mole.u2b(horse.uf);//possible problem if U is not anisotrop
               mole.kart2frac(at.pos,at.frac);
               at.peakHeight=b1;
               at.sof=a;
               at.Label=QString("L%1").arg(ll++);
               l.append(at);
               at.pos=horse.pos+(c-v)*rad;
               mole.kart2frac(at.pos,at.frac);
               at.Label=QString("L%1").arg(ll++);
               l.append(at);
               at.pos=horse.pos;
               at.frac=horse.frac;
               at.peakHeight=b2;
               at.sof=-a*l.size();
               at.Label=QString("L%1").arg(ll++);
               l.append(at);
               //qDebug()<<n1.Label<<n2.Label<<tok.size();
               if (tok.size()>8) {
                 QString s2=s;
                 s2.remove(horse.Label);
                 //qDebug()<<s2<<ll;

                 l.append(lonesome(s2,ll));
               }
             }
             break;
      default: 
             fprintf(stderr,"%d das kann ich noch nicht! %s\n",m,such.toStdString().c_str());
             infoKanalNews(QString("<H1>%1 das kann ich noch nicht! %2</H1>").arg(m).arg(such));
    }
  }
  //  qDebug()<<m<<such<<tok.size();
  return l;
}

void  Window::exportFMaps(){
  QString al;
  const double a0 = 0.52917720859;
  int ina=0;
  for (int i=0; i<mole.asymm.size();i++){
    if (mole.asymm[i].an<0) continue;
    ina++;
  }
  for (int i=0; i<mole.asymm.size();i++){
    if (mole.asymm[i].an<0) continue;
    mole.frac2kart(mole.asymm[i].frac,mole.asymm[i].pos);
    al.append(QString("\n%1%2%3%4%5").arg(mole.asymm[i].an+1,5).arg(mole.asymm[i].an+1.0,12,'f',6).arg(mole.asymm[i].pos.x/a0,12,'f',6).arg(mole.asymm[i].pos.y/a0,12,'f',6).arg(mole.asymm[i].pos.z/a0,12,'f',6));
  }
  fxle->exportMaps(ina, dirName.toStdString().c_str(), al.toStdString().c_str());

}

void Window::toggDocWid(bool weg){
  if (weg) {
    shxEditorDock->hide();
    shxOutputDock->hide();
    infotainmentDock->hide();
    dock->hide();
    renamDock->hide();
    histDock->hide();
    chgl->toggleDockWidgets->setText("Show Text Windows");
  }
  else{
    shxEditorDock->show();
    histDock->show();
    dock->show();
    chgl->toggleDockWidgets->setText("Hide Text Windows");
  }
  update();
  chgl->updateGL();
}

void Window::convergeWght(){
  /*! \brief Update WHGT scheme and refine in a loop until scheme has converged or a maximum of runs has exceeded.*/
  if (mole.asymm.isEmpty()) return;
  dirName.replace(QRegExp(".ins$",Qt::CaseInsensitive),".res");
  fileSave();
  finWasPressed=false;
  wght_cycls=0;
  xlPutor->clear();
  //xlPutor->highlighter->setOutputStyle();
  shxOutputDock->show();
  shxOutputDock->raise();
  //stoppRefinement->show();
  finishRefinement->show();
  loadRes->show();
  loadRes2->show();
  QObject::disconnect(stoppRefinement, 0, this, 0);
  QObject::disconnect(finishRefinement, 0, this, 0);
  refineButtonBox->hide();
  shxEditorDock->hide();
  dock->hide();
  histDock->hide();
  renamDock->hide();
  update();
  runXLWGHT();
}

void Window::finXL(){
  QString finname =dirName;
  finname.replace(QRegExp(".ins$",Qt::CaseInsensitive),".res");
  finname.replace(QRegExp(".res$",Qt::CaseInsensitive),".fin");
  QFile fin(finname);
  fin.open(QIODevice::WriteOnly|QIODevice::Text);
  fin.write("stopp",6);
  fin.close();
  finishRefinement->hide();
  finishRefinement2->hide();
  printf("FINISH!\n%s was written so shelxl should end soon.\n",finname.toStdString().c_str());
  finWasPressed=true;
}

void Window::runXLWGHT() {
  update();
  QString dn=dirName.section('/',0,-2),
          argument=dirName.section('/',-1);
  argument.remove(QRegExp(".res$|.ins$",Qt::CaseInsensitive));
  QStringList al;
  al.append(argument);
  defineBarray();
  al+=shelxlArgs.split(' ',skipEmptyParts);
  shelxl = new QProcess(this);
  shelxl->setWorkingDirectory(dn);                           // updateXLput()
  // stoppRefinement->show();
  finishRefinement->show();
  finishRefinement->setFocus();
  refineButtonBox->hide();
  connect(shelxl,SIGNAL(readyReadStandardOutput ()),this,SLOT(updateXLput()));
  connect(shelxl,SIGNAL(finished(int,QProcess::ExitStatus)),this,SLOT(updateXLput()));
  connect(shelxl,SIGNAL(finished(int,QProcess::ExitStatus)),this ,SLOT(runXLWGHT()));
  connect(shelxl,SIGNAL(error(QProcess::ProcessError)),this,SLOT(updateXLput())); 

  connect(finishRefinement,SIGNAL(clicked()),this,SLOT(finXL()));;
  shxOutputDock->show();
  shxOutputDock->raise();
  QFile test;
  QStringList alltest;
  QString alls;
  test.setFileName(dirName);
  QStringList wghts;
  if (test.exists()&&test.size()){
    test.open(QIODevice::ReadOnly|QIODevice::Text);
    alls=test.readAll();
    alltest=alls.split('\n');
    wghts=alltest.filter(QRegExp("^WGHT.*$",Qt::CaseInsensitive));
    if ((wghts.size()>1)&&(wght_cycls<10)) alls.replace(wghts.at(0),wghts.at(1));
    else if (wghts.size()<2) {
        alls.replace(wghts.at(0),"WGHT 0.2!default");
        printf("WGHT %s ==>>%d<==%d\n",wghts.at(0).toStdString().c_str(),wghts.size(),wght_cycls);
    }
    for (int i=0; i<wghts.size();i++) {
      wghts[i].remove(QRegExp("\\b0\\.[0]+\\b"));
      wghts[i].remove(QRegExp("\\B[0]+ "));
      wghts[i].remove(QRegExp("\\B[0]+$"));
      wghts[i] = wghts.at(i).simplified();
    }
    test.close();
    test.open(QIODevice::WriteOnly|QIODevice::Text);
    test.write(alls.toLatin1());    
    test.close();
  }else{loadRes->setEnabled(false);} 
  xlPutor->ListFile=false;
  QString s=xlPutor->toPlainText();
  /*I think this is good for nothing a job that has not ben started can't have output. Device not open on Qt5
    if ((s.isEmpty())&&(shelxl->isOpen())) {
  //qDebug()<<"what am I doing here?";
  s.append(shelxl->readAllStandardOutput());
  s.append(shelxl->readAllStandardError());
  }
  */
  bool same = ((wghts.size()>1)&&(wghts.at(0)==wghts.at(1)));
  if ((wghts.size()>1)&&(!same)) same = compareWGHTS(wghts.at(0), wghts.at(1));
  s.append(QString("############################\n%1\n%2\nConverged: %3\nafter %4 runs.\n############################\n")
      .arg((wghts.size()>0)?wghts.at(0):"WGHT 0.2!default")
      .arg((wghts.size()>1)?wghts.at(1):"WGHT 0.2!default")
      .arg((same)?"Yes":"No")
      .arg(wght_cycls)
      //                  .arg(wghts.at(0))
      //                  .arg(wghts.at(1))
      ); 
  xlPutor->setPlainText(s);
  QTextCursor tc = xlPutor->textCursor();
  tc.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
  xlPutor->setTextCursor(tc);
  xlPutor->ensureCursorVisible();
  update();

  if (same) {
    stoppRefinement->hide(); 
    refineButtonBox->show();
    loadRes->setEnabled((s.contains("for all data"))||(s.contains("Converged: Yes")));
    stoppRefinement2->hide(); 
    finishRefinement2->hide(); 
    finishRefinement->hide();
    refineButtonBox2->show();
    loadRes2->setEnabled(loadRes->isEnabled());
    QTextCursor tc = xlPutor->textCursor();
    tc.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
    xlPutor->setTextCursor(tc);
    xlPutor->ensureCursorVisible();
    update();
    return;
  }
  if ((!loadRes->isEnabled())||(wght_cycls>9)||finWasPressed) {
    stoppRefinement->hide(); 
    finishRefinement->hide();
    refineButtonBox->show(); 
    loadRes->setEnabled((s.contains("for all data")));
    stoppRefinement2->hide(); 
    finishRefinement2->hide(); 
    refineButtonBox2->show(); 
    loadRes2->setEnabled(loadRes->isEnabled());
    QTextCursor tc = xlPutor->textCursor();
    tc.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
    xlPutor->setTextCursor(tc);
    xlPutor->ensureCursorVisible();
    update();
    return;
  }
  if (dirName.contains(QRegExp(".res$",Qt::CaseInsensitive))){
    QString insname =dirName;
    insname.replace(QRegExp(".res$",Qt::CaseInsensitive),".ins");

    QString fcfname = dirName;
    fcfname.replace(QRegExp(".res$",Qt::CaseInsensitive),".fcf");
    QString fcfname2 = dirName;
    fcfname2.replace(QRegExp(".res$",Qt::CaseInsensitive),".2fcf");
    if (QFileInfo(dirName).lastModified()>=QFileInfo(insname).lastModified()){
      QDir work=QDir(QString("%1/%2saves/").arg(dn).arg(PROGRAM_NAME));
      QStringList filter;
      filter << QString("%1_*_.ins").arg(argument);
      QStringList resfs;
      resfs=work.entryList(filter,QDir::Files,QDir::Time|QDir::Reversed);
      int vers=0;
      if (resfs.isEmpty()) vers=1;
      else { 
        bool ok=true;
        for (int i = 0; i < resfs.size(); i++)
          vers = qMax(resfs.at(i).section("_",-2,-2).toInt(&ok,36),vers);
        vers++;
      }
      if (!work.exists ( QString("%1/%2saves/").arg(dn).arg(PROGRAM_NAME))) work.mkdir (QString("%1/%2saves/").arg(dn).arg(PROGRAM_NAME));
      QFile::copy(insname,QString("%1/%4saves/%2_%3_.ins").arg(dn).arg(argument).arg(vers,2,36,QLatin1Char('0')).arg(PROGRAM_NAME));
      QFile::remove(insname);
      QFile::copy(dirName,insname);
      QFile::copy(fcfname2,QString("%1/%4saves/%2_%3_.fcf").arg(dn).arg(argument).arg(vers,2,36,QLatin1Char('0')).arg(PROGRAM_NAME));
      QFile::remove(fcfname2);
      QFile::copy(fcfname,fcfname2);
    } else {
      QDir work=QDir(QString("%1/%2saves/").arg(dn).arg(PROGRAM_NAME));
      QStringList filter;
      filter << QString("%1_*_.ins").arg(argument);
      QStringList resfs;
      resfs=work.entryList(filter,QDir::Files,QDir::Time|QDir::Reversed);
      int vers=0;
      if (resfs.isEmpty()) vers=1;
      else {
        bool ok=true;
        for (int i = 0; i < resfs.size(); i++)
          vers = qMax(resfs.at(i).section("_",-2,-2).toInt(&ok,36),vers);
        vers++;
      }
      if (!work.exists ( QString("%1/%2saves/").arg(dn).arg(PROGRAM_NAME))) work.mkdir (QString("%1/%2saves/").arg(dn).arg(PROGRAM_NAME));
      QFile::copy(insname,QString("%1/%4saves/%2_%3_.ins").arg(dn).arg(argument).arg(vers,2,36,QLatin1Char('0')).arg(PROGRAM_NAME));
      QFile::remove(insname);
      QFile::copy(dirName,insname);

      QFile::copy(fcfname2,QString("%1/%4saves/%2_%3_.fcf").arg(dn).arg(argument).arg(vers,2,36,QLatin1Char('0')).arg(PROGRAM_NAME));
      QFile::remove(fcfname2);
      QFile::copy(fcfname,fcfname2);
    }
  } else {
    QDir work=QDir(QString("%1/%2saves/").arg(dn).arg(PROGRAM_NAME));
    QStringList filter;
    filter << QString("%1_*_.ins").arg(argument);
    QStringList resfs;
    resfs=work.entryList(filter,QDir::Files,QDir::Time|QDir::Reversed);
    int vers=0;
    if (resfs.isEmpty()) vers=1;
    else {
      bool ok=true;
      for (int i = 0; i < resfs.size(); i++)
        vers = qMax(resfs.at(i).section("_",-2,-2).toInt(&ok,36),vers);
      vers++;
    }
    if (!work.exists ( QString("%1/%2saves/").arg(dn).arg(PROGRAM_NAME))) work.mkdir (QString("%1/%2saves/").arg(dn).arg(PROGRAM_NAME));
    QFile::copy(dirName,QString("%1/%4saves/%2_%3_.ins").arg(dn).arg(argument).arg(vers,2,36,QLatin1Char('0')).arg(PROGRAM_NAME));
  }
  shxOutputDock->setWindowTitle(QString("SHELXL OUTPUT: %1").arg(argument));
  shelxl->start(shelxlPath,al);
  wght_cycls++;
}

bool Window::compareWGHTS(QString w1, QString w2, double tolerance){
  QStringList Ws1, Ws2;
  QList<double> Wd1, Wd2;
  Ws1 = w1.split(QRegExp("\\s+"));
  Ws2 = w2.split(QRegExp("\\s+"));
  for (int i = 1; i < Ws1.size(); i++) Wd1.append(Ws1.at(i).toDouble());//0th element will be 'wght' so we don't need it for comarison 
  for (int i = 1; i < Ws2.size(); i++) Wd2.append(Ws2.at(i).toDouble());
  bool same = true;
  if (Wd1.size() == Wd2.size()) {
    for (int i=0; i < Wd1.size(); i++){
      same = (same) && (fabs(Wd1.at(i) - Wd2.at(i)) < tolerance);
    }
  }else return false;
  return same;
}

void Window::fixIt(){
  if (mole.asymm.isEmpty()) return;
  QDialog *fixDlg = new QDialog(this);
  QGroupBox *gpx =new QGroupBox("Checked parameters will not be refined.",fixDlg);
  QVBoxLayout *vbl = new QVBoxLayout();
  QList<QCheckBox *> alleboxen;
  QSignalMapper *map = new QSignalMapper(this);
  int allIx=0;
  for (int i=0; i<mole.asymm.size(); i++){
    allIx=10*i;
    if (mole.asymm.at(i).an<0) continue;
    QGroupBox *gpx2 = new QGroupBox(mole.asymm.at(i).Label,fixDlg);
    QList<QCheckBox *> boxen;
    gpx2->setAlignment(Qt::AlignRight);
    QVBoxLayout *v = new QVBoxLayout(gpx2);
    QHBoxLayout *hbl1 = new QHBoxLayout();
    QCheckBox *Xlab = new QCheckBox(QString::number(mole.asymm.at(i).frac.x,'f',6).prepend("X: "),fixDlg);
    QCheckBox *Ylab = new QCheckBox(QString::number(mole.asymm.at(i).frac.y,'f',6).prepend("Y: "),fixDlg);
    QCheckBox *Zlab = new QCheckBox(QString::number(mole.asymm.at(i).frac.z,'f',6).prepend("Z: "),fixDlg);
    QCheckBox *Olab = new QCheckBox(QString::number(mole.asymm.at(i).sof,'f',6).prepend("site occupancy: "),fixDlg);
    hbl1->addWidget(Xlab);
    hbl1->addWidget(Ylab);
    hbl1->addWidget(Zlab);
    hbl1->addWidget(Olab);
    boxen.append(Xlab);
    boxen.append(Ylab);
    boxen.append(Zlab);
    boxen.append(Olab);
    v->addLayout(hbl1);
    if (!mole.asymm.at(i).isIso) {
      QHBoxLayout *hbl2 = new QHBoxLayout();
      QCheckBox *M11lab = new QCheckBox(QString::number(mole.asymm.at(i).uf.m11,'f',6).prepend("U11: "),fixDlg);
      QCheckBox *M22lab = new QCheckBox(QString::number(mole.asymm.at(i).uf.m22,'f',6).prepend("U22: "),fixDlg);
      QCheckBox *M33lab = new QCheckBox(QString::number(mole.asymm.at(i).uf.m33,'f',6).prepend("U33: "),fixDlg);
      QCheckBox *M23lab = new QCheckBox(QString::number(mole.asymm.at(i).uf.m23,'f',6).prepend("U23: "),fixDlg);
      QCheckBox *M13lab = new QCheckBox(QString::number(mole.asymm.at(i).uf.m13,'f',6).prepend("U13: "),fixDlg);
      QCheckBox *M12lab = new QCheckBox(QString::number(mole.asymm.at(i).uf.m12,'f',6).prepend("U12: "),fixDlg);
      hbl2->addWidget(M11lab);
      hbl2->addWidget(M22lab);
      hbl2->addWidget(M33lab);
      hbl2->addWidget(M23lab);
      hbl2->addWidget(M13lab);
      hbl2->addWidget(M12lab);
      boxen.append(M11lab);
      boxen.append(M22lab);
      boxen.append(M33lab);
      boxen.append(M23lab);
      boxen.append(M13lab);
      boxen.append(M12lab);
      v->addLayout(hbl2);
    }
    vbl->addWidget(gpx2);
    alleboxen.append(boxen);
    for (int j=0;j<boxen.size();j++){
      int idx=1<<j;
      boxen[j]->setChecked(mole.asymm.at(i).fixFlag&idx);
      map->setMapping(boxen[j],allIx++);
      connect(boxen[j], SIGNAL(stateChanged(int)), map, SLOT(map()));
    } 


  }
  connect(map, SIGNAL(mapped(int)), this, SLOT(changeFixes(int)));
  QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel,Qt::Horizontal,fixDlg);
  connect(bb, SIGNAL(accepted()), fixDlg, SLOT(accept()));
  connect(bb, SIGNAL(rejected()), fixDlg, SLOT(reject()));
  gpx->setLayout(vbl);
  QVBoxLayout *la = new QVBoxLayout();
  QScrollArea *qsa = new QScrollArea(fixDlg);
  qsa->setWidget(gpx);
  la->addWidget(qsa);
  la->addWidget(bb);
  fixDlg->setLayout(la);
  fixDlg->exec();
  fixDlg->deleteLater();
}

void Window::changeFixes(int i){
  int da=i/10;
  int blub=i%10;
  int vor=-1;
  if (da<mole.asymm.size()){
    vor=mole.asymm[da].fixFlag;
    if (vor&(1<<blub)) {
      mole.asymm[da].fixFlag-=1<<blub;
    } else {
      mole.asymm[da].fixFlag|=1<<blub;
    }    
    jumpToAtom(da);
    QTextCursor c = editor->textCursor();
    c.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
    if (c.selectedText().contains("=")) {
      c.movePosition(QTextCursor::Down,QTextCursor::KeepAnchor);
      c.movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
    }
    //qDebug()<<mole.asymm.at(da).orginalLine;
    //qDebug()<< c.selectedText();
    int end= (mole.asymm.at(da).isIso)?4:10;
    QString sn=c.selectedText();
    sn.remove(QRegExp("^\\S+\\s+\\d+\\s+"));
    sn.remove(QRegExp("[=\n\r]+"));
    QStringList snl=sn.split(QRegExp("\\s+"));
    int egal=0;  
    double w[10];
    for (int i=0; i<snl.size();i++){w[i]=getNumber(snl.at(i).toDouble(),fvar,i,egal);}
    for (int i=0; i<end; i++){
      int tst=1<<i;
      int m=(tst&mole.asymm.at(da).fixFlag)?1:0;
      /* free variables come here ... m*fvarNr*fvarType
       *
       * */
      w[i]+=m*10;
    }

    QString neu=(end==10)?QString("%1  %2 %3 %4 %5  %6 %7 %8 =\n      %9 %10 %11 %12")
      .arg(mole.asymm.at(da).Label.section('_',0,0),-4)
      .arg(qMax(1,editor->sfac.indexOf(mole.asymm.at(da).an)+1))
      .arg(w[0],11,'f',6)
      .arg(w[1],11,'f',6)
      .arg(w[2],11,'f',6)
      .arg(w[3],10,'f',5)
      .arg(w[4],10,'f',5)
      .arg(w[5],10,'f',5)
      .arg(w[6],10,'f',5)
      .arg(w[7],10,'f',5)
      .arg(w[8],10,'f',5)
      .arg(w[9],10,'f',5)
      :QString("%1  %2 %3 %4  %5 %6 %7")
      .arg(mole.asymm.at(da).Label.section('_',0,0),-4) 
      .arg(qMax(1,editor->sfac.indexOf(mole.asymm.at(da).an)+1))
      .arg(w[0],11,'f',6)
      .arg(w[1],11,'f',6)
      .arg(w[2],11,'f',6)
      .arg(w[3],10,'f',5)
      .arg(w[4],10,'f',5);
    c.insertText(neu);
    mole.showatoms[da].orginalLine=mole.asymm[da].orginalLine=neu;
    mole.asymm[da].orginalLine.truncate(77);
    //qDebug()<<da<<mole.asymm.at(da).orginalLine;
    update();

  }


}

bool Window::maybeSave() {
  if (!editor->document()->isModified()) return true;
  QMessageBox::StandardButton ret;
  ret = QMessageBox::warning(this, tr("Application"),
      tr("The document has been modified.\n"
        "Do you want to save your changes?"),
      QMessageBox::Save | QMessageBox::Discard
      | QMessageBox::Cancel);
  if (ret == QMessageBox::Save){
    return fileSave();
  }
  else {if (ret == QMessageBox::Cancel)
    return false;
  }
  return true;
}

bool Window::maybeSave2() {
  if (!editor->document()->isModified()) return true;
  if (doNotAnnoyMe) return fileSave();
  QMessageBox *box=new QMessageBox(QMessageBox::Question,tr("Application"),
      tr("The document has been modified.\n"
        "Do you want to save your changes?"),
      QMessageBox::Save | QMessageBox::Discard
      | QMessageBox::Cancel);
  QPushButton *ischkansonetabeida = box->addButton("Always!",QMessageBox::ActionRole);
  box->setDefaultButton(QMessageBox::Save);
  int ret;
  ret = box->exec();

  if (box->clickedButton()==ischkansonetabeida){
    doNotAnnoyMe=true;
    mole.einstellung->beginGroup("DoNotAskFileSave");
    mole.einstellung->setValue("DoNotAnnoyMe",doNotAnnoyMe);
    mole.einstellung->endGroup();
    return fileSave();
  }
  if (ret == QMessageBox::Save){
    return fileSave();
  }
  else {if (ret == QMessageBox::Cancel)
    return false;
  }
  return true;
}

QString Window::strippedName(const QString &fullFileName) {
  return QFileInfo(fullFileName).fileName();
}

void Window::updateRecentFileActions() {
  QSettings *einstellung =new QSettings( QSettings::IniFormat, QSettings::UserScope ,PROGRAM_NAME, mole.mynewnameis );
  einstellung->beginGroup("Files");
  QStringList files = einstellung->value("recentFileList").toStringList();
  int numRecentFiles = qMin(files.size(), (int)MaxRecentFiles);

  for (int i = 0; i < numRecentFiles; ++i) {
    QString text = tr("&%1 %2").arg(i + 1).arg(strippedName(files[i]));
    recentFileActs[i]->setText(text);
    recentFileActs[i]->setData(files[i]);
    recentFileActs[i]->setStatusTip(files[i]);
    recentFileActs[i]->setVisible(true);
  }
  for (int j = numRecentFiles; j < MaxRecentFiles; ++j)
    recentFileActs[j]->setVisible(false);
  einstellung->endGroup();
  delete einstellung;
}

void Window::linkHelp(){
  QMessageBox::about(this, tr("%1-Help").arg(PROGRAM_NAME),
      tr("<h1>%1-Help</h1><br> The offline help has ben removed. <a href=\"http://shelxle.org/shelx/help/\">Click here for Online Help.</a>\n"
        ).arg(PROGRAM_NAME));
}

void Window::aboutXLE(){
  QString MEM;
#if defined Q_WS_WIN  ||   defined Q_OS_WIN
  MEMORYSTATUSEX memory_status;

  ZeroMemory(&memory_status, sizeof(MEMORYSTATUSEX));
  memory_status.dwLength = sizeof(MEMORYSTATUSEX);
  if (GlobalMemoryStatusEx(&memory_status)) {
    double total = memory_status.ullTotalPhys;
    double avail = memory_status.ullAvailPhys;
    QString tu,au;
    int it=0,ia=0;
    while (total>1000.0){
      it++;
      total/=1024.0;
    }
    while (avail>1000.0){
      ia++;
      avail/=1024.0;
    }
    switch (it){
      case 0: tu="B"; break;
      case 1: tu="kB"; break;
      case 2: tu="MB"; break;
      case 3: tu="GB"; break;
    }
    switch (ia){
      case 0: au="B"; break;
      case 1: au="kB"; break;
      case 2: au="MB"; break;
      case 3: au="GB"; break;
    }


    MEM.append(QString("RAM: %1 %4 Available %2 %5 Memory load %3%\n").arg(total,0,'f',2).arg(avail,0,'f',2).arg(memory_status.dwMemoryLoad).arg(tu).arg(au));
  } else {
    MEM.append("Unknown RAM\n");
  }
#endif
  QString openGLVersion=QString("OpenGL Version %1").arg((char *)glGetString(GL_VERSION));
  int glminor,glmajor;
  const char *verstring=(char*)glGetString(GL_VERSION);
  if ((verstring==NULL)||(sscanf(verstring,"%d.%d",&glmajor,&glminor)!=2)) glminor=glmajor=0;
  QString GLSLVersion=(glmajor<2)?"Unsupported GLSL Version":QString("GLSL Version %1 (minimum 1.20)").arg((char*)glGetString(GL_SHADING_LANGUAGE_VERSION));
  //qDebug() << (QString(qgetenv("PATH")).split(QRegExp("[;:]")));
  QMessageBox::about(this, tr("About %1").arg(PROGRAM_NAME),
      tr("<p><b>%1</b>&nbsp;is&nbsp;a&nbsp;tool&nbsp;for&nbsp;<b>SHELX</b>&nbsp;small&nbsp;"\
        "molecule&nbsp;refinement.&nbsp;It&nbsp;combines&nbsp;an&nbsp;editor with simple syntax highlighting "\
        "with an OpenGL representation of the structure.</p> "\
        "<p><img src=\":/xle-icons/cbh.png\" alt=\"Christian B. H&uuml;bschle\">"\
        "<img src=\":/xle-icons/gms.png\" alt=\"George M. Sheldrick\"></p> "\
        "<p><b>%1</b> is written by <b>Christian B. H&uuml;bschle</b> "\
        " at the University of G&ouml;ttingen. "\
        "Some parts of the program are taken from Qt examples, others are from the "\
        "<b>SHELX</b> author <b>George M. Sheldrick</b> and/or his group Members</p> "\
        "<font color=darkgreen> Please cite: <br>C. B. H&uuml;bschle, G. M. Sheldrick and B. Dittrich<br>"
        "<em>'ShelXle:&nbsp;a&nbsp;Qt&nbsp;graphical&nbsp;user&nbsp;interface&nbsp;for&nbsp;SHELXL'</em><br>"
        "<em>J. Appl. Cryst.</em> (2011). <b>44</b>, 1281-1284 .</font><br>"
        "<a href=\"http://dx.doi.org/10.1107/S0021889811043202\">[&nbsp;doi:10.1107/S0021889811043202&nbsp;]</a>"
        "<p>Please visit the following web sites:<br>"
        "<a href=\"http://shelx.uni-goettingen.de\"><b>SHELX</b> site</a><p>"
        "<p><a href=\"http://shelxle.org/shelx/index.php\">"
        "Dowload new versions from here</a></p>"
#ifdef __x86_64__
        "<p>This is a 64 bit Version.</p> "
#else
        "<p>This is a 32 bit Version.</p> "
#endif
        "<p>This is Revision <b>%2</b>"
        //"last build was: <b>%3</b></p> "
        "<p>The latest Version available is '%6'"
        "<p>The Version of Qt used is %4. </p> "\
        "<p>%5<br>%8<br>%9 </p><p>The settings of this program are stored in: <b>%7</b><p>%10")
        .arg(PROGRAM_NAME)
        .arg(Revision)
        //		    .arg(datum)
        .arg(qVersion ())
        .arg(openGLVersion)
        .arg(latestRev)
        .arg(mole.einstellung->fileName ())
        .arg(QString("Graphics card: %1").arg((char *)glGetString(GL_RENDERER)))
        .arg(GLSLVersion)
        .arg(MEM)
        );
}

void Window::hintLhide(){
  hintL->hide();
  mole.einstellung->beginGroup("SaveHint");
  mole.einstellung->setValue("ShowRenameHint",hintL->isVisible());
  mole.einstellung->endGroup();
}

void Window::symmetryManager(){
  prosaTimer.setSingleShot(true);
  QDialog *sman = new QDialog(this);
  sman->setWindowTitle("Symmetry Manager");
  QGridLayout *lt = new QGridLayout(sman);
  sman->setMinimumSize(400,300);

  OrtepCodesbrowser=new QTextBrowser(sman);
  OrtepCodesbrowser->setOpenLinks(false);
  OrtepCodesbrowser->setLineWrapMode(QTextEdit::NoWrap);
  symmIntBx = new QSpinBox(sman);
  symmIntBx->setMinimum(1);
  symmIntBx->setMaximum(mole.cell.symmops.size());

  symmXBx = new QSpinBox(sman);
  symmXBx->setMinimum(1);
  symmXBx->setMaximum(9);
  symmXBx->setValue(5);

  symmYBx = new QSpinBox(sman);
  symmYBx->setMinimum(1);
  symmYBx->setMaximum(9);
  symmYBx->setValue(5);

  symmZBx = new QSpinBox(sman);
  symmZBx->setMinimum(1);
  symmZBx->setMaximum(9);
  symmZBx->setValue(5);


  symmFrgBx = new QSpinBox(sman);
  symmFrgBx->setMinimum(1);
  symmFrgBx->setMaximum(mole.maxmols());
  symmFrgBx->setValue(1);
  prosaSymm = new QLineEdit();
  prosaSymm->setText("x,y,z");
  connect(prosaSymm,SIGNAL(textEdited(QString)),this,SLOT(updateSM4(QString)));
  connect(symmIntBx,SIGNAL(valueChanged(int)),this,SLOT(updateSM1()));
  connect(symmXBx,SIGNAL(valueChanged(int)),this,SLOT(updateSM1()));
  connect(symmYBx,SIGNAL(valueChanged(int)),this,SLOT(updateSM1()));
  connect(symmZBx,SIGNAL(valueChanged(int)),this,SLOT(updateSM1()));
  connect(symmFrgBx,SIGNAL(valueChanged(int)),this,SLOT(updateSM1()));
  QLabel *unter = new QLabel("_");
  QLabel *doppl = new QLabel(":");
  shortestDistanceLabel = new QLabel("<p>Shortest distace to asymmetric unit: 0.00 &Aring;</p>");
  QPushButton *addSymmOp=new QPushButton("add symmetry to list");
  connect(addSymmOp,SIGNAL(clicked()),this,SLOT(updateSM2()));
  QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
  connect(buttonBox, SIGNAL(accepted()), sman, SLOT(accept()));
  connect(buttonBox, SIGNAL(rejected()), sman, SLOT(reject()));
  connect(OrtepCodesbrowser,SIGNAL(anchorClicked( const QUrl &)), this ,SLOT(updateSM3(const QUrl &)));
  lt->addWidget(new QLabel("List of symmetry in use:"),0,0,1,12,Qt::AlignHCenter);
  // lt->addWidget(SymmetryCodesbrowser,1,0,1,5);
  lt->addWidget(OrtepCodesbrowser,1,0,1,12);
  lt->addWidget(new QLabel("symmetry operation"),2,0,1,5);
  lt->addWidget(new QLabel("sym No"),2,5,1,1);
  lt->addWidget(new QLabel("translation"),2,7,1,3,Qt::AlignHCenter);
  lt->addWidget(new QLabel("fragment"),2,11,1,1);
  lt->addWidget(prosaSymm,3,0,1,5);
  lt->addWidget(symmIntBx,3,5,1,1);
  lt->addWidget(unter,3,6,1,1);
  lt->addWidget(symmXBx,3,7,1,1);
  lt->addWidget(symmYBx,3,8,1,1);
  lt->addWidget(symmZBx,3,9,1,1);
  lt->addWidget(doppl,3,10,1,1);
  lt->addWidget(symmFrgBx,3,11,1,1);
  lt->addWidget(shortestDistanceLabel,4,0,1,9);
  lt->addWidget(addSymmOp,4,9,1,3);
  lt->addWidget(buttonBox,10,0,1,12);
  sman->setLayout(lt);
  QStringList oldsymm=mole.usedSymmetry;
  QString text="<table><tr><th>ID</th><th>symmetry op. </th><th style=\"background:#d4d4d4\">internal code</th><th></th><th></th><th>distance to asymmetric unit</th></tr>";;
  for (int i=0; i<mole.usedSymmetry.size(); i++)
    text.append(QString("<tr><th>$%6</th><td> %5 </td><th style=\"background:#d4d4d4\"> %1</th> <td><a href=\"%2\">remove</a> </td><td> <a href=\"%4\">edit</a></td><td> %3 &Aring;</td></tr>")
        .arg(mole.usedSymmetry.at(i))
        .arg(i)
        .arg(mole.shortestDistance(mole.usedSymmetry.at(i)),0,'f',2)
        .arg(-1-i)
        .arg(mole.symmcode2human(mole.usedSymmetry.at(i)))
        .arg(i+1));
  text.append("</table>");
  OrtepCodesbrowser->setHtml(text);

  if (sman->exec()==QDialog::Accepted){

    mole.showatoms.clear();
    mole.showbonds.clear();
    mole.showatoms+=mole.asymm;
    mole.packer(mole.usedSymmetry);
    mole.showbonds =
      mole.connecting(mole.showatoms);
    chgl->mol->selectedatoms.clear();
    chgl->murx=__LINE__;
    chgl->updateBondActions();
  }else{
    mole.usedSymmetry.clear();
    mole.usedSymmetry=oldsymm;
    oldsymm.clear();

    mole.showatoms.clear();

    mole.showatoms+=mole.asymm;
    mole.showbonds.clear();
    mole.packer(mole.usedSymmetry);
    mole.showbonds =
      mole.connecting(mole.showatoms);
    chgl->mol->selectedatoms.clear();
    chgl->murx=__LINE__;
    chgl->updateBondActions();
  }
  ;
  delete buttonBox ;

  text.clear();
  OrtepCodesbrowser->clear();
  delete OrtepCodesbrowser;
  delete symmIntBx;
  delete symmXBx;
  delete symmYBx;
  delete symmZBx;
  delete doppl;
  delete unter;
  delete symmFrgBx;
  delete shortestDistanceLabel;
  delete lt;
  delete sman;

  chgl->updateGL();
  update();
  chgl->updateGL();
}

void Window::updateSM1(){
  if (prosaTimer.isActive()) return;
  QString t=QString("%1_%2%3%4:%5")
    .arg(symmIntBx->value())
    .arg(symmXBx->value())
    .arg(symmYBx->value())
    .arg(symmZBx->value())
    .arg(symmFrgBx->value());
  shortestDistanceLabel->setText(QString("<p>Shortest distace to asymmetric unit: %1 &Aring;</p>").arg(
        mole.shortestDistance(t),0,'f',2));
  prosaSymm->setText(mole.symmcode2human(t));
  QPalette p = prosaSymm->palette();
  p.setBrush(QPalette::Active,QPalette::Base,Qt::white);
  prosaSymm->setPalette(p);
}

void Window::updateSM2(){
  QString t=QString("%1_%2%3%4:%5,")
    .arg(symmIntBx->value())
    .arg(symmXBx->value())
    .arg(symmYBx->value())
    .arg(symmZBx->value())
    .arg(symmFrgBx->value());
  if (t.startsWith("1_555:1"))return;
  OrtepCodesbrowser->clear();
  if (!mole.usedSymmetry.contains(t)) mole.usedSymmetry.append(t);
  QString text="<table><tr><th>symmetry op. </th><th style=\"background:#d4d4d4\">internal code</th><th></th><th></th><th>distance to asymmetric unit</th></tr>";;
  for (int i=0; i<mole.usedSymmetry.size(); i++)
    text.append(QString("<tr><td>%5 </td><th style=\"background:#d4d4d4\"> %1</th> <td><a href=\"%2\">remove</a> </td><td> <a href=\"%4\">edit</a></td><td> %3 &Aring;</td></tr>")
        .arg(mole.usedSymmetry.at(i))
        .arg(i)
        .arg(mole.shortestDistance(mole.usedSymmetry.at(i)),0,'f',2)
        .arg(-1-i)
        .arg(mole.symmcode2human(mole.usedSymmetry.at(i))));
  text.append("</table>");
  OrtepCodesbrowser->setHtml(text);

}

void Window::updateSM3(const QUrl link){
  int index = link.toString().toInt();
  if (index<0) {
    index=-index-1;
    QString t = mole.usedSymmetry.at(index);
    int s,h,k,l,symmgroup;
    sscanf(t.toLatin1(),"%d_%1d%1d%1d:%d",&s,&h,&k,&l,&symmgroup);
    shortestDistanceLabel->setText(QString("<p>Shortest distace to asymmetric unit: %1 &Aring;</p>").arg(
          mole.shortestDistance(t),0,'f',2));
    prosaTimer.stop();
    symmIntBx->setValue(s);
    symmXBx->setValue(h);
    symmYBx->setValue(k);
    symmZBx->setValue(l);
    symmFrgBx->setValue(symmgroup);
    return;
  }
  if (mole.usedSymmetry.size()<=index) return;
  mole.usedSymmetry.removeAt(index);
  QString text="<table><tr><th>symmetry op. </th><th style=\"background:#d4d4d4\">internal code</th><th></th><th></th><th>distance to asymmetric unit</th></tr>";
  for (int i=0; i<mole.usedSymmetry.size(); i++)
    text.append(QString("<tr><td>%5 </td><th style=\"background:#d4d4d4\"> %1</th> <td><a href=\"%2\">remove</a> </td><td> <a href=\"%4\">edit</a></td><td> %3 &Aring;</td></tr>")
        .arg(mole.usedSymmetry.at(i))
        .arg(i)
        .arg(mole.shortestDistance(mole.usedSymmetry.at(i)),0,'f',2)
        .arg(-1-i)
        .arg(mole.symmcode2human(mole.usedSymmetry.at(i)))
        );
  text.append("</table>");
  OrtepCodesbrowser->setHtml(text);

}

void Window::updateSM4(QString symtxt){
  QString t = mole.symmCard2Code(symtxt);
  QPalette p = prosaSymm->palette();

  p.setBrush(QPalette::Active,QPalette::Base,QColor(205,100,100));
  if (t.isEmpty()) {prosaSymm->setPalette(p);return;}

  p.setBrush(QPalette::Active,QPalette::Base,Qt::white);
  int s,h,k,l,symmgroup;
  shortestDistanceLabel->setText(QString("<p>Shortest distace to asymmetric unit: %1 &Aring;</p>").arg(
        mole.shortestDistance(t),0,'f',2));

  sscanf(t.toLatin1(),"%d_%1d%1d%1d:%d",&s,&h,&k,&l,&symmgroup);
  prosaTimer.start(80);
  symmIntBx->setValue(s);
  symmXBx->setValue(h);
  symmYBx->setValue(k);
  symmZBx->setValue(l);
  symmFrgBx->setValue(symmgroup);
  prosaSymm->setPalette(p);
  update();
}

void Window::insertSADI(int selected){
  QString buffer = "SADI 0.02 ";
  if (selected>=mole.asymm.size()) return;
  QList<int> baerle;// only same sfac type and non H to prevent warnig in lst file. Experts can do what they want if they know what they do by hand
  for (int nb=1; nb<mole.knoepfe.at(selected).neighbors.size(); nb++){
    if ((mole.knoepfe.at(selected).neighbors.at(nb-1)>=mole.asymm.size())||(mole.knoepfe.at(selected).neighbors.at(nb)>=mole.asymm.size())) continue;
    if ((mole.asymm.at(mole.knoepfe.at(selected).neighbors.at(nb-1)).an>0)&&
        (mole.asymm.at(mole.knoepfe.at(selected).neighbors.at(nb-1)).an==mole.asymm.at(mole.knoepfe.at(selected).neighbors.at(nb)).an)){
      if (!baerle.contains(mole.knoepfe.at(selected).neighbors.at(nb-1))) baerle.append(mole.knoepfe.at(selected).neighbors.at(nb-1));
      if (!baerle.contains(mole.knoepfe.at(selected).neighbors.at(nb))) baerle.append(mole.knoepfe.at(selected).neighbors.at(nb));
    }
  }
  for (int n=0; n < baerle.size(); n++){
    MyAtom atom1 = mole.asymm.at(selected);
    QString resi1 = (atom1.resiNr > 0)?QString("_%1").arg(atom1.resiNr):"";
    MyAtom atom2 = mole.asymm.at(baerle.at(n));
    QString resi2 = (atom2.resiNr > 0)?QString("_%1").arg(atom2.resiNr):"";
    buffer += atom1.Label.section("_", 0, 0) + resi1 + " " +  atom2.Label.section("_", 0, 0) + resi2 + " " ;
  }
  if (buffer.size()<12) {
    return;
  }
  QTextDocument *document = editor->document();
  QTextCursor cursor = editor->textCursor();
  cursor.movePosition(QTextCursor::Start,QTextCursor::MoveAnchor);
  cursor = document->find(QRegExp("^UNIT",Qt::CaseInsensitive),cursor);
  cursor.movePosition(QTextCursor::StartOfLine,QTextCursor::MoveAnchor);
  cursor.movePosition(QTextCursor::Down,QTextCursor::MoveAnchor);
  cursor.insertText(DSRGui::textWrap(buffer.simplified()) + "\n");
  mole.selectedatoms.clear();
}

void Window::raiseTaff(){
  tabifyDockWidget(shxOutputDock, infotainmentDock);
  resid_label->clear();
  restr_table->clear();
  infotainmentDock->show();
  infotainmentDock->raise();
  vis_settings->beginGroup("infotaiment");
  vis_settings->setValue("info_as_default", true);
  vis_settings->endGroup();
}

void Window::raiseTaz(){
  tabifyDockWidget(shxOutputDock, infotainmentDock);
  shxOutputDock->show();
  shxOutputDock->raise();
  vis_settings->beginGroup("infotaiment");
  vis_settings->setValue("info_as_default", false);
  vis_settings->endGroup();
}


void Window::shredCIF(){
  QSettings *shrcifset = new QSettings( QSettings::IniFormat, QSettings::UserScope ,PROGRAM_NAME,mole.mynewnameis );
  shrcifset->beginGroup("ShredCIF");
  shredCIFPath = shrcifset->value("ShredCIF-PATH","").toString();
  shrcifset->endGroup();
  //inspired by Daniels 'which' in DSRGUI
  QStringList foundInPath;
  foundInPath.clear();
  //  qDebug()<<shredCIFPath.isEmpty()<<!QFileInfo(shredCIFPath).isExecutable()<<shredCIFPath;
  if ((shredCIFPath.isEmpty())||(!QFileInfo(shredCIFPath).isExecutable())) {
    QStringList execlist;
    QStringList pathList;
    pathList.clear();
    execlist.clear();
    pathList = QString(qgetenv("PATH")).split(QRegExp("[;:]"));
    // qDebug()<<pathList;
    foreach (QString path, pathList) {
      QString fullpath = path+"/shredcif";
      QFileInfo fi(fullpath);
      if (QFile::exists(fullpath) && (fi.isExecutable())){
        foundInPath.append(QDir::cleanPath(fullpath));
      }else {
        fi.setFile(fullpath+".exe");
        //		qDebug()<<QDir::cleanPath(fullpath+".exe")<<QFile::exists(fullpath+".exe")<<(fi.isExecutable());
        if (QFile::exists(fullpath+".exe") && (fi.isExecutable())){
          foundInPath.append(QDir::cleanPath(fullpath+".exe"));
        }
      }
    }

    if (foundInPath.isEmpty()){
      //file dialog 
      QString shcf = QFileDialog::getOpenFileName(this, "Where is SHREDCIF? (http://shelx.uni-goettingen.de/download.php)",
          QString(),QString(),nullptr,(useNativeDlg->isChecked())?noneopt:QFileDialog::DontUseNativeDialog);
      //(QWidget *parent = nullptr, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = nullptr, QFileDialog::Options options = Options())
      if (shcf.isEmpty()) return; // empty string means probably cancel 
      if (QFileInfo(shcf).isExecutable()) shredCIFPath = shcf;
    }else {
      shredCIFPath = foundInPath.first();
    } 
    shrcifset->beginGroup("ShredCIF");
    shrcifset->setValue("ShredCIF-PATH",shredCIFPath);
    shrcifset->endGroup();
  }
  // qDebug() << shredCIFPath;
  QString cif2shred = QFileDialog::getOpenFileName(this, "Open a CIF to shred",dirName,"Crystallographic Information File (*.cif)"
      ,nullptr,(useNativeDlg->isChecked())?noneopt:QFileDialog::DontUseNativeDialog);
  if (cif2shred.isEmpty()) return;
  QProcess *shred = new QProcess(this);
  QString dn=cif2shred.section('/',0,-2), argument=cif2shred.section('/',-1);
  QStringList al;
  al.append(argument);
  shred->setWorkingDirectory(dn);                           // updateXLput()
#if (QT_VERSION >= 0x040600)
  QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
  shred->setProcessEnvironment(env);//Thanks to Dr. Pavlo Solntsev!! 
#else
  QStringList env = QProcess::systemEnvironment();
  shred->setEnvironment(env);
#endif
  shred->start(shredCIFPath,al);
  shred->waitForFinished(5000);
  QString op= shred->readAllStandardOutput();
  QMessageBox::information ( this, "shredcif output", "ShredCIF output:" + op );
  //qDebug()<<(!op.contains("checksum O.K."));
  if (!op.contains("checksum O.K.")) {qDebug()<<"No res file in cif file found!";return;}
  QStringList filter;
  filter << "*.ins" << "*.res";
  QDir dir(dn);
  QStringList files = dir.entryList(filter,QDir::Files|QDir::Readable,QDir::Time|QDir::Reversed);
  //qDebug()<<files;
  QString fileName=files.last();
  if (fileName.isEmpty()) return;
  //qDebug()<<fileName;
  QString base = fileName;
  if (base.length()>4) base.chop(4);
  // qDebug()<<base<<op.contains(base);
  if (op.contains(base)) loadFile(dn+"/"+fileName);
}

void Window::showSearch(){
  if (editor->uCanSeeMe) editor->showSearch();
  else if (xlPutor->uCanSeeMe) xlPutor->showSearch();
}

void Window::findNext(){
  if (editor->uCanSeeMe) editor->findNext();
  else if (xlPutor->uCanSeeMe) xlPutor->findNext();
}

void Window::findPrev(){
  if (editor->uCanSeeMe) editor->findPrev();
  else if (xlPutor->uCanSeeMe) xlPutor->findPrev();
}

void Window::brwsEPS(){
  QString selectedFilter;
  fxle->contEPSFile->setText(QFileDialog::getSaveFileName(this, tr("Save Contour-Encapsulated PostScript file "), "",
        "Encapsulated PostScript-Files (*.eps);;"
        ,&selectedFilter,(useNativeDlg->isChecked())?noneopt:QFileDialog::DontUseNativeDialog));
  if (!fxle->contEPSFile->text().endsWith(".eps",Qt::CaseInsensitive))
    fxle->contEPSFile->setText(fxle->contEPSFile->text()+".eps");
}

void Window::nocontourPlot(){
  chgl->cont.clear();
  chgl->contval.clear();
  chgl->cntrPlot->setVisible(false);
  chgl->nocntrPlot->setVisible(false);
  chgl->rainbowPlot->setVisible(false);
  chgl->mol->selectedatoms.clear();
  chgl->updateBondActions();
  update();
  chgl->updateGL();
}
void Window::contourPlot(){
  if (mole.showatoms.isEmpty()) return;
  chgl->cntrPlot->setVisible(false);
  chgl->nocntrPlot->setVisible(true);

  QDialog *contDlg     = new QDialog(this);

  QLabel *contEPSFileL = new QLabel("Write Encapsulated Postscript file",contDlg);
  QPushButton *brwsEPS  = new QPushButton("Browse",contDlg);
  connect(brwsEPS,SIGNAL(pressed()),this,SLOT(brwsEPS()));
  fxle->contEPSFile  = new QLineEdit(contDlg);
  fxle->contEPSFile->setWhatsThis(
      "<h1>EPS file name</h1>"
      "If this field is not empty an encapsulated post script file is written to the given path");
  QLabel *planeAtomDefL = new QLabel("Define plane by:");
  int at1=0,at2=1,at3=2;
  if (chgl->mol->selectedatoms.size()>2){
    at1=chgl->mol->selectedatoms.at(0).style;
    at2=chgl->mol->selectedatoms.at(1).style;
    at3=chgl->mol->selectedatoms.at(2).style;
  }
  QLineEdit *planeAtomDef = new QLineEdit(QString("%1 %2 %3")
      .arg(mole.showatoms.at(at1).Label)
      .arg(mole.showatoms.at(at2).Label)
      .arg(mole.showatoms.at(at3).Label));
  planeAtomDef->setReadOnly(true);
  planeAtomDef->setEnabled(false);
  /*
     cubeGL->moliso->contMapFile->setReadOnly(true);
     cubeGL->moliso->contMapFile->setEnabled(false);
     */
  fxle->contourValueEdit = new QLineEdit(contDlg);
  fxle->contourValueEdit->setText("-1.0 0.0 1.0");
  QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
  connect(buttonBox, SIGNAL(accepted()), contDlg, SLOT(accept()));
  connect(buttonBox, SIGNAL(rejected()), contDlg, SLOT(reject()));  
  QPushButton *edo  = new QPushButton("uniform contours",contDlg);
  cStepBx = new QDoubleSpinBox(contDlg);
  cStepBx->setPrefix("Step size: ");
  cStepBx->setMinimum(0.001);
  cStepBx->setDecimals(3);
  cStepBx->setValue(0.1);
  cStepBx->setSingleStep(0.05);
  fxle->extendUnit = new QCheckBox("Extend over unit cell",contDlg);
  fxle->cScopeBx = new QDoubleSpinBox(contDlg);
  fxle->cScopeBx->setMinimum(0.0);
  fxle->cScopeBx->setDecimals(1);
  fxle->cScopeBx->setSingleStep(0.5);
  fxle->heightScale = new QDoubleSpinBox(contDlg);
  fxle->heightScale->setMinimum(0.0);
  fxle->heightScale->setDecimals(2);
  fxle->heightScale->setSingleStep(0.05);
  fxle->heightScale->setValue(0.0);
  fxle->heightScale->setPrefix("Height scale: ");
  QPushButton *eAIM = new QPushButton("+AIM contours",contDlg);
  eAIM->setWhatsThis(
      "<h1>Atoms In Molecules(AIM) contours</h1>"
      "This will add contours at <b>1 &times; 10<sup>n</sup>,2 &times; 10<sup>n</sup>,4 &times; 10<sup>n</sup>,6 &times; 10<sup>n</sup>and 8 &times; 10<sup>n</sup></b>. <b>n</b> ranges from -3 to 8.");
  connect(edo ,SIGNAL(released ()),this,SLOT(everyPointOne()));
  connect(eAIM,SIGNAL(released ()),this,SLOT(everyAIM()));

  edo->setWhatsThis(
      "<h1>uniform contours</h1>"
      "This will add contours from -10 to 10 in steps with given step size.");

  fxle->centerIsOn = new QComboBox(contDlg);
  fxle->centerIsOn ->addItem("first atom",0);
  fxle->centerIsOn ->addItem("second atom",1);
  fxle->centerIsOn ->addItem("third atom",2);
  fxle->centerIsOn ->addItem("center of 3 atoms",3);
  fxle->centerIsOn->setWhatsThis(
      "<h1>Center on</h1>"
      "When an EPS file is exported the center of the plot will be either on one of the selected atoms or the center of these three atoms."
      );

  fxle->aspectRatios = new QComboBox(contDlg);
  fxle->aspectRatios->addItem("4:3",0);
  fxle->aspectRatios->addItem("16:9",1);
  fxle->aspectRatios->addItem("1:1",2);
  fxle->aspectRatios->setCurrentIndex(0);

  fxle->sourceMap = new QComboBox(contDlg);
  fxle->sourceMap->addItem("Fo-Fc diffrence map",0);
  fxle->sourceMap->addItem("Fo map",1);
  fxle->sourceMap->setWhatsThis(
      "<h1>Source </h1>"
      "The contour plot can be based on the Diffrence Fourier Map (Fo-Fc Map) or the map of the observed structure factors with model phases (Fo map).");

  QGridLayout *gl = new QGridLayout(contDlg);
  gl->addWidget(planeAtomDefL, 1, 0, 1, 1);
  gl->addWidget(planeAtomDef, 1, 1, 1, 1);
  gl->addWidget(new QLabel("Center on",contDlg), 1, 3, 1, 1);
  gl->addWidget(fxle->centerIsOn, 1, 4, 1, 1);
  gl->addWidget(new QLabel("Contour plot is based on:",contDlg), 2, 0, 1, 1);
  gl->addWidget(fxle->sourceMap,2,1,1,1);
  gl->addWidget(new QLabel("Contour values",contDlg), 3, 0, 1, 4);
  gl->addWidget(fxle->contourValueEdit, 4, 0, 1, 5);
  gl->addWidget(cStepBx ,5,0,1,1);
  gl->addWidget(edo,5,1,1,1);
  gl->addWidget(eAIM,5,2,1,1);
  gl->addWidget(fxle->heightScale,5,3,1,1);
  gl->addWidget(fxle->extendUnit,5,4,1,1);
  gl->addWidget(new QLabel("Scope (0 means now restriction)"),6,0,1,1);
  gl->addWidget(fxle->cScopeBx,6,1,1,1);
  gl->addWidget(new QLabel("Aspect ratio"),6,3,1,1);
  gl->addWidget(fxle->aspectRatios,6,4,1,1);

  gl->addWidget(contEPSFileL, 7, 0, 1, 1);
  gl->addWidget(fxle->contEPSFile, 7, 1, 1, 3);
  gl->addWidget(brwsEPS, 7, 4, 1, 1);
  gl->addWidget(buttonBox, 10, 0, 1, 5);

  if (contDlg->exec()==QDialog::Accepted){
    fxle->makePlane(chgl->cont,at1,at2,at3);
    chgl->mol->selectedatoms.clear();
    chgl->rainbowPlot->setVisible(true);
    /*showLeg->setChecked ( true );
      showLeg->setVisible(true);
      cubeGL->setLegend(true);*/
    chgl->updateGL();
  }else{
    chgl->mol->selectedatoms.clear();
    chgl->updateBondActions();
    chgl->cntrPlot->setVisible(false);
    chgl->nocntrPlot->setVisible(false);
    chgl->rainbowPlot->setVisible(false);
  }

}

void Window::everyPointOne(){
  QString cfs;
  if (cStepBx->value()==0) return;
  double val=-100*cStepBx->value();
  double end=-val;  
  while (val<end) {
    cfs.append(QString("%1 ").arg(val));
    val+=cStepBx->value();
  }
  fxle->contourValueEdit->setText(cfs);
  update();
}

void Window::everyAIM(){
  double val=0.001;
  //  double step=fabs(0.001)/5.0f;
  int i=-3;
  QString cfs;
  while (val<1e9) {
    cfs.append(QString("%1 ").arg(val));//1
    val+=1*pow(10.0,i);
    cfs.append(QString("%1 ").arg(val));//2
    val+=2*pow(10.0,i);
    cfs.append(QString("%1 ").arg(val));//4
    val+=2*pow(10.0,i);
    cfs.append(QString("%1 ").arg(val));//6
    val+=2*pow(10.0,i);
    cfs.append(QString("%1 ").arg(val));//8
    val+=2*pow(10.0,i);

    i++;
  }

  fxle->contourValueEdit->setText(cfs);
  update();

}

// K.R. start============================================================
void Window::exportCC(){

#define GAUSS_FILES "gaussian (*.com | *.gjf)"
#define XYZ_FILES "xyz (*.xyz)"
#define TM_FILES "turbomole (*.coord)"

  QString selectedFilter;

  QString qmName = dirName;
  qmName.replace(QRegExp("(.ins)|(.res)",Qt::CaseInsensitive),"");
  QString fn=QFileDialog::getSaveFileName(this, "Export computational chemistry file", qmName,
      GAUSS_FILES ";;" XYZ_FILES ";;" TM_FILES, &selectedFilter);
  if (fn.isEmpty())return;
  if (selectedFilter==GAUSS_FILES){
    QDialog *dlg = new ExportCCDlg(dirName,chgl->mol,fn);
    dlg->exec();
  }
  else{
    QString headerQM, bodyQM, footerQM, filenameQM;
    double a0= 1.0 / 0.5291772109;
    QFile f;
    f.setFileName(fn);
    QFileInfo fileInfo(f.fileName());
    filenameQM = fileInfo.baseName();
    // center of molecule
    V3 Vo=V3(0,0,0);
    int visCount=0;
    for (int i=0; i<mole.showatoms.size();i++) {
      if (mole.showatoms.at(i).an<0) continue;   //ignore none atoms
      if ((mole.nopm1)&&(mole.showatoms.at(i).symmGroup)&&(mole.showatoms.at(i).part<-0)) continue; // ignore hidden parts (-1)
      if (mole.showatoms.at(i).hidden) continue;
      visCount++;
      Vo+=mole.showatoms.at(i).pos;
    }
    Vo*=1.0/visCount;


    // atoms themselves
    for (int i=0; i< mole.showatoms.size(); i++){
      if (mole.showatoms.at(i).an<0) continue;   //ignore none atoms
      if ((mole.nopm1)&&(mole.showatoms.at(i).symmGroup)&&(mole.showatoms.at(i).part<-0)) continue; // ignore hidden parts (-1)
      if (mole.showatoms.at(i).hidden) continue;
      if (selectedFilter == XYZ_FILES) {
        bodyQM.append(QString("%1 %2 %3 %4\n")
            .arg(mole.pse(mole.showatoms.at(i).an),-2)
            .arg(mole.showatoms.at(i).pos.x-Vo.x,13,'f',10)
            .arg(mole.showatoms.at(i).pos.y-Vo.y,13,'f',10)
            .arg(mole.showatoms.at(i).pos.z-Vo.z,13,'f',10) );
      }
      else {
        bodyQM.append(QString(" %2 %3 %4 %1\n")
            .arg(mole.pse(mole.showatoms.at(i).an).toLower(),-4)
            .arg((mole.showatoms.at(i).pos.x-Vo.x)*a0,20,'f',14)
            .arg((mole.showatoms.at(i).pos.y-Vo.y)*a0,20,'f',14)
            .arg((mole.showatoms.at(i).pos.z-Vo.z)*a0,20,'f',14) );
      }
    }

    if (selectedFilter == XYZ_FILES) {
      footerQM.append(QString("\n\n"));
    } else {
      footerQM.append(QString("$end\n\n"));
    }
    if (selectedFilter == XYZ_FILES) { // ================= XYZ
      headerQM.append(QString("%1\n").arg(visCount));
      headerQM.append(QString("from %1\n").arg(dirName));

    } else {
      headerQM.append(QString("$coord\n"));
    }
    bool success = f.open(QIODevice::WriteOnly|QIODevice::Text);
    if (success){
      f.write(QString("%1%2%3").arg(headerQM).arg(bodyQM).arg(footerQM).toLatin1());
      f.close();
    }
  }
}




