<commit_before>// kmfldsearch.cpp
// TODO: Add search in subfolder checkbox
// TODO: Use msgIdMD5 in MSGID_COLUMN

#include "kmfldsearch.h"
#include "kmglobal.h"
#include "kmfoldermgr.h"
#include "kmfolder.h"
#include "kmmessage.h"
#include "kmmainwin.h"

#include <qmessagebox.h>
#include <qpushbutton.h>
#include <qcombobox.h>
#include <qlineedit.h>
#include <qstring.h>
#include <qlayout.h>
#include <qlabel.h>
#include <assert.h>
#include <klocale.h>

#include <kapp.h>
#include <kbuttonbox.h>
#include <qlistview.h>
#include <qheader.h>

//-----------------------------------------------------------------------------
KMFldSearch::KMFldSearch(KMMainWin* w, const char* name,
  QString curFolder, bool modal, WFlags f):
  KMFldSearchInherited(NULL, name, modal, f)
{
  KButtonBox* bbox;
  QLabel* lbl;
  KMFldSearchRule* rule;
  int i;

  mMainWin = w;

  mNumRules  = 2;
  mSearching = false;

  setCaption(i18n("Search in Folders"));
  mGrid = new QGridLayout(this, mNumRules+4, 5, 4, 4);

  mCbxFolders = createFolderCombo(curFolder);
  mCbxFolders->setMinimumSize(mCbxFolders->sizeHint());
  mCbxFolders->setMaximumSize(1024, mCbxFolders->sizeHint().height());
  mGrid->addMultiCellWidget(mCbxFolders, 0, 0, 1, 2);

  mRules = new KMFldSearchRule*[mNumRules];

  for (i=0; i<mNumRules; i++)
  {
    lbl = new QLabel(i ? i18n("and") : i18n("where"), this);
    lbl->setMinimumSize(lbl->sizeHint());
    lbl->setAlignment(AlignRight|AlignVCenter);
    mGrid->addWidget(lbl, i+1, 0);

    rule = new KMFldSearchRule(this, mGrid, i+1, 1);
    mRules[i] = rule;
  }

  lbl = new QLabel(i18n("Search in"), this);
  lbl->setFixedSize(lbl->sizeHint().width(), mCbxFolders->sizeHint().height());
  lbl->setAlignment(AlignRight|AlignVCenter);
  mGrid->addWidget(lbl, 0, 0);

  mLastFocus = new QWidget();	// to remeber the position of the focus

  mLbxMatches = new QListView(this, "Search in Folders");
  /* Default is to sort by date. TODO: Unfortunately this sorts *while*
     inserting, which looks rather strange - the user cannot read
     the results so far as they are constantly sorted --dnaber
  */
  mLbxMatches->setSorting(2);
  mLbxMatches->setShowSortIndicator(true);
  mLbxMatches->setAllColumnsShowFocus(true);
  mLbxMatches->addColumn(i18n("Subject"), 150);
  mLbxMatches->addColumn(i18n("Sender"), 120);
  mLbxMatches->addColumn(i18n("Date"), 120);
#define LOCATION_COLUMN 3
  mLbxMatches->addColumn(i18n("Folder"), 100);

#define MSGID_COLUMN 4
  //TODO: Use msgIDMD5, and create KMFolder::findIdMD5(QString) method
  mLbxMatches->addColumn("");		// should be hidden
  mLbxMatches->setColumnWidthMode( MSGID_COLUMN, QListView::Manual );
  mLbxMatches->header()->setResizeEnabled(false, MSGID_COLUMN);
  mLbxMatches->setColumnWidth( MSGID_COLUMN, 0 );

#define FOLDERID_COLUMN 5
  mLbxMatches->addColumn("");		// should be hidden
  mLbxMatches->setColumnWidthMode( FOLDERID_COLUMN, QListView::Manual );
  mLbxMatches->header()->setResizeEnabled(false, FOLDERID_COLUMN);
  mLbxMatches->setColumnWidth( FOLDERID_COLUMN, 0 );

  connect(mLbxMatches, SIGNAL(doubleClicked(QListViewItem *)),
	  this, SLOT(slotShowMsg(QListViewItem *)));
  //mLbxMatches->readConfig();
  mGrid->addMultiCellWidget(mLbxMatches, mNumRules+2, mNumRules+2, 0, 4);

  bbox = new KButtonBox(this, Vertical);
  mGrid->addMultiCellWidget(bbox, 0, mNumRules-1, 4, 4);
  mBtnSearch = bbox->addButton(i18n("Search"));
  mBtnSearch->setDefault(true);
  connect(mBtnSearch, SIGNAL(clicked()), SLOT(slotSearch()));
  mBtnClose  = bbox->addButton(i18n("Close"));
  connect(mBtnClose, SIGNAL(clicked()), SLOT(slotClose()));
  bbox->layout();
  bbox->setFixedWidth(bbox->width());

  mLblStatus = new QLabel(" ", this);
  mLblStatus->setFixedHeight(mLblStatus->sizeHint().height());
  mGrid->addMultiCellWidget(mLblStatus, mNumRules+3, mNumRules+3, 0, 3);

  mGrid->setColStretch(0, 0);
  mGrid->setColStretch(1, 2);
  mGrid->setColStretch(2, 1);
  mGrid->setColStretch(3, 100);
  mGrid->setColStretch(4, 0);

  mGrid->setRowStretch(mNumRules+2, 100);
  mGrid->setRowStretch(mNumRules+3, 0);

  mGrid->activate();
  resize(sizeHint());
}

//-----------------------------------------------------------------------------
KMFldSearch::~KMFldSearch()
{
#warning Save QListView layout
  //  mLbxMatches->writeConfig();
}

//-----------------------------------------------------------------------------
QComboBox* KMFldSearch::createFolderCombo(const QString curFolder)
{
 QList<KMFolder> folders;
 QComboBox* cbx = new QComboBox(false, this);
 QStringList str;

 kernel->folderMgr()->createFolderList( &str, &folders );
 cbx->setFixedHeight(cbx->sizeHint().height());

 cbx->insertItem(i18n("<Search all folders>"));
 QStringList::Iterator st;
 int i = 1;
 for( st = str.begin(); st != str.end(); ++st, ++i) {
   cbx->insertItem(*st);
   QString fname = *st;
   if( fname.stripWhiteSpace() == curFolder ) {		// preselect current folder
     cbx->setCurrentItem(i);
   }
 }

 return cbx;
}

//-----------------------------------------------------------------------------
void KMFldSearch::updStatus(void)
{
  QString str;

  if (!mSearching) {
    if(!mStopped)
      str = i18n("Done, %1 matches (%2 messages processed)").arg(mNumMatches).arg(mCount);
    else
      str = i18n("Search cancelled, %1 matches so far (%3 messages processed)").arg(mNumMatches).arg(mCount);
  } else
    str = i18n("%1 matches, searching in %2 (message %3)")
		.arg(mNumMatches)
		.arg(mSearchFolder)
		.arg(mCount);
  mLblStatus->setText(str);
}

//-----------------------------------------------------------------------------
void KMFldSearch::keyPressEvent(QKeyEvent *evt)
{

  if(!evt)
    return;

  switch (evt->key()) {
      case Key_Return:
        KMFldSearchInherited::keyPressEvent(evt);
        break;
      case Key_Escape:
        if( mSearching )
          mSearching = false;
	else
          slotClose();
        break;
  }
}

//-----------------------------------------------------------------------------
bool KMFldSearch::searchInMessage(KMMessage* aMsg)
{
  int i;
  bool matches = true;

  assert(aMsg!=NULL);

  mCount++;
  updStatus();
  for(i=0; matches && i<mNumRules; i++)
    if (!mRules[i]->matches(aMsg))
      matches = false;

  return matches;
}

//-----------------------------------------------------------------------------
void KMFldSearch::searchInFolder(KMFolder* aFld, int fldNum)
{
  KMMessage* msg;
  int i, num, upd;
  QString str;

  assert(aFld!=NULL);

  mBtnSearch->setText("Stop");
  mSearchFolder=aFld->name();
  kapp->processEvents();
  if (aFld->open() != 0)
  {
    debug("Cannot open folder '%s'", (const char*)aFld->name());
    return;
  }

  num = aFld->count();
  for (i=0, upd=0; i<num && mSearching; i++, upd++)
  {
    msg = aFld->getMsg(i);
    if (msg && searchInMessage(msg))
    {
      (void)new QListViewItem(mLbxMatches,
			      msg->subject(),
			      msg->from(),
			      msg->dateIsoStr(),
			      aFld->name(),
			      QString("%1").arg(i),
			      QString("%1").arg(fldNum)
			      );
      mNumMatches++;
      updStatus();
    }
    if (upd > 10)
    {
      kapp->processEvents();
      upd = 0;
    }
    aFld->unGetMsg(i);
  }

  if(!mSearching)
    // was stopped
    mStopped = true;

  updStatus();

  aFld->close();
  mBtnSearch->setText(i18n("Search"));
}

//-----------------------------------------------------------------------------
void KMFldSearch::searchInAllFolders(void)
{
  QList<KMFolder> folders;
  KMFolder *folder;
  QStringList str;
  int i = 0;

  kernel->folderMgr()->createFolderList( &str, &folders );
  for(folder = folders.first(); folder != 0; folder = folders.next()) {
    // Stop pressed?
    if(!mSearching)
      break;
    searchInFolder(folder,i);
    ++i;
  }
}

//-----------------------------------------------------------------------------
void KMFldSearch::slotSearch()
{
  int i;
  mLastFocus = focusWidget();
  mBtnSearch->setFocus();	// set focus so we don't miss key event

  if (mSearching)
  {
    mSearching = false;
    return;
  }

  mCount = 0;
  mStopped = false;
  mNumMatches = 0;
  mSearching  = true;

  mBtnSearch->setCaption(i18n("Stop"));
  enableGUI();
  mLbxMatches->clear();
  kapp->processEvents();

  for (i=0; i<mNumRules; i++)
    mRules[i]->prepare();

  if (mCbxFolders->currentItem() <= 0)
    searchInAllFolders();
  else {
    QList<KMFolder> folders;
    QStringList str;
    kernel->folderMgr()->createFolderList( &str, &folders );
    if (str[mCbxFolders->currentItem()-1] == mCbxFolders->currentText()) {
      searchInFolder(folders.at(mCbxFolders->currentItem()-1),
		     mCbxFolders->currentItem()-1);
    }
  }

  mSearching=false;
  updStatus();

  mBtnSearch->setCaption(i18n("Search"));
  enableGUI();
  if( mLastFocus )
    mLastFocus->setFocus();
}

//-----------------------------------------------------------------------------
void KMFldSearch::slotClose()
{
  accept();
  delete this;
}

//-----------------------------------------------------------------------------
void KMFldSearch::slotShowMsg(QListViewItem *item)
{
  KMFolder* fld;
  KMMessage* msg;

  if(!item)
    return;

  QString fldName = item->text(LOCATION_COLUMN);
  QList<KMFolder> folders;
  QStringList str;
  int idx = atoi(item->text(FOLDERID_COLUMN));
  kernel->folderMgr()->createFolderList( &str, &folders );
  fld = folders.at(idx);
  if (!fld)
    return;
  // This could goto the wrong folder if the folder list has been modified

  mMainWin->slotSelectFolder(fld);
  msg = fld->getMsg(atoi(item->text(MSGID_COLUMN)));
  if (!msg)
    return;

  //  mMainWin->slotMsgSelected(msg);
  mMainWin->slotSelectMessage(msg);
}

//-----------------------------------------------------------------------------
void KMFldSearch::enableGUI() {
  mBtnClose->setEnabled(!mSearching);
  mCbxFolders->setEnabled(!mSearching);

  for(int i = 0; i < mNumRules; i++)
    mRules[i]->setEnabled(!mSearching);
}

//=============================================================================
KMFldSearchRule::KMFldSearchRule(QWidget* aParent, QGridLayout* aGrid,
				 int aRow, int aCol)
{
  assert(aParent!=NULL);
  assert(aGrid!=NULL);

  mCbxField = new QComboBox(true, aParent);
  if( aRow > 1 ) {
    mCbxField->insertItem("");
  }
  mCbxField->insertItem("Subject");
  mCbxField->insertItem("From");
  mCbxField->insertItem("To");
  mCbxField->insertItem("Cc");
  mCbxField->insertItem("Organization");
  mCbxField->insertItem(i18n("<complete message>"));
  mCbxField->setMinimumSize(mCbxField->sizeHint());
  mCbxField->setMaximumSize(1024, mCbxField->sizeHint().height());

  mCbxFunc = new QComboBox(false, aParent);
  mCbxFunc->insertItem(i18n("contains"));
  mCbxFunc->insertItem(i18n("doesn't contain"));
  mCbxFunc->insertItem(i18n("equals"));
  mCbxFunc->insertItem(i18n("not equal"));
  mCbxFunc->insertItem(i18n("less or equal"));
  mCbxFunc->insertItem(i18n("greater or equal"));
  mCbxFunc->setMinimumSize(mCbxFunc->sizeHint());
  mCbxFunc->setMaximumSize(1024, mCbxFunc->sizeHint().height());

  mEdtValue = new QLineEdit(aParent);
  mEdtValue->setMinimumSize(mCbxFunc->sizeHint());
  mEdtValue->setMaximumSize(1024, mCbxFunc->sizeHint().height());
  if( aRow == 1 ) {
	mEdtValue->setFocus();
  }
  aGrid->addWidget(mCbxField, aRow, aCol);
  aGrid->addWidget(mCbxFunc,  aRow, aCol+1);
  aGrid->addWidget(mEdtValue, aRow, aCol+2);
}

//-----------------------------------------------------------------------------
KMFldSearchRule::~KMFldSearchRule()
{
}

//-----------------------------------------------------------------------------
void KMFldSearchRule::prepare(void)
{
  mFieldIdx = mCbxField->currentItem();
  mField = mCbxField->currentText();
  mFunc = mCbxFunc->currentItem();
  mValue = mEdtValue->text();
}

//-----------------------------------------------------------------------------
bool KMFldSearchRule::matches(const KMMessage* aMsg) const
{
  QString value;

  if (mField.isEmpty() || !aMsg) return true;
  if( mField == i18n("<complete message>") ) {
    value = aMsg->headerField(mField);
    value =+ aMsg->bodyDecoded();
  } else {
    value = aMsg->headerField(mField);
  }
  // also see KMFilterRule::matches() for a similar function:
  switch(mFunc)
  {
  case Equal:
    return (stricmp(value, mValue) == 0);
  case NotEqual:
    return (stricmp(value, mValue) != 0);
  case Contains:
    return value.contains(mValue, FALSE);
  case NotContains:
    return ( ! value.contains(mValue, FALSE) );
  case GreaterEqual:
    return (stricmp(value, mValue) >= 0);
  case LessEqual:
    return (stricmp(value, mValue) <= 0);
  default:
    debug("KMFldSearchRule::matches: wrong rule func #%d", mFunc);
    return false;
  }
}

//-----------------------------------------------------------------------------
void KMFldSearchRule::setEnabled(bool b) {
  mCbxField->setEnabled(b);
  mCbxFunc->setEnabled(b);
  mEdtValue->setEnabled(b);
}

//-----------------------------------------------------------------------------
#include "kmfldsearch.moc"
<commit_msg>default sort order changed, new messages are now on the top<commit_after>// kmfldsearch.cpp
// TODO: Add search in subfolder checkbox
// TODO: Use msgIdMD5 in MSGID_COLUMN

#include "kmfldsearch.h"
#include "kmglobal.h"
#include "kmfoldermgr.h"
#include "kmfolder.h"
#include "kmmessage.h"
#include "kmmainwin.h"

#include <qmessagebox.h>
#include <qpushbutton.h>
#include <qcombobox.h>
#include <qlineedit.h>
#include <qstring.h>
#include <qlayout.h>
#include <qlabel.h>
#include <assert.h>
#include <klocale.h>

#include <kapp.h>
#include <kbuttonbox.h>
#include <qlistview.h>
#include <qheader.h>

//-----------------------------------------------------------------------------
KMFldSearch::KMFldSearch(KMMainWin* w, const char* name,
  QString curFolder, bool modal, WFlags f):
  KMFldSearchInherited(NULL, name, modal, f)
{
  KButtonBox* bbox;
  QLabel* lbl;
  KMFldSearchRule* rule;
  int i;

  mMainWin = w;

  mNumRules  = 2;
  mSearching = false;

  setCaption(i18n("Search in Folders"));
  mGrid = new QGridLayout(this, mNumRules+4, 5, 4, 4);

  mCbxFolders = createFolderCombo(curFolder);
  mCbxFolders->setMinimumSize(mCbxFolders->sizeHint());
  mCbxFolders->setMaximumSize(1024, mCbxFolders->sizeHint().height());
  mGrid->addMultiCellWidget(mCbxFolders, 0, 0, 1, 2);

  mRules = new KMFldSearchRule*[mNumRules];

  for (i=0; i<mNumRules; i++)
  {
    lbl = new QLabel(i ? i18n("and") : i18n("where"), this);
    lbl->setMinimumSize(lbl->sizeHint());
    lbl->setAlignment(AlignRight|AlignVCenter);
    mGrid->addWidget(lbl, i+1, 0);

    rule = new KMFldSearchRule(this, mGrid, i+1, 1);
    mRules[i] = rule;
  }

  lbl = new QLabel(i18n("Search in"), this);
  lbl->setFixedSize(lbl->sizeHint().width(), mCbxFolders->sizeHint().height());
  lbl->setAlignment(AlignRight|AlignVCenter);
  mGrid->addWidget(lbl, 0, 0);

  mLastFocus = new QWidget();	// to remeber the position of the focus

  mLbxMatches = new QListView(this, "Search in Folders");
  /* Default is to sort by date. TODO: Unfortunately this sorts *while*
     inserting, which looks rather strange - the user cannot read
     the results so far as they are constantly re-sorted --dnaber
  */
  mLbxMatches->setSorting(2, false);
  mLbxMatches->setShowSortIndicator(true);
  mLbxMatches->setAllColumnsShowFocus(true);
  mLbxMatches->addColumn(i18n("Subject"), 150);
  mLbxMatches->addColumn(i18n("Sender"), 120);
  mLbxMatches->addColumn(i18n("Date"), 120);
#define LOCATION_COLUMN 3
  mLbxMatches->addColumn(i18n("Folder"), 100);

#define MSGID_COLUMN 4
  //TODO: Use msgIDMD5, and create KMFolder::findIdMD5(QString) method
  mLbxMatches->addColumn("");		// should be hidden
  mLbxMatches->setColumnWidthMode( MSGID_COLUMN, QListView::Manual );
  mLbxMatches->header()->setResizeEnabled(false, MSGID_COLUMN);
  mLbxMatches->setColumnWidth( MSGID_COLUMN, 0 );

#define FOLDERID_COLUMN 5
  mLbxMatches->addColumn("");		// should be hidden
  mLbxMatches->setColumnWidthMode( FOLDERID_COLUMN, QListView::Manual );
  mLbxMatches->header()->setResizeEnabled(false, FOLDERID_COLUMN);
  mLbxMatches->setColumnWidth( FOLDERID_COLUMN, 0 );

  connect(mLbxMatches, SIGNAL(doubleClicked(QListViewItem *)),
	  this, SLOT(slotShowMsg(QListViewItem *)));
  //mLbxMatches->readConfig();
  mGrid->addMultiCellWidget(mLbxMatches, mNumRules+2, mNumRules+2, 0, 4);

  bbox = new KButtonBox(this, Vertical);
  mGrid->addMultiCellWidget(bbox, 0, mNumRules-1, 4, 4);
  mBtnSearch = bbox->addButton(i18n("Search"));
  mBtnSearch->setDefault(true);
  connect(mBtnSearch, SIGNAL(clicked()), SLOT(slotSearch()));
  mBtnClose  = bbox->addButton(i18n("Close"));
  connect(mBtnClose, SIGNAL(clicked()), SLOT(slotClose()));
  bbox->layout();
  bbox->setFixedWidth(bbox->width());

  mLblStatus = new QLabel(" ", this);
  mLblStatus->setFixedHeight(mLblStatus->sizeHint().height());
  mGrid->addMultiCellWidget(mLblStatus, mNumRules+3, mNumRules+3, 0, 3);

  mGrid->setColStretch(0, 0);
  mGrid->setColStretch(1, 2);
  mGrid->setColStretch(2, 1);
  mGrid->setColStretch(3, 100);
  mGrid->setColStretch(4, 0);

  mGrid->setRowStretch(mNumRules+2, 100);
  mGrid->setRowStretch(mNumRules+3, 0);

  mGrid->activate();
  resize(sizeHint());
}

//-----------------------------------------------------------------------------
KMFldSearch::~KMFldSearch()
{
#warning Save QListView layout
  //  mLbxMatches->writeConfig();
}

//-----------------------------------------------------------------------------
QComboBox* KMFldSearch::createFolderCombo(const QString curFolder)
{
 QList<KMFolder> folders;
 QComboBox* cbx = new QComboBox(false, this);
 QStringList str;

 kernel->folderMgr()->createFolderList( &str, &folders );
 cbx->setFixedHeight(cbx->sizeHint().height());

 cbx->insertItem(i18n("<Search all folders>"));
 QStringList::Iterator st;
 int i = 1;
 for( st = str.begin(); st != str.end(); ++st, ++i) {
   cbx->insertItem(*st);
   QString fname = *st;
   if( fname.stripWhiteSpace() == curFolder ) {		// preselect current folder
     cbx->setCurrentItem(i);
   }
 }

 return cbx;
}

//-----------------------------------------------------------------------------
void KMFldSearch::updStatus(void)
{
  QString str;

  if (!mSearching) {
    if(!mStopped)
      str = i18n("Done, %1 matches (%2 messages processed)").arg(mNumMatches).arg(mCount);
    else
      str = i18n("Search cancelled, %1 matches so far (%3 messages processed)").arg(mNumMatches).arg(mCount);
  } else
    str = i18n("%1 matches, searching in %2 (message %3)")
		.arg(mNumMatches)
		.arg(mSearchFolder)
		.arg(mCount);
  mLblStatus->setText(str);
}

//-----------------------------------------------------------------------------
void KMFldSearch::keyPressEvent(QKeyEvent *evt)
{

  if(!evt)
    return;

  switch (evt->key()) {
      case Key_Return:
        KMFldSearchInherited::keyPressEvent(evt);
        break;
      case Key_Escape:
        if( mSearching )
          mSearching = false;
	else
          slotClose();
        break;
  }
}

//-----------------------------------------------------------------------------
bool KMFldSearch::searchInMessage(KMMessage* aMsg)
{
  int i;
  bool matches = true;

  assert(aMsg!=NULL);

  mCount++;
  updStatus();
  for(i=0; matches && i<mNumRules; i++)
    if (!mRules[i]->matches(aMsg))
      matches = false;

  return matches;
}

//-----------------------------------------------------------------------------
void KMFldSearch::searchInFolder(KMFolder* aFld, int fldNum)
{
  KMMessage* msg;
  int i, num, upd;
  QString str;

  assert(aFld!=NULL);

  mBtnSearch->setText("Stop");
  mSearchFolder=aFld->name();
  kapp->processEvents();
  if (aFld->open() != 0)
  {
    debug("Cannot open folder '%s'", (const char*)aFld->name());
    return;
  }

  num = aFld->count();
  for (i=0, upd=0; i<num && mSearching; i++, upd++)
  {
    msg = aFld->getMsg(i);
    if (msg && searchInMessage(msg))
    {
      (void)new QListViewItem(mLbxMatches,
			      msg->subject(),
			      msg->from(),
			      msg->dateIsoStr(),
			      aFld->name(),
			      QString("%1").arg(i),
			      QString("%1").arg(fldNum)
			      );
      mNumMatches++;
      updStatus();
    }
    if (upd > 10)
    {
      kapp->processEvents();
      upd = 0;
    }
    aFld->unGetMsg(i);
  }

  if(!mSearching)
    // was stopped
    mStopped = true;

  updStatus();

  aFld->close();
  mBtnSearch->setText(i18n("Search"));
}

//-----------------------------------------------------------------------------
void KMFldSearch::searchInAllFolders(void)
{
  QList<KMFolder> folders;
  KMFolder *folder;
  QStringList str;
  int i = 0;

  kernel->folderMgr()->createFolderList( &str, &folders );
  for(folder = folders.first(); folder != 0; folder = folders.next()) {
    // Stop pressed?
    if(!mSearching)
      break;
    searchInFolder(folder,i);
    ++i;
  }
}

//-----------------------------------------------------------------------------
void KMFldSearch::slotSearch()
{
  int i;
  mLastFocus = focusWidget();
  mBtnSearch->setFocus();	// set focus so we don't miss key event

  if (mSearching)
  {
    mSearching = false;
    return;
  }

  mCount = 0;
  mStopped = false;
  mNumMatches = 0;
  mSearching  = true;

  mBtnSearch->setCaption(i18n("Stop"));
  enableGUI();
  mLbxMatches->clear();
  kapp->processEvents();

  for (i=0; i<mNumRules; i++)
    mRules[i]->prepare();

  if (mCbxFolders->currentItem() <= 0)
    searchInAllFolders();
  else {
    QList<KMFolder> folders;
    QStringList str;
    kernel->folderMgr()->createFolderList( &str, &folders );
    if (str[mCbxFolders->currentItem()-1] == mCbxFolders->currentText()) {
      searchInFolder(folders.at(mCbxFolders->currentItem()-1),
		     mCbxFolders->currentItem()-1);
    }
  }

  mSearching=false;
  updStatus();

  mBtnSearch->setCaption(i18n("Search"));
  enableGUI();
  if( mLastFocus )
    mLastFocus->setFocus();
}

//-----------------------------------------------------------------------------
void KMFldSearch::slotClose()
{
  accept();
  delete this;
}

//-----------------------------------------------------------------------------
void KMFldSearch::slotShowMsg(QListViewItem *item)
{
  KMFolder* fld;
  KMMessage* msg;

  if(!item)
    return;

  QString fldName = item->text(LOCATION_COLUMN);
  QList<KMFolder> folders;
  QStringList str;
  int idx = atoi(item->text(FOLDERID_COLUMN));
  kernel->folderMgr()->createFolderList( &str, &folders );
  fld = folders.at(idx);
  if (!fld)
    return;
  // This could goto the wrong folder if the folder list has been modified

  mMainWin->slotSelectFolder(fld);
  msg = fld->getMsg(atoi(item->text(MSGID_COLUMN)));
  if (!msg)
    return;

  //  mMainWin->slotMsgSelected(msg);
  mMainWin->slotSelectMessage(msg);
}

//-----------------------------------------------------------------------------
void KMFldSearch::enableGUI() {
  mBtnClose->setEnabled(!mSearching);
  mCbxFolders->setEnabled(!mSearching);

  for(int i = 0; i < mNumRules; i++)
    mRules[i]->setEnabled(!mSearching);
}

//=============================================================================
KMFldSearchRule::KMFldSearchRule(QWidget* aParent, QGridLayout* aGrid,
				 int aRow, int aCol)
{
  assert(aParent!=NULL);
  assert(aGrid!=NULL);

  mCbxField = new QComboBox(true, aParent);
  if( aRow > 1 ) {
    mCbxField->insertItem("");
  }
  mCbxField->insertItem("Subject");
  mCbxField->insertItem("From");
  mCbxField->insertItem("To");
  mCbxField->insertItem("Cc");
  mCbxField->insertItem("Organization");
  mCbxField->insertItem(i18n("<complete message>"));
  mCbxField->setMinimumSize(mCbxField->sizeHint());
  mCbxField->setMaximumSize(1024, mCbxField->sizeHint().height());

  mCbxFunc = new QComboBox(false, aParent);
  mCbxFunc->insertItem(i18n("contains"));
  mCbxFunc->insertItem(i18n("doesn't contain"));
  mCbxFunc->insertItem(i18n("equals"));
  mCbxFunc->insertItem(i18n("not equal"));
  mCbxFunc->insertItem(i18n("less or equal"));
  mCbxFunc->insertItem(i18n("greater or equal"));
  mCbxFunc->setMinimumSize(mCbxFunc->sizeHint());
  mCbxFunc->setMaximumSize(1024, mCbxFunc->sizeHint().height());

  mEdtValue = new QLineEdit(aParent);
  mEdtValue->setMinimumSize(mCbxFunc->sizeHint());
  mEdtValue->setMaximumSize(1024, mCbxFunc->sizeHint().height());
  if( aRow == 1 ) {
	mEdtValue->setFocus();
  }
  aGrid->addWidget(mCbxField, aRow, aCol);
  aGrid->addWidget(mCbxFunc,  aRow, aCol+1);
  aGrid->addWidget(mEdtValue, aRow, aCol+2);
}

//-----------------------------------------------------------------------------
KMFldSearchRule::~KMFldSearchRule()
{
}

//-----------------------------------------------------------------------------
void KMFldSearchRule::prepare(void)
{
  mFieldIdx = mCbxField->currentItem();
  mField = mCbxField->currentText();
  mFunc = mCbxFunc->currentItem();
  mValue = mEdtValue->text();
}

//-----------------------------------------------------------------------------
bool KMFldSearchRule::matches(const KMMessage* aMsg) const
{
  QString value;

  if (mField.isEmpty() || !aMsg) return true;
  if( mField == i18n("<complete message>") ) {
    value = aMsg->headerField(mField);
    value =+ aMsg->bodyDecoded();
  } else {
    value = aMsg->headerField(mField);
  }
  // also see KMFilterRule::matches() for a similar function:
  switch(mFunc)
  {
  case Equal:
    return (stricmp(value, mValue) == 0);
  case NotEqual:
    return (stricmp(value, mValue) != 0);
  case Contains:
    return value.contains(mValue, FALSE);
  case NotContains:
    return ( ! value.contains(mValue, FALSE) );
  case GreaterEqual:
    return (stricmp(value, mValue) >= 0);
  case LessEqual:
    return (stricmp(value, mValue) <= 0);
  default:
    debug("KMFldSearchRule::matches: wrong rule func #%d", mFunc);
    return false;
  }
}

//-----------------------------------------------------------------------------
void KMFldSearchRule::setEnabled(bool b) {
  mCbxField->setEnabled(b);
  mCbxFunc->setEnabled(b);
  mEdtValue->setEnabled(b);
}

//-----------------------------------------------------------------------------
#include "kmfldsearch.moc"
<|endoftext|>


<commit_before>#include "mainwindow.h"

#include <kapplication.h>
#include <dcopclient.h>
#include <kaboutdata.h>
#include <kcmdlineargs.h>
#include <klocale.h>
#include <kdebug.h>

static const char description[] =
    I18N_NOOP("XML Forms Editor");

static KCmdLineOptions options[] =
{
  { "+[URL]", I18N_NOOP( "Document to open" ), 0 },
  { "kxform <URL>", I18N_NOOP( "Form description" ), 0 },
  { "schema <URL>", I18N_NOOP( "XML Schema" ), 0 },
  KCmdLineLastOption
};

int main(int argc, char **argv)
{
  KAboutData about("kxforms", I18N_NOOP("KXForms"), "0.1", description,
    KAboutData::License_GPL, "(C) 2005 Cornelius Schumacher", 0, 0,
    "schumacher@kde.org");
  about.addAuthor( "Cornelius Schumacher", 0, "schumacher@kde.org" );
  KCmdLineArgs::init(argc, argv, &about);
  KCmdLineArgs::addCmdLineOptions(options);
  KApplication app;

  KCmdLineArgs *args = KCmdLineArgs::parsedArgs();

  MainWindow *widget = new MainWindow;

  widget->show();

  if ( args->isSet( "kxform" ) ) {
    QString form = args->getOption( "kxform" );
    KUrl formUrl( form );
    widget->loadForm( formUrl );
  }

  if ( args->count() == 1 ) {
    widget->load( KUrl( args->arg( 0 ) ) );
  }

  return app.exec();
}
<commit_msg>Correctly construct KUrl objects.<commit_after>#include "mainwindow.h"

#include <kapplication.h>
#include <dcopclient.h>
#include <kaboutdata.h>
#include <kcmdlineargs.h>
#include <klocale.h>
#include <kdebug.h>

static const char description[] =
    I18N_NOOP("XML Forms Editor");

static KCmdLineOptions options[] =
{
  { "+[URL]", I18N_NOOP( "Document to open" ), 0 },
  { "kxform <URL>", I18N_NOOP( "Form description" ), 0 },
  { "schema <URL>", I18N_NOOP( "XML Schema" ), 0 },
  KCmdLineLastOption
};

int main(int argc, char **argv)
{
  KAboutData about("kxforms", I18N_NOOP("KXForms"), "0.1", description,
    KAboutData::License_GPL, "(C) 2005 Cornelius Schumacher", 0, 0,
    "schumacher@kde.org");
  about.addAuthor( "Cornelius Schumacher", 0, "schumacher@kde.org" );
  KCmdLineArgs::init(argc, argv, &about);
  KCmdLineArgs::addCmdLineOptions(options);
  KApplication app;

  KCmdLineArgs *args = KCmdLineArgs::parsedArgs();

  MainWindow *widget = new MainWindow;

  widget->show();

  if ( args->isSet( "kxform" ) ) {
    QString form = args->getOption( "kxform" );
    widget->loadForm( KUrl::fromPath( form ) );
  }

  if ( args->count() == 1 ) {
    widget->load( KUrl::fromPath( args->arg( 0 ) ) );
  }

  return app.exec();
}
<|endoftext|>


<commit_before>#include "stxxl/algo/async_schedule.h"
#include "stxxl/common/rand.h"
#include <cstdlib>

int main(int argc, char * argv[])
{
    if (argc < 5)
    {
        STXXL_ERRMSG("Usage: " << argv[0] << " D L m seed")
        return -1;
    }
    int i;
    const int D = atoi(argv[1]);
    const int L = atoi(argv[2]);
    const int m = atoi(argv[3]);
    stxxl::ran32State = atoi(argv[4]);
    int * disks = new int [L];
    int * prefetch_order = new int [L];
    int * count = new int [D];

    for (i = 0; i < D; i++)
        count[i] =  0;

    stxxl::random_number<> rnd;
    for (i = 0; i < L; i++)
    {
        disks[i] = rnd(D);
        count[disks[i]]++;
    }

    for (i = 0; i < D; i++)
        std::cout << "Disk " << i << " has " << count[i] << " blocks" << std::endl;

    stxxl::compute_prefetch_schedule(disks, disks + L, prefetch_order, m, D);

    delete [] count;
    delete [] disks;
    delete [] prefetch_order;
}
<commit_msg>included async_schedule.cpp in algo/test_asch.cpp<commit_after>#include "stxxl/algo/async_schedule.h"
#include "stxxl/common/rand.h"
#include <cstdlib>

#include "async_schedule.cpp"

// Test async schedule algorithm

int main(int argc, char * argv[])
{
    if (argc < 5)
    {
        STXXL_ERRMSG("Usage: " << argv[0] << " D L m seed")
        return -1;
    }
    int i;
    const int D = atoi(argv[1]);
    const int L = atoi(argv[2]);
    const int m = atoi(argv[3]);
    stxxl::ran32State = atoi(argv[4]);
    int * disks = new int [L];
    int * prefetch_order = new int [L];
    int * count = new int [D];

    for (i = 0; i < D; i++)
        count[i] =  0;

    stxxl::random_number<> rnd;
    for (i = 0; i < L; i++)
    {
        disks[i] = rnd(D);
        count[disks[i]]++;
    }

    for (i = 0; i < D; i++)
        std::cout << "Disk " << i << " has " << count[i] << " blocks" << std::endl;

    stxxl::compute_prefetch_schedule(disks, disks + L, prefetch_order, m, D);

    delete [] count;
    delete [] disks;
    delete [] prefetch_order;
}
<|endoftext|>


<commit_before>#include "dataaccess.h"
#include "scientist.h"
#include <QtSql>
#include <iostream> // TEMP<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
#include <sstream>

using namespace std;

DataAccess::DataAccess()
{

    db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("test.sqlite");  // witch database to select ( aka what file )
    db.open();

}
//void DataAccess::saveScientists(const vector<Scientist>& scientists)  // From vector to text file
void DataAccess::saveScientists(const Scientist newScientist)  // Saving to database SQLite
{
    /*
     * This function uses ofstream to save the vector of scientists to the scientists.txt file.
     */
    string sName, line, name, gender, birthYear, deathYear, age;
    newScientist

    name = newScientist.getName();
    gender = newScientist.getGender();
    birthYear = newScientist.getBirth();
    deathYear = newScientist.getDeath();

    sName = "INSERT INTO Scientists(name,gender,birth,death) "
            "VALUES(\"" + name + "\",\"" + gender + "\"," + birthYear + "," + deathYear + ")";

    cout << sName;

    QString input = QString::fromStdString(sName);

    //db = QSqlDatabase::addDatabase("QSQLITE");
    //db.setDatabaseName("test.sqlite");  // witch database to select ( aka what file )

    //db.open();      // open database
    QSqlQuery query;
    query.exec(input); // open table scientists
    db.close();

}
vector<Scientist> DataAccess::loadScientists()                  // From text file to vector
{
    /*
     * This function uses ifstream to read from scientists.txt file and read them into a vector.
     */

    vector<Scientist> scientists;
    string line, name, gender, birthYear, deathYear, age;
    //char charGender;
    int intBirthYear, intDeathYear, intAge;

    //db = QSqlDatabase::addDatabase("QSQLITE");
    //db.setDatabaseName("test.sqlite");  // witch database to select ( aka what file )

    //db.open();      // open database
    QSqlQuery query;
    query.exec("SELECT * FROM Scientists"); // open table scientists

    while (query.next())
    {
        string name = query.value(1).toString().toStdString();
        string stringGender = query.value(2).toString().toStdString();
        int intBirthYear = query.value(3).toInt();
        int intDeathYear = query.value(4).toInt();
        char charGender = stringGender[0];

        Scientist scientist(name, charGender, intBirthYear, intDeathYear, intAge);
        scientists.push_back(scientist);
    }

    //db.close();
    return scientists;
}

// OLD CODE
/*
ofstream file;
file.open("scientists.txt");

if(file.is_open())
{
    for(size_t i = 0; i < scientists.size(); i++)
    {
        file << scientists[i].getName()   <<  ",";
        file << scientists[i].getGender() <<  ",";
        file << scientists[i].getBirth()  <<  ",";
        file << scientists[i].getDeath()  <<  ",";
        file << scientists[i].getAge()    << endl;
    }
    file.close( );
}
*/

/*
vector<Scientist> scientists;

string line, name, gender, birthYear, deathYear, age;
const string delimiter = ",";
char charGender;
int intBirthYear, intDeathYear, intAge, delimiterPos;

ifstream file;
file.open("scientists.txt");

if(file.is_open())
{
    while(getline(file, line))
    {
        delimiterPos = line.find(delimiter);
        name = line.substr(0, delimiterPos);
        line.erase(0, delimiterPos + 1);

        delimiterPos = line.find(delimiter);
        gender = line.substr(0, delimiterPos);
        line.erase(0, delimiterPos + 1);

        delimiterPos = line.find(delimiter);
        birthYear = line.substr(0, delimiterPos);
        line.erase(0, delimiterPos + 1);

        delimiterPos = line.find(delimiter);
        deathYear = line.substr(0, delimiterPos);
        line.erase(0, delimiterPos + 1);

        delimiterPos = line.find(delimiter);
        age = line.substr(0, delimiterPos);

        charGender = gender[0];
        intBirthYear = atoi(birthYear.c_str());
        intDeathYear = atoi(deathYear.c_str());
        intAge = atoi(age.c_str());

        Scientist scientist(name, charGender, intBirthYear, intDeathYear, intAge);

        scientists.push_back(scientist);
    }

file.close( );
}

return scientists;

*/
<commit_msg>small DA update<commit_after>#include "dataaccess.h"
#include "scientist.h"
#include <QtSql>
#include <iostream> // TEMP<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
#include <sstream>

using namespace std;

DataAccess::DataAccess()
{

    db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("test.sqlite");  // witch database to select ( aka what file )
    db.open();

}
//void DataAccess::saveScientists(const vector<Scientist>& scientists)  // From vector to text file
void DataAccess::saveScientists(const Scientist newScientist)  // Saving to database SQLite
{
    /*
     * This function uses ofstream to save the vector of scientists to the scientists.txt file.
     */
    string sName, line, name, gender, birthYear, deathYear, age;

    name = newScientist.getName();
    gender = newScientist.getGender();
    birthYear = newScientist.getBirth();
    deathYear = newScientist.getDeath();

    sName = "INSERT INTO Scientists(name,gender,birth,death) "
            "VALUES(\"" + name + "\",\"" + gender + "\"," + birthYear + "," + deathYear + ")";

    cout << sName;

    QString input = QString::fromStdString(sName);

    //db = QSqlDatabase::addDatabase("QSQLITE");
    //db.setDatabaseName("test.sqlite");  // witch database to select ( aka what file )

    //db.open();      // open database
    QSqlQuery query;
    query.exec(input); // open table scientists
    db.close();

}
vector<Scientist> DataAccess::loadScientists()                  // From text file to vector
{
    /*
     * This function uses ifstream to read from scientists.txt file and read them into a vector.
     */

    vector<Scientist> scientists;
    string line, name, gender, birthYear, deathYear, age;
    //char charGender;
    int intBirthYear, intDeathYear, intAge;

    //db = QSqlDatabase::addDatabase("QSQLITE");
    //db.setDatabaseName("test.sqlite");  // witch database to select ( aka what file )

    //db.open();      // open database
    QSqlQuery query;
    query.exec("SELECT * FROM Scientists"); // open table scientists

    while (query.next())
    {
        string name = query.value(1).toString().toStdString();
        string stringGender = query.value(2).toString().toStdString();
        int intBirthYear = query.value(3).toInt();
        int intDeathYear = query.value(4).toInt();
        char charGender = stringGender[0];

        Scientist scientist(name, charGender, intBirthYear, intDeathYear, intAge);
        scientists.push_back(scientist);
    }

    //db.close();
    return scientists;
}

// OLD CODE
/*
ofstream file;
file.open("scientists.txt");

if(file.is_open())
{
    for(size_t i = 0; i < scientists.size(); i++)
    {
        file << scientists[i].getName()   <<  ",";
        file << scientists[i].getGender() <<  ",";
        file << scientists[i].getBirth()  <<  ",";
        file << scientists[i].getDeath()  <<  ",";
        file << scientists[i].getAge()    << endl;
    }
    file.close( );
}
*/

/*
vector<Scientist> scientists;

string line, name, gender, birthYear, deathYear, age;
const string delimiter = ",";
char charGender;
int intBirthYear, intDeathYear, intAge, delimiterPos;

ifstream file;
file.open("scientists.txt");

if(file.is_open())
{
    while(getline(file, line))
    {
        delimiterPos = line.find(delimiter);
        name = line.substr(0, delimiterPos);
        line.erase(0, delimiterPos + 1);

        delimiterPos = line.find(delimiter);
        gender = line.substr(0, delimiterPos);
        line.erase(0, delimiterPos + 1);

        delimiterPos = line.find(delimiter);
        birthYear = line.substr(0, delimiterPos);
        line.erase(0, delimiterPos + 1);

        delimiterPos = line.find(delimiter);
        deathYear = line.substr(0, delimiterPos);
        line.erase(0, delimiterPos + 1);

        delimiterPos = line.find(delimiter);
        age = line.substr(0, delimiterPos);

        charGender = gender[0];
        intBirthYear = atoi(birthYear.c_str());
        intDeathYear = atoi(deathYear.c_str());
        intAge = atoi(age.c_str());

        Scientist scientist(name, charGender, intBirthYear, intDeathYear, intAge);

        scientists.push_back(scientist);
    }

file.close( );
}

return scientists;

*/
<|endoftext|>


<commit_before><commit_msg>Add options to planar reflection demo.<commit_after><|endoftext|>


<commit_before>/*******************************
Copyright (c) 2016-2017 Grégoire Angerand

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
**********************************/

#include "ShaderProgram.h"
#include <yave/Device.h>

#include <unordered_map>
#include <numeric>

#include <spirv_cross/spirv.hpp>
#include <spirv_cross/spirv_cross.hpp>
#include <spirv_cross/spirv_glsl.hpp>

namespace yave {

using Attribs = core::Vector<vk::VertexInputAttributeDescription>;
using Bindings = core::Vector<vk::VertexInputBindingDescription>;

template<typename T>
static void merge(T& into, const T& o) {
	into.insert(o.begin(), o.end());
}

static vk::Format vec_format(ShaderModuleBase::Attribute attr) {
	switch(attr.vec_size) {
		case 1:
			return vk::Format::eR32Sfloat;
		case 2:
			return vk::Format::eR32G32Sfloat;
		case 3:
			return vk::Format::eR32G32B32Sfloat;
		case 4:
			return vk::Format::eR32G32B32A32Sfloat;

		default:
			break;
	}
	return fatal("Unsupported vec format.");
}

static auto create_stage_info(core::Vector<vk::PipelineShaderStageCreateInfo>& stages, const ShaderModuleBase& mod) {
	if(mod.vk_shader_module()) {
		stages << vk::PipelineShaderStageCreateInfo()
				.setModule(mod.vk_shader_module())
				.setStage(vk::ShaderStageFlagBits(mod.type()))
				.setPName("main")
			;
	}
}

static void create_vertex_attribs(u32 binding,
								  vk::VertexInputRate rate,
								  const core::Vector<ShaderModuleBase::Attribute>& vertex_attribs,
								  Bindings& bindings,
								  Attribs& attribs) {

	if(!vertex_attribs.is_empty()) {
		u32 offset = 0;
		for(const auto& attr : vertex_attribs) {
			auto format = vec_format(attr);
			for(u32 i = 0; i != attr.columns; i++) {
				attribs << vk::VertexInputAttributeDescription()
						.setBinding(binding)
						.setLocation(attr.location + i)
						.setFormat(format)
						.setOffset(offset)
					;
				offset += attr.vec_size * attr.component_size;
			}
		}
		bindings << vk::VertexInputBindingDescription()
				.setBinding(binding)
				.setStride(offset)
				.setInputRate(rate)
			;
	}
}

// Takes a SORTED (by location) Attribute list
static void create_vertex_attribs(const core::Vector<ShaderModuleBase::Attribute>& vertex_attribs,
								  Bindings& bindings,
								  Attribs& attribs) {

	core::Vector<ShaderModuleBase::Attribute> v_attribs;
	core::Vector<ShaderModuleBase::Attribute> i_attribs;

	for(const auto& attr : vertex_attribs) {
		(attr.location < ShaderProgram::PerInstanceLocation ? v_attribs : i_attribs) << attr;
	}
	create_vertex_attribs(0, vk::VertexInputRate::eVertex, v_attribs, bindings, attribs);
	create_vertex_attribs(1, vk::VertexInputRate::eInstance, i_attribs, bindings, attribs);
}

ShaderProgram::ShaderProgram(const FragmentShader& frag, const VertexShader& vert, const GeometryShader& geom) : DeviceLinked(common_device(frag, vert, geom)) {
	{
		merge(_bindings, frag.bindings());
		merge(_bindings, vert.bindings());
		merge(_bindings, geom.bindings());

		create_stage_info(_stages, frag);
		create_stage_info(_stages, vert);
		create_stage_info(_stages, geom);

		u32 max_set = std::accumulate(_bindings.begin(), _bindings.end(), 0, [](u32 max, const auto& p) { return std::max(max, p.first); });

		_layouts = core::Vector<vk::DescriptorSetLayout>(max_set + 1, VK_NULL_HANDLE);
		for(const auto& binding : _bindings) {
			_layouts[binding.first] = device()->create_descriptor_set_layout(binding.second);
		}
	}
	{
		auto vertex_attribs = vert.attributes();
		std::sort(vertex_attribs.begin(), vertex_attribs.end(), [](const auto& a, const auto& b) { return a.location < b.location; });
		create_vertex_attribs(vertex_attribs, _vertex.bindings, _vertex.attribs);
	}
}

core::Vector<vk::PipelineShaderStageCreateInfo> ShaderProgram::vk_pipeline_stage_info() const {
	return _stages;
}

const core::Vector<vk::DescriptorSetLayout>& ShaderProgram::descriptor_layouts() const {
	return _layouts;
}

}
<commit_msg>Changed std::sort to sort.<commit_after>/*******************************
Copyright (c) 2016-2017 Grégoire Angerand

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
**********************************/

#include "ShaderProgram.h"
#include <yave/Device.h>

#include <unordered_map>
#include <numeric>

#include <spirv_cross/spirv.hpp>
#include <spirv_cross/spirv_cross.hpp>
#include <spirv_cross/spirv_glsl.hpp>

namespace yave {

using Attribs = core::Vector<vk::VertexInputAttributeDescription>;
using Bindings = core::Vector<vk::VertexInputBindingDescription>;

template<typename T>
static void merge(T& into, const T& o) {
	into.insert(o.begin(), o.end());
}

static vk::Format vec_format(ShaderModuleBase::Attribute attr) {
	switch(attr.vec_size) {
		case 1:
			return vk::Format::eR32Sfloat;
		case 2:
			return vk::Format::eR32G32Sfloat;
		case 3:
			return vk::Format::eR32G32B32Sfloat;
		case 4:
			return vk::Format::eR32G32B32A32Sfloat;

		default:
			break;
	}
	return fatal("Unsupported vec format.");
}

static auto create_stage_info(core::Vector<vk::PipelineShaderStageCreateInfo>& stages, const ShaderModuleBase& mod) {
	if(mod.vk_shader_module()) {
		stages << vk::PipelineShaderStageCreateInfo()
				.setModule(mod.vk_shader_module())
				.setStage(vk::ShaderStageFlagBits(mod.type()))
				.setPName("main")
			;
	}
}

static void create_vertex_attribs(u32 binding,
								  vk::VertexInputRate rate,
								  const core::Vector<ShaderModuleBase::Attribute>& vertex_attribs,
								  Bindings& bindings,
								  Attribs& attribs) {

	if(!vertex_attribs.is_empty()) {
		u32 offset = 0;
		for(const auto& attr : vertex_attribs) {
			auto format = vec_format(attr);
			for(u32 i = 0; i != attr.columns; i++) {
				attribs << vk::VertexInputAttributeDescription()
						.setBinding(binding)
						.setLocation(attr.location + i)
						.setFormat(format)
						.setOffset(offset)
					;
				offset += attr.vec_size * attr.component_size;
			}
		}
		bindings << vk::VertexInputBindingDescription()
				.setBinding(binding)
				.setStride(offset)
				.setInputRate(rate)
			;
	}
}

// Takes a SORTED (by location) Attribute list
static void create_vertex_attribs(const core::Vector<ShaderModuleBase::Attribute>& vertex_attribs,
								  Bindings& bindings,
								  Attribs& attribs) {

	core::Vector<ShaderModuleBase::Attribute> v_attribs;
	core::Vector<ShaderModuleBase::Attribute> i_attribs;

	for(const auto& attr : vertex_attribs) {
		(attr.location < ShaderProgram::PerInstanceLocation ? v_attribs : i_attribs) << attr;
	}
	create_vertex_attribs(0, vk::VertexInputRate::eVertex, v_attribs, bindings, attribs);
	create_vertex_attribs(1, vk::VertexInputRate::eInstance, i_attribs, bindings, attribs);
}

ShaderProgram::ShaderProgram(const FragmentShader& frag, const VertexShader& vert, const GeometryShader& geom) : DeviceLinked(common_device(frag, vert, geom)) {
	{
		merge(_bindings, frag.bindings());
		merge(_bindings, vert.bindings());
		merge(_bindings, geom.bindings());

		create_stage_info(_stages, frag);
		create_stage_info(_stages, vert);
		create_stage_info(_stages, geom);

		u32 max_set = std::accumulate(_bindings.begin(), _bindings.end(), 0, [](u32 max, const auto& p) { return std::max(max, p.first); });

		_layouts = core::Vector<vk::DescriptorSetLayout>(max_set + 1, VK_NULL_HANDLE);
		for(const auto& binding : _bindings) {
			_layouts[binding.first] = device()->create_descriptor_set_layout(binding.second);
		}
	}
	{
		auto vertex_attribs = vert.attributes();
		sort(vertex_attribs.begin(), vertex_attribs.end(), [](const auto& a, const auto& b) { return a.location < b.location; });
		create_vertex_attribs(vertex_attribs, _vertex.bindings, _vertex.attribs);
	}
}

core::Vector<vk::PipelineShaderStageCreateInfo> ShaderProgram::vk_pipeline_stage_info() const {
	return _stages;
}

const core::Vector<vk::DescriptorSetLayout>& ShaderProgram::descriptor_layouts() const {
	return _layouts;
}

}
<|endoftext|>


<commit_before>#ifndef VIENNAGRID_CONFIG_GENERIC_CONFIG_HPP
#define VIENNAGRID_CONFIG_GENERIC_CONFIG_HPP

/* =======================================================================
   Copyright (c) 2011-2012, Institute for Microelectronics,
                            Institute for Analysis and Scientific Computing,
                            TU Wien.

                            -----------------
                     ViennaGrid - The Vienna Grid Library
                            -----------------

   Authors:      Karl Rupp                           rupp@iue.tuwien.ac.at
                 Josef Weinbub                    weinbub@iue.tuwien.ac.at

   (A list of additional contributors can be found in the PDF manual)

   License:      MIT (X11), see file LICENSE in the base directory
======================================================================= */

#include "viennagrid/topology/simplex.hpp"

/** @file config/simplex.hpp
    @brief Provides default configuration classes for simplex domains
*/

namespace viennagrid
{
    namespace result_of
    {
        //
        // Meta Functions for creating a default config
        //

        template<typename element_tag, typename boundary_cell_tag>
        struct storage_layout_config
        {

            typedef typename viennameta::typemap::result_of::insert<
                typename storage_layout_config<element_tag, typename boundary_cell_tag::facet_tag>::type,
                viennameta::static_pair<
                    boundary_cell_tag,
                    viennagrid::full_handling_tag
                    //viennameta::static_pair< viennagrid::full_handling_tag, viennagrid::full_handling_tag >
                >
            >::type type;
        };

        template<typename element_tag>
        struct storage_layout_config<element_tag, viennagrid::vertex_tag>
        {
            //typedef viennameta::static_pair< viennagrid::full_handling_tag, viennagrid::no_handling_tag > type;
            typedef typename viennameta::make_typemap<
                viennagrid::vertex_tag,
                viennagrid::no_orientation_handling_tag
                //viennameta::static_pair< viennagrid::full_handling_tag, viennagrid::no_handling_tag >
            >::type type;
        };

        template<typename element_tag>
        struct storage_layout_config<element_tag, viennameta::null_type>
        {
            //typedef viennameta::static_pair< viennagrid::full_handling_tag, viennagrid::no_handling_tag > type;
            typedef viennameta::null_type type;
        };

        template<typename element_tag, typename boundary_cell_tag>
        struct default_container_tag
        {
            typedef viennagrid::storage::hidden_key_map_tag< viennagrid::storage::element_key_tag< viennagrid::storage::smart_id_tag<int> > > type;
        };

        template<typename element_tag>
        struct default_container_tag<element_tag, element_tag>
        {
            typedef viennagrid::storage::std_deque_tag type;
        };

        template<typename element_tag>
        struct default_container_tag<element_tag, viennagrid::vertex_tag>
        {
            typedef viennagrid::storage::std_deque_tag type;
        };

        template<typename element_tag, typename boundary_cell_tag, typename hook_tag>
        struct default_element_config
        {
            typedef typename viennameta::make_typemap<

                viennagrid::element_id_tag,
                viennagrid::storage::smart_id_tag<int>,

                viennagrid::element_container_tag,
                viennagrid::storage::hooked_container_tag<
                    //viennagrid::storage::std_deque_tag,
                    typename default_container_tag<element_tag, boundary_cell_tag>::type,
                    hook_tag
                >,

                viennagrid::element_boundary_storage_layout_tag,
                typename storage_layout_config<element_tag, typename boundary_cell_tag::facet_tag>::type

            >::type type;
        };

        template<typename element_tag, typename boundary_cell_tag, typename hook_tag>
        struct default_config_helper
        {
            typedef typename viennameta::typemap::result_of::insert<
                typename default_config_helper<element_tag, typename boundary_cell_tag::facet_tag, hook_tag>::type,
                viennameta::static_pair<
                    boundary_cell_tag,
                    typename default_element_config<element_tag, boundary_cell_tag, hook_tag>::type
                >
            >::type type;
        };

        template<typename element_tag, typename hook_tag>
        struct default_config_helper<element_tag, viennagrid::vertex_tag, hook_tag>
        {
            typedef typename viennameta::make_typemap<
                viennagrid::vertex_tag,
                typename default_element_config<element_tag, viennagrid::vertex_tag, hook_tag>::type
            >::type type;
        };

        template<typename element_tag, typename hook_tag>
        struct default_config
        {
            typedef typename default_config_helper<element_tag, element_tag, hook_tag>::type type;
        };
    }
}

#endif
<commit_msg>element_key now only has 1 template argument<commit_after>#ifndef VIENNAGRID_CONFIG_GENERIC_CONFIG_HPP
#define VIENNAGRID_CONFIG_GENERIC_CONFIG_HPP

/* =======================================================================
   Copyright (c) 2011-2012, Institute for Microelectronics,
                            Institute for Analysis and Scientific Computing,
                            TU Wien.

                            -----------------
                     ViennaGrid - The Vienna Grid Library
                            -----------------

   Authors:      Karl Rupp                           rupp@iue.tuwien.ac.at
                 Josef Weinbub                    weinbub@iue.tuwien.ac.at

   (A list of additional contributors can be found in the PDF manual)

   License:      MIT (X11), see file LICENSE in the base directory
======================================================================= */

#include "viennagrid/topology/simplex.hpp"

/** @file config/simplex.hpp
    @brief Provides default configuration classes for simplex domains
*/

namespace viennagrid
{
    namespace result_of
    {
        //
        // Meta Functions for creating a default config
        //

        template<typename element_tag, typename boundary_cell_tag>
        struct storage_layout_config
        {

            typedef typename viennameta::typemap::result_of::insert<
                typename storage_layout_config<element_tag, typename boundary_cell_tag::facet_tag>::type,
                viennameta::static_pair<
                    boundary_cell_tag,
                    viennagrid::full_handling_tag
                    //viennameta::static_pair< viennagrid::full_handling_tag, viennagrid::full_handling_tag >
                >
            >::type type;
        };

        template<typename element_tag>
        struct storage_layout_config<element_tag, viennagrid::vertex_tag>
        {
            //typedef viennameta::static_pair< viennagrid::full_handling_tag, viennagrid::no_handling_tag > type;
            typedef typename viennameta::make_typemap<
                viennagrid::vertex_tag,
                viennagrid::no_orientation_handling_tag
                //viennameta::static_pair< viennagrid::full_handling_tag, viennagrid::no_handling_tag >
            >::type type;
        };

        template<typename element_tag>
        struct storage_layout_config<element_tag, viennameta::null_type>
        {
            //typedef viennameta::static_pair< viennagrid::full_handling_tag, viennagrid::no_handling_tag > type;
            typedef viennameta::null_type type;
        };

        template<typename element_tag, typename boundary_cell_tag>
        struct default_container_tag
        {
            typedef viennagrid::storage::hidden_key_map_tag< viennagrid::storage::element_key_tag > type;
        };

        template<typename element_tag>
        struct default_container_tag<element_tag, element_tag>
        {
            typedef viennagrid::storage::std_deque_tag type;
        };

        template<typename element_tag>
        struct default_container_tag<element_tag, viennagrid::vertex_tag>
        {
            typedef viennagrid::storage::std_deque_tag type;
        };

        template<typename element_tag, typename boundary_cell_tag, typename hook_tag>
        struct default_element_config
        {
            typedef typename viennameta::make_typemap<

                viennagrid::element_id_tag,
                viennagrid::storage::smart_id_tag<int>,

                viennagrid::element_container_tag,
                viennagrid::storage::hooked_container_tag<
                    //viennagrid::storage::std_deque_tag,
                    typename default_container_tag<element_tag, boundary_cell_tag>::type,
                    hook_tag
                >,

                viennagrid::element_boundary_storage_layout_tag,
                typename storage_layout_config<element_tag, typename boundary_cell_tag::facet_tag>::type

            >::type type;
        };

        template<typename element_tag, typename boundary_cell_tag, typename hook_tag>
        struct default_config_helper
        {
            typedef typename viennameta::typemap::result_of::insert<
                typename default_config_helper<element_tag, typename boundary_cell_tag::facet_tag, hook_tag>::type,
                viennameta::static_pair<
                    boundary_cell_tag,
                    typename default_element_config<element_tag, boundary_cell_tag, hook_tag>::type
                >
            >::type type;
        };

        template<typename element_tag, typename hook_tag>
        struct default_config_helper<element_tag, viennagrid::vertex_tag, hook_tag>
        {
            typedef typename viennameta::make_typemap<
                viennagrid::vertex_tag,
                typename default_element_config<element_tag, viennagrid::vertex_tag, hook_tag>::type
            >::type type;
        };

        template<typename element_tag, typename hook_tag>
        struct default_config
        {
            typedef typename default_config_helper<element_tag, element_tag, hook_tag>::type type;
        };
    }
}

#endif
<|endoftext|>


<commit_before>/*##############################################################################
#    GIPPY: Geospatial Image Processing library for Python
#
#    Copyright (C) 2015 Applied Geosolutions
#
#    Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS,
#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#    See the License for the specific language governing permissions and
#    limitations under the License.
##############################################################################*/

#include <gip/GeoResource.h>
#include <boost/filesystem.hpp>

// logging
#include <boost/log/core.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/expressions.hpp>

namespace gip {

    // Options given initial values here
    //boost::filesystem::path Options::_ConfigDir("/usr/share/gip/");
    string Options::_DefaultFormat("GTiff");
    float Options::_ChunkSize(128.0);
    int Options::_Verbose(1);
    string Options::_WorkDir("/tmp/");

    // Constructors
    GeoResource::GeoResource(string filename, bool update)
        : _Filename(filename) {

        // read/write permissions
        GDALAccess access = update ? GA_Update : GA_ReadOnly;
        if (access == GA_ReadOnly)
            CPLSetConfigOption("GDAL_PAM_ENABLED","NO");
        else CPLSetConfigOption("GDAL_PAM_ENABLED",NULL);

        // open dataset
        GDALDataset* ds = (GDALDataset*)GDALOpenShared(_Filename.string().c_str(), access);
        // Check if Update access not supported
        if (ds == NULL) // && CPLGetLastErrorNo() == 6)
            ds = (GDALDataset*)GDALOpenShared(_Filename.string().c_str(), GA_ReadOnly);
        if (ds == NULL) {
            throw std::runtime_error(to_string(CPLGetLastErrorNo()) + ": " + string(CPLGetLastErrorMsg()));
        }
        _GDALDataset.reset(ds);

        // boost logging test
        BOOST_LOG_TRIVIAL(trace) << Basename() << ": GeoResource Open (use_count = " << _GDALDataset.use_count() << ")" << std::endl;

        if (Options::Verbose() > 3)
            std::cout << Basename() << ": GeoResource Open (use_count = " << _GDALDataset.use_count() << ")" << std::endl;
    }

    GeoResource::GeoResource(int xsz, int ysz, int bsz, GDALDataType datatype, string filename, dictionary options)
        : _Filename(filename) {

        // format, driver, and file extension
        string format = Options::DefaultFormat();
        //if (format == "GTiff") options["COMPRESS"] = "LZW";
        GDALDriver *driver = GetGDALDriverManager()->GetDriverByName(format.c_str());
        // TODO check for null driver and create method
        // Check extension
        string ext = driver->GetMetadataItem(GDAL_DMD_EXTENSION);
        if (ext != "" && _Filename.extension().string() != ('.'+ext)) _Filename = boost::filesystem::path(_Filename.string() + '.' + ext);

        // add options
        char **papszOptions = NULL;
        if (options.size()) {
            for (dictionary::const_iterator imap=options.begin(); imap!=options.end(); imap++)
                papszOptions = CSLSetNameValue(papszOptions,imap->first.c_str(),imap->second.c_str());
        }

        // create file
        BOOST_LOG_TRIVIAL(info) << Basename() << ": create new file " << xsz << " x " << ysz << " x " << bsz << std::endl;
        if (Options::Verbose() > 3)
            std::cout << Basename() << ": create new file " << xsz << " x " << ysz << " x " << bsz << std::endl;
        _GDALDataset.reset( driver->Create(_Filename.string().c_str(), xsz,ysz,bsz,datatype, papszOptions) );
        BOOST_LOG_TRIVIAL(fatal) << "Error creating " << _Filename.string() << CPLGetLastErrorMsg() << std::endl;
        if (_GDALDataset.get() == NULL)
            std::cout << "Error creating " << _Filename.string() << CPLGetLastErrorMsg() << std::endl;
    }

    GeoResource::GeoResource(const GeoResource& resource)
        : _Filename(resource._Filename), _GDALDataset(resource._GDALDataset) {}

    GeoResource& GeoResource::operator=(const GeoResource& resource) {
        if (this == &resource) return *this;
        _Filename = resource._Filename;
        _GDALDataset = resource._GDALDataset;
        return *this;
    }

    GeoResource::~GeoResource() {
        // flush GDALDataset if last open pointer
        if (_GDALDataset.unique()) {
            _GDALDataset->FlushCache();
            BOOST_LOG_TRIVIAL(trace) << Basename() << ": ~GeoResource (use_count = " << _GDALDataset.use_count() << ")" << std::endl;
            if (Options::Verbose() > 3) std::cout << Basename() << ": ~GeoResource (use_count = " << _GDALDataset.use_count() << ")" << std::endl;
        }
    }

    // Info
    string GeoResource::Filename() const {
        return _Filename.string();
    }

    path GeoResource::Path() const {
        return _Filename;
    }

    string GeoResource::Basename() const {
        return _Filename.stem().string();
    }

    // Geospatial
    Point<double> GeoResource::GeoLoc(float xloc, float yloc) const {
        CImg<double> affine = Affine();
        Point<double> pt(affine[0] + xloc*affine[1] + yloc*affine[2], affine[3] + xloc*affine[4] + yloc*affine[5]);
        return pt;
    }

    Point<double> GeoResource::TopLeft() const {
        return GeoLoc(0, 0);
    }

    Point<double> GeoResource::LowerLeft() const {
        return GeoLoc(0, YSize()-1);
    }

    Point<double> GeoResource::TopRight() const {
        return GeoLoc(XSize()-1, 0);
    }

    Point<double> GeoResource::LowerRight() const {
        return GeoLoc(XSize()-1, YSize()-1);
    }

    Point<double> GeoResource::MinXY() const {
        Point<double> pt1(TopLeft()), pt2(LowerRight());
        double MinX(std::min(pt1.x(), pt2.x()));
        double MinY(std::min(pt1.y(), pt2.y()));
        return Point<double>(MinX, MinY);
    }

    Point<double> GeoResource::MaxXY() const {
        Point<double> pt1(TopLeft()), pt2(LowerRight());
        double MaxX(std::max(pt1.x(), pt2.x()));
        double MaxY(std::max(pt1.y(), pt2.y()));
        return Point<double>(MaxX, MaxY);
    }

    OGRSpatialReference GeoResource::SRS() const {
        string s(Projection());
        return OGRSpatialReference(s.c_str());
    }

    Point<double> GeoResource::Resolution() const {
        CImg<double> affine = Affine();
        return Point<double>(affine[1], affine[5]);
    }

    GeoResource& GeoResource::SetCoordinateSystem(const GeoResource& res) {
        SetProjection(res.Projection());
        SetAffine(res.Affine());
        return *this;
    }

    ChunkSet GeoResource::Chunks(unsigned int padding, unsigned int numchunks) const {
        return ChunkSet(XSize(), YSize(), padding, numchunks);
    }

    // Metadata
    string GeoResource::Meta(string key) const {
        const char* item = GetGDALObject()->GetMetadataItem(key.c_str());
        return (item == NULL) ? "": item;
    }

    // Get metadata group
    vector<string> GeoResource::MetaGroup(string group, string filter) const {
        char** meta= GetGDALObject()->GetMetadata(group.c_str());
        int num = CSLCount(meta);
        std::vector<string> items;
        for (int i=0;i<num; i++) {
                if (filter != "") {
                        string md = string(meta[i]);
                        string::size_type pos = md.find(filter);
                        if (pos != string::npos) items.push_back(md.substr(pos+filter.length()));
                } else items.push_back( meta[i] );
        }
        return items;
    }

    GeoResource& GeoResource::SetMeta(string key, string item) {
        GetGDALObject()->SetMetadataItem(key.c_str(), item.c_str());
        return *this;
    }

    GeoResource& GeoResource::SetMeta(std::map<string, string> items) {
        for (dictionary::const_iterator i=items.begin(); i!=items.end(); i++) {
            SetMeta(i->first, i->second);
        }
        return *this;
    }

    GeoResource& GeoResource::CopyMeta(const GeoResource& resource) {
        GetGDALObject()->SetMetadata(resource.GetGDALObject()->GetMetadata());
        return *this;
    }

} // namespace gip<commit_msg>added logging<commit_after>/*##############################################################################
#    GIPPY: Geospatial Image Processing library for Python
#
#    Copyright (C) 2015 Applied Geosolutions
#
#    Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS,
#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#    See the License for the specific language governing permissions and
#    limitations under the License.
##############################################################################*/

#include <gip/GeoResource.h>
#include <boost/filesystem.hpp>

// logging
#include <boost/log/core.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/expressions.hpp>

namespace gip {

    // Options given initial values here
    //boost::filesystem::path Options::_ConfigDir("/usr/share/gip/");
    string Options::_DefaultFormat("GTiff");
    float Options::_ChunkSize(128.0);
    int Options::_Verbose(1);
    string Options::_WorkDir("/tmp/");

    // Constructors
    GeoResource::GeoResource(string filename, bool update)
        : _Filename(filename) {

        // read/write permissions
        GDALAccess access = update ? GA_Update : GA_ReadOnly;
        if (access == GA_ReadOnly)
            CPLSetConfigOption("GDAL_PAM_ENABLED","NO");
        else CPLSetConfigOption("GDAL_PAM_ENABLED",NULL);

        // open dataset
        GDALDataset* ds = (GDALDataset*)GDALOpenShared(_Filename.string().c_str(), access);
        // Check if Update access not supported
        if (ds == NULL) // && CPLGetLastErrorNo() == 6)
            ds = (GDALDataset*)GDALOpenShared(_Filename.string().c_str(), GA_ReadOnly);
        if (ds == NULL) {
            throw std::runtime_error(to_string(CPLGetLastErrorNo()) + ": " + string(CPLGetLastErrorMsg()));
        }
        _GDALDataset.reset(ds);

        // boost logging test
        BOOST_LOG_TRIVIAL(trace) << Basename() << ": GeoResource Open (use_count = " << _GDALDataset.use_count() << ")" << std::endl;

        if (Options::Verbose() > 3)
            std::cout << Basename() << ": GeoResource Open (use_count = " << _GDALDataset.use_count() << ")" << std::endl;
    }

    GeoResource::GeoResource(int xsz, int ysz, int bsz, GDALDataType datatype, string filename, dictionary options)
        : _Filename(filename) {

        // format, driver, and file extension
        string format = Options::DefaultFormat();
        //if (format == "GTiff") options["COMPRESS"] = "LZW";
        GDALDriver *driver = GetGDALDriverManager()->GetDriverByName(format.c_str());
        // TODO check for null driver and create method
        // Check extension
        string ext = driver->GetMetadataItem(GDAL_DMD_EXTENSION);
        if (ext != "" && _Filename.extension().string() != ('.'+ext)) _Filename = boost::filesystem::path(_Filename.string() + '.' + ext);

        // add options
        char **papszOptions = NULL;
        if (options.size()) {
            for (dictionary::const_iterator imap=options.begin(); imap!=options.end(); imap++)
                papszOptions = CSLSetNameValue(papszOptions,imap->first.c_str(),imap->second.c_str());
        }

        // create file
        BOOST_LOG_TRIVIAL(info) << Basename() << ": create new file " << xsz << " x " << ysz << " x " << bsz << std::endl;
        if (Options::Verbose() > 3)
            std::cout << Basename() << ": create new file " << xsz << " x " << ysz << " x " << bsz << std::endl;
        _GDALDataset.reset( driver->Create(_Filename.string().c_str(), xsz,ysz,bsz,datatype, papszOptions) );
        if (_GDALDataset.get() == NULL)
            BOOST_LOG_TRIVIAL(fatal) << "Error creating " << _Filename.string() << CPLGetLastErrorMsg() << std::endl;
            std::cout << "Error creating " << _Filename.string() << CPLGetLastErrorMsg() << std::endl;
    }

    GeoResource::GeoResource(const GeoResource& resource)
        : _Filename(resource._Filename), _GDALDataset(resource._GDALDataset) {}

    GeoResource& GeoResource::operator=(const GeoResource& resource) {
        if (this == &resource) return *this;
        _Filename = resource._Filename;
        _GDALDataset = resource._GDALDataset;
        return *this;
    }

    GeoResource::~GeoResource() {
        // flush GDALDataset if last open pointer
        if (_GDALDataset.unique()) {
            _GDALDataset->FlushCache();
            BOOST_LOG_TRIVIAL(trace) << Basename() << ": ~GeoResource (use_count = " << _GDALDataset.use_count() << ")" << std::endl;
            if (Options::Verbose() > 3) std::cout << Basename() << ": ~GeoResource (use_count = " << _GDALDataset.use_count() << ")" << std::endl;
        }
    }

    // Info
    string GeoResource::Filename() const {
        return _Filename.string();
    }

    path GeoResource::Path() const {
        return _Filename;
    }

    string GeoResource::Basename() const {
        return _Filename.stem().string();
    }

    // Geospatial
    Point<double> GeoResource::GeoLoc(float xloc, float yloc) const {
        CImg<double> affine = Affine();
        Point<double> pt(affine[0] + xloc*affine[1] + yloc*affine[2], affine[3] + xloc*affine[4] + yloc*affine[5]);
        return pt;
    }

    Point<double> GeoResource::TopLeft() const {
        return GeoLoc(0, 0);
    }

    Point<double> GeoResource::LowerLeft() const {
        return GeoLoc(0, YSize()-1);
    }

    Point<double> GeoResource::TopRight() const {
        return GeoLoc(XSize()-1, 0);
    }

    Point<double> GeoResource::LowerRight() const {
        return GeoLoc(XSize()-1, YSize()-1);
    }

    Point<double> GeoResource::MinXY() const {
        Point<double> pt1(TopLeft()), pt2(LowerRight());
        double MinX(std::min(pt1.x(), pt2.x()));
        double MinY(std::min(pt1.y(), pt2.y()));
        return Point<double>(MinX, MinY);
    }

    Point<double> GeoResource::MaxXY() const {
        Point<double> pt1(TopLeft()), pt2(LowerRight());
        double MaxX(std::max(pt1.x(), pt2.x()));
        double MaxY(std::max(pt1.y(), pt2.y()));
        return Point<double>(MaxX, MaxY);
    }

    OGRSpatialReference GeoResource::SRS() const {
        string s(Projection());
        return OGRSpatialReference(s.c_str());
    }

    Point<double> GeoResource::Resolution() const {
        CImg<double> affine = Affine();
        return Point<double>(affine[1], affine[5]);
    }

    GeoResource& GeoResource::SetCoordinateSystem(const GeoResource& res) {
        SetProjection(res.Projection());
        SetAffine(res.Affine());
        return *this;
    }

    ChunkSet GeoResource::Chunks(unsigned int padding, unsigned int numchunks) const {
        return ChunkSet(XSize(), YSize(), padding, numchunks);
    }

    // Metadata
    string GeoResource::Meta(string key) const {
        const char* item = GetGDALObject()->GetMetadataItem(key.c_str());
        return (item == NULL) ? "": item;
    }

    // Get metadata group
    vector<string> GeoResource::MetaGroup(string group, string filter) const {
        char** meta= GetGDALObject()->GetMetadata(group.c_str());
        int num = CSLCount(meta);
        std::vector<string> items;
        for (int i=0;i<num; i++) {
                if (filter != "") {
                        string md = string(meta[i]);
                        string::size_type pos = md.find(filter);
                        if (pos != string::npos) items.push_back(md.substr(pos+filter.length()));
                } else items.push_back( meta[i] );
        }
        return items;
    }

    GeoResource& GeoResource::SetMeta(string key, string item) {
        GetGDALObject()->SetMetadataItem(key.c_str(), item.c_str());
        return *this;
    }

    GeoResource& GeoResource::SetMeta(std::map<string, string> items) {
        for (dictionary::const_iterator i=items.begin(); i!=items.end(); i++) {
            SetMeta(i->first, i->second);
        }
        return *this;
    }

    GeoResource& GeoResource::CopyMeta(const GeoResource& resource) {
        GetGDALObject()->SetMetadata(resource.GetGDALObject()->GetMetadata());
        return *this;
    }

} // namespace gip<|endoftext|>


<commit_before><commit_msg>Additional layer of protection to disable funky URLs through view-source in chrome frame <commit_after><|endoftext|>


<commit_before>#include <cstdio>

using namespace std;
const int N = 15 , M = 1e4 +5, OO = 1000000007;

int n;
bool col[N], md[2*N], sd[2*N];
char board[N][N];

void printGrid(){
  puts("---------------------------------");
  for(int i = 0 ; i < n ; ++i){
    for(int j = 0; j < n ; ++j)
      printf("%c", board[i][j]);
    puts("");
  }
  puts("---------------------------------");
}

bool valid(int r, int c){
  return (!col[c] && !md[r-c+N] && !sd[r+c]);
}

void solveNQ(int r = 0){
  if(r == n){
    printGrid();
  }else{
    for(int c = 0 ; c < n ; ++c){
      if(valid(r, c)){
        col[c] = md[r-c+N] = sd[r+c] = 1;     //do
        board[r][c] = 'Q';                    //do
        solveNQ(r+1);                         //recurse
        col[c] = md[r-c+N] = sd[r+c] = 0;     //undo
        board[r][c] = '.';                    //undo
      }
    }
  }
}

int main(){
  scanf("%d", &n);
  for(int i = 0 ; i < n ; ++i)
    for(int j = 0 ; j < n ; ++j)  board[i][j] = '.';
  solveNQ();
  return 0;
}
<commit_msg>edited infinity value<commit_after>#include <cstdio>

using namespace std;
const int N = 15 , M = 1e4 +5, OO = 0x3f3f3f3f;

int n;
bool col[N], md[2*N], sd[2*N];
char board[N][N];

void printGrid(){
  puts("---------------------------------");
  for(int i = 0 ; i < n ; ++i){
    for(int j = 0; j < n ; ++j)
      printf("%c", board[i][j]);
    puts("");
  }
  puts("---------------------------------");
}

bool valid(int r, int c){
  return (!col[c] && !md[r-c+N] && !sd[r+c]);
}

void solveNQ(int r = 0){
  if(r == n){
    printGrid();
  }else{
    for(int c = 0 ; c < n ; ++c){
      if(valid(r, c)){
        col[c] = md[r-c+N] = sd[r+c] = 1;     //do
        board[r][c] = 'Q';                    //do
        solveNQ(r+1);                         //recurse
        col[c] = md[r-c+N] = sd[r+c] = 0;     //undo
        board[r][c] = '.';                    //undo
      }
    }
  }
}

int main(){
  scanf("%d", &n);
  for(int i = 0 ; i < n ; ++i)
    for(int j = 0 ; j < n ; ++j)  board[i][j] = '.';
  solveNQ();
  return 0;
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2008-2010 The QXmpp developers
 *
 * Author:
 *	Manjeet Dahiya
 *
 * Source:
 *	http://code.google.com/p/qxmpp
 *
 * This file is a part of QXmpp library.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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.
 *
 */

#include "vCardCache.h"
#include "utils.h"

#include "QXmppClient.h"
#include "QXmppUtils.h"
#include "QXmppVCardManager.h"

#include <QDir>
#include <QDomDocument>
#include <QCoreApplication>

vCardCache::vCardCache(QXmppClient* client) : QObject(client),
                m_client(client)
{
}

void vCardCache::vCardReceived(const QXmppVCardIq& vcard)
{
    QString from = vcard.from();

    if(from.isEmpty() && m_client)
        from = m_client->configuration().jidBare();

    m_mapBareJidVcard[from] = vcard;

    saveToFile(from);

    emit vCardReadyToUse(from);
}

bool vCardCache::isVCardAvailable(const QString& bareJid)
{
    return m_mapBareJidVcard.contains(bareJid);
}

void vCardCache::requestVCard(const QString& bareJid)
{
    if(m_client)
        m_client->vCardManager().requestVCard(bareJid);
}

//TODO not a good way to handle
QXmppVCardIq& vCardCache::getVCard(const QString& bareJid)
{
    return m_mapBareJidVcard[bareJid];
}

void vCardCache::saveToFile(const QString& bareJid)
{
    QDir dir;
    if(!dir.exists(getSettingsDir(m_client->configuration().jidBare())))
        dir.mkpath(getSettingsDir(m_client->configuration().jidBare()));

    QDir dir2;
    if(!dir2.exists(getSettingsDir(m_client->configuration().jidBare())+ "vCards/"))
        dir2.mkpath(getSettingsDir(m_client->configuration().jidBare())+ "vCards/");

    if(m_mapBareJidVcard.contains(bareJid))
    {
        QString fileVCard = getSettingsDir(m_client->configuration().jidBare()) + "vCards/" + bareJid + ".xml";
        QFile file(fileVCard);

        if(file.open(QIODevice::ReadWrite))
        {
            QXmlStreamWriter stream(&file);
            stream.setAutoFormatting(true);
            stream.setAutoFormattingIndent(2);
            m_mapBareJidVcard[bareJid].toXml(&stream);
            file.close();
        }
    }
}

void vCardCache::loadFromFile()
{
    m_mapBareJidVcard.clear();

    QDir dirVCards(getSettingsDir(m_client->configuration().jidBare())+ "vCards/");
    if(dirVCards.exists())
    {
        QStringList list = dirVCards.entryList(QStringList("*.xml"));
        foreach(QString fileName, list)
        {
            QFile file(getSettingsDir(m_client->configuration().jidBare())+ "vCards/" + fileName);
            QString bareJid = fileName;
            bareJid.chop(4);
            if(file.open(QIODevice::ReadOnly))
            {
                QDomDocument doc;
                if(doc.setContent(&file, true))
                {
                    QXmppVCardIq vCardIq;
                    vCardIq.parse(doc.documentElement());
                    m_mapBareJidVcard[bareJid] = vCardIq;
                    QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
                }
            }
        }
    }
}

//TODO: this should return scaled image
QImage vCardCache::getAvatar(const QString& bareJid) const
{
    if(m_mapBareJidVcard.contains(bareJid))
        return getImageFromByteArray(m_mapBareJidVcard[bareJid].photo());
    else
        return QImage();
}
<commit_msg>mark TODO<commit_after>/*
 * Copyright (C) 2008-2010 The QXmpp developers
 *
 * Author:
 *	Manjeet Dahiya
 *
 * Source:
 *	http://code.google.com/p/qxmpp
 *
 * This file is a part of QXmpp library.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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.
 *
 */

#include "vCardCache.h"
#include "utils.h"

#include "QXmppClient.h"
#include "QXmppUtils.h"
#include "QXmppVCardManager.h"

#include <QDir>
#include <QDomDocument>
#include <QCoreApplication>

vCardCache::vCardCache(QXmppClient* client) : QObject(client),
                m_client(client)
{
}

void vCardCache::vCardReceived(const QXmppVCardIq& vcard)
{
    QString from = vcard.from();

    if(from.isEmpty() && m_client)
        from = m_client->configuration().jidBare();

    m_mapBareJidVcard[from] = vcard;

    saveToFile(from);

    emit vCardReadyToUse(from);
}

bool vCardCache::isVCardAvailable(const QString& bareJid)
{
    return m_mapBareJidVcard.contains(bareJid);
}

// TODO don't request again, if it is already requested
void vCardCache::requestVCard(const QString& bareJid)
{
    if(m_client)
        m_client->vCardManager().requestVCard(bareJid);
}

//TODO not a good way to handle
QXmppVCardIq& vCardCache::getVCard(const QString& bareJid)
{
    return m_mapBareJidVcard[bareJid];
}

void vCardCache::saveToFile(const QString& bareJid)
{
    QDir dir;
    if(!dir.exists(getSettingsDir(m_client->configuration().jidBare())))
        dir.mkpath(getSettingsDir(m_client->configuration().jidBare()));

    QDir dir2;
    if(!dir2.exists(getSettingsDir(m_client->configuration().jidBare())+ "vCards/"))
        dir2.mkpath(getSettingsDir(m_client->configuration().jidBare())+ "vCards/");

    if(m_mapBareJidVcard.contains(bareJid))
    {
        QString fileVCard = getSettingsDir(m_client->configuration().jidBare()) + "vCards/" + bareJid + ".xml";
        QFile file(fileVCard);

        if(file.open(QIODevice::ReadWrite))
        {
            QXmlStreamWriter stream(&file);
            stream.setAutoFormatting(true);
            stream.setAutoFormattingIndent(2);
            m_mapBareJidVcard[bareJid].toXml(&stream);
            file.close();
        }
    }
}

void vCardCache::loadFromFile()
{
    m_mapBareJidVcard.clear();

    QDir dirVCards(getSettingsDir(m_client->configuration().jidBare())+ "vCards/");
    if(dirVCards.exists())
    {
        QStringList list = dirVCards.entryList(QStringList("*.xml"));
        foreach(QString fileName, list)
        {
            QFile file(getSettingsDir(m_client->configuration().jidBare())+ "vCards/" + fileName);
            QString bareJid = fileName;
            bareJid.chop(4);
            if(file.open(QIODevice::ReadOnly))
            {
                QDomDocument doc;
                if(doc.setContent(&file, true))
                {
                    QXmppVCardIq vCardIq;
                    vCardIq.parse(doc.documentElement());
                    m_mapBareJidVcard[bareJid] = vCardIq;
                    QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
                }
            }
        }
    }
}

//TODO: this should return scaled image
QImage vCardCache::getAvatar(const QString& bareJid) const
{
    if(m_mapBareJidVcard.contains(bareJid))
        return getImageFromByteArray(m_mapBareJidVcard[bareJid].photo());
    else
        return QImage();
}
<|endoftext|>


<commit_before>// Copyright (c) 2014 Quanta Research Cambridge, Inc.

// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <pthread.h>

//#define LIBNAME EXECDIRECTORY "/libHdmi.so"

typedef int (*qtmain_t)(void *param);
typedef void (*show_data_t)(unsigned int vsync, unsigned int hsync, unsigned int de, unsigned int data);

static show_data_t show_data;
static pthread_t threaddata;
static unsigned int vsync, hsync, de;

static void startmeup()
{
    void* handle = dlopen(LIBNAME, RTLD_LAZY);
    if (!handle) {
        printf( "Cannot open library\n");
        exit(-1);
    }
    printf("Loading symbol qtmain...\n");
    dlerror();
    qtmain_t qtmain = (qtmain_t) dlsym(handle, "qtmain");
    const char *dlsym_error = dlerror();
    if (dlsym_error) {
        printf( "Cannot load symbol 'qtmain': %s\n", dlsym_error);
        dlclose(handle);
        exit(-1);
    }
    show_data = (show_data_t) dlsym(handle, "show_data");
    dlsym_error = dlerror();
    if (dlsym_error) {
        printf( "Cannot load symbol 'show_data': %s\n", dlsym_error);
        dlclose(handle);
        exit(-1);
    }
    printf( "Calling qtmain...\n");
    pthread_create(&threaddata, NULL, (void* (*)(void*))qtmain, (void*)NULL);
    //dlclose(handle);
}

extern "C" void bdpi_hdmi_vsync(unsigned int v)
{
    vsync = v;
}

extern "C" void bdpi_hdmi_hsync(unsigned int v)
{
    hsync = v;
}

extern "C" void bdpi_hdmi_de(unsigned int v)
{
    de = v;
}

extern "C" void bdpi_hdmi_data(unsigned int v)
{
    static int once = 1;
    if (once)
       startmeup();
    once = 0;
    if (show_data)
        show_data(vsync, hsync, de, v);
    else
        printf("v %x; h %x; e %x = %4x\n", vsync, hsync, de, v);
}
<commit_msg>for examples/hdmidisplay/bluesim, make running X display optional<commit_after>// Copyright (c) 2014 Quanta Research Cambridge, Inc.

// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <pthread.h>

//#define LIBNAME EXECDIRECTORY "/libHdmi.so"

static int run_xwindows = 1;
typedef int (*qtmain_t)(void *param);
typedef void (*show_data_t)(unsigned int vsync, unsigned int hsync, unsigned int de, unsigned int data);

static show_data_t show_data;
static pthread_t threaddata;
static unsigned int vsync, hsync, de;
static int trace_data;//= 1;

static void startmeup()
{
    void* handle = dlopen(LIBNAME, RTLD_LAZY);
    if (!handle) {
        printf( "Cannot open library\n");
        exit(-1);
    }
    printf("Loading library for qtmain...\n");
    dlerror();
    if (!run_xwindows) {
        printf( "Not calling qtmain...\n");
        return;
    }
    qtmain_t qtmain = (qtmain_t) dlsym(handle, "qtmain");
    const char *dlsym_error = dlerror();
    if (dlsym_error) {
        printf( "Cannot load symbol 'qtmain': %s\n", dlsym_error);
        dlclose(handle);
        exit(-1);
    }
    show_data = (show_data_t) dlsym(handle, "show_data");
    dlsym_error = dlerror();
    if (dlsym_error) {
        printf( "Cannot load symbol 'show_data': %s\n", dlsym_error);
        dlclose(handle);
        exit(-1);
    }
    printf( "Calling qtmain...\n");
    pthread_create(&threaddata, NULL, (void* (*)(void*))qtmain, (void*)NULL);
    //dlclose(handle);
}

extern "C" void bdpi_hdmi_vsync(unsigned int v)
{
    vsync = v;
}

extern "C" void bdpi_hdmi_hsync(unsigned int v)
{
    hsync = v;
}

extern "C" void bdpi_hdmi_de(unsigned int v)
{
    de = v;
}

extern "C" void bdpi_hdmi_data(unsigned int v)
{
    static int once = 1;
    if (once)
       startmeup();
    once = 0;
    if (show_data)
        show_data(vsync, hsync, de, v);
    else if (trace_data)
        printf("bdpi_hdmi_data: v %x; h %x; e %x = %4x\n", vsync, hsync, de, v);
}
<|endoftext|>


<commit_before>#include <QCoreApplication>
#include <QSettings>
#include <QDir>
#include <QDesktopServices>
#include <QJsonDocument>
#include "kernel.h"
#include "ilwisdata.h"
#include "errorobject.h"
#include "abstractfactory.h"
#include "connectorinterface.h"
#include "ilwisobjectconnector.h"
#include "catalogconnector.h"
#include "catalog.h"
#include "ilwiscontext.h"
#include "mastercatalog.h"

Ilwis::IlwisContext *Ilwis::IlwisContext::_context = 0;

using namespace Ilwis;

IlwisContext* Ilwis::context() {
    if (Ilwis::IlwisContext::_context == 0) {
        Ilwis::IlwisContext::_context = new Ilwis::IlwisContext();
        Ilwis::IlwisContext::_context->init();

    }
    return Ilwis::IlwisContext::_context;
}

IlwisContext::IlwisContext() : _workingCatalog(0), _memoryLimit(9e8), _memoryLeft(_memoryLimit)
{
    QDir localDir(QStandardPaths::writableLocation(QStandardPaths::CacheLocation));
    _cacheLocation = QUrl::fromLocalFile(localDir.absolutePath());
    QStringList files = localDir.entryList(QStringList() << "*.*", QDir::Files);
    foreach(QString file, files)
        localDir.remove(file);
    _workingCatalog = new Catalog(); // empty catalog>
}

IlwisContext::~IlwisContext()
{
}

void IlwisContext::addSystemLocation(const QUrl &resource)
{
    if ( std::find(_systemlocations.begin(), _systemlocations.end(), resource) == _systemlocations.end() ) {
        _systemlocations.push_back(resource);
    }

}

void IlwisContext::removeSystemLocation(const QUrl &)
{
    //TODO:
}

void IlwisContext::loadConfigFile(QFileInfo configFile){
    if (configFile.exists()){
        QSettings settings(configFile.filePath(), QSettings::IniFormat);
        this->_ilwisDir = QFileInfo(settings.value("ilwisDir").toString());
        if (!this->_ilwisDir.isDir()){
            printf_s("Ilwis directory %s from config file not found\n",this->_ilwisDir.filePath().toStdString().c_str());
            this->_ilwisDir = QFileInfo( qApp->applicationDirPath());
        }
    }else{
        this->_ilwisDir = QFileInfo( qApp->applicationDirPath());
    }
}

QFileInfo IlwisContext::ilwisFolder() const {
    return this->_ilwisDir;
}

void IlwisContext::init()
{
    QString loc = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation);
    QString configfile = loc + "/" + "ilwis.config";
    QFile file;
    file.setFileName(configfile);
    if (file.open(QIODevice::ReadOnly)) {
        QString settings = file.readAll();
        QJsonDocument doc = QJsonDocument::fromJson(settings.toUtf8());
        if ( !doc.isNull())
            _configuration = doc.object();
    }
    this->_ilwisDir = QFileInfo( qApp->applicationDirPath());
}

ICatalog IlwisContext::workingCatalog() const{
//    if ( _workingCatalog.hasLocalData())
//        return static_cast<Catalog *>(_workingCatalog.localData());

    return _workingCatalog;
}

void IlwisContext::setWorkingCatalog(const ICatalog &cat)
{
    mastercatalog()->addContainer(cat->source().url());
    _workingCatalog = cat;
}

QUrl IlwisContext::cacheLocation() const
{
    return _cacheLocation;
}

quint64 IlwisContext::memoryLeft() const
{
    return _memoryLeft;
}
quint64 IlwisContext::changeMemoryLeft(quint64 amount)
{
    if ( _memoryLeft + std::abs(amount) > 0) {
        _memoryLeft += amount;
    }
    else
        _memoryLeft = 0;

    return _memoryLeft;
}

QJsonObject IlwisContext::configuration() const
{
    return _configuration;
}

<commit_msg>renaming header file<commit_after>#include <QCoreApplication>
#include <QSettings>
#include <QDir>
#include <QDesktopServices>
#include <QJsonDocument>
#include "kernel.h"
#include "ilwisdata.h"
#include "errorobject.h"
#include "abstractfactory.h"
#include "connectorinterface.h"
#include "ilwisobjectconnector.h"
#include "catalogexplorer.h"
#include "catalogconnector.h"
#include "catalog.h"
#include "ilwiscontext.h"
#include "mastercatalog.h"

Ilwis::IlwisContext *Ilwis::IlwisContext::_context = 0;

using namespace Ilwis;

IlwisContext* Ilwis::context() {
    if (Ilwis::IlwisContext::_context == 0) {
        Ilwis::IlwisContext::_context = new Ilwis::IlwisContext();
        Ilwis::IlwisContext::_context->init();

    }
    return Ilwis::IlwisContext::_context;
}

IlwisContext::IlwisContext() : _workingCatalog(0), _memoryLimit(9e8), _memoryLeft(_memoryLimit)
{
    QDir localDir(QStandardPaths::writableLocation(QStandardPaths::CacheLocation));
    _cacheLocation = QUrl::fromLocalFile(localDir.absolutePath());
    QStringList files = localDir.entryList(QStringList() << "*.*", QDir::Files);
    foreach(QString file, files)
        localDir.remove(file);
    _workingCatalog = new Catalog(); // empty catalog>
}

IlwisContext::~IlwisContext()
{
}

void IlwisContext::addSystemLocation(const QUrl &resource)
{
    if ( std::find(_systemlocations.begin(), _systemlocations.end(), resource) == _systemlocations.end() ) {
        _systemlocations.push_back(resource);
    }

}

void IlwisContext::removeSystemLocation(const QUrl &)
{
    //TODO:
}

void IlwisContext::loadConfigFile(QFileInfo configFile){
    if (configFile.exists()){
        QSettings settings(configFile.filePath(), QSettings::IniFormat);
        this->_ilwisDir = QFileInfo(settings.value("ilwisDir").toString());
        if (!this->_ilwisDir.isDir()){
            printf_s("Ilwis directory %s from config file not found\n",this->_ilwisDir.filePath().toStdString().c_str());
            this->_ilwisDir = QFileInfo( qApp->applicationDirPath());
        }
    }else{
        this->_ilwisDir = QFileInfo( qApp->applicationDirPath());
    }
}

QFileInfo IlwisContext::ilwisFolder() const {
    return this->_ilwisDir;
}

void IlwisContext::init()
{
    QString loc = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation);
    QString configfile = loc + "/" + "ilwis.config";
    QFile file;
    file.setFileName(configfile);
    if (file.open(QIODevice::ReadOnly)) {
        QString settings = file.readAll();
        QJsonDocument doc = QJsonDocument::fromJson(settings.toUtf8());
        if ( !doc.isNull())
            _configuration = doc.object();
    }
    this->_ilwisDir = QFileInfo( qApp->applicationDirPath());
}

ICatalog IlwisContext::workingCatalog() const{
//    if ( _workingCatalog.hasLocalData())
//        return static_cast<Catalog *>(_workingCatalog.localData());

    return _workingCatalog;
}

void IlwisContext::setWorkingCatalog(const ICatalog &cat)
{
    mastercatalog()->addContainer(cat->source().url());
    _workingCatalog = cat;
}

QUrl IlwisContext::cacheLocation() const
{
    return _cacheLocation;
}

quint64 IlwisContext::memoryLeft() const
{
    return _memoryLeft;
}
quint64 IlwisContext::changeMemoryLeft(quint64 amount)
{
    if ( _memoryLeft + std::abs(amount) > 0) {
        _memoryLeft += amount;
    }
    else
        _memoryLeft = 0;

    return _memoryLeft;
}

QJsonObject IlwisContext::configuration() const
{
    return _configuration;
}

<|endoftext|>