Logo Search packages:      
Sourcecode: udav version File versions  Download package

scriptwindow.cpp

/***************************************************************************
 *   Copyright (C) 2008 by Alexey Balakin                                  *
 *   mathgl.abalakin@gmail.com                                             *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include <QTime>
#include <qtextedit.h>
#include <QPrintDialog>
#include <QCloseEvent>
#include <qstatusbar.h>
#include <qmessagebox.h>
#include <QPrinter>
#include <qapplication.h>
#include <qpainter.h>
#include <QScrollArea>
#include <qsplitter.h>
#include <qtimer.h>
#include <qaction.h>
#include <qpixmap.h>
#include <QTabWidget>
#include <mgl/mgl_parse.h>
//-----------------------------------------------------------------------------
#include "scriptwindow.h"
#include "qmglsyntax.h"
#include "qmglcanvas.h"
#include "finddialog.h"
#include "helpwindow.h"
#include "optiondialog.h"
#include "styledialog.h"
#include "animparam.h"
#include "argsdialog.h"
#include "propdialog.h"
#include "setupdialog.h"
#include "infodialog.h"
//#include "xpm/udav.xpm"
//-----------------------------------------------------------------------------
extern bool mglAutoExecute;
extern bool mglAutoSave;
extern HelpWindow *hlp;
extern mglParse parser;
int animDelay=500;
ArgsDialog *args_dlg=0;
QString defFontFamily;
int defFontSize;
PropDialog *propDlg=0;
int ScriptWindow::num_wnd=0;
//-----------------------------------------------------------------------------
ScriptWindow::ScriptWindow(QWidget *wp) : QMainWindow(wp)
{
      gifOn = jpgOn = false;
      setWindowTitle(tr("untitled - UDAV"));
      setAttribute(Qt::WA_DeleteOnClose);
      printer = new QPrinter;
      if(!args_dlg)     args_dlg = new ArgsDialog;
      infoDlg = new InfoDialog(this);
      infoDlg->setModal(true);      infoDlg->allowRefresh=false;
      findDialog = new FindDialog(this);
      optDialog = new OptionDialog(this);
      stlDialog = new StyleDialog(this);
      animDialog = new AnimParam(this);
      setupDlg = new SetupDialog(this);
      connect(findDialog, SIGNAL(findText(const QString &, bool, bool)), this, SLOT(findText(const QString &, bool, bool)));
      connect(findDialog, SIGNAL(replText(const QString &, const QString &, bool, bool)), this, SLOT(replText(const QString &, const QString &, bool, bool)));
      connect(animDialog, SIGNAL(putText(const QString &)), this, SLOT(animPutText(const QString &)));
      connect(setupDlg, SIGNAL(putText(const QString &)), this, SLOT(animPutText(const QString &)));

      animPos = -1;
      timer = new QTimer(this);
      connect(timer, SIGNAL(timeout()), this, SLOT(nextSlide()));

      splitG = new QSplitter(this); splitG->setOrientation(Qt::Vertical);
      split = new QSplitter(splitG);
      edit = new QTextEdit(split);
      edit->setFocus(); edit->setAcceptRichText(false);
      connect(edit, SIGNAL(cursorPositionChanged()), this, SLOT(editPosChanged()));
      new QMGLSyntax(edit);
      defFontFamily = edit->fontFamily();
      defFontSize = edit->fontPointSize();


      sv = new QScrollArea(split);
      mgl = new QMGLCanvas(split);  mgl->textMGL = edit;
//    connect(this, SIGNAL(gotoLine(int,int)), this, SLOT(setCursorPosition(int,int)));
      connect(mgl, SIGNAL(posChanged(QString)), statusBar(), SLOT(showMessage(QString)));
      connect(mgl, SIGNAL(refreshData()), this, SLOT(refresh()));
      sv->setWidget(mgl);

      info = setupInfo(splitG);     mgl->warnMGL = mess;    new MessSyntax(mess);
      connect(mess, SIGNAL(textChanged()), this, SLOT(warnChanged()));

      makeMenu();
//    setDockMenuEnabled(true);
      mgl->setPopup(popup);
      setCentralWidget(splitG);
      setWindowIcon(QIcon(":/udav.png"));
      readSettings();
      if(!propDlg)      propDlg = new PropDialog;
      edit->setLineWrapMode(QTextEdit::NoWrap);
      connect(edit,SIGNAL(textChanged()), this, SLOT(setAsterix()));
      info->setCurrentIndex(1);
      statusBar()->showMessage(tr("Ready"), 2000);
      num_wnd++;
}
//-----------------------------------------------------------------------------
ScriptWindow::~ScriptWindow()
{
      delete printer;
}
//-----------------------------------------------------------------------------
void ScriptWindow::printText()
{
      QPrintDialog printDlg(printer, this);
      if (printDlg.exec() == QDialog::Accepted)
      {
            statusBar()->showMessage(tr("Printing..."));
            edit->print(printer);
            statusBar()->showMessage(tr("Printing completed"), 2000);
      }
      else
            statusBar()->showMessage(tr("Printing aborted"), 2000);
}
//-----------------------------------------------------------------------------
void ScriptWindow::printPlot()
{
      QPrintDialog printDlg(printer, this);
      if (printDlg.exec() == QDialog::Accepted)
      {
            statusBar()->showMessage(tr("Printing..."));
            QPainter p;
            if(!p.begin(printer))   return;     // paint on printer
            QRect r = p.viewport();
            int w = r.width(), h = r.height(), h1;
            h1 = int(w/mgl->getRatio());
            if(h1<h)    h = h1;     else  w = int(h*mgl->getRatio());
            mglGraphZB gr(w, h);
            if(w*h > 240000)  gr.BaseLineWidth = sqrt(w*h/2.4e5);
            mgl->execute(&gr);

            uchar *grBuf=0;
            QPixmap pic;
            convertFromGraph(pic, &gr, &grBuf);
            p.drawPixmap(0,0,pic);
            delete []grBuf;
            statusBar()->showMessage(tr("Printing completed"), 2000);
      }
      else
            statusBar()->showMessage(tr("Printing aborted"), 2000);
}
//-----------------------------------------------------------------------------
void ScriptWindow::closeEvent(QCloseEvent* ce)
{
      bool ok=true;
      writeSettings();
      if(edit->document()->isModified())
            switch(QMessageBox::information(this, tr("Qt Application Example"), tr("Do you want to save the changes to the document?"), QMessageBox::Yes, QMessageBox::No, QMessageBox::Cancel))
            {
                  case QMessageBox::Yes:  save();     break;
                  case QMessageBox::No:   break;
                  default:    ok=false;   break;
            }
      if(ok)
      {
            num_wnd--;
            ce->accept();
            if(num_wnd==0)    QApplication::quit();
      }
      else  ce->ignore();
}
//-----------------------------------------------------------------------------
void ScriptWindow::pressF5()
{
      if(mglAutoSave)   save();
      QTime t;
      t.start();
      mgl->execute();
      statusBar()->showMessage(QString(tr("Drawing time %1 ms")).arg(t.elapsed()*1e-3));
}
//-----------------------------------------------------------------------------
void ScriptWindow::find()
{
      findDialog->show();
      findDialog->raise();
      findDialog->activateWindow();
}
//-----------------------------------------------------------------------------
bool ScriptWindow::findText(const QString &str, bool cs, bool fw)
{
//    static int para=0, index=0;
      static QTextDocument::FindFlags f;
      static QString stri="";
      if(!str.isEmpty())
      {
            stri = str;
            f = QTextDocument::FindFlags();
            if(fw)      f = f|QTextDocument::FindBackward;
            if(cs)      f = f|QTextDocument::FindCaseSensitively;
      }
      bool res = edit->find(stri, f);
      if(!res)
            QMessageBox::information(this, tr("UDAV - find text"), tr("No string occurrence is found"));
      return res;
}
//-----------------------------------------------------------------------------
void ScriptWindow::replText(const QString &str, const QString &txt, bool cs, bool fw)
{
      static bool res=false;
      if(str.isEmpty()) {     res = false;      return;     }
      if(res)     edit->textCursor().insertText(txt);
      res = findText(str, cs, fw);
}
//-----------------------------------------------------------------------------
void ScriptWindow::showHelp()
{
      QString s = edit->textCursor().block().text(), dlm(" #;\t");
      int i, n = s.length();
      for(i=0;i<n;i++)  if(dlm.contains(s[i]))  break;
      s.truncate(i);
//    s = s.section(' ',0);
      hlp->showHelp(s);
}
//-----------------------------------------------------------------------------
int mgl_cmd_cmp(const void *a, const void *b);
void ScriptWindow::editPosChanged()
{
      register int i, n, m;
      QString text = edit->textCursor().block().text(), dlm(" #;\t");
      n = text.length();
      for(i=0;i<n;i++)  if(dlm.contains(text[i]))     break;
      text.truncate(i); m = text.length();

      for(n=0;parser.Cmd[n].name[0];n++){};     // determine the number of symbols in parser
      mglCommand tst, *rts;
      wchar_t *s = new wchar_t[m+1];
      text.toWCharArray(s);   s[m]=0;     tst.name = s;
      rts = (mglCommand *)bsearch(&tst, parser.Cmd, n, sizeof(mglCommand), mgl_cmd_cmp);
      if(rts)
      {
            statusBar()->showMessage(QString::fromWCharArray(rts->desc)+": " + QString::fromWCharArray(rts->form));
      }
      else  statusBar()->showMessage(tr("Not recognized"));
      delete []s;
}
//-----------------------------------------------------------------------------
void ScriptWindow::addOptions()
{
      if(optDialog->exec()==QDialog::Accepted)
      {
            edit->moveCursor(QTextCursor::EndOfLine);
            edit->insertPlainText(optDialog->getOption());
      }
}
//-----------------------------------------------------------------------------
void ScriptWindow::animStart(bool st)
{
      if(animParam.isEmpty())
      {
            if(animDialog->exec())
            {
                  animParam = animDialog->getResult();
                  gifName = animDialog->gifName;
                  gifOn = animDialog->gifOn;
                  jpgOn = animDialog->jpgOn;
            }
            else  return;
      }
      if(st)
      {
            timer->start(animDelay);
            if(gifOn)   mgl->graph->StartGIF(gifName.toAscii(), animDelay);
            mgl->graph->ResetFrames();
      }
      else
      {
            timer->stop();
            if(gifOn)   mgl->graph->CloseGIF();
      }
}
//-----------------------------------------------------------------------------
void ScriptWindow::nextSlide()
{
      if(animParam.isEmpty())
      {
            if(animDialog->exec())
            {
                  animParam = animDialog->getResult();
                  gifName = animDialog->gifName;
                  gifOn = animDialog->gifOn;
                  jpgOn = animDialog->jpgOn;
            }
            else  return;
      }
      int l=animParam.length(), n=animParam.count('\n') + (animParam[l-1]=='\n' ? 0:1), i;
      wchar_t *str = new wchar_t[l+2];
      animPos = (animPos+1)%n;
      QString cur = animParam.section('\n',animPos,animPos);
      for(i=0;i<l;i++)  str[i] = (cur[i]).unicode();
      str[i] = 0;
      parser.AddParam(0,str);
      if(mgl->graph->GetNumFrame() >= n)
            mgl->execute();
      else
      {
            mgl->graph->NewFrame();
            mgl->execute();
            mgl->graph->EndFrame();
            if(jpgOn)   mgl->graph->WriteFrame();
            QString s;  s.sprintf("%d - %d of %d",mgl->graph->GetNumFrame(),animPos,n);
            statusBar()->showMessage(QString(tr("Frame %1 of %2")).arg(animPos).arg(n));
      }
}
//-----------------------------------------------------------------------------
void ScriptWindow::prevSlide()
{
      if(animParam.isEmpty())
      {
            if(animDialog->exec())
            {
                  animParam = animDialog->getResult();
                  gifName = animDialog->gifName;
                  gifOn = animDialog->gifOn;
                  jpgOn = animDialog->jpgOn;
            }
            else  return;
      }
      int l=animParam.length(), n=animParam.count('\n') + (animParam[l-1]=='\n' ? 0:1), i;
      wchar_t *str = new wchar_t[l+2];
      animPos = (animPos-1+n)%n;
      QString cur = animParam.section('\n',animPos,animPos);
      for(i=0;i<l;i++)  str[i] = (cur[i]).unicode();
      str[i] = 0;
      parser.AddParam(0,str);
      mgl->execute();
}
//-----------------------------------------------------------------------------
void ScriptWindow::animSetup()
{
      if(animDialog->exec())
      {
            animParam = animDialog->getResult();
            gifName = animDialog->gifName;
            gifOn = animDialog->gifOn;
            jpgOn = animDialog->jpgOn;
      }
}
//-----------------------------------------------------------------------------
void ScriptWindow::addSetup()
{
      setupDlg->exec();
}
//-----------------------------------------------------------------------------
void ScriptWindow::animPutText(const QString &s)
{
      edit->moveCursor(QTextCursor::Start);
      edit->insertPlainText(s);
}
//-----------------------------------------------------------------------------
void ScriptWindow::animParseText()
{
      int i, n = edit->toPlainText().count('\n')+1;
      QString s, all;
      for(i=0;i<n;i++)
      {
            s = edit->toPlainText().section('\n',i,i);
            if(s[0]=='#' && s[1]=='#' && s[2]=='a' && (s[3]==' ' || s[3]=='\t'))
                  all = all + s.mid(4) + "\n";
      }
      if(!all.isEmpty())
      {
            animDialog->setResult(all);
            animParam = all;
      }
}
//-----------------------------------------------------------------------------
void ScriptWindow::addStyle()
{
      if(stlDialog->exec()==QDialog::Accepted)
      {
            QString s = edit->textCursor().block().text();
            int i = s.indexOf(';');
            if(i<0)     edit->moveCursor(QTextCursor::EndOfLine);
            else
            {
                  edit->moveCursor(QTextCursor::StartOfBlock);
                  // foolish way :(
                  for(;i>0;i--)     edit->moveCursor(QTextCursor::Left);
            }
            edit->insertPlainText(stlDialog->getStyle());
      }
}
//-----------------------------------------------------------------------------
void ScriptWindow::setEditorFont(QFont *f)
{     edit->setFont(f ? *f : QFont(defFontFamily, defFontSize));  }
//-----------------------------------------------------------------------------
void ScriptWindow::setMGLFont(QString path)     {     mgl->setMGLFont(path);  }
//-----------------------------------------------------------------------------
void ScriptWindow::setEditPos(bool bottom)
{
      splitG->setOrientation(bottom? Qt::Horizontal : Qt::Vertical);
      split->setOrientation(bottom ? Qt::Vertical : Qt::Horizontal);
}
//-----------------------------------------------------------------------------
void ScriptWindow::properties()     {     propDlg->exec();  }
//-----------------------------------------------------------------------------
void ScriptWindow::setCursorPosition(int n,int)
{
      edit->moveCursor(QTextCursor::Start);
      for(int i=0;i<n;i++)    edit->moveCursor(QTextCursor::NextBlock);
      edit->setFocus();
}
//-----------------------------------------------------------------------------
void ScriptWindow::adjust()   {     mgl->setSize(sv->width()-5, sv->height()-5);    }
//-----------------------------------------------------------------------------
void ScriptWindow::warnChanged()
{
      if(mess->toPlainText().isEmpty())   return;
      info->setCurrentIndex(0);     ainfo->setChecked(true);
}
//-----------------------------------------------------------------------------
#ifndef USE_HDF5
void ScriptWindow::saveHDF5(const QString &fileName){}
void ScriptWindow::loadHDF5(const QString &fileName){}
//-----------------------------------------------------------------------------
#else
#include <hdf5.h>
void ScriptWindow::loadHDF5(const QString &fileName)
{
      // H5T_C_S1 - C string
      hid_t hf,hg,hd,hs,ht;
      hsize_t dims[3];
      long rank;
      hf = H5Fopen(fileName.toAscii().constData(), H5F_ACC_RDONLY, H5P_DEFAULT);
      if(!hf)     return;
      hg = H5Gopen(hf, "/");
      hsize_t num, nx, ny, nz, i;
      char name[256];
      H5Gget_num_objs(hg, &num);
      for(i=0;i<num;i++)            // TODO: add script loading
      {
            if(H5Gget_objtype_by_idx(hg, i)!=H5G_DATASET)   continue;
            H5Gget_objname_by_idx(hg, i, name, 256);
            hd = H5Dopen(hg,name);  hs = H5Dget_space(hd);
            ht = H5Dget_type(hd);
            rank = H5Sget_simple_extent_ndims(hs);
            if(H5Tget_class(ht)==H5T_STRING)    // load script
            {
                  H5Sget_simple_extent_dims(hs,dims,0);
                  char *buf = new char[dims[0]+1];
                  H5Dread(hd, H5T_C_S1, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf);
                  buf[dims[0]]=0;         // to be sure :)
                  edit->setText(buf);
                  animParseText();
                  setCurrentFile(fileName);
                  delete []buf;
                  statusBar()->showMessage(tr("Loaded document %1").arg(fileName), 2000);
                  if(mglAutoExecute)      mgl->execute();
            }
            else if(H5Tget_class(ht)==H5T_FLOAT || H5Tget_class(ht)==H5T_INTEGER)
            {
                  for(int j=0;name[j];j++)      if(!isalnum(name[j]))   name[j]='_';
                  mglVar *v = parser.AddVar(name);
                  nx = ny = nz = 1;
                  if(rank>0 && rank<=3)
                  {
                        H5Sget_simple_extent_dims(hs,dims,0);
                        switch(rank)
                        {
                              case 1:     nx=dims[0]; break;
                              case 2:     nx=dims[1]; ny=dims[0]; break;
                              case 3:     nx=dims[2]; ny=dims[1]; nz=dims[0]; break;
                        }
                        v->d.Create(nx, ny, nz);
                        H5Dread(hd, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, v->d.a);
                  }
            }
            H5Dclose(hd);     H5Sclose(hs);     H5Tclose(ht);
      }
      H5Gclose(hg);     H5Fclose(hf);
}
//-----------------------------------------------------------------------------
void ScriptWindow::saveHDF5(const QString &fileName)
{
      hid_t hf,hd,hs;
      hsize_t dims[3];
      long rank = 3;
      const char *fname = fileName.toAscii().constData();

      H5Eset_auto(0,0);
//    int res=H5Fis_hdf5(fname);
//    if(res>0)   hf = H5Fopen(fname, H5F_ACC_RDWR, H5P_DEFAULT);
//    else
      hf = H5Fcreate(fname, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
      if(hf<0)
      {
            statusBar()->showMessage(tr("Could not write to %1").arg(fileName), 2000);
            return;
      }
      {     // save script
            QString txt = edit->toPlainText();
            dims[0] = txt.length()+1;
            char *buf = new char[dims[0]+1];
            memcpy(buf, txt.toAscii().constData(), dims[0]);
            buf[dims[0]]=0;
            hs = H5Screate_simple(1, dims, 0);
            hd = H5Dcreate(hf, "mgl_script", H5T_C_S1, hs, H5P_DEFAULT);
            H5Dwrite(hd, H5T_C_S1, hs, hs, H5P_DEFAULT, buf);
            H5Dclose(hd);     H5Sclose(hs);
            delete []buf;
      }
      mglVar *v = parser.DataList;
      char name[256];
      while(v)
      {
            wcstombs(name,v->s,wcslen(v->s)+1);
            if(v->d.nz==1 && v->d.ny == 1)
            {     rank = 1;   dims[0] = v->d.nx;      }
            else if(v->d.nz==1)
            {     rank = 2;   dims[0] = v->d.ny;      dims[1] = v->d.nx;      }
            else
            {     rank = 3;   dims[0] = v->d.nz;      dims[1] = v->d.ny;      dims[2] = v->d.nx;      }
            hs = H5Screate_simple(rank, dims, 0);
            hd = H5Dcreate(hf, name, H5T_IEEE_F32LE, hs, H5P_DEFAULT);

            H5Dwrite(hd, H5T_NATIVE_FLOAT, hs, hs, H5P_DEFAULT, v->d.a);
            H5Dclose(hd);     H5Sclose(hs);
            v = v->next;
      }
      H5Fclose(hf);
      setCurrentFile(fileName);
      statusBar()->showMessage(tr("File %1 saved").arg(fileName), 2000);
      return;
}
//-----------------------------------------------------------------------------
#endif

Generated by  Doxygen 1.6.0   Back to index