<commit_before>// This file is part of BlueSky
//
// BlueSky 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 3
// of the License, or (at your option) any later version.
//
// BlueSky is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with BlueSky; if not, see <http://www.gnu.org/licenses/>.

#include "bs_link.h"
#include "bs_tree.h"
#include "py_bs_exports.h"
#include "py_smart_ptr.h"

namespace blue_sky { namespace python {

using namespace boost::python;

namespace {
using namespace std;
// objbase wrapper
class bs_link_pyw : public bs_link, public wrapper< bs_link > {
public:
	string name() const {
		if(override f = this->get_override("name"))
			return (const string&)f();
		else
			return bs_link::name();
	}

	string default_name() const {
		return bs_link::name();
	}

	bool is_node() const {
		if(override f = this->get_override("is_node"))
			return f();
		else
			return bs_link::is_node();
	}

	bool default_is_node() const {
		return bs_link::is_node();
	}

	link_type link_type_id() const {
		if(override f = this->get_override("link_type_id"))
			return f();
		else
			return bs_link::link_type_id();
	}

	link_type default_link_type_id() const {
		return bs_link::link_type_id();
	}

	sp_link clone(const std::string& clone_name = "") const {
		if(override f = this->get_override("clone"))
			return f(clone_name);
		else
			return bs_link::clone(clone_name);
	}

	sp_link default_clone(const std::string& clone_name = "") const {
		return bs_link::clone(clone_name);
	}

	sp_node parent() const {
		if(override f = this->get_override("parent"))
			return f();
		else
			return bs_link::parent();
	}
	sp_node def_parent() const {
		return bs_link::parent();
	}
};

// link hash is it's address - so multiple smart_ptrs poining to the same link will have
// identical hashes
ulong link_hash(const bs_link& l) {
	return reinterpret_cast< ulong >(&l);
	//return uint(big_hash);
}

}

// exporting function
void py_bind_link() {
	// bs_inode binding
	class_<
		bs_inode,
		smart_ptr< bs_inode, true >,
		bases< bs_refcounter >,
		boost::noncopyable
		>
	("inode", no_init)
		.add_property("size", &bs_inode::size)
		.add_property("uid", &bs_inode::uid)
		.add_property("gid", &bs_inode::gid)
		.add_property("mode", &bs_inode::mode)
		.add_property("mtime", &bs_inode::mtime)
		.def("links_begin", &bs_inode::links_begin)
		.def("links_end", &bs_inode::links_end)
		.add_property("links_count", &bs_inode::links_count)
		.add_property("data", &bs_inode::data)
		;

	// bs_link binding
	class_<
		bs_link_pyw,
		smart_ptr< bs_link_pyw, true >,
		bases< objbase >,
		boost::noncopyable
		>
	("link", no_init)
		.def("__hash__", &link_hash)
		.def("create", &bs_link::create)
		.staticmethod("create")
		.def("bs_type", &bs_link::bs_type)
		.staticmethod("bs_type")
		.def("bs_resolve_type", &bs_link::bs_resolve_type)
		.add_property("inode", &bs_link::inode)
		.add_property("data", &bs_link::data)
		.def("name", &bs_link::name, &bs_link_pyw::default_name)
		.def("is_node", &bs_link::is_node, &bs_link_pyw::default_is_node)
		.add_property("node", &bs_link::node)
		.def("is_hard_link", &bs_link::is_hard_link)
		.def("link_type_id", &bs_link::link_type_id, &bs_link_pyw::default_link_type_id)
		.def("clone", &bs_link::clone, &bs_link_pyw::default_clone)
		.def("dumb_link", &bs_link::dumb_link)
		.def("parent", &bs_link::parent, &bs_link_pyw::def_parent)
		;

	// register smart_ptr conversions
	implicitly_convertible< smart_ptr< bs_link_pyw, true >, blue_sky::smart_ptr< bs_link, true > >();
	register_ptr_to_python< blue_sky::smart_ptr< bs_link, true > >();

	// bs_alias bindings
	class_<
		bs_alias,
		smart_ptr< bs_alias >,
		bases< bs_link >,
		boost::noncopyable
		>
	("alias", no_init)
		.def("create", &bs_alias::create)
		.staticmethod("create")
		.def("bs_type", &bs_alias::bs_type)
		.staticmethod("bs_type")
		.def("bs_resolve_type", &bs_alias::bs_resolve_type)
		.def("clone", &bs_alias::clone)
		.def("link_type_id", &bs_alias::link_type_id)
		;
}

}}	// eof namespace blue_sky::python

<commit_msg>TREE.Python: hash for bs_link always output std::size_t<commit_after>// This file is part of BlueSky
//
// BlueSky 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 3
// of the License, or (at your option) any later version.
//
// BlueSky is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with BlueSky; if not, see <http://www.gnu.org/licenses/>.

#include "bs_link.h"
#include "bs_tree.h"
#include "py_bs_exports.h"
#include "py_smart_ptr.h"

namespace blue_sky { namespace python {

using namespace boost::python;

namespace {
using namespace std;
// objbase wrapper
class bs_link_pyw : public bs_link, public wrapper< bs_link > {
public:
	string name() const {
		if(override f = this->get_override("name"))
			return (const string&)f();
		else
			return bs_link::name();
	}

	string default_name() const {
		return bs_link::name();
	}

	bool is_node() const {
		if(override f = this->get_override("is_node"))
			return f();
		else
			return bs_link::is_node();
	}

	bool default_is_node() const {
		return bs_link::is_node();
	}

	link_type link_type_id() const {
		if(override f = this->get_override("link_type_id"))
			return f();
		else
			return bs_link::link_type_id();
	}

	link_type default_link_type_id() const {
		return bs_link::link_type_id();
	}

	sp_link clone(const std::string& clone_name = "") const {
		if(override f = this->get_override("clone"))
			return f(clone_name);
		else
			return bs_link::clone(clone_name);
	}

	sp_link default_clone(const std::string& clone_name = "") const {
		return bs_link::clone(clone_name);
	}

	sp_node parent() const {
		if(override f = this->get_override("parent"))
			return f();
		else
			return bs_link::parent();
	}
	sp_node def_parent() const {
		return bs_link::parent();
	}
};

// link hash is it's address - so multiple smart_ptrs poining to the same link will have
// identical hashes
std::size_t link_hash(const bs_link& l) {
	return reinterpret_cast< std::size_t >(&l);
	//return uint(big_hash);
}

}

// exporting function
void py_bind_link() {
	// bs_inode binding
	class_<
		bs_inode,
		smart_ptr< bs_inode, true >,
		bases< bs_refcounter >,
		boost::noncopyable
		>
	("inode", no_init)
		.add_property("size", &bs_inode::size)
		.add_property("uid", &bs_inode::uid)
		.add_property("gid", &bs_inode::gid)
		.add_property("mode", &bs_inode::mode)
		.add_property("mtime", &bs_inode::mtime)
		.def("links_begin", &bs_inode::links_begin)
		.def("links_end", &bs_inode::links_end)
		.add_property("links_count", &bs_inode::links_count)
		.add_property("data", &bs_inode::data)
		;

	// bs_link binding
	class_<
		bs_link_pyw,
		smart_ptr< bs_link_pyw, true >,
		bases< objbase >,
		boost::noncopyable
		>
	("link", no_init)
		.def("__hash__", &link_hash)
		.def("create", &bs_link::create)
		.staticmethod("create")
		.def("bs_type", &bs_link::bs_type)
		.staticmethod("bs_type")
		.def("bs_resolve_type", &bs_link::bs_resolve_type)
		.add_property("inode", &bs_link::inode)
		.add_property("data", &bs_link::data)
		.def("name", &bs_link::name, &bs_link_pyw::default_name)
		.def("is_node", &bs_link::is_node, &bs_link_pyw::default_is_node)
		.add_property("node", &bs_link::node)
		.def("is_hard_link", &bs_link::is_hard_link)
		.def("link_type_id", &bs_link::link_type_id, &bs_link_pyw::default_link_type_id)
		.def("clone", &bs_link::clone, &bs_link_pyw::default_clone)
		.def("dumb_link", &bs_link::dumb_link)
		.def("parent", &bs_link::parent, &bs_link_pyw::def_parent)
		;

	// register smart_ptr conversions
	implicitly_convertible< smart_ptr< bs_link_pyw, true >, blue_sky::smart_ptr< bs_link, true > >();
	register_ptr_to_python< blue_sky::smart_ptr< bs_link, true > >();

	// bs_alias bindings
	class_<
		bs_alias,
		smart_ptr< bs_alias >,
		bases< bs_link >,
		boost::noncopyable
		>
	("alias", no_init)
		.def("create", &bs_alias::create)
		.staticmethod("create")
		.def("bs_type", &bs_alias::bs_type)
		.staticmethod("bs_type")
		.def("bs_resolve_type", &bs_alias::bs_resolve_type)
		.def("clone", &bs_alias::clone)
		.def("link_type_id", &bs_alias::link_type_id)
		;
}

}}	// eof namespace blue_sky::python

<|endoftext|>


<commit_before>/* Copyright 2009 Klarälvdalens Datakonsult AB

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License as
   published by the Free Software Foundation; either version 2 of
   the License or (at your option) version 3 or any later version
   accepted by the membership of KDE e.V. (or its successor approved
   by the membership of KDE e.V.), which shall act as a proxy
   defined in Section 14 of version 3 of the license.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "archivefolderdialog.h"

#include "backupjob.h"
#include "kmkernel.h"
#include "kmfolder.h"
#include "kmmainwidget.h"
#include "folderrequester.h"
#include "util.h"

#include <klocale.h>
#include <kcombobox.h>
#include <kurlrequester.h>
#include <kmessagebox.h>

#include <qlabel.h>
#include <qcheckbox.h>
#include <qlayout.h>

using namespace KMail;

static QString standardArchivePath( const QString &folderName )
{
  QString currentPath = KGlobalSettings::documentPath();
  QDir dir( currentPath );
  if( !dir.exists() )
    currentPath = QDir::homePath();
  return currentPath + '/' +
    i18nc( "Start of the filename for a mail archive file" , "Archive" ) + '_' + folderName + '_' + QDate::currentDate().toString( Qt::ISODate ) + ".zip";
}

ArchiveFolderDialog::ArchiveFolderDialog( QWidget *parent )
  : KDialog( parent ), mParentWidget( parent )
{
  setObjectName( "archive_folder_dialog" );
  setCaption( i18n( "Archive Folder" ) );
  setButtons( Ok|Cancel );
  setDefaultButton( Ok );
  setModal( true );
  QWidget *mainWidget = new QWidget( this );
  QGridLayout *mainLayout = new QGridLayout( mainWidget );
  mainLayout->setSpacing( KDialog::spacingHint() );
  mainLayout->setMargin( KDialog::marginHint() );
  setMainWidget( mainWidget );

  int row = 0;

  // TODO: better label for "Ok" button
  // TODO: Explaination label
  // TODO: Use QFormLayout in KDE4

  QLabel *folderLabel = new QLabel( i18n( "&Folder:" ), mainWidget );
  mainLayout->addWidget( folderLabel, row, 0 );
  mFolderRequester = new FolderRequester( mainWidget );
  mFolderRequester->setMustBeReadWrite( false );
  mFolderRequester->setFolderTree( kmkernel->getKMMainWidget()->mainFolderView() );
  connect( mFolderRequester, SIGNAL( folderChanged( KMFolder* ) ), SLOT( slotFolderChanged( KMFolder* ) ) );
  folderLabel->setBuddy( mFolderRequester );
  mainLayout->addWidget( mFolderRequester, row, 1 );
  row++;

  QLabel *formatLabel = new QLabel( i18n( "F&ormat:" ), mainWidget );
  mainLayout->addWidget( formatLabel, row, 0 );
  mFormatComboBox = new KComboBox( mainWidget );
  formatLabel->setBuddy( mFormatComboBox );

  // These combobox values have to stay in sync with the ArchiveType enum from BackupJob!
  mFormatComboBox->addItem( i18n( "Compressed Zip Archive (.zip)" ) );
  mFormatComboBox->addItem( i18n( "Uncompressed Archive (.tar)" ) );
  mFormatComboBox->addItem( i18n( "BZ2-Compressed Tar Archive (.tar.bz2)" ) );
  mFormatComboBox->addItem( i18n( "GZ-Compressed Tar Archive (.tar.gz)" ) );
  mFormatComboBox->setCurrentIndex( 0 );
  connect( mFormatComboBox, SIGNAL(activated(int)),
           this, SLOT(slotFixFileExtension()) );
  mainLayout->addWidget( mFormatComboBox, row, 1 );
  row++;

  QLabel *fileNameLabel = new QLabel( i18n( "&Archive File:" ), mainWidget );
  mainLayout->addWidget( fileNameLabel, row, 0 );
  mUrlRequester = new KUrlRequester( mainWidget );
  mUrlRequester->setMode( KFile::LocalOnly | KFile::File );
  mUrlRequester->setFilter( "*.tar *.zip *.tar.gz *.tar.bz2" );
  fileNameLabel->setBuddy( mUrlRequester );
  connect( mUrlRequester->lineEdit(), SIGNAL(textChanged(const QString &)), SLOT( slotUrlChanged(const QString&)));
  connect( mUrlRequester, SIGNAL(urlSelected(const KUrl&)),
           this, SLOT(slotFixFileExtension()) );
  mainLayout->addWidget( mUrlRequester, row, 1 );
  row++;

  // TODO: Make this appear more dangerous!
  mDeleteCheckBox = new QCheckBox( i18n( "&Delete folders after completion" ), mainWidget );
  mainLayout->addWidget( mDeleteCheckBox, row, 0, 1, 2, Qt::AlignLeft );
  row++;

  // TODO: what's this, tooltips

  // TODO: Warn that user should do mail check for online IMAP and possibly cached IMAP as well

  mainLayout->setColumnStretch( 1, 1 );
  mainLayout->addItem( new QSpacerItem( 1, 1, QSizePolicy::Expanding, QSizePolicy::Expanding ), row, 0 );

  // Make it a bit bigger, else the folder requester cuts off the text too early
  resize( 500, minimumSize().height() );
}

void ArchiveFolderDialog::slotUrlChanged( const QString & text)
{
  enableButtonOk( !text.isEmpty() );
}

bool canRemoveFolder( KMFolder *folder )
{
  return folder && folder->canDeleteMessages() && !folder->noContent() && !folder->isSystemFolder();
}

void ArchiveFolderDialog::slotFolderChanged( KMFolder *folder )
{
  mDeleteCheckBox->setEnabled( canRemoveFolder( folder ));
  enableButtonOk( folder && !folder->noContent());
}

void ArchiveFolderDialog::setFolder( KMFolder *defaultFolder )
{
  mFolderRequester->setFolder( defaultFolder );
  // TODO: what if the file already exists?
  mUrlRequester->setUrl( standardArchivePath( defaultFolder->name() ) );
  mDeleteCheckBox->setEnabled( canRemoveFolder( defaultFolder ) );
}

void ArchiveFolderDialog::slotButtonClicked( int button )
{
  if ( button == KDialog::Cancel ) {
    reject();
    return;
  }
  Q_ASSERT( button == KDialog::Ok );

  if ( !Util::checkOverwrite( mUrlRequester->url(), this ) ) {
    return;
  }

  if ( !mFolderRequester->folder() ) {
    KMessageBox::information( this, i18n( "Please select the folder that should be archived." ),
                              i18n( "No folder selected" ) );
    return;
  }

  KMail::BackupJob *backupJob = new KMail::BackupJob( mParentWidget );
  backupJob->setRootFolder( mFolderRequester->folder() );
  backupJob->setSaveLocation( mUrlRequester->url() );
  backupJob->setArchiveType( static_cast<BackupJob::ArchiveType>( mFormatComboBox->currentIndex() ) );
  backupJob->setDeleteFoldersAfterCompletion( mDeleteCheckBox->isEnabled() && mDeleteCheckBox->isChecked() );
  backupJob->start();
  accept();
}

void ArchiveFolderDialog::slotFixFileExtension()
{
  // KDE4: use KMimeType::extractKnownExtension() here
  const int numExtensions = 4;

  // These extensions are sorted differently, .tar has to come last, or it will match before giving
  // the more specific ones time to match.
  const char *sortedExtensions[numExtensions] = { ".zip", ".tar.bz2", ".tar.gz", ".tar" };

  // The extensions here are also sorted, like the enum order of BackupJob::ArchiveType
  const char *extensions[numExtensions] = { ".zip", ".tar", ".tar.bz2", ".tar.gz" };

  QString fileName = mUrlRequester->url().path();
  if ( fileName.isEmpty() )
    fileName = standardArchivePath( mFolderRequester->folder() ? mFolderRequester->folder()->name() : "" );

  // First, try to find the extension of the file name and remove it
  for( int i = 0; i < numExtensions; i++ ) {
    int index = fileName.toLower().lastIndexOf( sortedExtensions[i] );
    if ( index != -1 ) {
      fileName = fileName.left( fileName.length() - QString( sortedExtensions[i] ).length() );
      break;
    }
  }

  // Now, we've got a filename without an extension, simply append the correct one
  fileName += extensions[mFormatComboBox->currentIndex()];
  mUrlRequester->setUrl( fileName );
}

#include "archivefolderdialog.moc"
<commit_msg>SVN_MERGE: Merged revisions 1071227 via svnmerge from svn+ssh://tmcguire@svn.kde.org/home/kde/branches/kdepim/enterprise4/kdepim<commit_after>/* Copyright 2009 Klarälvdalens Datakonsult AB

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License as
   published by the Free Software Foundation; either version 2 of
   the License or (at your option) version 3 or any later version
   accepted by the membership of KDE e.V. (or its successor approved
   by the membership of KDE e.V.), which shall act as a proxy
   defined in Section 14 of version 3 of the license.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "archivefolderdialog.h"

#include "backupjob.h"
#include "kmkernel.h"
#include "kmfolder.h"
#include "kmmainwidget.h"
#include "folderrequester.h"
#include "util.h"

#include <klocale.h>
#include <kcombobox.h>
#include <kurlrequester.h>
#include <kmessagebox.h>

#include <qlabel.h>
#include <qcheckbox.h>
#include <qlayout.h>

using namespace KMail;

static QString standardArchivePath( const QString &folderName )
{
  QString currentPath = KGlobalSettings::documentPath();
  QDir dir( currentPath );
  if( !dir.exists() )
    currentPath = QDir::homePath();
  return currentPath + '/' +
    i18nc( "Start of the filename for a mail archive file" , "Archive" ) + '_' + folderName + '_' + QDate::currentDate().toString( Qt::ISODate ) + ".tar.bz2";
}

ArchiveFolderDialog::ArchiveFolderDialog( QWidget *parent )
  : KDialog( parent ), mParentWidget( parent )
{
  setObjectName( "archive_folder_dialog" );
  setCaption( i18n( "Archive Folder" ) );
  setButtons( Ok|Cancel );
  setDefaultButton( Ok );
  setModal( true );
  QWidget *mainWidget = new QWidget( this );
  QGridLayout *mainLayout = new QGridLayout( mainWidget );
  mainLayout->setSpacing( KDialog::spacingHint() );
  mainLayout->setMargin( KDialog::marginHint() );
  setMainWidget( mainWidget );

  int row = 0;

  // TODO: better label for "Ok" button
  // TODO: Explaination label
  // TODO: Use QFormLayout in KDE4

  QLabel *folderLabel = new QLabel( i18n( "&Folder:" ), mainWidget );
  mainLayout->addWidget( folderLabel, row, 0 );
  mFolderRequester = new FolderRequester( mainWidget );
  mFolderRequester->setMustBeReadWrite( false );
  mFolderRequester->setFolderTree( kmkernel->getKMMainWidget()->mainFolderView() );
  connect( mFolderRequester, SIGNAL( folderChanged( KMFolder* ) ), SLOT( slotFolderChanged( KMFolder* ) ) );
  folderLabel->setBuddy( mFolderRequester );
  mainLayout->addWidget( mFolderRequester, row, 1 );
  row++;

  QLabel *formatLabel = new QLabel( i18n( "F&ormat:" ), mainWidget );
  mainLayout->addWidget( formatLabel, row, 0 );
  mFormatComboBox = new KComboBox( mainWidget );
  formatLabel->setBuddy( mFormatComboBox );

  // These combobox values have to stay in sync with the ArchiveType enum from BackupJob!
  mFormatComboBox->addItem( i18n( "Compressed Zip Archive (.zip)" ) );
  mFormatComboBox->addItem( i18n( "Uncompressed Archive (.tar)" ) );
  mFormatComboBox->addItem( i18n( "BZ2-Compressed Tar Archive (.tar.bz2)" ) );
  mFormatComboBox->addItem( i18n( "GZ-Compressed Tar Archive (.tar.gz)" ) );
  mFormatComboBox->setCurrentIndex( 2 );
  connect( mFormatComboBox, SIGNAL(activated(int)),
           this, SLOT(slotFixFileExtension()) );
  mainLayout->addWidget( mFormatComboBox, row, 1 );
  row++;

  QLabel *fileNameLabel = new QLabel( i18n( "&Archive File:" ), mainWidget );
  mainLayout->addWidget( fileNameLabel, row, 0 );
  mUrlRequester = new KUrlRequester( mainWidget );
  mUrlRequester->setMode( KFile::LocalOnly | KFile::File );
  mUrlRequester->setFilter( "*.tar *.zip *.tar.gz *.tar.bz2" );
  fileNameLabel->setBuddy( mUrlRequester );
  connect( mUrlRequester->lineEdit(), SIGNAL(textChanged(const QString &)), SLOT( slotUrlChanged(const QString&)));
  connect( mUrlRequester, SIGNAL(urlSelected(const KUrl&)),
           this, SLOT(slotFixFileExtension()) );
  mainLayout->addWidget( mUrlRequester, row, 1 );
  row++;

  // TODO: Make this appear more dangerous!
  mDeleteCheckBox = new QCheckBox( i18n( "&Delete folders after completion" ), mainWidget );
  mainLayout->addWidget( mDeleteCheckBox, row, 0, 1, 2, Qt::AlignLeft );
  row++;

  // TODO: what's this, tooltips

  // TODO: Warn that user should do mail check for online IMAP and possibly cached IMAP as well

  mainLayout->setColumnStretch( 1, 1 );
  mainLayout->addItem( new QSpacerItem( 1, 1, QSizePolicy::Expanding, QSizePolicy::Expanding ), row, 0 );

  // Make it a bit bigger, else the folder requester cuts off the text too early
  resize( 500, minimumSize().height() );
}

void ArchiveFolderDialog::slotUrlChanged( const QString & text)
{
  enableButtonOk( !text.isEmpty() );
}

bool canRemoveFolder( KMFolder *folder )
{
  return folder && folder->canDeleteMessages() && !folder->noContent() && !folder->isSystemFolder();
}

void ArchiveFolderDialog::slotFolderChanged( KMFolder *folder )
{
  mDeleteCheckBox->setEnabled( canRemoveFolder( folder ));
  enableButtonOk( folder && !folder->noContent());
}

void ArchiveFolderDialog::setFolder( KMFolder *defaultFolder )
{
  mFolderRequester->setFolder( defaultFolder );
  // TODO: what if the file already exists?
  mUrlRequester->setUrl( standardArchivePath( defaultFolder->name() ) );
  mDeleteCheckBox->setEnabled( canRemoveFolder( defaultFolder ) );
}

void ArchiveFolderDialog::slotButtonClicked( int button )
{
  if ( button == KDialog::Cancel ) {
    reject();
    return;
  }
  Q_ASSERT( button == KDialog::Ok );

  if ( !Util::checkOverwrite( mUrlRequester->url(), this ) ) {
    return;
  }

  if ( !mFolderRequester->folder() ) {
    KMessageBox::information( this, i18n( "Please select the folder that should be archived." ),
                              i18n( "No folder selected" ) );
    return;
  }

  KMail::BackupJob *backupJob = new KMail::BackupJob( mParentWidget );
  backupJob->setRootFolder( mFolderRequester->folder() );
  backupJob->setSaveLocation( mUrlRequester->url() );
  backupJob->setArchiveType( static_cast<BackupJob::ArchiveType>( mFormatComboBox->currentIndex() ) );
  backupJob->setDeleteFoldersAfterCompletion( mDeleteCheckBox->isEnabled() && mDeleteCheckBox->isChecked() );
  backupJob->start();
  accept();
}

void ArchiveFolderDialog::slotFixFileExtension()
{
  // KDE4: use KMimeType::extractKnownExtension() here
  const int numExtensions = 4;

  // These extensions are sorted differently, .tar has to come last, or it will match before giving
  // the more specific ones time to match.
  const char *sortedExtensions[numExtensions] = { ".zip", ".tar.bz2", ".tar.gz", ".tar" };

  // The extensions here are also sorted, like the enum order of BackupJob::ArchiveType
  const char *extensions[numExtensions] = { ".zip", ".tar", ".tar.bz2", ".tar.gz" };

  QString fileName = mUrlRequester->url().path();
  if ( fileName.isEmpty() )
    fileName = standardArchivePath( mFolderRequester->folder() ? mFolderRequester->folder()->name() : "" );

  // First, try to find the extension of the file name and remove it
  for( int i = 0; i < numExtensions; i++ ) {
    int index = fileName.toLower().lastIndexOf( sortedExtensions[i] );
    if ( index != -1 ) {
      fileName = fileName.left( fileName.length() - QString( sortedExtensions[i] ).length() );
      break;
    }
  }

  // Now, we've got a filename without an extension, simply append the correct one
  fileName += extensions[mFormatComboBox->currentIndex()];
  mUrlRequester->setUrl( fileName );
}

#include "archivefolderdialog.moc"
<|endoftext|>


<commit_before>#include <osgFX/AnisotropicLighting>
#include <osgFX/Registry>

#include <osg/VertexProgram>
#include <osg/Texture2D>
#include <osg/TexEnv>

#include <osgDB/ReadFile>

#include <sstream>

using namespace osgFX;

namespace
{

    // a state attribute class that grabs the initial inverse view matrix
    // and sends it to a VertexProgram.
    // NOTE: due to lack of support for per-context parameters in VertexProgram,
    // this class will send the matrix to the vp only while the first context
    // is being rendered. All subsequent contexts will use the first context's
    // matrix.
    class ViewMatrixExtractor: public osg::StateAttribute {
    public:
        ViewMatrixExtractor()
        :    osg::StateAttribute(),
            vp_(0),
            param_(0),
            first_context_(-1)
        {
        }

        ViewMatrixExtractor(const ViewMatrixExtractor &copy, const osg::CopyOp &copyop)
        :    osg::StateAttribute(copy, copyop),
            vp_(static_cast<osg::VertexProgram *>(copyop(copy.vp_.get()))),
            param_(copy.param_),
            first_context_(-1)
        {
        }

        ViewMatrixExtractor(osg::VertexProgram *vp, int param)
        :    osg::StateAttribute(),
            vp_(vp),
            param_(param),
            first_context_(-1)
        {
        }

        META_StateAttribute(osgFX, ViewMatrixExtractor, 0x564d4548);

        int compare(const osg::StateAttribute &sa) const
        {
            COMPARE_StateAttribute_Types(ViewMatrixExtractor, sa);
            if (vp_.get() != rhs.vp_.get()) return -1;
            if (param_ < rhs.param_) return -1;
            if (param_ > rhs.param_) return 1;
            return 0;
        }

        void apply(osg::State &state) const
        {
            if (first_context_ == -1) {
                first_context_ = state.getContextID();
            }
            if (state.getContextID() == (unsigned int)first_context_) {
                if (vp_.valid()) {
                    osg::Matrix M = state.getInitialInverseViewMatrix();
                    for (int i=0; i<4; ++i) {
                        vp_->setProgramLocalParameter(param_+i, osg::Vec4(M(0, i), M(1, i), M(2, i), M(3, i)));
                    }
                }
            }
        }

    private:
        mutable osg::ref_ptr<osg::VertexProgram> vp_;
        int param_;
        mutable int first_context_;
    };

}

namespace
{

    osg::Image *create_default_image()
    {
        const int texture_size = 16;
        osg::ref_ptr<osg::Image> image = new osg::Image;
        image->setImage(texture_size, texture_size, 1, 3, GL_RGB, GL_UNSIGNED_BYTE, new unsigned char[3*texture_size*texture_size], osg::Image::USE_NEW_DELETE);
        for (int i=0; i<texture_size; ++i) {
            for (int j=0; j<texture_size; ++j) {
                float s = static_cast<float>(j) / (texture_size-1);
                float t = static_cast<float>(i) / (texture_size-1);
                float lum = t * 0.75f;
                float red = lum + 0.2f * powf(cosf(s*10), 3.0f);
                float green = lum;
                float blue = lum + 0.2f * powf(sinf(s*10), 3.0f);
                if (red > 1) red = 1;
                if (red < 0) red = 0;
                if (blue > 1) blue = 1;
                if (blue < 0) blue = 0;
                *(image->data(j, i)+0) = static_cast<unsigned char>(red * 255);
                *(image->data(j, i)+1) = static_cast<unsigned char>(green * 255);
                *(image->data(j, i)+2) = static_cast<unsigned char>(blue * 255);
            }
        }
        return image.take();
    }

}

namespace
{

    Registry::Proxy proxy(new AnisotropicLighting);

    class DefaultTechnique: public Technique {
    public:

        DefaultTechnique(int lightnum, osg::Texture2D *texture)
        :    Technique(),
            lightnum_(lightnum),
            texture_(texture)
        {
        }

        void getRequiredExtensions(std::vector<std::string> &extensions) const
        {
            extensions.push_back("GL_ARB_vertex_program");
        }

    protected:

        void define_passes()
        {
            std::ostringstream vp_oss;
            vp_oss <<
                "!!ARBvp1.0\n"
                "PARAM c5 = { 0, 0, 0, 1 };"
                "PARAM c4 = { 0, 0, 0, 0 };"
                "TEMP R0, R1, R2, R3, R4, R5, R6, R7, R8, R9;"
                "ATTRIB v18 = vertex.normal;"
                "ATTRIB v16 = vertex.position;"
                "PARAM s259[4] = { state.matrix.mvp };"
                "PARAM s18 = state.light[" << lightnum_ << "].position;"
                "PARAM s223[4] = { state.matrix.modelview[0] };"
                "PARAM c0[4] = { program.local[0..3] };"
                "    DP4 result.position.x, s259[0], v16;"
                "    DP4 result.position.y, s259[1], v16;"
                "    DP4 result.position.z, s259[2], v16;"
                "    DP4 result.position.w, s259[3], v16;"
                "    MOV R9, c0[0];"
                "    MUL R0, R9.y, s223[1];"
                "    MAD R0, R9.x, s223[0], R0;"
                "    MAD R0, R9.z, s223[2], R0;"
                "    MAD R8, R9.w, s223[3], R0;"
                "    DP4 R0.x, R8, v16;"
                "    MOV R7, c0[1];"
                "    MUL R1, R7.y, s223[1];"
                "    MAD R1, R7.x, s223[0], R1;"
                "    MAD R1, R7.z, s223[2], R1;"
                "    MAD R6, R7.w, s223[3], R1;"
                "    DP4 R0.y, R6, v16;"
                "    MOV R5, c0[2];"
                "    MUL R1, R5.y, s223[1];"
                "    MAD R1, R5.x, s223[0], R1;"
                "    MAD R1, R5.z, s223[2], R1;"
                "    MAD R4, R5.w, s223[3], R1;"
                "    DP4 R0.z, R4, v16;"
                "    MOV R3, c0[3];"
                "    MUL R1, R3.y, s223[1];"
                "    MAD R1, R3.x, s223[0], R1;"
                "    MAD R1, R3.z, s223[2], R1;"
                "    MAD R1, R3.w, s223[3], R1;"
                "    DP4 R0.w, R1, v16;"
                "    MOV R1.x, R9.w;"
                "    MOV R1.y, R7.w;"
                "    MOV R1.z, R5.w;"
                "    MOV R1.w, R3.w;"
                "    ADD R2, R1, -R0;"
                "    DP4 R0.x, R2, R2;"
                "    RSQ R1.x, R0.x;"
                "    DP4 R0.x, R9, s18;"
                "    DP4 R0.y, R7, s18;"
                "    DP4 R0.z, R5, s18;"
                "    DP4 R0.w, R3, s18;"
                "    DP4 R1.y, R0, R0;"
                "    RSQ R1.y, R1.y;"
                "    MUL R3, R1.y, R0;"
                "    MAD R2, R1.x, R2, R3;"
                "    DP4 R1.x, R2, R2;"
                "    RSQ R1.x, R1.x;"
                "    MUL R1, R1.x, R2;"
                "    DP3 R2.x, R8.xyzx, v18.xyzx;"
                "    DP3 R2.y, R6.xyzx, v18.xyzx;"
                "    DP3 R2.z, R4.xyzx, v18.xyzx;"
                "    MOV R2.w, c4.x;"
                "    DP4 R1.x, R1, R2;"
                "    MAX result.texcoord[0].x, R1.x, c4.x;"
                "    DP4 R0.x, R0, R2;"
                "    MAX result.texcoord[0].y, R0.x, c4.x;"
                "END\n";

            osg::ref_ptr<osg::StateSet> ss = new osg::StateSet;

            osg::ref_ptr<osg::VertexProgram> vp = new osg::VertexProgram;
            vp->setVertexProgram(vp_oss.str());
            ss->setAttributeAndModes(vp.get(), osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);

            ss->setAttributeAndModes(new ViewMatrixExtractor(vp.get(), 0), osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);

            ss->setTextureAttributeAndModes(0, texture_.get(), osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);

            osg::ref_ptr<osg::TexEnv> texenv = new osg::TexEnv;
            texenv->setMode(osg::TexEnv::DECAL);
            ss->setTextureAttributeAndModes(0, texenv.get(), osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);

            addPass(ss.get());
        }

    private:
        int lightnum_;
        osg::ref_ptr<osg::Texture2D> texture_;
    };

}

AnisotropicLighting::AnisotropicLighting()
:    Effect(),
    lightnum_(0),
    texture_(new osg::Texture2D)
{
    texture_->setImage(create_default_image());
    texture_->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP);
    texture_->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP);
}

AnisotropicLighting::AnisotropicLighting(const AnisotropicLighting &copy, const osg::CopyOp &copyop)
:    Effect(copy, copyop),
    lightnum_(copy.lightnum_),
    texture_(static_cast<osg::Texture2D *>(copyop(copy.texture_.get())))
{
}

bool AnisotropicLighting::define_techniques()
{
    addTechnique(new DefaultTechnique(lightnum_, texture_.get()));
    return true;
}
<commit_msg>From Mike Weiblen, switched of alpha test on anisotropic effect, due to missing write of colour.<commit_after>#include <osgFX/AnisotropicLighting>
#include <osgFX/Registry>

#include <osg/VertexProgram>
#include <osg/Texture2D>
#include <osg/TexEnv>

#include <osgDB/ReadFile>

#include <sstream>

using namespace osgFX;

namespace
{

    // a state attribute class that grabs the initial inverse view matrix
    // and sends it to a VertexProgram.
    // NOTE: due to lack of support for per-context parameters in VertexProgram,
    // this class will send the matrix to the vp only while the first context
    // is being rendered. All subsequent contexts will use the first context's
    // matrix.
    class ViewMatrixExtractor: public osg::StateAttribute {
    public:
        ViewMatrixExtractor()
        :    osg::StateAttribute(),
            vp_(0),
            param_(0),
            first_context_(-1)
        {
        }

        ViewMatrixExtractor(const ViewMatrixExtractor &copy, const osg::CopyOp &copyop)
        :    osg::StateAttribute(copy, copyop),
            vp_(static_cast<osg::VertexProgram *>(copyop(copy.vp_.get()))),
            param_(copy.param_),
            first_context_(-1)
        {
        }

        ViewMatrixExtractor(osg::VertexProgram *vp, int param)
        :    osg::StateAttribute(),
            vp_(vp),
            param_(param),
            first_context_(-1)
        {
        }

        META_StateAttribute(osgFX, ViewMatrixExtractor, 0x564d4548);

        int compare(const osg::StateAttribute &sa) const
        {
            COMPARE_StateAttribute_Types(ViewMatrixExtractor, sa);
            if (vp_.get() != rhs.vp_.get()) return -1;
            if (param_ < rhs.param_) return -1;
            if (param_ > rhs.param_) return 1;
            return 0;
        }

        void apply(osg::State &state) const
        {
            if (first_context_ == -1) {
                first_context_ = state.getContextID();
            }
            if (state.getContextID() == (unsigned int)first_context_) {
                if (vp_.valid()) {
                    osg::Matrix M = state.getInitialInverseViewMatrix();
                    for (int i=0; i<4; ++i) {
                        vp_->setProgramLocalParameter(param_+i, osg::Vec4(M(0, i), M(1, i), M(2, i), M(3, i)));
                    }
                }
            }
        }

    private:
        mutable osg::ref_ptr<osg::VertexProgram> vp_;
        int param_;
        mutable int first_context_;
    };

}

namespace
{

    osg::Image *create_default_image()
    {
        const int texture_size = 16;
        osg::ref_ptr<osg::Image> image = new osg::Image;
        image->setImage(texture_size, texture_size, 1, 3, GL_RGB, GL_UNSIGNED_BYTE, new unsigned char[3*texture_size*texture_size], osg::Image::USE_NEW_DELETE);
        for (int i=0; i<texture_size; ++i) {
            for (int j=0; j<texture_size; ++j) {
                float s = static_cast<float>(j) / (texture_size-1);
                float t = static_cast<float>(i) / (texture_size-1);
                float lum = t * 0.75f;
                float red = lum + 0.2f * powf(cosf(s*10), 3.0f);
                float green = lum;
                float blue = lum + 0.2f * powf(sinf(s*10), 3.0f);
                if (red > 1) red = 1;
                if (red < 0) red = 0;
                if (blue > 1) blue = 1;
                if (blue < 0) blue = 0;
                *(image->data(j, i)+0) = static_cast<unsigned char>(red * 255);
                *(image->data(j, i)+1) = static_cast<unsigned char>(green * 255);
                *(image->data(j, i)+2) = static_cast<unsigned char>(blue * 255);
            }
        }
        return image.take();
    }

}

namespace
{

    Registry::Proxy proxy(new AnisotropicLighting);

    class DefaultTechnique: public Technique {
    public:

        DefaultTechnique(int lightnum, osg::Texture2D *texture)
        :    Technique(),
            lightnum_(lightnum),
            texture_(texture)
        {
        }

        void getRequiredExtensions(std::vector<std::string> &extensions) const
        {
            extensions.push_back("GL_ARB_vertex_program");
        }

    protected:

        void define_passes()
        {
            std::ostringstream vp_oss;
            vp_oss <<
                "!!ARBvp1.0\n"
                "PARAM c5 = { 0, 0, 0, 1 };"
                "PARAM c4 = { 0, 0, 0, 0 };"
                "TEMP R0, R1, R2, R3, R4, R5, R6, R7, R8, R9;"
                "ATTRIB v18 = vertex.normal;"
                "ATTRIB v16 = vertex.position;"
                "PARAM s259[4] = { state.matrix.mvp };"
                "PARAM s18 = state.light[" << lightnum_ << "].position;"
                "PARAM s223[4] = { state.matrix.modelview[0] };"
                "PARAM c0[4] = { program.local[0..3] };"
                "    DP4 result.position.x, s259[0], v16;"
                "    DP4 result.position.y, s259[1], v16;"
                "    DP4 result.position.z, s259[2], v16;"
                "    DP4 result.position.w, s259[3], v16;"
                "    MOV R9, c0[0];"
                "    MUL R0, R9.y, s223[1];"
                "    MAD R0, R9.x, s223[0], R0;"
                "    MAD R0, R9.z, s223[2], R0;"
                "    MAD R8, R9.w, s223[3], R0;"
                "    DP4 R0.x, R8, v16;"
                "    MOV R7, c0[1];"
                "    MUL R1, R7.y, s223[1];"
                "    MAD R1, R7.x, s223[0], R1;"
                "    MAD R1, R7.z, s223[2], R1;"
                "    MAD R6, R7.w, s223[3], R1;"
                "    DP4 R0.y, R6, v16;"
                "    MOV R5, c0[2];"
                "    MUL R1, R5.y, s223[1];"
                "    MAD R1, R5.x, s223[0], R1;"
                "    MAD R1, R5.z, s223[2], R1;"
                "    MAD R4, R5.w, s223[3], R1;"
                "    DP4 R0.z, R4, v16;"
                "    MOV R3, c0[3];"
                "    MUL R1, R3.y, s223[1];"
                "    MAD R1, R3.x, s223[0], R1;"
                "    MAD R1, R3.z, s223[2], R1;"
                "    MAD R1, R3.w, s223[3], R1;"
                "    DP4 R0.w, R1, v16;"
                "    MOV R1.x, R9.w;"
                "    MOV R1.y, R7.w;"
                "    MOV R1.z, R5.w;"
                "    MOV R1.w, R3.w;"
                "    ADD R2, R1, -R0;"
                "    DP4 R0.x, R2, R2;"
                "    RSQ R1.x, R0.x;"
                "    DP4 R0.x, R9, s18;"
                "    DP4 R0.y, R7, s18;"
                "    DP4 R0.z, R5, s18;"
                "    DP4 R0.w, R3, s18;"
                "    DP4 R1.y, R0, R0;"
                "    RSQ R1.y, R1.y;"
                "    MUL R3, R1.y, R0;"
                "    MAD R2, R1.x, R2, R3;"
                "    DP4 R1.x, R2, R2;"
                "    RSQ R1.x, R1.x;"
                "    MUL R1, R1.x, R2;"
                "    DP3 R2.x, R8.xyzx, v18.xyzx;"
                "    DP3 R2.y, R6.xyzx, v18.xyzx;"
                "    DP3 R2.z, R4.xyzx, v18.xyzx;"
                "    MOV R2.w, c4.x;"
                "    DP4 R1.x, R1, R2;"
                "    MAX result.texcoord[0].x, R1.x, c4.x;"
                "    DP4 R0.x, R0, R2;"
                "    MAX result.texcoord[0].y, R0.x, c4.x;"
                "END\n";

            osg::ref_ptr<osg::StateSet> ss = new osg::StateSet;

            osg::ref_ptr<osg::VertexProgram> vp = new osg::VertexProgram;
            vp->setVertexProgram(vp_oss.str());
            ss->setAttributeAndModes(vp.get(), osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);

            ss->setAttributeAndModes(new ViewMatrixExtractor(vp.get(), 0), osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);

            ss->setTextureAttributeAndModes(0, texture_.get(), osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);

            osg::ref_ptr<osg::TexEnv> texenv = new osg::TexEnv;
            texenv->setMode(osg::TexEnv::DECAL);
            ss->setTextureAttributeAndModes(0, texenv.get(), osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);

            ss->setMode( GL_ALPHA_TEST, osg::StateAttribute::OFF );

            addPass(ss.get());
        }

    private:
        int lightnum_;
        osg::ref_ptr<osg::Texture2D> texture_;
    };

}

AnisotropicLighting::AnisotropicLighting()
:    Effect(),
    lightnum_(0),
    texture_(new osg::Texture2D)
{
    texture_->setImage(create_default_image());
    texture_->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP);
    texture_->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP);
}

AnisotropicLighting::AnisotropicLighting(const AnisotropicLighting &copy, const osg::CopyOp &copyop)
:    Effect(copy, copyop),
    lightnum_(copy.lightnum_),
    texture_(static_cast<osg::Texture2D *>(copyop(copy.texture_.get())))
{
}

bool AnisotropicLighting::define_techniques()
{
    addTechnique(new DefaultTechnique(lightnum_, texture_.get()));
    return true;
}
<|endoftext|>


<commit_before>//---------------------------------------------------------------------------------------
// This file is part of the Lomse library.
// Lomse is copyrighted work (c) 2010-2016. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//    * Redistributions of source code must retain the above copyright notice, this
//      list of conditions and the following disclaimer.
//
//    * Redistributions in binary form must reproduce the above copyright notice, this
//      list of conditions and the following disclaimer in the documentation and/or
//      other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
// DAMAGE.
//
// For any comment, suggestion or feature request, please contact the manager of
// the project at cecilios@users.sourceforge.net
//---------------------------------------------------------------------------------------

//  This file is based on Anti-Grain Geometry version 2.4 examples' code.
//  Anti-Grain Geometry (AGG) is copyright (C) 2002-2005 Maxim Shemanarev
//  (http://www.antigrain.com). AGG 2.4 is distributed as follows:
//    "Permission to copy, use, modify, sell and distribute this software
//    is granted provided this copyright notice appears in all copies.
//    This software is provided "as is" without express or implied
//    warranty, and with no claim as to its suitability for any purpose."
//
//---------------------------------------------------------------------------------------

#include "lomse_font_storage.h"

#include "lomse_build_options.h"

#include <boost/algorithm/string.hpp>   //to upper conversion

using namespace agg;

namespace lomse
{

//=======================================================================================
// FontStorage implementation
//=======================================================================================
FontStorage::FontStorage(LibraryScope* pLibScope)
    : m_fontEngine(1000)        //1000 = number of faces in cache
    , m_fontCacheManager(m_fontEngine)
    , m_pLibScope(pLibScope)
    , m_fontHeight(14.0)
    , m_fontWidth(14.0)
    , m_fHinting(false)
    , m_fValidFont(false)
    , m_fKerning(true)
    , m_fFlip_y(true)
    , m_fontCacheType(k_raster_font_cache)
{
    //AWARE:
    //Apple Computer, Inc., owns three patents that are related to the
    //hinting process of glyph outlines within TrueType fonts. Hinting (also named
    //grid-fitting) is used to enhance the quality of glyphs at small bitmap sizes.
    //Therefore, you can not use hinting unless you are authorized (you purchased
    //a license from Apple, or because you are in a country where the patents do
    //not apply, etc.). Nevertheless lenmus font doesn't include hinting information
    //and, so, previous flag value doesn't matter. But its value is important
    //if I finally use FreeType for all fonts.

    //font settings
    unsigned ppi = unsigned(pLibScope->get_screen_ppi());
    m_fontEngine.resolution(ppi);
    m_fontEngine.gamma(agg::gamma_none());
    m_fontEngine.hinting(m_fHinting);
    m_fontEngine.flip_y(m_fFlip_y);

    //load music font
    string fullname = m_pLibScope->get_music_font_path();
    fullname += m_pLibScope->get_music_font_file();
    set_font(fullname, 24.0);
}

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

//---------------------------------------------------------------------------------------
bool FontStorage::set_font(const std::string& fontFullName, double height,
                           EFontCacheType type)
{
    m_fValidFont = false;
    lomse::glyph_rendering gren = lomse::glyph_ren_agg_gray8;
    if(! m_fontEngine.select_font(fontFullName, 0, gren))
        return !m_fValidFont;    //error

    //set curren values for renderization
    m_fontCacheType = type;
    set_font_size(height);

    ////un-comment this to rotate/skew/translate the text
    ////agg::trans_affine mtx;
    ////mtx *= agg::trans_affine_rotation(agg::deg2rad(-4.0));
    //////mtx *= agg::trans_affine_skewing(-0.4, 0);
    //////mtx *= agg::trans_affine_translation(1, 0);
    ////m_fontEngine.transform(mtx);

    m_fValidFont = true;
    return !m_fValidFont;
}

//---------------------------------------------------------------------------------------
void FontStorage::set_font_size(double rPoints)
{
    m_fontHeight = rPoints;
    m_fontWidth = rPoints;
    m_fontEngine.height(m_fontHeight);
    m_fontEngine.width(m_fontWidth);
}

//---------------------------------------------------------------------------------------
void FontStorage::set_font_height(double rPoints)
{
    m_fontHeight = rPoints;
    m_fontEngine.height(rPoints);
}

//---------------------------------------------------------------------------------------
void FontStorage::set_font_width(double rPoints)
{
    m_fontWidth = rPoints;
    m_fontEngine.width(rPoints);
}

//---------------------------------------------------------------------------------------
bool FontStorage::select_font(const std::string& language,
                               const std::string& fontFile,
                               const std::string& fontName, double height,
                               bool fBold, bool fItalic)
{
    return select_raster_font(language, fontFile, fontName, height, fBold, fItalic);
}

//---------------------------------------------------------------------------------------
bool FontStorage::select_raster_font(const std::string& language,
                                      const std::string& fontFile,
                                      const std::string& fontName, double height,
                                      bool fBold, bool fItalic)
{
    //Returns true if any error
    FontSelector fs(m_pLibScope);
    string fullFile = fs.find_font(language, fontFile, fontName, fBold, fItalic);
    return set_font(fullFile, height, k_raster_font_cache);
}

//---------------------------------------------------------------------------------------
bool FontStorage::select_vector_font(const std::string& language,
                                      const std::string& fontFile,
                                      const std::string& fontName, double height,
                                      bool fBold, bool fItalic)
{
    //Returns true if any error
    FontSelector fs(m_pLibScope);
    string fullFile = fs.find_font(language, fontFile, fontName, fBold, fItalic);
    return set_font(fullFile, height, k_vector_font_cache);
}

//=======================================================================================
// FontSelector implementation
//=======================================================================================
std::string FontSelector::find_font(const std::string& language,
                                     const std::string& fontFile,
                                     const std::string& name,
                                     bool fBold, bool fItalic)
{
    //Returns the font filename, including its full path.
    //Priority is given to font file.
    //For generic families (i.e.: sans, serif, monospace, ...) priority is given to
    //language

    string fullpath = m_pLibScope->fonts_path();

    if (!fontFile.empty())
        return fullpath + fontFile;

    //transform name to capital letters for comparisons
    string fontname = boost::to_upper_copy(name);

    //music font
    if (fontname == "BRAVURA")
    {
        fullpath += "Bravura.otf";
        return fullpath;
    }

    //Chinese fonts
    if (language == "zh_CN")
    {
        fullpath += "wqy-zenhei.ttc";
        return fullpath;
    }

    if (fontname == "LIBERATION SERIF" || fontname == "SERIF"
             || fontname == "TIMES NEW ROMAN")
    {
        if (fBold && fItalic)
            fullpath += "LiberationSerif-BoldItalic.ttf";
        else if (fBold)
            fullpath += "LiberationSerif-Bold.ttf";
        else if (fItalic)
            fullpath += "LiberationSerif-Italic.ttf";
        else
            fullpath += "LiberationSerif-Regular.ttf";
        return fullpath;
    }

    else if (fontname == "LIBERATION SANS" || fontname == "SANS-SERIF" || fontname == "SANS"
             || fontname == "HELVETICA")
    {
        if (fBold && fItalic)
            fullpath += "LiberationSans-BoldItalic.ttf";
        else if (fBold)
            fullpath += "LiberationSans-Bold.ttf";
        else if (fItalic)
            fullpath += "LiberationSans-Italic.ttf";
        else
            fullpath += "LiberationSans-Regular.ttf";
        return fullpath;
    }

#if (0)
    //else if (fontname == "MONOSPACE" || fontname == "DEJAVU SANS MONO")
    else if (fontname == "MONOSPACE" || fontname == "COURIER")
    {
        if (italic && bold)
            fullpath += "FreeMonoBoldOblique.ttf";
        else if (italic)
            fullpath += "FreeMonoOblique.ttf";
        else if (bold)
            fullpath += "FreeMonoBold.ttf";
        else
            fullpath += "FreeMono.ttf";
        return fullpath;
    }

    else if (fontname == "HANDWRITTEN" || fontname == "CURSIVE")
    {
        fullpath += "DejaVuSans-Oblique.ttf";
        return fullpath;
    }
#endif

    else
        return m_pLibScope->get_font(name, fBold, fItalic);

}

}   //namespace lomse
<commit_msg>Replaced boost::to_upper_copy with standard function<commit_after>//---------------------------------------------------------------------------------------
// This file is part of the Lomse library.
// Lomse is copyrighted work (c) 2010-2016. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//    * Redistributions of source code must retain the above copyright notice, this
//      list of conditions and the following disclaimer.
//
//    * Redistributions in binary form must reproduce the above copyright notice, this
//      list of conditions and the following disclaimer in the documentation and/or
//      other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
// DAMAGE.
//
// For any comment, suggestion or feature request, please contact the manager of
// the project at cecilios@users.sourceforge.net
//---------------------------------------------------------------------------------------

//  This file is based on Anti-Grain Geometry version 2.4 examples' code.
//  Anti-Grain Geometry (AGG) is copyright (C) 2002-2005 Maxim Shemanarev
//  (http://www.antigrain.com). AGG 2.4 is distributed as follows:
//    "Permission to copy, use, modify, sell and distribute this software
//    is granted provided this copyright notice appears in all copies.
//    This software is provided "as is" without express or implied
//    warranty, and with no claim as to its suitability for any purpose."
//
//---------------------------------------------------------------------------------------

#include "lomse_font_storage.h"

#include "lomse_build_options.h"

#include <locale>   //to upper conversion
using namespace agg;

namespace lomse
{

//=======================================================================================
// FontStorage implementation
//=======================================================================================
FontStorage::FontStorage(LibraryScope* pLibScope)
    : m_fontEngine(1000)        //1000 = number of faces in cache
    , m_fontCacheManager(m_fontEngine)
    , m_pLibScope(pLibScope)
    , m_fontHeight(14.0)
    , m_fontWidth(14.0)
    , m_fHinting(false)
    , m_fValidFont(false)
    , m_fKerning(true)
    , m_fFlip_y(true)
    , m_fontCacheType(k_raster_font_cache)
{
    //AWARE:
    //Apple Computer, Inc., owns three patents that are related to the
    //hinting process of glyph outlines within TrueType fonts. Hinting (also named
    //grid-fitting) is used to enhance the quality of glyphs at small bitmap sizes.
    //Therefore, you can not use hinting unless you are authorized (you purchased
    //a license from Apple, or because you are in a country where the patents do
    //not apply, etc.). Nevertheless lenmus font doesn't include hinting information
    //and, so, previous flag value doesn't matter. But its value is important
    //if I finally use FreeType for all fonts.

    //font settings
    unsigned ppi = unsigned(pLibScope->get_screen_ppi());
    m_fontEngine.resolution(ppi);
    m_fontEngine.gamma(agg::gamma_none());
    m_fontEngine.hinting(m_fHinting);
    m_fontEngine.flip_y(m_fFlip_y);

    //load music font
    string fullname = m_pLibScope->get_music_font_path();
    fullname += m_pLibScope->get_music_font_file();
    set_font(fullname, 24.0);
}

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

//---------------------------------------------------------------------------------------
bool FontStorage::set_font(const std::string& fontFullName, double height,
                           EFontCacheType type)
{
    m_fValidFont = false;
    lomse::glyph_rendering gren = lomse::glyph_ren_agg_gray8;
    if(! m_fontEngine.select_font(fontFullName, 0, gren))
        return !m_fValidFont;    //error

    //set curren values for renderization
    m_fontCacheType = type;
    set_font_size(height);

    ////un-comment this to rotate/skew/translate the text
    ////agg::trans_affine mtx;
    ////mtx *= agg::trans_affine_rotation(agg::deg2rad(-4.0));
    //////mtx *= agg::trans_affine_skewing(-0.4, 0);
    //////mtx *= agg::trans_affine_translation(1, 0);
    ////m_fontEngine.transform(mtx);

    m_fValidFont = true;
    return !m_fValidFont;
}

//---------------------------------------------------------------------------------------
void FontStorage::set_font_size(double rPoints)
{
    m_fontHeight = rPoints;
    m_fontWidth = rPoints;
    m_fontEngine.height(m_fontHeight);
    m_fontEngine.width(m_fontWidth);
}

//---------------------------------------------------------------------------------------
void FontStorage::set_font_height(double rPoints)
{
    m_fontHeight = rPoints;
    m_fontEngine.height(rPoints);
}

//---------------------------------------------------------------------------------------
void FontStorage::set_font_width(double rPoints)
{
    m_fontWidth = rPoints;
    m_fontEngine.width(rPoints);
}

//---------------------------------------------------------------------------------------
bool FontStorage::select_font(const std::string& language,
                               const std::string& fontFile,
                               const std::string& fontName, double height,
                               bool fBold, bool fItalic)
{
    return select_raster_font(language, fontFile, fontName, height, fBold, fItalic);
}

//---------------------------------------------------------------------------------------
bool FontStorage::select_raster_font(const std::string& language,
                                      const std::string& fontFile,
                                      const std::string& fontName, double height,
                                      bool fBold, bool fItalic)
{
    //Returns true if any error
    FontSelector fs(m_pLibScope);
    string fullFile = fs.find_font(language, fontFile, fontName, fBold, fItalic);
    return set_font(fullFile, height, k_raster_font_cache);
}

//---------------------------------------------------------------------------------------
bool FontStorage::select_vector_font(const std::string& language,
                                      const std::string& fontFile,
                                      const std::string& fontName, double height,
                                      bool fBold, bool fItalic)
{
    //Returns true if any error
    FontSelector fs(m_pLibScope);
    string fullFile = fs.find_font(language, fontFile, fontName, fBold, fItalic);
    return set_font(fullFile, height, k_vector_font_cache);
}

//=======================================================================================
// FontSelector implementation
//=======================================================================================
std::string FontSelector::find_font(const std::string& language,
                                     const std::string& fontFile,
                                     const std::string& name,
                                     bool fBold, bool fItalic)
{
    //Returns the font filename, including its full path.
    //Priority is given to font file.
    //For generic families (i.e.: sans, serif, monospace, ...) priority is given to
    //language

    string fullpath = m_pLibScope->fonts_path();

    if (!fontFile.empty())
        return fullpath + fontFile;

    //transform name to capital letters for comparisons
    const locale& loc = locale();
    string fontname;
    for (string::value_type a : name)
        fontname += std::toupper(a, loc);

    //music font
    if (fontname == "BRAVURA")
    {
        fullpath += "Bravura.otf";
        return fullpath;
    }

    //Chinese fonts
    if (language == "zh_CN")
    {
        fullpath += "wqy-zenhei.ttc";
        return fullpath;
    }

    if (fontname == "LIBERATION SERIF" || fontname == "SERIF"
             || fontname == "TIMES NEW ROMAN")
    {
        if (fBold && fItalic)
            fullpath += "LiberationSerif-BoldItalic.ttf";
        else if (fBold)
            fullpath += "LiberationSerif-Bold.ttf";
        else if (fItalic)
            fullpath += "LiberationSerif-Italic.ttf";
        else
            fullpath += "LiberationSerif-Regular.ttf";
        return fullpath;
    }

    else if (fontname == "LIBERATION SANS" || fontname == "SANS-SERIF" || fontname == "SANS"
             || fontname == "HELVETICA")
    {
        if (fBold && fItalic)
            fullpath += "LiberationSans-BoldItalic.ttf";
        else if (fBold)
            fullpath += "LiberationSans-Bold.ttf";
        else if (fItalic)
            fullpath += "LiberationSans-Italic.ttf";
        else
            fullpath += "LiberationSans-Regular.ttf";
        return fullpath;
    }

#if (0)
    //else if (fontname == "MONOSPACE" || fontname == "DEJAVU SANS MONO")
    else if (fontname == "MONOSPACE" || fontname == "COURIER")
    {
        if (italic && bold)
            fullpath += "FreeMonoBoldOblique.ttf";
        else if (italic)
            fullpath += "FreeMonoOblique.ttf";
        else if (bold)
            fullpath += "FreeMonoBold.ttf";
        else
            fullpath += "FreeMono.ttf";
        return fullpath;
    }

    else if (fontname == "HANDWRITTEN" || fontname == "CURSIVE")
    {
        fullpath += "DejaVuSans-Oblique.ttf";
        return fullpath;
    }
#endif

    else
        return m_pLibScope->get_font(name, fBold, fItalic);

}

}   //namespace lomse
<|endoftext|>


<commit_before>//
// Copyright RIME Developers
// Distributed under the BSD License
//
// 2012-02-26 GONG Chen <chen.sst@gmail.com>
//
#include <boost/algorithm/string.hpp>
#include <boost/filesystem.hpp>
#include <rime/config.h>
#include <rime/deployer.h>
#include <rime/signature.h>
#include <rime/lever/custom_settings.h>

namespace fs = boost::filesystem;

namespace rime {

static string remove_suffix(const string& input, const string& suffix) {
  return boost::ends_with(input, suffix) ?
      input.substr(0, input.length() - suffix.length()) : input;
}

static string custom_config_file(const string& config_id) {
  return remove_suffix(config_id, ".schema") + ".custom.yaml";
}

CustomSettings::CustomSettings(Deployer* deployer,
                               const string& config_id,
                               const string& generator_id)
    : deployer_(deployer),
      config_id_(config_id),
      generator_id_(generator_id) {
}

bool CustomSettings::Load() {
  fs::path user_data_path(deployer_->user_data_dir);
  fs::path shared_data_path(deployer_->shared_data_dir);
  fs::path config_path(user_data_path / "build" / (config_id_ + ".yaml"));
  if (!config_.LoadFromFile(config_path.string())) {
    config_path = shared_data_path / "build" / (config_id_ + ".yaml");
    if (!config_.LoadFromFile(config_path.string())) {
      LOG(WARNING) << "cannot find '" << config_id_ << ".yaml'.";
      return false;
    }
  }
  fs::path custom_config_path(user_data_path / custom_config_file(config_id_));
  custom_config_.LoadFromFile(custom_config_path.string());
  modified_ = false;
  return true;
}

bool CustomSettings::Save() {
  if (!modified_)
    return false;
  Signature signature(generator_id_, "customization");
  signature.Sign(&custom_config_, deployer_);
  fs::path custom_config_path(deployer_->user_data_dir);
  custom_config_path /= custom_config_file(config_id_);
  custom_config_.SaveToFile(custom_config_path.string());
  modified_ = false;
  return true;
}

an<ConfigValue> CustomSettings::GetValue(const string& key) {
  return config_.GetValue(key);
}

an<ConfigList> CustomSettings::GetList(const string& key) {
  return config_.GetList(key);
}

an<ConfigMap> CustomSettings::GetMap(const string& key) {
  return config_.GetMap(key);
}

bool CustomSettings::Customize(const string& key,
                               const an<ConfigItem>& item) {
  auto patch = custom_config_.GetMap("patch");
  if (!patch) {
    patch = New<ConfigMap>();
  }
  patch->Set(key, item);
  // the branch 'patch' should be set as a whole in order to be saved, for
  // its sub-key may contain slashes which disables directly setting a sub-item
  custom_config_.SetItem("patch", patch);
  modified_ = true;
  return true;
}

bool CustomSettings::IsFirstRun() {
  fs::path custom_config_path(deployer_->user_data_dir);
  custom_config_path /= custom_config_file(config_id_);
  Config config;
  if (!config.LoadFromFile(custom_config_path.string()))
    return true;
  return !config.GetMap("customization");
}

}  // namespace rime
<commit_msg>chore(custom_settings): tolerate failure loading built config<commit_after>//
// Copyright RIME Developers
// Distributed under the BSD License
//
// 2012-02-26 GONG Chen <chen.sst@gmail.com>
//
#include <boost/algorithm/string.hpp>
#include <boost/filesystem.hpp>
#include <rime/config.h>
#include <rime/deployer.h>
#include <rime/signature.h>
#include <rime/lever/custom_settings.h>

namespace fs = boost::filesystem;

namespace rime {

static string remove_suffix(const string& input, const string& suffix) {
  return boost::ends_with(input, suffix) ?
      input.substr(0, input.length() - suffix.length()) : input;
}

static string custom_config_file(const string& config_id) {
  return remove_suffix(config_id, ".schema") + ".custom.yaml";
}

CustomSettings::CustomSettings(Deployer* deployer,
                               const string& config_id,
                               const string& generator_id)
    : deployer_(deployer),
      config_id_(config_id),
      generator_id_(generator_id) {
}

bool CustomSettings::Load() {
  fs::path user_data_path(deployer_->user_data_dir);
  fs::path shared_data_path(deployer_->shared_data_dir);
  fs::path config_path(user_data_path / "build" / (config_id_ + ".yaml"));
  if (!config_.LoadFromFile(config_path.string())) {
    config_path = shared_data_path / "build" / (config_id_ + ".yaml");
    if (!config_.LoadFromFile(config_path.string())) {
      LOG(WARNING) << "cannot find '" << config_id_ << ".yaml'.";
    }
  }
  fs::path custom_config_path(user_data_path / custom_config_file(config_id_));
  if (!custom_config_.LoadFromFile(custom_config_path.string())) {
    return false;
  }
  modified_ = false;
  return true;
}

bool CustomSettings::Save() {
  if (!modified_)
    return false;
  Signature signature(generator_id_, "customization");
  signature.Sign(&custom_config_, deployer_);
  fs::path custom_config_path(deployer_->user_data_dir);
  custom_config_path /= custom_config_file(config_id_);
  custom_config_.SaveToFile(custom_config_path.string());
  modified_ = false;
  return true;
}

an<ConfigValue> CustomSettings::GetValue(const string& key) {
  return config_.GetValue(key);
}

an<ConfigList> CustomSettings::GetList(const string& key) {
  return config_.GetList(key);
}

an<ConfigMap> CustomSettings::GetMap(const string& key) {
  return config_.GetMap(key);
}

bool CustomSettings::Customize(const string& key,
                               const an<ConfigItem>& item) {
  auto patch = custom_config_.GetMap("patch");
  if (!patch) {
    patch = New<ConfigMap>();
  }
  patch->Set(key, item);
  // the branch 'patch' should be set as a whole in order to be saved, for
  // its sub-key may contain slashes which disables directly setting a sub-item
  custom_config_.SetItem("patch", patch);
  modified_ = true;
  return true;
}

bool CustomSettings::IsFirstRun() {
  fs::path custom_config_path(deployer_->user_data_dir);
  custom_config_path /= custom_config_file(config_id_);
  Config config;
  if (!config.LoadFromFile(custom_config_path.string()))
    return true;
  return !config.GetMap("customization");
}

}  // namespace rime
<|endoftext|>


<commit_before>/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * Copyright (C) 2012 Sergey Lisitsyn
 */

#include <shogun/lib/IndexBlockTree.h>
#include <vector>

using namespace std;
using namespace shogun;

struct tree_node_t
{
	tree_node_t** desc;
	int32_t n_desc;
	int32_t sub_nodes_count;
	int32_t idx;
};

struct block_tree_node_t
{
	block_tree_node_t(int32_t min, int32_t max, float64_t w)
	{
		t_min_index = min;
		t_max_index = max;
		weight = w;
	}
	int32_t t_min_index, t_max_index;
	float64_t weight;
};

int count_sub_nodes_recursive(tree_node_t* node)
{
	if (node->n_desc==0)
	{
		return 1;
	}
	else
	{
		node->sub_nodes_count = 0;
		for (int32_t i=0; i<node->n_desc; i++)
		{
			node->sub_nodes_count += count_sub_nodes_recursive(node->desc[i]);
		}
		return node->sub_nodes_count;
	}
}

void print_tree(tree_node_t* node, int tabs)
{
	for (int32_t t=0; t<tabs; t++)
		SG_SPRINT("  ");
	SG_SPRINT("%d %d\n",node->idx, node->sub_nodes_count);
	for (int32_t i=0; i<node->n_desc; i++)
		print_tree(node->desc[i],tabs+1);
}

void fill_ind_recursive(tree_node_t* node, vector<block_tree_node_t>* tree_nodes, int32_t lower)
{
	int32_t l = lower;
	for (int32_t i=0; i<node->n_desc; i++)
	{
		int32_t c = node->desc[i]->n_desc;
		if (c>0)
		{
			tree_nodes->push_back(block_tree_node_t(l,l+c-1,1.0));
			fill_ind_recursive(node->desc[i], tree_nodes, l);
			l+=c;
		}
		else
			l++;
	}
}

void collect_tree_nodes_recursive(CIndexBlock* subtree_root_block, vector<block_tree_node_t>* tree_nodes)
{
	CList* sub_blocks = subtree_root_block->get_sub_blocks();
	if (sub_blocks->get_num_elements()>0)
	{
		CIndexBlock* iterator = (CIndexBlock*)sub_blocks->get_first_element();
		do
		{
			SG_SDEBUG("Block [%d %d] \n",iterator->get_min_index(), iterator->get_max_index());
			tree_nodes->push_back(block_tree_node_t(iterator->get_min_index(),iterator->get_max_index(),iterator->get_weight()));
			if (iterator->get_num_sub_blocks()>0)
				collect_tree_nodes_recursive(iterator, tree_nodes);
			SG_UNREF(iterator);
		}
		while ((iterator = (CIndexBlock*)sub_blocks->get_next_element()) != NULL);
	}
	SG_UNREF(sub_blocks);
}

CIndexBlockTree::CIndexBlockTree() : CIndexBlockRelation(), m_root_block(NULL)
{

}

CIndexBlockTree::CIndexBlockTree(CIndexBlock* root_block) : CIndexBlockRelation(),
	m_root_block(NULL)
{
	set_root_block(root_block);
}

CIndexBlockTree::CIndexBlockTree(SGMatrix<float64_t> adjacency_matrix) :
	CIndexBlockRelation(),
	m_root_block(NULL)
{
	ASSERT(adjacency_matrix.num_rows == adjacency_matrix.num_cols);
	int32_t n_features = adjacency_matrix.num_rows;

	// well ordering is assumed

	tree_node_t* nodes = SG_CALLOC(tree_node_t, n_features);

	int32_t* nz_row = SG_CALLOC(int32_t, n_features);
	for (int32_t i=0; i<n_features; i++)
	{
		nodes[i].idx = i;
		nodes[i].sub_nodes_count = 0;
		int32_t c = 0;
		for (int32_t j=i; j<n_features; j++)
		{
			if (adjacency_matrix(j,i)!=0.0)
				nz_row[c++] = j;
		}
		nodes[i].n_desc = c;
		nodes[i].desc = SG_MALLOC(tree_node_t*, c);
		for (int32_t j=0; j<c; j++)
		{
			nodes[i].desc[j] = &nodes[nz_row[j]];
		}
		if (nz_row[c] == n_features)
			break;
	}
	SG_FREE(nz_row);

	count_sub_nodes_recursive(nodes);
	//print_tree(nodes,0);
	m_precomputed_ind_t = SGVector<float64_t>(3*(n_features-nodes[0].sub_nodes_count));
	vector<block_tree_node_t> blocks;
	fill_ind_recursive(nodes, &blocks, 1);
	m_precomputed_ind_t[0] = -1;
	m_precomputed_ind_t[1] = -1;
	m_precomputed_ind_t[2] = 1.0;

	for (int32_t i=0; i<(int)blocks.size(); i++)
	{
		m_precomputed_ind_t[3+3*i+0] = blocks[i].t_min_index;
		m_precomputed_ind_t[3+3*i+1] = blocks[i].t_max_index;
		m_precomputed_ind_t[3+3*i+2] = blocks[i].weight;
	}
	SG_FREE(nodes);
}

CIndexBlockTree::~CIndexBlockTree()
{
	SG_UNREF(m_root_block);
}

CIndexBlock* CIndexBlockTree::get_root_block() const
{
	SG_REF(m_root_block);
	return m_root_block;
}

void CIndexBlockTree::set_root_block(CIndexBlock* root_block)
{
	SG_REF(root_block);
	SG_UNREF(m_root_block);
	m_root_block = root_block;
}

SGVector<index_t> CIndexBlockTree::get_SLEP_ind()
{
	SG_SNOTIMPLEMENTED;
	return SGVector<index_t>();
}

SGVector<float64_t> CIndexBlockTree::get_SLEP_ind_t()
{
	if (m_precomputed_ind_t.vlen)
		return m_precomputed_ind_t;

	else
	{
		CList* blocks = new CList(true);

		vector<block_tree_node_t> tree_nodes = vector<block_tree_node_t>();

		collect_tree_nodes_recursive(m_root_block, &tree_nodes);

		SGVector<float64_t> ind_t(3+3*tree_nodes.size());
		// supernode
		ind_t[0] = -1;
		ind_t[1] = -1;
		ind_t[2] = 1.0;

		for (int32_t i=0; i<(int32_t)tree_nodes.size(); i++)
		{
			ind_t[3+i*3] = tree_nodes[i].t_min_index + 1;
			ind_t[3+i*3+1] = tree_nodes[i].t_max_index;
			ind_t[3+i*3+2] = tree_nodes[i].weight;
		}

		SG_UNREF(blocks);

		return ind_t;
	}
}
<commit_msg>Updated IndexBlockTree constructor routine<commit_after>/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * Copyright (C) 2012 Sergey Lisitsyn
 */

#include <shogun/lib/IndexBlockTree.h>
#include <vector>

using namespace std;
using namespace shogun;

struct tree_node_t
{
	tree_node_t** desc;
	int32_t n_desc;
	int32_t sub_nodes_count;
	int32_t idx;
};

struct block_tree_node_t
{
	block_tree_node_t(int32_t min, int32_t max, float64_t w)
	{
		t_min_index = min;
		t_max_index = max;
		weight = w;
	}
	int32_t t_min_index, t_max_index;
	float64_t weight;
};

int count_sub_nodes_recursive(tree_node_t* node, int32_t self)
{
	if (node->n_desc==0)
	{
		return 1;
	}
	else
	{
		int c = 0;
		for (int32_t i=0; i<node->n_desc; i++)
		{
			c += count_sub_nodes_recursive(node->desc[i], self);
		}
		if (self)
			node->sub_nodes_count = c;
		return c + self;
	}
}

void print_tree(tree_node_t* node, int tabs)
{
	for (int32_t t=0; t<tabs; t++)
		SG_SPRINT("  ");
	SG_SPRINT("%d %d\n",node->idx, node->sub_nodes_count);
	for (int32_t i=0; i<node->n_desc; i++)
		print_tree(node->desc[i],tabs+1);
}

void fill_ind_recursive(tree_node_t* node, vector<block_tree_node_t>* tree_nodes, int32_t lower)
{
	int32_t l = lower;
	for (int32_t i=0; i<node->n_desc; i++)
	{
		int32_t c = node->desc[i]->sub_nodes_count;
		if (c>0)
		{
			tree_nodes->push_back(block_tree_node_t(l,l+c-1,1.0));
			fill_ind_recursive(node->desc[i], tree_nodes, l);
			l+=c;
		}
		else
			l++;
	}
}

void collect_tree_nodes_recursive(CIndexBlock* subtree_root_block, vector<block_tree_node_t>* tree_nodes)
{
	CList* sub_blocks = subtree_root_block->get_sub_blocks();
	if (sub_blocks->get_num_elements()>0)
	{
		CIndexBlock* iterator = (CIndexBlock*)sub_blocks->get_first_element();
		do
		{
			SG_SDEBUG("Block [%d %d] \n",iterator->get_min_index(), iterator->get_max_index());
			tree_nodes->push_back(block_tree_node_t(iterator->get_min_index(),iterator->get_max_index(),iterator->get_weight()));
			if (iterator->get_num_sub_blocks()>0)
				collect_tree_nodes_recursive(iterator, tree_nodes);
			SG_UNREF(iterator);
		}
		while ((iterator = (CIndexBlock*)sub_blocks->get_next_element()) != NULL);
	}
	SG_UNREF(sub_blocks);
}

CIndexBlockTree::CIndexBlockTree() : CIndexBlockRelation(), m_root_block(NULL)
{

}

CIndexBlockTree::CIndexBlockTree(CIndexBlock* root_block) : CIndexBlockRelation(),
	m_root_block(NULL)
{
	set_root_block(root_block);
}

CIndexBlockTree::CIndexBlockTree(SGMatrix<float64_t> adjacency_matrix) :
	CIndexBlockRelation(),
	m_root_block(NULL)
{
	ASSERT(adjacency_matrix.num_rows == adjacency_matrix.num_cols);
	int32_t n_features = adjacency_matrix.num_rows;

	// well ordering is assumed

	tree_node_t* nodes = SG_CALLOC(tree_node_t, n_features);

	int32_t* nz_row = SG_CALLOC(int32_t, n_features);
	for (int32_t i=0; i<n_features; i++)
	{
		nodes[i].idx = i;
		nodes[i].sub_nodes_count = 0;
		int32_t c = 0;
		for (int32_t j=i; j<n_features; j++)
		{
			if (adjacency_matrix(j,i)!=0.0)
				nz_row[c++] = j;
		}
		nodes[i].n_desc = c;
		nodes[i].desc = SG_MALLOC(tree_node_t*, c);
		for (int32_t j=0; j<c; j++)
		{
			nodes[i].desc[j] = &nodes[nz_row[j]];
		}
		if (nz_row[c] == n_features)
			break;
	}
	SG_FREE(nz_row);

	count_sub_nodes_recursive(nodes,1);
	print_tree(nodes,0);
	int32_t n_leaves = count_sub_nodes_recursive(nodes,0);
	m_precomputed_ind_t = SGVector<float64_t>((n_features-n_leaves)*3);
	SG_PRINT("n_leaves = %d\n",n_leaves);
	vector<block_tree_node_t> blocks;
	fill_ind_recursive(nodes, &blocks, 1);
	m_precomputed_ind_t[0] = -1;
	m_precomputed_ind_t[1] = -1;
	m_precomputed_ind_t[2] = 1.0;

	for (int32_t i=0; i<(int)blocks.size(); i++)
	{
		m_precomputed_ind_t[3+3*i+0] = blocks[i].t_min_index;
		m_precomputed_ind_t[3+3*i+1] = blocks[i].t_max_index;
		m_precomputed_ind_t[3+3*i+2] = blocks[i].weight;
	}
	for (int32_t i=0; i<n_features; i++)
		SG_FREE(nodes[i].desc);
	SG_FREE(nodes);
}

CIndexBlockTree::~CIndexBlockTree()
{
	SG_UNREF(m_root_block);
}

CIndexBlock* CIndexBlockTree::get_root_block() const
{
	SG_REF(m_root_block);
	return m_root_block;
}

void CIndexBlockTree::set_root_block(CIndexBlock* root_block)
{
	SG_REF(root_block);
	SG_UNREF(m_root_block);
	m_root_block = root_block;
}

SGVector<index_t> CIndexBlockTree::get_SLEP_ind()
{
	SG_SNOTIMPLEMENTED;
	return SGVector<index_t>();
}

SGVector<float64_t> CIndexBlockTree::get_SLEP_ind_t()
{
	if (m_precomputed_ind_t.vlen)
		return m_precomputed_ind_t;

	else
	{
		CList* blocks = new CList(true);

		vector<block_tree_node_t> tree_nodes = vector<block_tree_node_t>();

		collect_tree_nodes_recursive(m_root_block, &tree_nodes);

		SGVector<float64_t> ind_t(3+3*tree_nodes.size());
		// supernode
		ind_t[0] = -1;
		ind_t[1] = -1;
		ind_t[2] = 1.0;

		for (int32_t i=0; i<(int32_t)tree_nodes.size(); i++)
		{
			ind_t[3+i*3] = tree_nodes[i].t_min_index + 1;
			ind_t[3+i*3+1] = tree_nodes[i].t_max_index;
			ind_t[3+i*3+2] = tree_nodes[i].weight;
		}

		SG_UNREF(blocks);

		return ind_t;
	}
}
<|endoftext|>


<commit_before>/*****************************************************************************
  shuffleBedMain.cpp

  (c) 2009 - Aaron Quinlan
  Hall Laboratory
  Department of Biochemistry and Molecular Genetics
  University of Virginia
  aaronquinlan@gmail.com

  Licenced under the GNU General Public License 2.0 license.
******************************************************************************/
#include "shuffleBed.h"

using namespace std;

// define our program name
#define PROGRAM_NAME "bedtools shuffle"

// define our parameter checking macro
#define PARAMETER_CHECK(param, paramLen, actualLen) (strncmp(argv[i], param, min(actualLen, paramLen))== 0) && (actualLen == paramLen)

// function declarations
void shuffle_help(void);

int shuffle_main(int argc, char* argv[]) {

    // our configuration variables
    bool showHelp = false;

    // input files
    string bedFile = "stdin";
    string excludeFile;
    string includeFile;
    string genomeFile;

    bool haveBed          = true;
    bool haveGenome       = false;
    bool haveExclude      = false;
    bool haveInclude      = false;
    bool haveSeed         = false;
    float overlapFraction = 0.0;
    int seed              = -1;
    bool sameChrom        = false;
    bool chooseChrom      = false;

    for(int i = 1; i < argc; i++) {
        int parameterLength = (int)strlen(argv[i]);

        if((PARAMETER_CHECK("-h", 2, parameterLength)) ||
        (PARAMETER_CHECK("--help", 5, parameterLength))) {
            showHelp = true;
        }
    }

    if(showHelp) shuffle_help();

    // do some parsing (all of these parameters require 2 strings)
    for(int i = 1; i < argc; i++) {

        int parameterLength = (int)strlen(argv[i]);

        if(PARAMETER_CHECK("-i", 2, parameterLength)) {
            if ((i+1) < argc) {
                bedFile = argv[i + 1];
                i++;
            }
        }
        else if(PARAMETER_CHECK("-g", 2, parameterLength)) {
            if ((i+1) < argc) {
                haveGenome = true;
                genomeFile = argv[i + 1];
                i++;
            }
        }
        else if(PARAMETER_CHECK("-excl", 5, parameterLength)) {
            if ((i+1) < argc) {
                haveExclude = true;
                excludeFile = argv[i + 1];
                i++;
            }
        }
        else if(PARAMETER_CHECK("-incl", 5, parameterLength)) {
            if ((i+1) < argc) {
                haveInclude = true;
                includeFile = argv[i + 1];
                i++;
            }
        }
        else if(PARAMETER_CHECK("-seed", 5, parameterLength)) {
            if ((i+1) < argc) {
                haveSeed = true;
                seed = atoi(argv[i + 1]);
                i++;
            }
        }
        else if(PARAMETER_CHECK("-chrom", 6, parameterLength)) {
            sameChrom = true;
        }
        else if(PARAMETER_CHECK("-chromFirst", 11, parameterLength)) {
            chooseChrom = true;
        }
        else if(PARAMETER_CHECK("-f", 2, parameterLength)) {
            if ((i+1) < argc) {
                overlapFraction = atof(argv[i + 1]);
                i++;
            }
        }
        else {
          cerr << endl << "*****ERROR: Unrecognized parameter: " << argv[i] << " *****" << endl << endl;
            showHelp = true;
        }
    }

    // make sure we have both input files
    if (!haveBed || !haveGenome) {
      cerr << endl << "*****" << endl << "*****ERROR: Need both a BED (-i) and a genome (-g) file. " << endl << "*****" << endl;
      showHelp = true;
    }

    if (haveInclude && haveExclude) {
      cerr << endl << "*****" << endl << "*****ERROR: Cannot use -incl and -excl together." << endl << "*****" << endl;
      showHelp = true;
    }

    if (sameChrom && !chooseChrom) {
        cerr << endl << "*****" << endl << "*****ERROR: Must use -chromThenStart with -chrom" << endl << "*****" << endl;
        showHelp = true;
    }

    if (!showHelp) {
        BedShuffle *bc = new BedShuffle(bedFile, genomeFile, excludeFile, includeFile,
                                        haveSeed, haveExclude, haveInclude, sameChrom,
                                        overlapFraction, seed, chooseChrom);
        delete bc;
        return 0;
    }
    else {
        shuffle_help();
    }
    return 0;
}

void shuffle_help(void) {

    cerr << "\nTool:    bedtools shuffle (aka shuffleBed)" << endl;

    cerr << "Summary: Randomly permute the locations of a feature file among a genome." << endl << endl;

    cerr << "Usage:   " << PROGRAM_NAME << " [OPTIONS] -i <bed/gff/vcf> -g <genome>" << endl << endl;

    cerr << "Options: " << endl;
    cerr << "\t-excl\t"             << "A BED/GFF/VCF file of coordinates in which features in -i" << endl;
    cerr                            << "\t\tshould not be placed (e.g. gaps.bed)." << endl << endl;

    cerr << "\t-incl\t"             << "Instead of randomly placing features in a genome, the -incl" << endl;
    cerr                            << "\t\toptions defines a BED/GFF/VCF file of coordinates in which " << endl;
    cerr                            << "\t\tfeatures in -i should be randomly placed (e.g. genes.bed). " << endl;
    cerr                            << "\t\t- NOTE: must use with -chromThenStart." << endl << endl;

    cerr << "\t-chrom\t"            << "Keep features in -i on the same chromosome."<< endl;
    cerr                            << "\t\t- By default, the chrom and position are randomly chosen." << endl;
    cerr                            << "\t\t- NOTE: must use with -chromThenStart." << endl << endl;

    cerr << "\t-seed\t"             << "Supply an integer seed for the shuffling." << endl;
    cerr                            << "\t\t- By default, the seed is chosen automatically." << endl;
    cerr                            << "\t\t- (INTEGER)" << endl << endl;

    cerr << "\t-f\t"                << "Maximum overlap (as a fraction of the -i feature) with an -excl" << endl;
    cerr                            << "\t\tfeature that is tolerated before searching for a new, " << endl;
    cerr                            << "\t\trandomized locus. For example, -f 0.10 allows up to 10%" << endl;
    cerr                            << "\t\tof a randomized feature to overlap with a given feature" << endl;
    cerr                            << "\t\tin the -excl file. **Cannot be used with -incl file.**" << endl;
    cerr                            << "\t\t- Default is 1E-9 (i.e., 1bp)." << endl;
    cerr                            << "\t\t- FLOAT (e.g. 0.50)" << endl << endl;

    cerr << "\t-chromFirst\t"       << "\n\t\tInstead of choosing a position randomly among the entire" << endl;
    cerr                            << "\t\tgenome, first choose a chrom randomly, and then" << endl;
    cerr                            << "\t\tchoose a random start coordinate on that chrom." << endl << endl;

    cerr << "Notes: " << endl;
    cerr << "\t(1)  The genome file should tab delimited and structured as follows:" << endl;
    cerr << "\t     <chromName><TAB><chromSize>" << endl << endl;
    cerr << "\tFor example, Human (hg19):" << endl;
    cerr << "\tchr1\t249250621" << endl;
    cerr << "\tchr2\t243199373" << endl;
    cerr << "\t..." << endl;
    cerr << "\tchr18_gl000207_random\t4262" << endl << endl;

    cerr << "Tips: " << endl;
    cerr << "\tOne can use the UCSC Genome Browser's MySQL database to extract" << endl;
    cerr << "\tchromosome sizes. For example, H. sapiens:" << endl << endl;
    cerr << "\tmysql --user=genome --host=genome-mysql.cse.ucsc.edu -A -e \\" << endl;
    cerr << "\t\"select chrom, size from hg19.chromInfo\"  > hg19.genome" << endl << endl;

    // end the program here
    exit(1);
}
<commit_msg>Change shuffleBed defaults.<commit_after>/*****************************************************************************
  shuffleBedMain.cpp

  (c) 2009 - Aaron Quinlan
  Hall Laboratory
  Department of Biochemistry and Molecular Genetics
  University of Virginia
  aaronquinlan@gmail.com

  Licenced under the GNU General Public License 2.0 license.
******************************************************************************/
#include "shuffleBed.h"

using namespace std;

// define our program name
#define PROGRAM_NAME "bedtools shuffle"

// define our parameter checking macro
#define PARAMETER_CHECK(param, paramLen, actualLen) (strncmp(argv[i], param, min(actualLen, paramLen))== 0) && (actualLen == paramLen)

// function declarations
void shuffle_help(void);

int shuffle_main(int argc, char* argv[]) {

    // our configuration variables
    bool showHelp = false;

    // input files
    string bedFile = "stdin";
    string excludeFile;
    string includeFile;
    string genomeFile;

    bool haveBed          = true;
    bool haveGenome       = false;
    bool haveExclude      = false;
    bool haveInclude      = false;
    bool haveSeed         = false;
    float overlapFraction = 0.0;
    int seed              = -1;
    bool sameChrom        = false;
    bool chooseChrom      = false;

    for(int i = 1; i < argc; i++) {
        int parameterLength = (int)strlen(argv[i]);

        if((PARAMETER_CHECK("-h", 2, parameterLength)) ||
        (PARAMETER_CHECK("--help", 5, parameterLength))) {
            showHelp = true;
        }
    }

    if(showHelp) shuffle_help();

    // do some parsing (all of these parameters require 2 strings)
    for(int i = 1; i < argc; i++) {

        int parameterLength = (int)strlen(argv[i]);

        if(PARAMETER_CHECK("-i", 2, parameterLength)) {
            if ((i+1) < argc) {
                bedFile = argv[i + 1];
                i++;
            }
        }
        else if(PARAMETER_CHECK("-g", 2, parameterLength)) {
            if ((i+1) < argc) {
                haveGenome = true;
                genomeFile = argv[i + 1];
                i++;
            }
        }
        else if(PARAMETER_CHECK("-excl", 5, parameterLength)) {
            if ((i+1) < argc) {
                haveExclude = true;
                excludeFile = argv[i + 1];
                i++;
            }
        }
        else if(PARAMETER_CHECK("-incl", 5, parameterLength)) {
            if ((i+1) < argc) {
                haveInclude = true;
                chooseChrom = true;
                includeFile = argv[i + 1];
                i++;
            }
        }
        else if(PARAMETER_CHECK("-seed", 5, parameterLength)) {
            if ((i+1) < argc) {
                haveSeed = true;
                seed = atoi(argv[i + 1]);
                i++;
            }
        }
        else if(PARAMETER_CHECK("-chrom", 6, parameterLength)) {
            chooseChrom = true;
            sameChrom = true;
        }
        else if(PARAMETER_CHECK("-chromFirst", 11, parameterLength)) {
            chooseChrom = true;
        }
        else if(PARAMETER_CHECK("-f", 2, parameterLength)) {
            if ((i+1) < argc) {
                overlapFraction = atof(argv[i + 1]);
                i++;
            }
        }
        else {
          cerr << endl << "*****ERROR: Unrecognized parameter: " << argv[i] << " *****" << endl << endl;
            showHelp = true;
        }
    }

    // make sure we have both input files
    if (!haveBed || !haveGenome) {
      cerr << endl << "*****" << endl << "*****ERROR: Need both a BED (-i) and a genome (-g) file. " << endl << "*****" << endl;
      showHelp = true;
    }

    if (haveInclude && haveExclude) {
      cerr << endl << "*****" << endl << "*****ERROR: Cannot use -incl and -excl together." << endl << "*****" << endl;
      showHelp = true;
    }

    if (!showHelp) {
        BedShuffle *bc = new BedShuffle(bedFile, genomeFile, excludeFile, includeFile,
                                        haveSeed, haveExclude, haveInclude, sameChrom,
                                        overlapFraction, seed, chooseChrom);
        delete bc;
        return 0;
    }
    else {
        shuffle_help();
    }
    return 0;
}

void shuffle_help(void) {

    cerr << "\nTool:    bedtools shuffle (aka shuffleBed)" << endl;

    cerr << "Summary: Randomly permute the locations of a feature file among a genome." << endl << endl;

    cerr << "Usage:   " << PROGRAM_NAME << " [OPTIONS] -i <bed/gff/vcf> -g <genome>" << endl << endl;

    cerr << "Options: " << endl;
    cerr << "\t-excl\t"             << "A BED/GFF/VCF file of coordinates in which features in -i" << endl;
    cerr                            << "\t\tshould not be placed (e.g. gaps.bed)." << endl << endl;

    cerr << "\t-incl\t"             << "Instead of randomly placing features in a genome, the -incl" << endl;
    cerr                            << "\t\toptions defines a BED/GFF/VCF file of coordinates in which " << endl;
    cerr                            << "\t\tfeatures in -i should be randomly placed (e.g. genes.bed). " << endl;
    cerr                            << "\t\t- NOTE: Forces use of -chromFirst (see below)." << endl << endl;

    cerr << "\t-chrom\t"            << "Keep features in -i on the same chromosome."<< endl;
    cerr                            << "\t\t- By default, the chrom and position are randomly chosen." << endl;
    cerr                            << "\t\t- NOTE: Forces use of -chromFirst (see below)." << endl << endl;

    cerr << "\t-seed\t"             << "Supply an integer seed for the shuffling." << endl;
    cerr                            << "\t\t- By default, the seed is chosen automatically." << endl;
    cerr                            << "\t\t- (INTEGER)" << endl << endl;

    cerr << "\t-f\t"                << "Maximum overlap (as a fraction of the -i feature) with an -excl" << endl;
    cerr                            << "\t\tfeature that is tolerated before searching for a new, " << endl;
    cerr                            << "\t\trandomized locus. For example, -f 0.10 allows up to 10%" << endl;
    cerr                            << "\t\tof a randomized feature to overlap with a given feature" << endl;
    cerr                            << "\t\tin the -excl file. **Cannot be used with -incl file.**" << endl;
    cerr                            << "\t\t- Default is 1E-9 (i.e., 1bp)." << endl;
    cerr                            << "\t\t- FLOAT (e.g. 0.50)" << endl << endl;

    cerr << "\t-chromFirst\t"       << "\n\t\tInstead of choosing a position randomly among the entire" << endl;
    cerr                            << "\t\tgenome (the default), first choose a chrom randomly, and then" << endl;
    cerr                            << "\t\tchoose a random start coordinate on that chrom.  This leads" << endl;
    cerr                            << "\t\tto features being ~uniformly distributed among the chroms," << endl;
    cerr                            << "\t\tas opposed to features being distribute as a function of chrom size." << endl << endl;

    cerr << "Notes: " << endl;
    cerr << "\t(1)  The genome file should tab delimited and structured as follows:" << endl;
    cerr << "\t     <chromName><TAB><chromSize>" << endl << endl;
    cerr << "\tFor example, Human (hg19):" << endl;
    cerr << "\tchr1\t249250621" << endl;
    cerr << "\tchr2\t243199373" << endl;
    cerr << "\t..." << endl;
    cerr << "\tchr18_gl000207_random\t4262" << endl << endl;

    cerr << "Tips: " << endl;
    cerr << "\tOne can use the UCSC Genome Browser's MySQL database to extract" << endl;
    cerr << "\tchromosome sizes. For example, H. sapiens:" << endl << endl;
    cerr << "\tmysql --user=genome --host=genome-mysql.cse.ucsc.edu -A -e \\" << endl;
    cerr << "\t\"select chrom, size from hg19.chromInfo\"  > hg19.genome" << endl << endl;

    // end the program here
    exit(1);
}
<|endoftext|>