<commit_before>
#include <QApplication>

#include "cmd.h"
#include "font.h"
#include "wd.h"
#include "../base/bedit.h"
#include "../base/dlog.h"
#include "../base/jsvr.h"
#include "../base/note.h"
#include "../base/state.h"
#include "../base/tedit.h"
#include "../base/term.h"

// sm does its own parsing of the wd command
extern Cmd cmd;
extern int rc;

static string smact();
static string smactive();
static string smclose();
static string smerror(string p);
static string smfocus();
static string smfont();
static string smget();
static string smgetactive();
static string smgetinputlog();
static string smgetscript(string);
static string smgettabs(QString);
static string smgetwin(string);
static string smgetwin1(Bedit *);
static string smgetwin2(Note *n);
static string smgetxywh();
static string smgetxywh1(QWidget *);
static string smopen();
static string smprompt();
static string smreplace();
static string smsave();
static string smsaveactive();
static string smsaveall();
static string smset();
static string smsetscroll(Bedit *,string);
static string smsetinputlog(string,string);
static string smsetselect(Bedit *,string);
static string smsettext(string,string);
static string smsetxywh(string,string);

// ---------------------------------------------------------------------
string sm(string c)
{
  rc=0;
  if (c=="act")
    return smact();
  if (c=="active")
    return smactive();
  if (c=="close")
    return smclose();
  if (c=="focus")
    return smfocus();
  if (c=="font")
    return smfont();
  if (c=="get")
    return smget();
  if (c=="new")
    return smopen();
  if (c=="open")
    return smopen();
  if (c=="replace")
    return smreplace();
  if (c=="save")
    return smsave();
  if (c=="set")
    return smset();
  else if (c=="prompt")
    return smprompt();
  cmd.getparms();
  return smerror("unrecognized sm command: " + c);
}

// ---------------------------------------------------------------------
string smact()
{
  cmd.getparms();
  term->smact();
  return"";
}

// ---------------------------------------------------------------------
string smactive()
{
  string p=cmd.getparms();
  QStringList opt=qsplit(p);
  if (note==0 || note->editIndex()<0)
    return smerror ("No active edit window");
  if (opt[0]!="tab")
    return smerror ("unrecognized sm command parameters: " + p);
  int ndx=opt[1].toInt();
  if (ndx<0 || ndx>=note->count())
    return smerror ("invalid tab index: " + p);
  note->setindex(ndx);
  return "";
}

// ---------------------------------------------------------------------
string smclose()
{
  string c=cmd.getid();
  string p=cmd.getparms();
  if (c=="tab") {
    if (note==0 || note->editIndex()<0)
      return smerror ("No active edit window");
    int ndx=s2q(p).toInt();
    if (ndx<0 || ndx>=note->count())
      return smerror ("invalid tab index: " + p);
    note->tabclose(ndx);
  } else if (c=="edit") {
    if (note==0)
      return smerror ("No edit window");
    note->close();
  } else if (c=="edit2") {
    if (note2==0)
      return smerror ("No edit2 window");
    note2->close();
  } else
    return smerror ("unrecognized sm command parameters: " + p);
  return "";
}

// ---------------------------------------------------------------------
string smerror(string p)
{
  rc=1;
  return p;
}

// ---------------------------------------------------------------------
string smfocus()
{
  string p=cmd.getparms();
  if (p.empty())
    return smerror("sm focus needs additional parameters");
  if (p=="term")
    term->smact();
  else if (p=="edit") {
    if (note==0 || note->editIndex()==-1)
      return smerror("No active edit window");
    note->activateWindow();
    note->raise();
    note->repaint();
  } else if (p=="edit2") {
    if (note2==0 || note2->editIndex()==-1)
      return smerror("No active edit2 window");
    setnote(note2);
    note->activateWindow();
    note->raise();
    note->repaint();
  } else
    return smerror("unrecognized sm command: focus " + p);
  return "";
}

// ---------------------------------------------------------------------
string smfont()
{
  string p=cmd.getparms();
  if (!p.empty()) {
    Font *fnt = new Font(p);
    if (fnt->error) {
      delete fnt;
      return smerror("unrecognized sm command: font " + p);
    } else {
      config.Font=fnt->font;
      delete fnt;
    }
  }
  fontset(config.Font);
  return "";
}

// ---------------------------------------------------------------------
string smget()
{
  string p=cmd.getparms();
  if (p.size()==0)
    return smerror("sm get needs additional parameters");
  if (p=="active")
    return smgetactive();
  if (p=="term" || p=="edit" || p=="edit2")
    return smgetwin(p);
  if (p=="inputlog")
    return smgetinputlog();
  if (p=="xywh")
    return smgetxywh();
  QStringList s=qsplit(p);
  if (s[0]=="tabs") {
    if(s.size()<=1)
      return smerror("sm command requires another parameter: get tabs");
    else
      return smgettabs(s[1]);
  }
  return smerror("unrecognized sm command: get " + p);
}

// ---------------------------------------------------------------------
string smgetactive()
{
  rc=-1;
  return (note && ActiveWindows.indexOf(note)<ActiveWindows.indexOf(term))
         ? "edit" : "term";
}

// ---------------------------------------------------------------------
string smgetinputlog()
{
  rc=-1;
  return q2s(dlog_get());
}

// ---------------------------------------------------------------------
string smgetscript(string f)
{
  return dors(">{.getscripts_j_ '" + f + "'");
}

// ---------------------------------------------------------------------
string smgettabs(QString p)
{
  Note *n;
  if (p=="edit") {
    if (note==0)
      return smerror("No active edit window");
    n=note;
  } else if (p=="edit2") {
    if (note2==0)
      return smerror("No active edit2 window");
    n=note2;
  } else
    return smerror("sm get tabs needs edit or edit2 parameter");
  rc=-2;
  return n->gettabstate();
}

// ---------------------------------------------------------------------
string smgetwin(string p)
{
  rc=-2;
  if (p=="term")
    return smgetwin1(tedit);
  if (p=="edit") {
    if (note==0)
      return smerror("No active edit window");
    return smgetwin2(note);
  }
  if (note2==0)
    return smerror("No active edit2 window");
  return smgetwin2(note2);
}

// ---------------------------------------------------------------------
string smgetwin1(Bedit *t)
{
  string r;
  if (t==0) {
    r+=spair("text",(string)"");
    r+=spair("select",(string)"");
  } else {
    QTextCursor c=t->textCursor();
    int b=c.selectionStart();
    int e=c.selectionEnd();
    r+=spair("text",t->toPlainText());
    r+=spair("select",QString::number(b)+" "+QString::number(e));
  }
  return r;
}

// ---------------------------------------------------------------------
string smgetwin2(Note *n)
{
  if (n->editIndex()==-1)
    return smgetwin1((Bedit *)0);
  string r=smgetwin1((Bedit *)n->editPage());
  r+=spair("file",n->editFile());
  return r;
}

// ---------------------------------------------------------------------
string smgetxywh()
{
  rc=-2;
  string r;
  r+=spair("text",smgetxywh1(term));
  if (note)
    r+=spair("edit",smgetxywh1(note));
  if (note2)
    r+=spair("edit2",smgetxywh1(note2));
  return r;
}

// ---------------------------------------------------------------------
string smgetxywh1(QWidget *w)
{
  QPoint p=w->pos();
  QSize z=w->size();
  return q2s(QString::number(p.rx())+" "+QString::number(p.ry())+" "+
             QString::number(z.width())+" "+QString::number(z.height()));
}

// ---------------------------------------------------------------------
string smopen()
{
  string c=cmd.getid();
  string p=cmd.getparms();

  if (c=="edit")
    term->vieweditor();
  if (c=="edit2") {
    if (note==0)
      return smerror("no edit window open");
    note->on_winotherAct_triggered();
  }
  if (c=="edit" || c=="edit2")
    return "";
  if (c!="tab") {
    return smerror("unrecognized sm command: open " + c);
  }
  term->vieweditor();
  if (p.empty())
    note->newtemp();
  else {
    QString f=s2q(smgetscript(p));
    if (!cfexist(f))
      return smerror("file not found: " + q2s(f));
    note->fileopen(f);
  }
  rc=-1;
  return i2s(note->editIndex());
}

// ---------------------------------------------------------------------
string smprompt()
{
  string p=cmd.getparms();
  term->smprompt(s2q(p));
  return"";
}

// ---------------------------------------------------------------------
string smreplace()
{
  string c=cmd.getid();
  string p=cmd.getparms();
  if (note==0 || note->editIndex()<0)
    return smerror ("No active edit window");
  if (c!="edit")
    return smerror("unrecognized sm command: replace " + c);
  if (p.empty())
    return smerror("replace needs 2 parameters: edit filename");
  QString f=s2q(smgetscript(p));
  if (!cfexist(f))
    return smerror("file not found: " + q2s(f));
  note->filereplace(f);
  return"";
}

// ---------------------------------------------------------------------
string smsave()
{
  string p=cmd.getparms();
  if (note==0)
    return smerror("No active edit window");
  if (p.empty())
    return smerror("sm save parameter not given");
  if (p=="edit")
    return smsaveactive();
  if (p=="tabs")
    return smsaveall();
  return smerror("sm save parameter should be 'edit' or 'tabs': " + p);
}

// ---------------------------------------------------------------------
string smsaveactive()
{
  note->savecurrent();
  return "";
}

// ---------------------------------------------------------------------
string smsaveall()
{
  note->saveall();
  return "";
}

// ---------------------------------------------------------------------
string smset()
{
  string p=cmd.getid();
  if (p.empty())
    return smerror("sm set parameters not given");

  string c=cmd.getid();
  if (c.empty())
    return smerror("sm set " + p + " parameters not given");
  string q=cmd.getparms();
  Bedit *e;

  if (p=="term") {
    e=tedit;
  } else if (p=="edit") {
    if (note==0)
      return smerror("No active edit window");
    e=(Bedit *)note->editPage();
  } else if (p=="edit2") {
    if (note2==0)
      return smerror("No active edit2 window");
    e=(Bedit *)note2->editPage();
  } else if (p=="inputlog")
    return smsetinputlog(c,q);
  else
    return smerror("unrecognized sm command: set " + p);

  if (e==0 && (c=="scroll" || c=="select" || c=="text"))
    return smerror("no edit window for sm command: set " + c);

  if (p=="term" && (c=="scroll" || c=="select"))
    return smerror("command applies only to an edit window: " + c);

  if (c=="scroll")
    return smsetscroll(e,q);
  if (c=="select")
    return smsetselect(e,q);
  if (c=="text")
    return smsettext(p,q);
  if (c=="xywh")
    return smsetxywh(p,q);

  return smerror("unrecognized sm command: set " + p + " " + q);
}

// ---------------------------------------------------------------------
string smsetinputlog(string c,string q)
{
  if (c!="text")
    return smerror("unrecognized sm command: set inputlog " + c + "..." );
  dlog_set(s2q(q));
  return "";
}

// ---------------------------------------------------------------------
// set vertical scroll
string smsetscroll(Bedit *e, string q)
{
  QList<int> s=qsl2intlist(qsplit(q));
  if (s.size()!= 1)
    return smerror("sm set scroll should have a single parameter of scroll size");
  e->settop(s[0]);
  return"";
}

// ---------------------------------------------------------------------
string smsetselect(Bedit *e, string q)
{
  QList<int> s=qsl2intlist(qsplit(q));
  if (s.size()!= 2)
    return smerror("sm set select should have begin and end parameters");
  int m=e->toPlainText().size();
  if (s[1]==-1) s[1]=m;
  s[1]=qMin(m,s[1]);
  s[0]=qMin(s[0],s[1]);
  e->setselect(s[0],s[1]-s[0]);
  return"";
}

// ---------------------------------------------------------------------
string smsettext(string p,string s)
{
  QString t=s2q(s);
  if (p=="term")
    tedit->setPlainText(t);
  else if (p=="edit")
    note->settext(t);
  else
    note2->settext(t);
  return"";
}

// ---------------------------------------------------------------------
string smsetxywh(string m,string q)
{
  QWidget *w;
  if (m=="term")
    w=term;
  else if (m=="edit")
    w=note;
  else
    w=note2;
  QList<int> s=qsl2intlist(qsplit(q));
  QPoint p=w->pos();
  QSize z=w->size();
  if (s[0]==-1) s[0]=p.rx();
  if (s[1]==-1) s[1]=p.ry();
  if (s[2]==-1) s[2]=z.width();
  if (s[3]==-1) s[3]=z.height();
  w->move(s[0],s[1]);
  w->resize(s[2],s[3]);
  return"";
}

<commit_msg>add sm get termcwh for term character width and height<commit_after>
#include <QApplication>

#include "cmd.h"
#include "font.h"
#include "wd.h"
#include "../base/bedit.h"
#include "../base/dlog.h"
#include "../base/jsvr.h"
#include "../base/note.h"
#include "../base/state.h"
#include "../base/tedit.h"
#include "../base/term.h"

// sm does its own parsing of the wd command
extern Cmd cmd;
extern int rc;

static string smact();
static string smactive();
static string smclose();
static string smerror(string p);
static string smfocus();
static string smfont();
static string smget();
static string smgetactive();
static string smgetinputlog();
static string smgetscript(string);
static string smgettabs(QString);
static string smgettermcwh();
static string smgetwin(string);
static string smgetwin1(Bedit *);
static string smgetwin2(Note *n);
static string smgetxywh();
static string smgetxywh1(QWidget *);
static string smopen();
static string smprompt();
static string smreplace();
static string smsave();
static string smsaveactive();
static string smsaveall();
static string smset();
static string smsetscroll(Bedit *,string);
static string smsetinputlog(string,string);
static string smsetselect(Bedit *,string);
static string smsettext(string,string);
static string smsetxywh(string,string);

// ---------------------------------------------------------------------
string sm(string c)
{
  rc=0;
  if (c=="act")
    return smact();
  if (c=="active")
    return smactive();
  if (c=="close")
    return smclose();
  if (c=="focus")
    return smfocus();
  if (c=="font")
    return smfont();
  if (c=="get")
    return smget();
  if (c=="new")
    return smopen();
  if (c=="open")
    return smopen();
  if (c=="replace")
    return smreplace();
  if (c=="save")
    return smsave();
  if (c=="set")
    return smset();
  else if (c=="prompt")
    return smprompt();
  cmd.getparms();
  return smerror("unrecognized sm command: " + c);
}

// ---------------------------------------------------------------------
string smact()
{
  cmd.getparms();
  term->smact();
  return"";
}

// ---------------------------------------------------------------------
string smactive()
{
  string p=cmd.getparms();
  QStringList opt=qsplit(p);
  if (note==0 || note->editIndex()<0)
    return smerror ("No active edit window");
  if (opt[0]!="tab")
    return smerror ("unrecognized sm command parameters: " + p);
  int ndx=opt[1].toInt();
  if (ndx<0 || ndx>=note->count())
    return smerror ("invalid tab index: " + p);
  note->setindex(ndx);
  return "";
}

// ---------------------------------------------------------------------
string smclose()
{
  string c=cmd.getid();
  string p=cmd.getparms();
  if (c=="tab") {
    if (note==0 || note->editIndex()<0)
      return smerror ("No active edit window");
    int ndx=s2q(p).toInt();
    if (ndx<0 || ndx>=note->count())
      return smerror ("invalid tab index: " + p);
    note->tabclose(ndx);
  } else if (c=="edit") {
    if (note==0)
      return smerror ("No edit window");
    note->close();
  } else if (c=="edit2") {
    if (note2==0)
      return smerror ("No edit2 window");
    note2->close();
  } else
    return smerror ("unrecognized sm command parameters: " + p);
  return "";
}

// ---------------------------------------------------------------------
string smerror(string p)
{
  rc=1;
  return p;
}

// ---------------------------------------------------------------------
string smfocus()
{
  string p=cmd.getparms();
  if (p.empty())
    return smerror("sm focus needs additional parameters");
  if (p=="term")
    term->smact();
  else if (p=="edit") {
    if (note==0 || note->editIndex()==-1)
      return smerror("No active edit window");
    note->activateWindow();
    note->raise();
    note->repaint();
  } else if (p=="edit2") {
    if (note2==0 || note2->editIndex()==-1)
      return smerror("No active edit2 window");
    setnote(note2);
    note->activateWindow();
    note->raise();
    note->repaint();
  } else
    return smerror("unrecognized sm command: focus " + p);
  return "";
}

// ---------------------------------------------------------------------
string smfont()
{
  string p=cmd.getparms();
  if (!p.empty()) {
    Font *fnt = new Font(p);
    if (fnt->error) {
      delete fnt;
      return smerror("unrecognized sm command: font " + p);
    } else {
      config.Font=fnt->font;
      delete fnt;
    }
  }
  fontset(config.Font);
  return "";
}

// ---------------------------------------------------------------------
string smget()
{
  string p=cmd.getparms();
  if (p.size()==0)
    return smerror("sm get needs additional parameters");
  if (p=="active")
    return smgetactive();
  if (p=="term" || p=="edit" || p=="edit2")
    return smgetwin(p);
  if (p=="termcwh")
    return smgettermcwh();
  if (p=="inputlog")
    return smgetinputlog();
  if (p=="xywh")
    return smgetxywh();
  QStringList s=qsplit(p);
  if (s[0]=="tabs") {
    if(s.size()<=1)
      return smerror("sm command requires another parameter: get tabs");
    else
      return smgettabs(s[1]);
  }
  return smerror("unrecognized sm command: get " + p);
}

// ---------------------------------------------------------------------
string smgetactive()
{
  rc=-1;
  return (note && ActiveWindows.indexOf(note)<ActiveWindows.indexOf(term))
         ? "edit" : "term";
}

// ---------------------------------------------------------------------
string smgetinputlog()
{
  rc=-1;
  return q2s(dlog_get());
}

// ---------------------------------------------------------------------
string smgetscript(string f)
{
  return dors(">{.getscripts_j_ '" + f + "'");
}

// ---------------------------------------------------------------------
string smgettabs(QString p)
{
  Note *n;
  if (p=="edit") {
    if (note==0)
      return smerror("No active edit window");
    n=note;
  } else if (p=="edit2") {
    if (note2==0)
      return smerror("No active edit2 window");
    n=note2;
  } else
    return smerror("sm get tabs needs edit or edit2 parameter");
  rc=-2;
  return n->gettabstate();
}

// ---------------------------------------------------------------------
string smgettermcwh() {
  rc=-1;
  QSize z=tedit->size();
  QFontMetrics fm=QFontMetrics(config.Font,0);
  int sb=app->style()->pixelMetric(QStyle::PM_ScrollBarExtent);
  sb+=4; // padding
  int fh=fm.height();
  int fw=fm.width("X");
  int ch=(z.height()-sb)/fh;
  int cw=(z.width()-sb)/fw;
  return q2s(QString::number(cw)+" "+QString::number(ch));
}

// ---------------------------------------------------------------------
string smgetwin(string p)
{
  rc=-2;
  if (p=="term")
    return smgetwin1(tedit);
  if (p=="edit") {
    if (note==0)
      return smerror("No active edit window");
    return smgetwin2(note);
  }
  if (note2==0)
    return smerror("No active edit2 window");
  return smgetwin2(note2);
}

// ---------------------------------------------------------------------
string smgetwin1(Bedit *t)
{
  string r;
  if (t==0) {
    r+=spair("text",(string)"");
    r+=spair("select",(string)"");
  } else {
    QTextCursor c=t->textCursor();
    int b=c.selectionStart();
    int e=c.selectionEnd();
    r+=spair("text",t->toPlainText());
    r+=spair("select",QString::number(b)+" "+QString::number(e));
  }
  return r;
}

// ---------------------------------------------------------------------
string smgetwin2(Note *n)
{
  if (n->editIndex()==-1)
    return smgetwin1((Bedit *)0);
  string r=smgetwin1((Bedit *)n->editPage());
  r+=spair("file",n->editFile());
  return r;
}

// ---------------------------------------------------------------------
string smgetxywh()
{
  rc=-2;
  string r;
  r+=spair("text",smgetxywh1(term));
  if (note)
    r+=spair("edit",smgetxywh1(note));
  if (note2)
    r+=spair("edit2",smgetxywh1(note2));
  return r;
}

// ---------------------------------------------------------------------
string smgetxywh1(QWidget *w)
{
  QPoint p=w->pos();
  QSize z=w->size();
  return q2s(QString::number(p.rx())+" "+QString::number(p.ry())+" "+
             QString::number(z.width())+" "+QString::number(z.height()));
}

// ---------------------------------------------------------------------
string smopen()
{
  string c=cmd.getid();
  string p=cmd.getparms();

  if (c=="edit")
    term->vieweditor();
  if (c=="edit2") {
    if (note==0)
      return smerror("no edit window open");
    note->on_winotherAct_triggered();
  }
  if (c=="edit" || c=="edit2")
    return "";
  if (c!="tab") {
    return smerror("unrecognized sm command: open " + c);
  }
  term->vieweditor();
  if (p.empty())
    note->newtemp();
  else {
    QString f=s2q(smgetscript(p));
    if (!cfexist(f))
      return smerror("file not found: " + q2s(f));
    note->fileopen(f);
  }
  rc=-1;
  return i2s(note->editIndex());
}

// ---------------------------------------------------------------------
string smprompt()
{
  string p=cmd.getparms();
  term->smprompt(s2q(p));
  return"";
}

// ---------------------------------------------------------------------
string smreplace()
{
  string c=cmd.getid();
  string p=cmd.getparms();
  if (note==0 || note->editIndex()<0)
    return smerror ("No active edit window");
  if (c!="edit")
    return smerror("unrecognized sm command: replace " + c);
  if (p.empty())
    return smerror("replace needs 2 parameters: edit filename");
  QString f=s2q(smgetscript(p));
  if (!cfexist(f))
    return smerror("file not found: " + q2s(f));
  note->filereplace(f);
  return"";
}

// ---------------------------------------------------------------------
string smsave()
{
  string p=cmd.getparms();
  if (note==0)
    return smerror("No active edit window");
  if (p.empty())
    return smerror("sm save parameter not given");
  if (p=="edit")
    return smsaveactive();
  if (p=="tabs")
    return smsaveall();
  return smerror("sm save parameter should be 'edit' or 'tabs': " + p);
}

// ---------------------------------------------------------------------
string smsaveactive()
{
  note->savecurrent();
  return "";
}

// ---------------------------------------------------------------------
string smsaveall()
{
  note->saveall();
  return "";
}

// ---------------------------------------------------------------------
string smset()
{
  string p=cmd.getid();
  if (p.empty())
    return smerror("sm set parameters not given");

  string c=cmd.getid();
  if (c.empty())
    return smerror("sm set " + p + " parameters not given");
  string q=cmd.getparms();
  Bedit *e;

  if (p=="term") {
    e=tedit;
  } else if (p=="edit") {
    if (note==0)
      return smerror("No active edit window");
    e=(Bedit *)note->editPage();
  } else if (p=="edit2") {
    if (note2==0)
      return smerror("No active edit2 window");
    e=(Bedit *)note2->editPage();
  } else if (p=="inputlog")
    return smsetinputlog(c,q);
  else
    return smerror("unrecognized sm command: set " + p);

  if (e==0 && (c=="scroll" || c=="select" || c=="text"))
    return smerror("no edit window for sm command: set " + c);

  if (p=="term" && (c=="scroll" || c=="select"))
    return smerror("command applies only to an edit window: " + c);

  if (c=="scroll")
    return smsetscroll(e,q);
  if (c=="select")
    return smsetselect(e,q);
  if (c=="text")
    return smsettext(p,q);
  if (c=="xywh")
    return smsetxywh(p,q);

  return smerror("unrecognized sm command: set " + p + " " + q);
}

// ---------------------------------------------------------------------
string smsetinputlog(string c,string q)
{
  if (c!="text")
    return smerror("unrecognized sm command: set inputlog " + c + "..." );
  dlog_set(s2q(q));
  return "";
}

// ---------------------------------------------------------------------
// set vertical scroll
string smsetscroll(Bedit *e, string q)
{
  QList<int> s=qsl2intlist(qsplit(q));
  if (s.size()!= 1)
    return smerror("sm set scroll should have a single parameter of scroll size");
  e->settop(s[0]);
  return"";
}

// ---------------------------------------------------------------------
string smsetselect(Bedit *e, string q)
{
  QList<int> s=qsl2intlist(qsplit(q));
  if (s.size()!= 2)
    return smerror("sm set select should have begin and end parameters");
  int m=e->toPlainText().size();
  if (s[1]==-1) s[1]=m;
  s[1]=qMin(m,s[1]);
  s[0]=qMin(s[0],s[1]);
  e->setselect(s[0],s[1]-s[0]);
  return"";
}

// ---------------------------------------------------------------------
string smsettext(string p,string s)
{
  QString t=s2q(s);
  if (p=="term")
    tedit->setPlainText(t);
  else if (p=="edit")
    note->settext(t);
  else
    note2->settext(t);
  return"";
}

// ---------------------------------------------------------------------
string smsetxywh(string m,string q)
{
  QWidget *w;
  if (m=="term")
    w=term;
  else if (m=="edit")
    w=note;
  else
    w=note2;
  QList<int> s=qsl2intlist(qsplit(q));
  QPoint p=w->pos();
  QSize z=w->size();
  if (s[0]==-1) s[0]=p.rx();
  if (s[1]==-1) s[1]=p.ry();
  if (s[2]==-1) s[2]=z.width();
  if (s[3]==-1) s[3]=z.height();
  w->move(s[0],s[1]);
  w->resize(s[2],s[3]);
  return"";
}

<|endoftext|>


<commit_before>#include "LLVMCodeGenerator.h"

using namespace std;
using namespace llvm;
using namespace codegen;

void LLVMCodeGenerator::visit(common::Function &Node) {
    // Create function and entry block
    auto Ty = getFuncType(Node.Signature);
    CurFunc = llvm::Function::Create(getFuncType(Node.Signature),
                                     llvm::Function::ExternalLinkage, Node.Id,
                                     Module.get());
    CurEntry = BasicBlock::Create(Ctx, "entry", CurFunc);

    // Create error block
    CurErrBlock = BasicBlock::Create(Ctx, "error", CurFunc);
    Builder.SetInsertPoint(CurErrBlock);
    Builder.CreateRet(UndefValue::get(CurFunc->getReturnType()));

    // Setup return block and phi node
    CurRetBlock = BasicBlock::Create(Ctx, "ret", CurFunc);
    Builder.SetInsertPoint(CurRetBlock);

    if (CurFunc->getReturnType()->getTypeID() != llvm::Type::TypeID::VoidTyID) {
        CurPhiNode = Builder.CreatePHI(CurFunc->getReturnType(),
                                       (unsigned) Node.Cases.size(), "rettmp");

        // Create ret instruction
        Builder.CreateRet(CurPhiNode);
    } else {
        Builder.CreateRetVoid();
    }

    // Setup names for arguments
    auto ArgId = 0;
    for (auto &Arg : CurFunc->args()) {
        Arg.setName("_arg" + to_string(ArgId++));
        Args.push_back(&Arg);
    }

    // Setup case and pattern blocks
    CaseBlocks.clear();
    PatVecBlocks.clear();
    int PatId, CaseId = 0;
    for (auto &Case : Node.Cases) {
        PatId = 0;
        auto PatVecBlock = vector<BasicBlock *>();
        for (auto &Pattern : Case->Patterns) {
            PatVecBlock.push_back(BasicBlock::Create(
                Ctx,
                "case" + to_string(CaseId) + "_pattern" + to_string(PatId++),
                CurFunc));
        }
        PatVecBlocks.push_back(PatVecBlock);

        CaseBlocks.push_back(BasicBlock::Create(
            Ctx, "case" + to_string(CaseId++), CurFunc));
    }

    // Visit cases
    for (CurCase = Node.Cases.cbegin(), CurCaseBlock = CaseBlocks.cbegin(),
        LastCaseBlock = CaseBlocks.cend(),
        CurPatVecBlock = PatVecBlocks.cbegin();
         CurCase != Node.Cases.cend();
         ++CurCase, ++CurCaseBlock, ++CurPatVecBlock) {
        (*CurCase)->accept(*this);
    }

    // Make entry point to first block
    Builder.SetInsertPoint(CurEntry);
    BasicBlock *FirstBlock;
    if (PatVecBlocks[0].empty())
        FirstBlock = CaseBlocks[0];
    else
        FirstBlock = PatVecBlocks[0][0];
    Builder.CreateBr(FirstBlock);

    verifyFunction(*CurFunc);
}

void LLVMCodeGenerator::visit(common::Case &Node) {

    BasicBlock *TrueBlock;
    BasicBlock *FalseBlock;

    CtxVals.clear();
    for (CurPat = Node.Patterns.cbegin(), CurArg = Args.cbegin(),
        CurPatBlock = CurPatVecBlock->cbegin(),
        LastPatBlock = CurPatVecBlock->cend();
         CurPat != Node.Patterns.cend(); ++CurPat, ++CurArg, ++CurPatBlock) {

        if (next(CurPatBlock) != LastPatBlock)
            TrueBlock = *next(CurPatBlock);
        else
            TrueBlock = *CurCaseBlock;

        if (next(CurCaseBlock) != LastCaseBlock)
            FalseBlock = (*next(CurPatVecBlock))[0];
        else
            FalseBlock = CurErrBlock;

        Builder.SetInsertPoint(*CurPatBlock);
        (*CurPat)->accept(*this);

        // Create condition
        Builder.CreateCondBr(CurVal, TrueBlock, FalseBlock);
    }

    // Generate expression in case block
    Builder.SetInsertPoint(*CurCaseBlock);
    Node.Expr->accept(*this);

    //auto Ty1 = CurPhiNode->getType();
    //auto Ty2 = CurVal->getType();

    //auto Arr1 = CurVal->getType()->getPointerElementType()->getArrayNumElements();
    //auto Arr2 = CurPhiNode->getType()->getPointerElementType()->getArrayNumElements();

    // Ignore expression type if function is void
    if (CurFunc->getReturnType()->getTypeID() != llvm::Type::TypeID::VoidTyID)
        CurPhiNode->addIncoming(CurVal, *CurCaseBlock);

    // Add return value to phi node
    Builder.CreateBr(CurRetBlock);
}
<commit_msg>llvm: simplify case loop<commit_after>#include "LLVMCodeGenerator.h"

using namespace std;
using namespace llvm;
using namespace codegen;

void LLVMCodeGenerator::visit(common::Function &Node) {
    // Create function and entry block
    auto Ty = getFuncType(Node.Signature);
    CurFunc = llvm::Function::Create(getFuncType(Node.Signature),
                                     llvm::Function::ExternalLinkage, Node.Id,
                                     Module.get());
    CurEntry = BasicBlock::Create(Ctx, "entry", CurFunc);

    // Create error block
    CurErrBlock = BasicBlock::Create(Ctx, "error", CurFunc);
    Builder.SetInsertPoint(CurErrBlock);
    Builder.CreateRet(UndefValue::get(CurFunc->getReturnType()));

    // Setup return block and phi node
    CurRetBlock = BasicBlock::Create(Ctx, "ret", CurFunc);
    Builder.SetInsertPoint(CurRetBlock);

    if (CurFunc->getReturnType()->getTypeID() != llvm::Type::TypeID::VoidTyID) {
        CurPhiNode = Builder.CreatePHI(CurFunc->getReturnType(),
                                       (unsigned) Node.Cases.size(), "rettmp");

        // Create ret instruction
        Builder.CreateRet(CurPhiNode);
    } else {
        Builder.CreateRetVoid();
    }

    // Setup names for arguments
    auto ArgId = 0;
    for (auto &Arg : CurFunc->args()) {
        Arg.setName("_arg" + to_string(ArgId++));
        Args.push_back(&Arg);
    }

    // Setup case and pattern blocks
    CaseBlocks.clear();
    PatVecBlocks.clear();
    for (size_t i = 0; i < Node.Cases.size(); ++i) {
        auto PatVecBlock = vector<BasicBlock *>();
        for (size_t j = 0; j < Node.Cases[i]->Patterns.size(); ++j) {
            PatVecBlock.push_back(BasicBlock::Create(
                Ctx,
                "case" + to_string(i) + "_pattern" + to_string(j),
                CurFunc));
        }
        PatVecBlocks.push_back(PatVecBlock);

        CaseBlocks.push_back(BasicBlock::Create(
            Ctx, "case" + to_string(i), CurFunc));
    }

    // Visit cases
    for (CurCase = Node.Cases.cbegin(), CurCaseBlock = CaseBlocks.cbegin(),
        LastCaseBlock = CaseBlocks.cend(),
        CurPatVecBlock = PatVecBlocks.cbegin();
         CurCase != Node.Cases.cend();
         ++CurCase, ++CurCaseBlock, ++CurPatVecBlock) {
        (*CurCase)->accept(*this);
    }

    // Make entry point to first block
    Builder.SetInsertPoint(CurEntry);
    BasicBlock *FirstBlock;
    if (PatVecBlocks[0].empty())
        FirstBlock = CaseBlocks[0];
    else
        FirstBlock = PatVecBlocks[0][0];
    Builder.CreateBr(FirstBlock);

    verifyFunction(*CurFunc);
}

void LLVMCodeGenerator::visit(common::Case &Node) {

    BasicBlock *TrueBlock;
    BasicBlock *FalseBlock;

    CtxVals.clear();
    for (CurPat = Node.Patterns.cbegin(), CurArg = Args.cbegin(),
        CurPatBlock = CurPatVecBlock->cbegin(),
        LastPatBlock = CurPatVecBlock->cend();
         CurPat != Node.Patterns.cend(); ++CurPat, ++CurArg, ++CurPatBlock) {

        if (next(CurPatBlock) != LastPatBlock)
            TrueBlock = *next(CurPatBlock);
        else
            TrueBlock = *CurCaseBlock;

        if (next(CurCaseBlock) != LastCaseBlock)
            FalseBlock = (*next(CurPatVecBlock))[0];
        else
            FalseBlock = CurErrBlock;

        Builder.SetInsertPoint(*CurPatBlock);
        (*CurPat)->accept(*this);

        // Create condition
        Builder.CreateCondBr(CurVal, TrueBlock, FalseBlock);
    }

    // Generate expression in case block
    Builder.SetInsertPoint(*CurCaseBlock);
    Node.Expr->accept(*this);

    //auto Ty1 = CurPhiNode->getType();
    //auto Ty2 = CurVal->getType();

    //auto Arr1 = CurVal->getType()->getPointerElementType()->getArrayNumElements();
    //auto Arr2 = CurPhiNode->getType()->getPointerElementType()->getArrayNumElements();

    // Ignore expression type if function is void
    if (CurFunc->getReturnType()->getTypeID() != llvm::Type::TypeID::VoidTyID)
        CurPhiNode->addIncoming(CurVal, *CurCaseBlock);

    // Add return value to phi node
    Builder.CreateBr(CurRetBlock);
}
<|endoftext|>


<commit_before>//---------------------------------------------------------
// Copyright 2018 Ontario Institute for Cancer Research
// Written by Jared Simpson (jared.simpson@oicr.on.ca)
//---------------------------------------------------------
//
// nanopolish_vcf2fasta - write a new genome sequence
// by introducing variants from a set of vcf files
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <vector>
#include <map>
#include <inttypes.h>
#include <assert.h>
#include <math.h>
#include <sys/time.h>
#include <algorithm>
#include <sstream>
#include <set>
#include <omp.h>
#include <getopt.h>
#include <fast5.hpp>
#include "htslib/faidx.h"
#include "nanopolish_common.h"
#include "nanopolish_variant.h"
#include "nanopolish_eventalign.h"
#include "nanopolish_haplotype.h"

//
// Getopt
//
#define SUBPROGRAM "vcf2fasta"

static const char *VCF2FASTA_VERSION_MESSAGE =
SUBPROGRAM " Version " PACKAGE_VERSION "\n"
"Written by Jared Simpson.\n"
"\n"
"Copyright 2018 Ontario Institute for Cancer Research\n";

static const char *VCF2FASTA_USAGE_MESSAGE =
"Usage: " PACKAGE_NAME " " SUBPROGRAM " -g draft.fa segment1.vcf segment2.vcf ...\n"
"Write a new genome sequence by introducing variants from the input files\n"
"\n"
"  -v, --verbose                        display verbose output\n"
"      --version                        display version\n"
"      --help                           display this help and exit\n"
"  -g, --genome=FILE                    the input genome is in FILE\n"
"  -f, --fofn=FILE                      read the list of VCF files to use from FILE\n"
"      --skip-checks                    skip the sanity checks\n"
"\nReport bugs to " PACKAGE_BUGREPORT "\n\n";

namespace opt
{
    static unsigned int verbose;
    static std::vector<std::string> input_vcf_files;
    static std::string vcf_fofn;
    static std::string genome_file;
    static bool skip_checks = false;
}

static const char* shortopts = "g:f:v";

enum { OPT_HELP = 1, OPT_VERSION, OPT_SKIP_CHECKS };

static const struct option longopts[] = {
    { "verbose",       no_argument,       NULL, 'v' },
    { "help",          no_argument,       NULL, OPT_HELP },
    { "version",       no_argument,       NULL, OPT_VERSION },
    { "skip-checks",   no_argument,       NULL, OPT_SKIP_CHECKS },
    { "genome",        required_argument, NULL, 'g' },
    { "fofn",          required_argument, NULL, 'f' },
    { NULL, 0, NULL, 0 }
};

void parse_vcf2fasta_options(int argc, char** argv)
{
    bool die = false;
    for (char c; (c = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1;) {
        std::istringstream arg(optarg != NULL ? optarg : "");
        switch (c) {
            case '?': die = true; break;
            case 'v': opt::verbose++; break;
            case 'g': arg >> opt::genome_file; break;
            case 'f': arg >> opt::vcf_fofn; break;
            case OPT_SKIP_CHECKS: opt::skip_checks = true; break;
            case OPT_HELP:
                std::cout << VCF2FASTA_USAGE_MESSAGE;
                exit(EXIT_SUCCESS);
            case OPT_VERSION:
                std::cout << VCF2FASTA_VERSION_MESSAGE;
                exit(EXIT_SUCCESS);
        }
    }

    if(opt::genome_file.empty()) {
        std::cerr << SUBPROGRAM ": -g/--genome file is required\n";
        die = true;
    }

    if (argc - optind < 1 && opt::vcf_fofn.empty()) {
        std::cerr << SUBPROGRAM ": not enough arguments\n";
        die = true;
    }

    if (die)
    {
        std::cout << "\n" << VCF2FASTA_USAGE_MESSAGE;
        exit(EXIT_FAILURE);
    }

    for(; optind < argc; ++optind) {
        opt::input_vcf_files.push_back(argv[optind]);
    }

    // add files from the fofn
    if(!opt::vcf_fofn.empty()) {
        std::ifstream infile(opt::vcf_fofn);
        std::string line;
        while(getline(infile, line)) {
            opt::input_vcf_files.push_back(line);
        }
    }
}

int vcf2fasta_main(int argc, char** argv)
{
    parse_vcf2fasta_options(argc, argv);

    // Read genome file
    faidx_t *fai = fai_load(opt::genome_file.c_str());

    // Read VCF files and gather variants for each contig and the polishing window coordinates
    std::map<std::string, std::vector<Variant>> variants_by_contig;
    std::map<std::string, std::vector<std::pair<int, int>>> windows_by_contig;

    for(const auto& filename : opt::input_vcf_files) {

        std::string window_str;
        std::vector<Variant> out;
        std::ifstream infile(filename);
        std::string line;
        while(getline(infile, line)) {

            // parse header
            if(line[0] == '#') {

                // check for window coordinates
                std::string window_key = "nanopolish_window=";
                size_t key_pos = line.find(window_key);
                if(key_pos != std::string::npos) {
                    window_str = line.substr(key_pos + window_key.size());
                }
            } else {
                Variant v(line);
                variants_by_contig[v.ref_name].push_back(v);
            }
        }

        if(window_str.empty()) {
            fprintf(stderr, "error: could not detect polishing window from input file %s\n", filename.c_str());
            exit(EXIT_FAILURE);
        }

        std::string window_contig;
        int window_start, window_end;
        parse_region_string(window_str, window_contig, window_start, window_end);
        windows_by_contig[window_contig].push_back(std::make_pair(window_start, window_end));
    }

    size_t n_contigs = faidx_nseq(fai);

    for(size_t contig_idx = 0; contig_idx < n_contigs; ++contig_idx) {
        std::string contig = faidx_iseq(fai, contig_idx);
        int contig_length = faidx_seq_len(fai, contig.c_str());

        // Confirm that all windows on this contig have been polished
        bool window_check_ok = true;
        auto& windows = windows_by_contig[contig];
        std::sort(windows.begin(), windows.end());

        if(!opt::skip_checks) {
            if(windows.empty()) {
                fprintf(stderr, "error: no polishing windows found for %s\n", contig.c_str());
                exit(EXIT_FAILURE);
            }

            for(size_t window_idx = 1; window_idx < windows.size(); ++window_idx) {
                int prev_start = windows[window_idx - 1].first;
                int prev_end = windows[window_idx - 1].second;
                int curr_start = windows[window_idx].first;
                int curr_end = windows[window_idx].second;
                if(curr_start > prev_end) {
                    fprintf(stderr, "error: adjacent polishing windows do not overlap (%d-%d and %d-%d)\n", prev_start, prev_end, curr_start, curr_end);
                    window_check_ok = false;
                }
            }

            // check the first and last windows of the contig were polished
            if(windows[0].first != 0) {
                fprintf(stderr, "error: first %d bases are not covered by a polished window for contig %s.\n", windows[0].first, contig.c_str());
                window_check_ok = false;
            }

            int end_gap = contig_length - windows.back().second;
            if(end_gap > 500) {
                fprintf(stderr, "error: last %d bases are not covered by a polished window for contig %s.\n", end_gap, contig.c_str());
                window_check_ok = false;
            }
        }

        if(!window_check_ok) {
            fprintf(stderr, "error: one or more polishing windows are missing. Please check that all nanopolish variants --consensus jobs ran to completion\n");
            exit(EXIT_FAILURE);
        }

        int length;
        char* seq = fai_fetch(fai, contig.c_str(), &length);
        if(length < 0) {
            fprintf(stderr, "error: could not fetch contig %s\n", contig.c_str());
            exit(EXIT_FAILURE);
        }

        auto& variants = variants_by_contig[contig];
        std::sort(variants.begin(), variants.end(), sortByPosition);

        // remove duplicate variants
        VariantKeyEqualityComp vkec;
        auto last = std::unique(variants.begin(), variants.end(), vkec);
        variants.erase(last, variants.end());

        assert(variants.size() < (1 << 30));
        uint32_t deleted_tag = 1 << 30;
        uint32_t variant_tag = 1 << 31;

        // make a vector holding either a literal character or an index to the variant that needs to be applied
        std::vector<uint32_t> consensus_record(length);
        for(size_t i = 0; i < length; ++i) {
            consensus_record[i] = seq[i];
        }

        size_t num_skipped = 0;
        size_t num_subs = 0;
        size_t num_insertions = 0;
        size_t num_deletions = 0;

        // update the consensus record according to the variants for this contig
        size_t applied_variants = 0;
        for(size_t variant_idx = 0; variant_idx < variants.size(); ++variant_idx) {
            const Variant& v = variants[variant_idx];

            // check if the variant record matches the reference sequence
            bool matches_ref = true;
            for(size_t i = 0; i < v.ref_seq.length(); ++i) {
                matches_ref = matches_ref && v.ref_seq[i] == consensus_record[v.ref_position + i];
            }

            if(!matches_ref) {
                num_skipped += 1;
                continue;
            }

            // mark the first base of the reference sequence as a variant and set the index
            consensus_record[v.ref_position] = variant_tag | variant_idx;

            // mark the subsequent bases of the reference as deleted
            for(size_t i = 1; i < v.ref_seq.length(); ++i) {
                consensus_record[v.ref_position + i] = deleted_tag;
            }

            num_subs += v.ref_seq.length() == v.alt_seq.length();
            num_insertions += v.ref_seq.length() < v.alt_seq.length();
            num_deletions += v.ref_seq.length() > v.alt_seq.length();
        }

        // write out the consensus record
        std::string out;
        out.reserve(length);
        for(size_t i = 0; i < length; ++i) {
            uint32_t r = consensus_record[i];
            if(r & variant_tag) {
                out.append(variants[r & ~variant_tag].alt_seq);
            } else if(r & ~deleted_tag) {
                out.append(1, r);
            } else {
                assert(r & deleted_tag);
            }
        }

        fprintf(stderr, "[vcf2fasta] rewrote contig %s with %zu subs, %zu ins, %zu dels (%zu skipped)\n", contig.c_str(), num_subs, num_insertions, num_deletions, num_skipped);
        fprintf(stdout, ">%s\n%s\n", contig.c_str(), out.c_str());

        free(seq);
        seq = NULL;
    }

    return 0;
}
<commit_msg>vcf2fasta: handle lower case input genomes (#676)<commit_after>//---------------------------------------------------------
// Copyright 2018 Ontario Institute for Cancer Research
// Written by Jared Simpson (jared.simpson@oicr.on.ca)
//---------------------------------------------------------
//
// nanopolish_vcf2fasta - write a new genome sequence
// by introducing variants from a set of vcf files
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <vector>
#include <map>
#include <inttypes.h>
#include <assert.h>
#include <math.h>
#include <sys/time.h>
#include <algorithm>
#include <sstream>
#include <set>
#include <omp.h>
#include <getopt.h>
#include <fast5.hpp>
#include "htslib/faidx.h"
#include "nanopolish_common.h"
#include "nanopolish_variant.h"
#include "nanopolish_eventalign.h"
#include "nanopolish_haplotype.h"

//
// Getopt
//
#define SUBPROGRAM "vcf2fasta"

static const char *VCF2FASTA_VERSION_MESSAGE =
SUBPROGRAM " Version " PACKAGE_VERSION "\n"
"Written by Jared Simpson.\n"
"\n"
"Copyright 2018 Ontario Institute for Cancer Research\n";

static const char *VCF2FASTA_USAGE_MESSAGE =
"Usage: " PACKAGE_NAME " " SUBPROGRAM " -g draft.fa segment1.vcf segment2.vcf ...\n"
"Write a new genome sequence by introducing variants from the input files\n"
"\n"
"  -v, --verbose                        display verbose output\n"
"      --version                        display version\n"
"      --help                           display this help and exit\n"
"  -g, --genome=FILE                    the input genome is in FILE\n"
"  -f, --fofn=FILE                      read the list of VCF files to use from FILE\n"
"      --skip-checks                    skip the sanity checks\n"
"\nReport bugs to " PACKAGE_BUGREPORT "\n\n";

namespace opt
{
    static unsigned int verbose;
    static std::vector<std::string> input_vcf_files;
    static std::string vcf_fofn;
    static std::string genome_file;
    static bool skip_checks = false;
}

static const char* shortopts = "g:f:v";

enum { OPT_HELP = 1, OPT_VERSION, OPT_SKIP_CHECKS };

static const struct option longopts[] = {
    { "verbose",       no_argument,       NULL, 'v' },
    { "help",          no_argument,       NULL, OPT_HELP },
    { "version",       no_argument,       NULL, OPT_VERSION },
    { "skip-checks",   no_argument,       NULL, OPT_SKIP_CHECKS },
    { "genome",        required_argument, NULL, 'g' },
    { "fofn",          required_argument, NULL, 'f' },
    { NULL, 0, NULL, 0 }
};

void parse_vcf2fasta_options(int argc, char** argv)
{
    bool die = false;
    for (char c; (c = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1;) {
        std::istringstream arg(optarg != NULL ? optarg : "");
        switch (c) {
            case '?': die = true; break;
            case 'v': opt::verbose++; break;
            case 'g': arg >> opt::genome_file; break;
            case 'f': arg >> opt::vcf_fofn; break;
            case OPT_SKIP_CHECKS: opt::skip_checks = true; break;
            case OPT_HELP:
                std::cout << VCF2FASTA_USAGE_MESSAGE;
                exit(EXIT_SUCCESS);
            case OPT_VERSION:
                std::cout << VCF2FASTA_VERSION_MESSAGE;
                exit(EXIT_SUCCESS);
        }
    }

    if(opt::genome_file.empty()) {
        std::cerr << SUBPROGRAM ": -g/--genome file is required\n";
        die = true;
    }

    if (argc - optind < 1 && opt::vcf_fofn.empty()) {
        std::cerr << SUBPROGRAM ": not enough arguments\n";
        die = true;
    }

    if (die)
    {
        std::cout << "\n" << VCF2FASTA_USAGE_MESSAGE;
        exit(EXIT_FAILURE);
    }

    for(; optind < argc; ++optind) {
        opt::input_vcf_files.push_back(argv[optind]);
    }

    // add files from the fofn
    if(!opt::vcf_fofn.empty()) {
        std::ifstream infile(opt::vcf_fofn);
        std::string line;
        while(getline(infile, line)) {
            opt::input_vcf_files.push_back(line);
        }
    }
}

int vcf2fasta_main(int argc, char** argv)
{
    parse_vcf2fasta_options(argc, argv);

    // Read genome file
    faidx_t *fai = fai_load(opt::genome_file.c_str());

    // Read VCF files and gather variants for each contig and the polishing window coordinates
    std::map<std::string, std::vector<Variant>> variants_by_contig;
    std::map<std::string, std::vector<std::pair<int, int>>> windows_by_contig;

    for(const auto& filename : opt::input_vcf_files) {

        std::string window_str;
        std::vector<Variant> out;
        std::ifstream infile(filename);
        std::string line;
        while(getline(infile, line)) {

            // parse header
            if(line[0] == '#') {

                // check for window coordinates
                std::string window_key = "nanopolish_window=";
                size_t key_pos = line.find(window_key);
                if(key_pos != std::string::npos) {
                    window_str = line.substr(key_pos + window_key.size());
                }
            } else {
                Variant v(line);
                variants_by_contig[v.ref_name].push_back(v);
            }
        }

        if(window_str.empty()) {
            fprintf(stderr, "error: could not detect polishing window from input file %s\n", filename.c_str());
            exit(EXIT_FAILURE);
        }

        std::string window_contig;
        int window_start, window_end;
        parse_region_string(window_str, window_contig, window_start, window_end);
        windows_by_contig[window_contig].push_back(std::make_pair(window_start, window_end));
    }

    size_t n_contigs = faidx_nseq(fai);

    for(size_t contig_idx = 0; contig_idx < n_contigs; ++contig_idx) {
        std::string contig = faidx_iseq(fai, contig_idx);
        int contig_length = faidx_seq_len(fai, contig.c_str());

        // Confirm that all windows on this contig have been polished
        bool window_check_ok = true;
        auto& windows = windows_by_contig[contig];
        std::sort(windows.begin(), windows.end());

        if(!opt::skip_checks) {
            if(windows.empty()) {
                fprintf(stderr, "error: no polishing windows found for %s\n", contig.c_str());
                exit(EXIT_FAILURE);
            }

            for(size_t window_idx = 1; window_idx < windows.size(); ++window_idx) {
                int prev_start = windows[window_idx - 1].first;
                int prev_end = windows[window_idx - 1].second;
                int curr_start = windows[window_idx].first;
                int curr_end = windows[window_idx].second;
                if(curr_start > prev_end) {
                    fprintf(stderr, "error: adjacent polishing windows do not overlap (%d-%d and %d-%d)\n", prev_start, prev_end, curr_start, curr_end);
                    window_check_ok = false;
                }
            }

            // check the first and last windows of the contig were polished
            if(windows[0].first != 0) {
                fprintf(stderr, "error: first %d bases are not covered by a polished window for contig %s.\n", windows[0].first, contig.c_str());
                window_check_ok = false;
            }

            int end_gap = contig_length - windows.back().second;
            if(end_gap > 500) {
                fprintf(stderr, "error: last %d bases are not covered by a polished window for contig %s.\n", end_gap, contig.c_str());
                window_check_ok = false;
            }
        }

        if(!window_check_ok) {
            fprintf(stderr, "error: one or more polishing windows are missing. Please check that all nanopolish variants --consensus jobs ran to completion\n");
            exit(EXIT_FAILURE);
        }

        int length;
        char* seq = fai_fetch(fai, contig.c_str(), &length);
        if(length < 0) {
            fprintf(stderr, "error: could not fetch contig %s\n", contig.c_str());
            exit(EXIT_FAILURE);
        }

        auto& variants = variants_by_contig[contig];
        std::sort(variants.begin(), variants.end(), sortByPosition);

        // remove duplicate variants
        VariantKeyEqualityComp vkec;
        auto last = std::unique(variants.begin(), variants.end(), vkec);
        variants.erase(last, variants.end());

        assert(variants.size() < (1 << 30));
        uint32_t deleted_tag = 1 << 30;
        uint32_t variant_tag = 1 << 31;

        // make a vector holding either a literal character or an index to the variant that needs to be applied
        std::vector<uint32_t> consensus_record(length);
        for(size_t i = 0; i < length; ++i) {
            consensus_record[i] = toupper(seq[i]);
        }

        size_t num_skipped = 0;
        size_t num_subs = 0;
        size_t num_insertions = 0;
        size_t num_deletions = 0;

        // update the consensus record according to the variants for this contig
        size_t applied_variants = 0;
        for(size_t variant_idx = 0; variant_idx < variants.size(); ++variant_idx) {
            const Variant& v = variants[variant_idx];

            // check if the variant record matches the reference sequence
            bool matches_ref = true;
            for(size_t i = 0; i < v.ref_seq.length(); ++i) {
                matches_ref = matches_ref && v.ref_seq[i] == consensus_record[v.ref_position + i];
            }

            if(!matches_ref) {
                num_skipped += 1;
                continue;
            }

            // mark the first base of the reference sequence as a variant and set the index
            consensus_record[v.ref_position] = variant_tag | variant_idx;

            // mark the subsequent bases of the reference as deleted
            for(size_t i = 1; i < v.ref_seq.length(); ++i) {
                consensus_record[v.ref_position + i] = deleted_tag;
            }

            num_subs += v.ref_seq.length() == v.alt_seq.length();
            num_insertions += v.ref_seq.length() < v.alt_seq.length();
            num_deletions += v.ref_seq.length() > v.alt_seq.length();
        }

        // write out the consensus record
        std::string out;
        out.reserve(length);
        for(size_t i = 0; i < length; ++i) {
            uint32_t r = consensus_record[i];
            if(r & variant_tag) {
                out.append(variants[r & ~variant_tag].alt_seq);
            } else if(r & ~deleted_tag) {
                out.append(1, r);
            } else {
                assert(r & deleted_tag);
            }
        }

        fprintf(stderr, "[vcf2fasta] rewrote contig %s with %zu subs, %zu ins, %zu dels (%zu skipped)\n", contig.c_str(), num_subs, num_insertions, num_deletions, num_skipped);
        fprintf(stdout, ">%s\n%s\n", contig.c_str(), out.c_str());

        free(seq);
        seq = NULL;
    }

    return 0;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: zoomctrl.hxx,v $
 *
 *  $Revision: 1.1.1.1 $
 *
 *  last change: $Author: hr $ $Date: 2000-09-18 17:14:43 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _ZOOMCTRL_HXX
#define _ZOOMCTRL_HXX

#ifndef _SVX_ZOOMCTRL_HXX //autogen
#include <svx/zoomctrl.hxx>
#endif

class SwZoomControl : public SvxZoomStatusBarControl
{
private:
    String  sPreviewZoom;
public:
    virtual void    Command( const CommandEvent& rCEvt );
    virtual void    StateChanged( USHORT nSID, SfxItemState eState,
                                  const SfxPoolItem* pState );
    virtual void    Paint( const UserDrawEvent& rEvt );

    SFX_DECL_STATUSBAR_CONTROL();

    SwZoomControl( USHORT nId, StatusBar& rStb, SfxBindings& rBind );
    ~SwZoomControl();

};

#endif

<commit_msg>INTEGRATION: CWS toolbars2 (1.1.1.1.836); FILE MERGED 2004/08/11 10:47:33 cd 1.1.1.1.836.1: #i32219# Adapt statusbar controller to new base class<commit_after>/*************************************************************************
 *
 *  $RCSfile: zoomctrl.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: obo $ $Date: 2004-09-09 15:35:46 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _ZOOMCTRL_HXX
#define _ZOOMCTRL_HXX

#ifndef _SVX_ZOOMCTRL_HXX //autogen
#include <svx/zoomctrl.hxx>
#endif

class SwZoomControl : public SvxZoomStatusBarControl
{
private:
    String  sPreviewZoom;
public:
    virtual void    Command( const CommandEvent& rCEvt );
    virtual void    StateChanged( USHORT nSID, SfxItemState eState,
                                  const SfxPoolItem* pState );
    virtual void    Paint( const UserDrawEvent& rEvt );

    SFX_DECL_STATUSBAR_CONTROL();

    SwZoomControl( USHORT nSlotId, USHORT nId, StatusBar& rStb );
    ~SwZoomControl();

};

#endif

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: generictoolboxcontroller.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: kz $ $Date: 2007-09-05 17:39:34 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svtools.hxx"

#ifndef __SVTOOLS_GENERICTOOLBOXCONTROLLER_HXX_
#include <svtools/generictoolboxcontroller.hxx>
#endif

//_________________________________________________________________________________________________________________
//  my own includes
//_________________________________________________________________________________________________________________

//_________________________________________________________________________________________________________________
//  interface includes
//_________________________________________________________________________________________________________________

#ifndef _COM_SUN_STAR_UTIL_XURLTRANSFORMER_HPP_
#include <com/sun/star/util/XURLTransformer.hpp>
#endif
#ifndef _COM_SUN_STAR_FRAME_XDISPATCHPROVIDER_HPP_
#include <com/sun/star/frame/XDispatchProvider.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/PropertyValue.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_
#include <com/sun/star/lang/DisposedException.hpp>
#endif
#ifndef _COM_SUN_STAR_FRAME_STATUS_ITEMSTATUS_HPP_
#include <com/sun/star/frame/status/ItemStatus.hpp>
#endif
#ifndef _COM_SUN_STAR_FRAME_STATUS_ITEMSTATE_HPP_
#include <com/sun/star/frame/status/ItemState.hpp>
#endif

//_________________________________________________________________________________________________________________
//  other includes
//_________________________________________________________________________________________________________________

#ifndef _VOS_MUTEX_HXX_
#include <vos/mutex.hxx>
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif

using namespace ::com::sun::star::awt;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::frame;
using namespace ::com::sun::star::frame::status;
using namespace ::com::sun::star::util;

namespace svt
{

struct ExecuteInfo
{
    ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch >     xDispatch;
    ::com::sun::star::util::URL                                                aTargetURL;
    ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >  aArgs;
};

GenericToolboxController::GenericToolboxController( const Reference< XMultiServiceFactory >& rServiceManager,
                                                    const Reference< XFrame >&               rFrame,
                                                    ToolBox*                                 pToolbox,
                                                    USHORT                                   nID,
                                                    const ::rtl::OUString&                          aCommand ) :
    svt::ToolboxController( rServiceManager, rFrame, aCommand )
    ,   m_pToolbox( pToolbox )
    ,   m_nID( nID )
{
    // Initialization is done through ctor
    m_bInitialized = sal_True;

    // insert main command to our listener map
    if ( m_aCommandURL.getLength() )
        m_aListenerMap.insert( URLToDispatchMap::value_type( aCommand, Reference< XDispatch >() ));
}

GenericToolboxController::~GenericToolboxController()
{
}

void SAL_CALL GenericToolboxController::dispose()
throw ( RuntimeException )
{
    vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );

    svt::ToolboxController::dispose();

    m_pToolbox = 0;
    m_nID = 0;
}

void SAL_CALL GenericToolboxController::execute( sal_Int16 /*KeyModifier*/ )
throw ( RuntimeException )
{
    Reference< XDispatch >       xDispatch;
    Reference< XURLTransformer > xURLTransformer;
    ::rtl::OUString                     aCommandURL;

    {
        vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );

        if ( m_bDisposed )
            throw DisposedException();

        if ( m_bInitialized &&
             m_xFrame.is() &&
             m_xServiceManager.is() &&
             m_aCommandURL.getLength() )
        {
            xURLTransformer = Reference< XURLTransformer >( m_xServiceManager->createInstance(
                                                                rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))),
                                                            UNO_QUERY );

            aCommandURL = m_aCommandURL;
            URLToDispatchMap::iterator pIter = m_aListenerMap.find( m_aCommandURL );
            if ( pIter != m_aListenerMap.end() )
                xDispatch = pIter->second;
        }
    }

    if ( xDispatch.is() && xURLTransformer.is() )
    {
        com::sun::star::util::URL aTargetURL;
        Sequence<PropertyValue>   aArgs;

        aTargetURL.Complete = aCommandURL;
        xURLTransformer->parseStrict( aTargetURL );

        // Execute dispatch asynchronously
        ExecuteInfo* pExecuteInfo = new ExecuteInfo;
        pExecuteInfo->xDispatch     = xDispatch;
        pExecuteInfo->aTargetURL    = aTargetURL;
        pExecuteInfo->aArgs         = aArgs;
        Application::PostUserEvent( STATIC_LINK(0, GenericToolboxController , ExecuteHdl_Impl), pExecuteInfo );
    }
}

void GenericToolboxController::statusChanged( const FeatureStateEvent& Event )
throw ( RuntimeException )
{
    vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );

    if ( m_bDisposed )
        return;

    if ( m_pToolbox )
    {
        m_pToolbox->EnableItem( m_nID, Event.IsEnabled );

        USHORT nItemBits = m_pToolbox->GetItemBits( m_nID );
        nItemBits &= ~TIB_CHECKABLE;
        TriState eTri = STATE_NOCHECK;

        sal_Bool        bValue = sal_Bool();
        rtl::OUString   aStrValue;
        ItemStatus      aItemState;

        if ( Event.State >>= bValue )
        {
            // Boolean, treat it as checked/unchecked
            m_pToolbox->SetItemBits( m_nID, nItemBits );
            m_pToolbox->CheckItem( m_nID, bValue );
            if ( bValue )
                eTri = STATE_CHECK;
            nItemBits |= TIB_CHECKABLE;
        }
        else if ( Event.State >>= aStrValue )
        {
            m_pToolbox->SetItemText( m_nID, aStrValue );
        }
        else if ( Event.State >>= aItemState )
        {
            eTri = STATE_DONTKNOW;
            nItemBits |= TIB_CHECKABLE;
        }

        m_pToolbox->SetItemState( m_nID, eTri );
        m_pToolbox->SetItemBits( m_nID, nItemBits );
    }
}

IMPL_STATIC_LINK_NOINSTANCE( GenericToolboxController, ExecuteHdl_Impl, ExecuteInfo*, pExecuteInfo )
{
   try
   {
       // Asynchronous execution as this can lead to our own destruction!
       // Framework can recycle our current frame and the layout manager disposes all user interface
       // elements if a component gets detached from its frame!
       pExecuteInfo->xDispatch->dispatch( pExecuteInfo->aTargetURL, pExecuteInfo->aArgs );
   }
   catch ( Exception& )
   {
   }
   delete pExecuteInfo;
   return 0;
}

} // namespace
<commit_msg>INTEGRATION: CWS changefileheader (1.8.170); FILE MERGED 2008/04/01 15:45:31 thb 1.8.170.3: #i85898# Stripping all external header guards 2008/04/01 12:43:57 thb 1.8.170.2: #i85898# Stripping all external header guards 2008/03/31 13:02:37 rt 1.8.170.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: generictoolboxcontroller.cxx,v $
 * $Revision: 1.9 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svtools.hxx"
#include <svtools/generictoolboxcontroller.hxx>

//_________________________________________________________________________________________________________________
//  my own includes
//_________________________________________________________________________________________________________________

//_________________________________________________________________________________________________________________
//  interface includes
//_________________________________________________________________________________________________________________
#include <com/sun/star/util/XURLTransformer.hpp>
#include <com/sun/star/frame/XDispatchProvider.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/lang/DisposedException.hpp>
#include <com/sun/star/frame/status/ItemStatus.hpp>
#include <com/sun/star/frame/status/ItemState.hpp>

//_________________________________________________________________________________________________________________
//  other includes
//_________________________________________________________________________________________________________________
#include <vos/mutex.hxx>
#include <vcl/svapp.hxx>

using namespace ::com::sun::star::awt;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::frame;
using namespace ::com::sun::star::frame::status;
using namespace ::com::sun::star::util;

namespace svt
{

struct ExecuteInfo
{
    ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch >     xDispatch;
    ::com::sun::star::util::URL                                                aTargetURL;
    ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >  aArgs;
};

GenericToolboxController::GenericToolboxController( const Reference< XMultiServiceFactory >& rServiceManager,
                                                    const Reference< XFrame >&               rFrame,
                                                    ToolBox*                                 pToolbox,
                                                    USHORT                                   nID,
                                                    const ::rtl::OUString&                          aCommand ) :
    svt::ToolboxController( rServiceManager, rFrame, aCommand )
    ,   m_pToolbox( pToolbox )
    ,   m_nID( nID )
{
    // Initialization is done through ctor
    m_bInitialized = sal_True;

    // insert main command to our listener map
    if ( m_aCommandURL.getLength() )
        m_aListenerMap.insert( URLToDispatchMap::value_type( aCommand, Reference< XDispatch >() ));
}

GenericToolboxController::~GenericToolboxController()
{
}

void SAL_CALL GenericToolboxController::dispose()
throw ( RuntimeException )
{
    vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );

    svt::ToolboxController::dispose();

    m_pToolbox = 0;
    m_nID = 0;
}

void SAL_CALL GenericToolboxController::execute( sal_Int16 /*KeyModifier*/ )
throw ( RuntimeException )
{
    Reference< XDispatch >       xDispatch;
    Reference< XURLTransformer > xURLTransformer;
    ::rtl::OUString                     aCommandURL;

    {
        vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );

        if ( m_bDisposed )
            throw DisposedException();

        if ( m_bInitialized &&
             m_xFrame.is() &&
             m_xServiceManager.is() &&
             m_aCommandURL.getLength() )
        {
            xURLTransformer = Reference< XURLTransformer >( m_xServiceManager->createInstance(
                                                                rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))),
                                                            UNO_QUERY );

            aCommandURL = m_aCommandURL;
            URLToDispatchMap::iterator pIter = m_aListenerMap.find( m_aCommandURL );
            if ( pIter != m_aListenerMap.end() )
                xDispatch = pIter->second;
        }
    }

    if ( xDispatch.is() && xURLTransformer.is() )
    {
        com::sun::star::util::URL aTargetURL;
        Sequence<PropertyValue>   aArgs;

        aTargetURL.Complete = aCommandURL;
        xURLTransformer->parseStrict( aTargetURL );

        // Execute dispatch asynchronously
        ExecuteInfo* pExecuteInfo = new ExecuteInfo;
        pExecuteInfo->xDispatch     = xDispatch;
        pExecuteInfo->aTargetURL    = aTargetURL;
        pExecuteInfo->aArgs         = aArgs;
        Application::PostUserEvent( STATIC_LINK(0, GenericToolboxController , ExecuteHdl_Impl), pExecuteInfo );
    }
}

void GenericToolboxController::statusChanged( const FeatureStateEvent& Event )
throw ( RuntimeException )
{
    vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );

    if ( m_bDisposed )
        return;

    if ( m_pToolbox )
    {
        m_pToolbox->EnableItem( m_nID, Event.IsEnabled );

        USHORT nItemBits = m_pToolbox->GetItemBits( m_nID );
        nItemBits &= ~TIB_CHECKABLE;
        TriState eTri = STATE_NOCHECK;

        sal_Bool        bValue = sal_Bool();
        rtl::OUString   aStrValue;
        ItemStatus      aItemState;

        if ( Event.State >>= bValue )
        {
            // Boolean, treat it as checked/unchecked
            m_pToolbox->SetItemBits( m_nID, nItemBits );
            m_pToolbox->CheckItem( m_nID, bValue );
            if ( bValue )
                eTri = STATE_CHECK;
            nItemBits |= TIB_CHECKABLE;
        }
        else if ( Event.State >>= aStrValue )
        {
            m_pToolbox->SetItemText( m_nID, aStrValue );
        }
        else if ( Event.State >>= aItemState )
        {
            eTri = STATE_DONTKNOW;
            nItemBits |= TIB_CHECKABLE;
        }

        m_pToolbox->SetItemState( m_nID, eTri );
        m_pToolbox->SetItemBits( m_nID, nItemBits );
    }
}

IMPL_STATIC_LINK_NOINSTANCE( GenericToolboxController, ExecuteHdl_Impl, ExecuteInfo*, pExecuteInfo )
{
   try
   {
       // Asynchronous execution as this can lead to our own destruction!
       // Framework can recycle our current frame and the layout manager disposes all user interface
       // elements if a component gets detached from its frame!
       pExecuteInfo->xDispatch->dispatch( pExecuteInfo->aTargetURL, pExecuteInfo->aArgs );
   }
   catch ( Exception& )
   {
   }
   delete pExecuteInfo;
   return 0;
}

} // namespace
<|endoftext|>