<commit_before>/*
 *  autostart.cpp - autostart KAlarm when session restoration is complete
 *  Program:  kalarmautostart
 *  Copyright © 2001,2008 by David Jarvie <djarvie@kde.org>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include "kalarm.h"
#include "autostart.moc"

#include <QTimer>
#include <QtDBus/QtDBus>

#include <kcmdlineargs.h>
#include <kaboutdata.h>
#include <klocale.h>
#include <kstandarddirs.h>
#include <kprocess.h>
#include <kdebug.h>

// Number of seconds to wait before autostarting KAlarm.
// Allow plenty of time for session restoration to happen first.
static const int AUTOSTART_DELAY = 30;

#define PROGRAM_VERSION      "1.0"
#define PROGRAM_NAME "kalarmautostart"

int main(int argc, char *argv[])
{
	KAboutData aboutData(PROGRAM_NAME, "kalarm", ki18n("KAlarm Autostart"),
		PROGRAM_VERSION, ki18n("KAlarm autostart at login"), KAboutData::License_GPL,
		ki18n("Copyright 2001,2008 David Jarvie"), KLocalizedString(),
		"http://www.astrojar.org.uk/kalarm");
	aboutData.addAuthor(ki18n("David Jarvie"), ki18n("Maintainer"), "djarvie@kde.org");
	aboutData.setOrganizationDomain("kalarm.kde.org");
	KCmdLineArgs::init(argc, argv, &aboutData);

	KCmdLineOptions options;
	options.add("!+app", ki18n("Application to autostart"));
	options.add("+[arg]", ki18n("Command line arguments"));
	KCmdLineArgs::addCmdLineOptions(options);

	AutostartApp app;
	return app.exec();
}

AutostartApp::AutostartApp()
	: KApplication(false)       // initialise as non-GUI application
{
	// Login session is starting up - need to wait for it to complete
	// in order to avoid starting the client before it is restored by
	// the session (where applicable).
	QTimer::singleShot(AUTOSTART_DELAY * 1000, this, SLOT(slotAutostart()));
}

void AutostartApp::slotAutostart()
{
	QDBusReply<bool> reply = QDBusConnection::sessionBus().interface()->isServiceRegistered(KALARM_DBUS_SERVICE);
	if (reply.isValid()  &&  reply.value())
		kDebug(5900) << "KAlarm already running";
	else
	{
		KCmdLineArgs* args = KCmdLineArgs::parsedArgs();
		if (args->count() <= 0)
			kWarning(5900) << "No command line";
		else
		{
			QString prog = args->arg(0);
			QString exe = KStandardDirs::locate("exe", prog);
			if (exe.isEmpty())
				kWarning(5900) << "Executable not found:" << prog;
			else
			{
				kDebug(5900) << "Starting" << prog;
				KProcess proc;
				proc << exe;
				for (int i = 1;  i < args->count();  ++i)
					proc << args->arg(i);
				proc.startDetached();
			}
		}
	}
	exit();
}
<commit_msg>Load translations<commit_after>/*
 *  autostart.cpp - autostart KAlarm when session restoration is complete
 *  Program:  kalarmautostart
 *  Copyright © 2001,2008 by David Jarvie <djarvie@kde.org>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include "kalarm.h"
#include "autostart.moc"

#include <QTimer>
#include <QtDBus/QtDBus>

#include <kcmdlineargs.h>
#include <kaboutdata.h>
#include <klocale.h>
#include <kstandarddirs.h>
#include <kprocess.h>
#include <kdebug.h>

// Number of seconds to wait before autostarting KAlarm.
// Allow plenty of time for session restoration to happen first.
static const int AUTOSTART_DELAY = 30;

#define PROGRAM_VERSION      "1.0"
#define PROGRAM_NAME "kalarmautostart"

int main(int argc, char *argv[])
{
	KAboutData aboutData(PROGRAM_NAME, "kalarm", ki18n("KAlarm Autostart"),
		PROGRAM_VERSION, ki18n("KAlarm autostart at login"), KAboutData::License_GPL,
		ki18n("Copyright 2001,2008 David Jarvie"), KLocalizedString(),
		"http://www.astrojar.org.uk/kalarm");
	aboutData.addAuthor(ki18n("David Jarvie"), ki18n("Maintainer"), "djarvie@kde.org");
	aboutData.setOrganizationDomain("kalarm.kde.org");
	KCmdLineArgs::init(argc, argv, &aboutData);

	KCmdLineOptions options;
	options.add("!+app", ki18n("Application to autostart"));
	options.add("+[arg]", ki18n("Command line arguments"));
	KCmdLineArgs::addCmdLineOptions(options);

	AutostartApp app;
	KGlobal::locale()->insertCatalog("kalarm");
	return app.exec();
}

AutostartApp::AutostartApp()
	: KApplication(false)       // initialise as non-GUI application
{
	// Login session is starting up - need to wait for it to complete
	// in order to avoid starting the client before it is restored by
	// the session (where applicable).
	QTimer::singleShot(AUTOSTART_DELAY * 1000, this, SLOT(slotAutostart()));
}

void AutostartApp::slotAutostart()
{
	QDBusReply<bool> reply = QDBusConnection::sessionBus().interface()->isServiceRegistered(KALARM_DBUS_SERVICE);
	if (reply.isValid()  &&  reply.value())
		kDebug(5900) << "KAlarm already running";
	else
	{
		KCmdLineArgs* args = KCmdLineArgs::parsedArgs();
		if (args->count() <= 0)
			kWarning(5900) << "No command line";
		else
		{
			QString prog = args->arg(0);
			QString exe = KStandardDirs::locate("exe", prog);
			if (exe.isEmpty())
				kWarning(5900) << "Executable not found:" << prog;
			else
			{
				kDebug(5900) << "Starting" << prog;
				KProcess proc;
				proc << exe;
				for (int i = 1;  i < args->count();  ++i)
					proc << args->arg(i);
				proc.startDetached();
			}
		}
	}
	exit();
}
<|endoftext|>


<commit_before>/*
  This file is part of KOrganizer.

  Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
  Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

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

  You should have received a copy of the GNU General Public License along
  with this program; if not, write to the Free Software Foundation, Inc.,
  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

  As a special exception, permission is given to link this program
  with any edition of Qt, and distribute the resulting executable,
  without including the source code for Qt in the source distribution.
*/

#include "kodialogmanager.h"
#include "calendarview.h"
#include "koprefsdialog.h"
#include "koprefs.h"
#include "koeventeditor.h"
#include "kotodoeditor.h"
#include "kojournaleditor.h"
#include "searchdialog.h"
#include "filtereditdialog.h"
#ifndef KORG_NOARCHIVE
#include "archivedialog.h"
#endif
#include "koviewmanager.h"
#include "koagendaview.h"
#include "koglobals.h"

#include <libkdepim/categoryeditdialog.h>

#include <kcmultidialog.h>
#include <ksettings/dialog.h>
#include <kwindowsystem.h>

#include <QByteArray>
#include <QList>

#include "kodialogmanager.moc"

// FIXME: Handle KOEventViewerDialogs in dialog manager. Pass
// KOPrefs::mCompactDialog.

class KODialogManager::DialogManagerVisitor : public IncidenceBase::Visitor
{
  public:
    DialogManagerVisitor() : mDialogManager( 0 ) {}

    bool act( IncidenceBase *incidence, KODialogManager *manager )
    {
      mDialogManager = manager;
      return incidence->accept( *this );
    }

  protected:
    KODialogManager *mDialogManager;
};

class KODialogManager::EditorDialogVisitor :
      public KODialogManager::DialogManagerVisitor
{
  public:
    EditorDialogVisitor() : DialogManagerVisitor(), mEditor( 0 ) {}
    KOIncidenceEditor *editor() const { return mEditor; }
  protected:
    bool visit( Event * ) { mEditor = mDialogManager->getEventEditor(); return mEditor; }
    bool visit( Todo * ) { mEditor = mDialogManager->getTodoEditor(); return mEditor; }
    bool visit( Journal * ) { mEditor = mDialogManager->getJournalEditor(); return mEditor; }
  protected:
    KOIncidenceEditor *mEditor;
};

KODialogManager::KODialogManager( CalendarView *mainView ) :
  QObject(), mMainView( mainView )
{
  mOptionsDialog = 0;
  mSearchDialog = 0;
  mArchiveDialog = 0;
  mFilterEditDialog = 0;

  mCategoryEditDialog = new KPIM::CategoryEditDialog( KOPrefs::instance(), mMainView );
  KWindowSystem::setMainWindow( mCategoryEditDialog, 0 );
  connect( mainView, SIGNAL( categoriesChanged() ),
           mCategoryEditDialog, SLOT( reload() ) );
  connect( mCategoryEditDialog, SIGNAL( categoryConfigChanged() ), mainView,
           SIGNAL( categoryConfigChanged() ) );
  KOGlobals::fitDialogToScreen( mCategoryEditDialog );
}

KODialogManager::~KODialogManager()
{
  delete mOptionsDialog;
  delete mSearchDialog;
#ifndef KORG_NOARCHIVE
  delete mArchiveDialog;
#endif
  delete mFilterEditDialog;
}

void KODialogManager::errorSaveIncidence( QWidget *parent, Incidence *incidence )
{
  KMessageBox::sorry( parent, i18n("Unable to save %1 \"%2\".",
                        i18n( incidence->type() ) ,
                        incidence->summary() ) );
}

void KODialogManager::showOptionsDialog()
{
  if (!mOptionsDialog) {
#if 0
    mOptionsDialog = new KConfigureDialog();
//    mOptionsDialog = new KConfigureDialog( KConfigureDialog::Configurable );
//    mOptionsDialog = new KConfigureDialog( mMainView );
    connect( mOptionsDialog->dialog(),
             SIGNAL( configCommitted( const QByteArray & ) ),
             mMainView, SLOT( updateConfig() ) );
#else
    mOptionsDialog = new KCMultiDialog( mMainView );
    connect( mOptionsDialog, SIGNAL( configCommitted( const QByteArray & ) ),
             mMainView, SLOT( updateConfig( const QByteArray& ) ) );
#if 0
    connect( mOptionsDialog, SIGNAL( applyClicked() ),
             mMainView, SLOT( updateConfig() ) );
    connect( mOptionsDialog, SIGNAL( okClicked() ),
             mMainView, SLOT( updateConfig() ) );
    // @TODO Find a way to do this with KCMultiDialog
    connect(mCategoryEditDialog,SIGNAL(categoryConfigChanged()),
            mOptionsDialog,SLOT(updateCategories()));
#endif

    QStringList modules;

    modules.append( "korganizer_configmain.desktop" );
    modules.append( "korganizer_configtime.desktop" );
    modules.append( "korganizer_configviews.desktop" );
    modules.append( "korganizer_configcolorsandfonts.desktop" );
    modules.append( "korganizer_configgroupscheduling.desktop" );
    modules.append( "korganizer_configgroupautomation.desktop" );
    modules.append( "korganizer_configfreebusy.desktop" );
    modules.append( "korganizer_configplugins.desktop" );
    modules.append( "korganizer_configdesignerfields.desktop" );

    // add them all
    QStringList::iterator mit;
    for ( mit = modules.begin(); mit != modules.end(); ++mit )
      mOptionsDialog->addModule( *mit );
#endif
  }

  mOptionsDialog->show();
  mOptionsDialog->raise();
}

void KODialogManager::showCategoryEditDialog()
{
  mCategoryEditDialog->show();
}

void KODialogManager::showSearchDialog()
{
  if (!mSearchDialog) {
    mSearchDialog = new SearchDialog(mMainView->calendar(),mMainView);
    connect(mSearchDialog,SIGNAL(showIncidenceSignal(Incidence *)),
            mMainView,SLOT(showIncidence(Incidence *)));
    connect(mSearchDialog,SIGNAL(editIncidenceSignal(Incidence *)),
            mMainView,SLOT(editIncidence(Incidence *)));
    connect(mSearchDialog,SIGNAL(deleteIncidenceSignal(Incidence *)),
            mMainView, SLOT(deleteIncidence(Incidence *)));
    connect(mMainView,SIGNAL(closingDown()),mSearchDialog,SLOT(reject()));
  }
  // make sure the widget is on top again
  mSearchDialog->show();
  mSearchDialog->raise();
}

void KODialogManager::showArchiveDialog()
{
#ifndef KORG_NOARCHIVE
  if (!mArchiveDialog) {
    mArchiveDialog = new ArchiveDialog(mMainView->calendar(),mMainView);
    connect(mArchiveDialog,SIGNAL(eventsDeleted()),
            mMainView,SLOT(updateView()));
    connect(mArchiveDialog,SIGNAL(autoArchivingSettingsModified()),
            mMainView,SLOT(slotAutoArchivingSettingsModified()));
  }
  mArchiveDialog->show();
  mArchiveDialog->raise();

  // Workaround.
  QApplication::restoreOverrideCursor();
#endif
}

void KODialogManager::showFilterEditDialog( QList<CalFilter*> *filters )
{
  if ( !mFilterEditDialog ) {
    mFilterEditDialog = new FilterEditDialog( filters, mMainView );
    connect( mFilterEditDialog, SIGNAL( filterChanged() ),
             mMainView, SLOT( updateFilter() ) );
    connect( mFilterEditDialog, SIGNAL( editCategories() ),
             mCategoryEditDialog, SLOT( show() ) );
    connect( mCategoryEditDialog, SIGNAL( categoryConfigChanged() ),
             mFilterEditDialog, SLOT( updateCategoryConfig() ) );
  }
  mFilterEditDialog->show();
  mFilterEditDialog->raise();
}

KOIncidenceEditor *KODialogManager::getEditor( Incidence *incidence )
{
  if ( !incidence ) return 0;
  EditorDialogVisitor v;
  if ( v.act( incidence, this ) ) {
    return v.editor();
  } else
    return 0;
}

KOEventEditor *KODialogManager::getEventEditor()
{
  KOEventEditor *eventEditor = new KOEventEditor( mMainView->calendar(),
                                                  mMainView );
  connectEditor( eventEditor );
  return eventEditor;
}

void KODialogManager::connectTypeAhead( KOEventEditor *editor,
                                        KOrg::AgendaView *agenda )
{
  if ( editor && agenda ) {
    agenda->setTypeAheadReceiver( editor->typeAheadReceiver() );
    connect( editor, SIGNAL( focusReceivedSignal() ),
             agenda, SLOT( finishTypeAhead() ) );
  }
}

void KODialogManager::connectEditor( KOIncidenceEditor*editor )
{
/*  connect( editor, SIGNAL( deleteIncidenceSignal( Incidence * ) ),
           mMainView, SLOT( deleteIncidence( Incidence * ) ) );*/

  connect( mCategoryEditDialog, SIGNAL( categoryConfigChanged() ),
           editor, SLOT( updateCategoryConfig() ) );
  connect( editor, SIGNAL( editCategories() ),
           mCategoryEditDialog, SLOT( show() ) );

  connect( editor, SIGNAL( dialogClose( Incidence * ) ),
           mMainView, SLOT( dialogClosing( Incidence * ) ) );
  connect( editor, SIGNAL( editCanceled( Incidence * ) ),
           mMainView, SLOT( editCanceled( Incidence * ) ) );
  connect( mMainView, SIGNAL( closingDown() ), editor, SLOT( reject() ) );

  connect( editor, SIGNAL( deleteAttendee( Incidence * ) ),
           mMainView, SIGNAL( cancelAttendees( Incidence * ) ) );
}

KOTodoEditor *KODialogManager::getTodoEditor()
{
  kDebug(5850) ;
  KOTodoEditor *todoEditor = new KOTodoEditor( mMainView->calendar(), mMainView );
  connectEditor( todoEditor );
  return todoEditor;
}

KOJournalEditor *KODialogManager::getJournalEditor()
{
  KOJournalEditor *journalEditor = new KOJournalEditor( mMainView->calendar(), mMainView );
  connectEditor( journalEditor );
  return journalEditor;
}

void KODialogManager::updateSearchDialog()
{
  if (mSearchDialog) mSearchDialog->updateView();
}

<commit_msg>cruft cleaning SVN_SILENT:<commit_after>/*
  This file is part of KOrganizer.

  Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
  Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

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

  You should have received a copy of the GNU General Public License along
  with this program; if not, write to the Free Software Foundation, Inc.,
  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

  As a special exception, permission is given to link this program
  with any edition of Qt, and distribute the resulting executable,
  without including the source code for Qt in the source distribution.
*/

#include "kodialogmanager.h"
#include "calendarview.h"
#include "koprefsdialog.h"
#include "koprefs.h"
#include "koeventeditor.h"
#include "kotodoeditor.h"
#include "kojournaleditor.h"
#include "searchdialog.h"
#include "filtereditdialog.h"
#ifndef KORG_NOARCHIVE
#include "archivedialog.h"
#endif
#include "koviewmanager.h"
#include "koagendaview.h"
#include "koglobals.h"

#include <libkdepim/categoryeditdialog.h>

#include <kcmultidialog.h>
#include <ksettings/dialog.h>
#include <kwindowsystem.h>

#include <QByteArray>
#include <QList>

#include "kodialogmanager.moc"

// FIXME: Handle KOEventViewerDialogs in dialog manager. Pass
// KOPrefs::mCompactDialog.

class KODialogManager::DialogManagerVisitor : public IncidenceBase::Visitor
{
  public:
    DialogManagerVisitor() : mDialogManager( 0 ) {}

    bool act( IncidenceBase *incidence, KODialogManager *manager )
    {
      mDialogManager = manager;
      return incidence->accept( *this );
    }

  protected:
    KODialogManager *mDialogManager;
};

class KODialogManager::EditorDialogVisitor :
      public KODialogManager::DialogManagerVisitor
{
  public:
    EditorDialogVisitor() : DialogManagerVisitor(), mEditor( 0 ) {}
    KOIncidenceEditor *editor() const { return mEditor; }
  protected:
    bool visit( Event * ) { mEditor = mDialogManager->getEventEditor(); return mEditor; }
    bool visit( Todo * ) { mEditor = mDialogManager->getTodoEditor(); return mEditor; }
    bool visit( Journal * ) { mEditor = mDialogManager->getJournalEditor(); return mEditor; }
  protected:
    KOIncidenceEditor *mEditor;
};

KODialogManager::KODialogManager( CalendarView *mainView ) :
  QObject(), mMainView( mainView )
{
  mOptionsDialog = 0;
  mSearchDialog = 0;
  mArchiveDialog = 0;
  mFilterEditDialog = 0;

  mCategoryEditDialog = new KPIM::CategoryEditDialog( KOPrefs::instance(), mMainView );
  KWindowSystem::setMainWindow( mCategoryEditDialog, 0 );
  connect( mainView, SIGNAL( categoriesChanged() ),
           mCategoryEditDialog, SLOT( reload() ) );
  connect( mCategoryEditDialog, SIGNAL( categoryConfigChanged() ), mainView,
           SIGNAL( categoryConfigChanged() ) );
  KOGlobals::fitDialogToScreen( mCategoryEditDialog );
}

KODialogManager::~KODialogManager()
{
  delete mOptionsDialog;
  delete mSearchDialog;
#ifndef KORG_NOARCHIVE
  delete mArchiveDialog;
#endif
  delete mFilterEditDialog;
}

void KODialogManager::errorSaveIncidence( QWidget *parent, Incidence *incidence )
{
  KMessageBox::sorry( parent, i18n("Unable to save %1 \"%2\".",
                        i18n( incidence->type() ) ,
                        incidence->summary() ) );
}

void KODialogManager::showOptionsDialog()
{
  if (!mOptionsDialog) {
    mOptionsDialog = new KCMultiDialog( mMainView );
    connect( mOptionsDialog, SIGNAL( configCommitted( const QByteArray & ) ),
             mMainView, SLOT( updateConfig( const QByteArray& ) ) );
    QStringList modules;

    modules.append( "korganizer_configmain.desktop" );
    modules.append( "korganizer_configtime.desktop" );
    modules.append( "korganizer_configviews.desktop" );
    modules.append( "korganizer_configcolorsandfonts.desktop" );
    modules.append( "korganizer_configgroupscheduling.desktop" );
    modules.append( "korganizer_configgroupautomation.desktop" );
    modules.append( "korganizer_configfreebusy.desktop" );
    modules.append( "korganizer_configplugins.desktop" );
    modules.append( "korganizer_configdesignerfields.desktop" );

    // add them all
    QStringList::iterator mit;
    for ( mit = modules.begin(); mit != modules.end(); ++mit )
      mOptionsDialog->addModule( *mit );
  }

  mOptionsDialog->show();
  mOptionsDialog->raise();
}

void KODialogManager::showCategoryEditDialog()
{
  mCategoryEditDialog->show();
}

void KODialogManager::showSearchDialog()
{
  if (!mSearchDialog) {
    mSearchDialog = new SearchDialog(mMainView->calendar(),mMainView);
    connect(mSearchDialog,SIGNAL(showIncidenceSignal(Incidence *)),
            mMainView,SLOT(showIncidence(Incidence *)));
    connect(mSearchDialog,SIGNAL(editIncidenceSignal(Incidence *)),
            mMainView,SLOT(editIncidence(Incidence *)));
    connect(mSearchDialog,SIGNAL(deleteIncidenceSignal(Incidence *)),
            mMainView, SLOT(deleteIncidence(Incidence *)));
    connect(mMainView,SIGNAL(closingDown()),mSearchDialog,SLOT(reject()));
  }
  // make sure the widget is on top again
  mSearchDialog->show();
  mSearchDialog->raise();
}

void KODialogManager::showArchiveDialog()
{
#ifndef KORG_NOARCHIVE
  if (!mArchiveDialog) {
    mArchiveDialog = new ArchiveDialog(mMainView->calendar(),mMainView);
    connect(mArchiveDialog,SIGNAL(eventsDeleted()),
            mMainView,SLOT(updateView()));
    connect(mArchiveDialog,SIGNAL(autoArchivingSettingsModified()),
            mMainView,SLOT(slotAutoArchivingSettingsModified()));
  }
  mArchiveDialog->show();
  mArchiveDialog->raise();

  // Workaround.
  QApplication::restoreOverrideCursor();
#endif
}

void KODialogManager::showFilterEditDialog( QList<CalFilter*> *filters )
{
  if ( !mFilterEditDialog ) {
    mFilterEditDialog = new FilterEditDialog( filters, mMainView );
    connect( mFilterEditDialog, SIGNAL( filterChanged() ),
             mMainView, SLOT( updateFilter() ) );
    connect( mFilterEditDialog, SIGNAL( editCategories() ),
             mCategoryEditDialog, SLOT( show() ) );
    connect( mCategoryEditDialog, SIGNAL( categoryConfigChanged() ),
             mFilterEditDialog, SLOT( updateCategoryConfig() ) );
  }
  mFilterEditDialog->show();
  mFilterEditDialog->raise();
}

KOIncidenceEditor *KODialogManager::getEditor( Incidence *incidence )
{
  if ( !incidence ) return 0;
  EditorDialogVisitor v;
  if ( v.act( incidence, this ) ) {
    return v.editor();
  } else
    return 0;
}

KOEventEditor *KODialogManager::getEventEditor()
{
  KOEventEditor *eventEditor = new KOEventEditor( mMainView->calendar(),
                                                  mMainView );
  connectEditor( eventEditor );
  return eventEditor;
}

void KODialogManager::connectTypeAhead( KOEventEditor *editor,
                                        KOrg::AgendaView *agenda )
{
  if ( editor && agenda ) {
    agenda->setTypeAheadReceiver( editor->typeAheadReceiver() );
    connect( editor, SIGNAL( focusReceivedSignal() ),
             agenda, SLOT( finishTypeAhead() ) );
  }
}

void KODialogManager::connectEditor( KOIncidenceEditor*editor )
{
/*  connect( editor, SIGNAL( deleteIncidenceSignal( Incidence * ) ),
           mMainView, SLOT( deleteIncidence( Incidence * ) ) );*/

  connect( mCategoryEditDialog, SIGNAL( categoryConfigChanged() ),
           editor, SLOT( updateCategoryConfig() ) );
  connect( editor, SIGNAL( editCategories() ),
           mCategoryEditDialog, SLOT( show() ) );

  connect( editor, SIGNAL( dialogClose( Incidence * ) ),
           mMainView, SLOT( dialogClosing( Incidence * ) ) );
  connect( editor, SIGNAL( editCanceled( Incidence * ) ),
           mMainView, SLOT( editCanceled( Incidence * ) ) );
  connect( mMainView, SIGNAL( closingDown() ), editor, SLOT( reject() ) );

  connect( editor, SIGNAL( deleteAttendee( Incidence * ) ),
           mMainView, SIGNAL( cancelAttendees( Incidence * ) ) );
}

KOTodoEditor *KODialogManager::getTodoEditor()
{
  kDebug(5850) ;
  KOTodoEditor *todoEditor = new KOTodoEditor( mMainView->calendar(), mMainView );
  connectEditor( todoEditor );
  return todoEditor;
}

KOJournalEditor *KODialogManager::getJournalEditor()
{
  KOJournalEditor *journalEditor = new KOJournalEditor( mMainView->calendar(), mMainView );
  connectEditor( journalEditor );
  return journalEditor;
}

void KODialogManager::updateSearchDialog()
{
  if (mSearchDialog) mSearchDialog->updateView();
}

<|endoftext|>


<commit_before>#include "CssTokenizer.h"

CssTokenizer::CssTokenizer(istream* in){
  this->in = in;
  line = 1;
  column = 0;
  nextline = false;
  readChar();
}

CssTokenizer::~CssTokenizer(){
}

void CssTokenizer::readChar(){
  if (in != NULL) {
    // Last char was a newline. Increment the line counter.
    if (lastRead == '\n') {
      line++;
      column = 0;
    }

    in->get(lastRead);

    // check for end of file or escape key
    if(in->eof() || lastRead == 27) {
      in = NULL;
      lastRead = -1;
    } else if (in->fail() || in->bad())
      throw new IOException("Error reading input");

    if (lastRead != '\n') // count chars that aren't newlines
      column++;
  }
}

Token::Type CssTokenizer::readNextToken(){
  if (in == NULL) {
    currentToken.type = Token::EOS;
    return Token::EOS;
  }

  currentToken.clear();

  if (lastRead == '@') {
    currentToken.type = Token::ATKEYWORD;
    currentToken.add(lastRead);
    readChar();
    if (!readIdent()) {
      currentToken.type = Token::OTHER;
    }
  } else if (lastRead == '#') {
    currentToken.type = Token::HASH;
    currentToken.add(lastRead);
    readChar();
    if (!readName()) {
      throw new ParseException(&lastRead,
                               "name following '#'");
    }
  } else if (readString()) {
    currentToken.type = Token::STRING;
  } else if (lastRead == '-') {
    currentToken.add(lastRead);
    readChar();
    if (readNum()) {
      currentToken.type = Token::NUMBER;
      if (lastRead == '%') {
        currentToken.type = Token::PERCENTAGE;
        currentToken.add(lastRead);
        readChar();
      } else if (readIdent())
        currentToken.type = Token::DIMENSION;
    } else if (readIdent()) {
      currentToken.type = Token::IDENTIFIER;
      if (lastRead == '(') {
        currentToken.add(lastRead);
        readChar();
        currentToken.type = Token::FUNCTION;
      }
    } else
      currentToken.type = Token::OTHER;
  } else if (readNum()) {
    currentToken.type = Token::NUMBER;
    if (lastRead == '%') {
      currentToken.type = Token::PERCENTAGE;
      currentToken.add(lastRead);
      readChar();
    } else if (readIdent())
      currentToken.type = Token::DIMENSION;

  } else if (readIdent()) {
    currentToken.type = Token::IDENTIFIER;

    if (currentToken.str == "url" && readUrl())
      currentToken.type = Token::URL;
    else if (currentToken.str == "u" && lastRead == '+') {
      currentToken.add(lastRead);
      readChar();
      currentToken.type = Token::UNICODE_RANGE;
      readUnicodeRange();
    } else if (lastRead == '(') {
      currentToken.add(lastRead);
      readChar();
      currentToken.type = Token::FUNCTION;
    }
  } else if (readWhitespace()) {
    currentToken.type = Token::WHITESPACE;
    while (readWhitespace()) {};
  } else if (lastRead == '~') {
    currentToken.add(lastRead);
    readChar();
    if (lastRead == '=') {
      currentToken.add(lastRead);
      readChar();
      currentToken.type = Token::INCLUDES;
    } else
      currentToken.type = Token::OTHER;
  } else if (lastRead == '|') {
    currentToken.add(lastRead);
    readChar();
    if (lastRead == '=') {
      currentToken.add(lastRead);
      readChar();
      currentToken.type = Token::DASHMATCH;
    } else
      currentToken.type = Token::OTHER;
  } else if (lastRead == '/') {
    currentToken.add(lastRead);
    readChar();
    if (readComment())
      currentToken.type = Token::COMMENT;
    else
      currentToken.type = Token::OTHER;
  } else {
    switch (lastRead) {
    case ';':
      currentToken.type = Token::DELIMITER;
      break;
    case ':':
      currentToken.type = Token::COLON;
      break;
    case '{':
      currentToken.type = Token::BRACKET_OPEN;
      break;
    case '}':
      currentToken.type = Token::BRACKET_CLOSED;
      break;
    case '(':
      currentToken.type = Token::PAREN_OPEN;
      break;
    case ')':
      currentToken.type = Token::PAREN_CLOSED;
      break;
    case '[':
      currentToken.type = Token::BRACE_OPEN;
      break;
    case ']':
      currentToken.type = Token::BRACE_CLOSED;
      break;
    }
    currentToken.add(lastRead);
    readChar();
  }
  return currentToken.type;
}

bool CssTokenizer::readIdent () {
  if (lastRead == '-') {
    currentToken.add(lastRead);
    readChar();
  }
  if (!readNMStart())
    return false;
  else
    while (readNMChar()) {}
  return true;
}

bool CssTokenizer::readName () {
  if (!readNMChar())
    return false;
  while (readNMChar()) {}
  return true;
}

bool CssTokenizer::readNMStart () {
  if (lastRead == '_' ||
      (lastRead >= 'a' && lastRead <= 'z') ||
      (lastRead >= 'A' && lastRead <= 'Z')) {
    currentToken.add(lastRead);
    readChar();
    return true;
  } else
    return (readNonAscii() || readEscape());
}
bool CssTokenizer::readNonAscii () {
  if (lastRead > 237) {
    currentToken.add(lastRead);
    readChar();
    return true;
  } else
    return false;
}
bool CssTokenizer::readEscape () {
  if (lastRead != '\\')
    return false;
  currentToken.add(lastRead);
  readChar();

  if (readUnicode())
    return true;
  else if (lastRead != '\n' ||
           lastRead != '\r' ||
           lastRead != '\f') {
    currentToken.add(lastRead);
    readChar();
    return true;
  } else
    return false;
}
bool CssTokenizer::readUnicode () {
  if (!isHex(lastRead))
    return false;

  // [0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?
  for (int i=0; i < 6; i++) {
    if (readWhitespace())
      break;
    currentToken.add(lastRead);
    readChar();
    if (!isHex(lastRead)) {
      /*throw new ParseException(&lastRead,
        "hex code(0-9a-f) in unicode character");*/
      /* Just ignore and assume the unicode stops here  */
      break;
    }
  }
  return true;
}

bool CssTokenizer::readNMChar () {
  if (lastRead == '_' ||
      (lastRead >= 'a' && lastRead <= 'z') ||
      (lastRead >= 'A' && lastRead <= 'Z') ||
      isdigit(lastRead) ||
      lastRead == '-') {
    currentToken.add(lastRead);
    readChar();
    return true;
  } else
    return (readNonAscii() || readEscape());
}

bool CssTokenizer::readNum () {
  if (!isdigit(lastRead) && lastRead != '.')
    return false;
  while (isdigit(lastRead)) {
    currentToken.add(lastRead);
    readChar();
  }
  if (lastRead == '.') {
    currentToken.add(lastRead);
    readChar();

    while (isdigit(lastRead)) {
      currentToken.add(lastRead);
      readChar();
    }
  }
  return true;
}

bool CssTokenizer::readString() {
  if (lastRead != '"' && lastRead != '\'')
    return false;
  char delim = lastRead;

  currentToken.add(lastRead);
  readChar();
  while (lastRead != -1) {
    if (lastRead == delim) {
      currentToken.add(lastRead);
      readChar();
      return true;
    } else if (lastRead == '\n' ||
        lastRead == '\r' ||
        lastRead == '\f') {
      throw new ParseException("end of line",
                               "end of string");
    } else if (lastRead == '\\')
      readEscape() || readNewline();
    else {
      currentToken.add(lastRead);
      readChar();
    }
  }
  throw new ParseException(&lastRead,
                           "end of string");
  return true;
}

bool CssTokenizer::readNewline () {
  if (lastRead == '\r') {
    currentToken.add(lastRead);
    readChar();
    if (lastRead == '\n') {
      currentToken.add(lastRead);
      readChar();
    }
    return true;
  } else if (lastRead == '\n' ||
             lastRead == '\f') {
    currentToken.add(lastRead);
    readChar();
    return true;
  } else
    return false;
}

bool CssTokenizer::readWhitespace () {
  if (lastRead != ' ' &&
      lastRead != '\t' &&
      lastRead != '\r' &&
      lastRead != '\n' &&
      lastRead != '\f')
    return false;

  currentToken.add(lastRead);
  readChar();
  return true;
}

bool CssTokenizer::readUrl() {
  string urlchars = "!#$%&*-[]-~";

  if (lastRead != '(')
    return false;
  currentToken.add(lastRead);
  readChar();
  while(readWhitespace()) {};

  if (readString()) {
    if (lastRead == ')') {
      currentToken.add(lastRead);
      readChar();
      return true;
    } else {
      throw new ParseException(&lastRead,
                               "end of url (')')");
    }
  }

  while (lastRead != -1) {
    if (readWhitespace() || lastRead == ')') {
      while (readWhitespace()) {};
      if (lastRead == ')') {
        currentToken.add(lastRead);
        readChar();
        return true;
      } else {
        throw new ParseException(&lastRead,
                                 "end of url (')')");
      }
    } else if (urlchars.find(lastRead)) {
      currentToken.add(lastRead);
      readChar();
    } else if (!readNonAscii() &&
               !readEscape()) {
      throw new ParseException(&lastRead,
                               "end of url (')')");
    }
  }
  throw new ParseException(&lastRead,
                           "end of url (')')");
  return true;
}

bool CssTokenizer::isHex(char c) {
  return isdigit(c) ||
    (c >= 'a' && c <= 'f') ||
    (c >= 'A' && c <= 'F');
}

bool CssTokenizer::readComment () {
  if (lastRead != '*')
    return false;
  currentToken.add(lastRead);
  readChar();
  while (in != NULL) {
    if (lastRead == '*') {
      currentToken.add(lastRead);
      readChar();

      if (lastRead == '/') {
        currentToken.add(lastRead);
        readChar();
        return true;
      }
    }
    currentToken.add(lastRead);
    readChar();
  }
  throw new ParseException(&lastRead,
                           "end of comment (*/)");
  return true;
}

bool CssTokenizer::readUnicodeRange () {
  for (int i=0; i < 6; i++) {
    if (isHex(lastRead))
      break;
    currentToken.add(lastRead);
    readChar();
  }
  if (lastRead != '-')
    return true;

  for (int i=0; i < 6; i++) {
    if (isHex(lastRead))
      break;
    currentToken.add(lastRead);
    readChar();
  }
  return true;
}

Token* CssTokenizer::getToken(){
  return &currentToken;
}
Token::Type CssTokenizer::getTokenType() {
  return currentToken.type;
}

unsigned int CssTokenizer::getLineNumber(){
  return line;
}
unsigned int CssTokenizer::getColumn(){
  return column;
}
<commit_msg>Bugfix: reference to a removed attribute.<commit_after>#include "CssTokenizer.h"

CssTokenizer::CssTokenizer(istream* in){
  this->in = in;
  line = 1;
  column = 0;
  readChar();
}

CssTokenizer::~CssTokenizer(){
}

void CssTokenizer::readChar(){
  if (in != NULL) {
    // Last char was a newline. Increment the line counter.
    if (lastRead == '\n') {
      line++;
      column = 0;
    }

    in->get(lastRead);

    // check for end of file or escape key
    if(in->eof() || lastRead == 27) {
      in = NULL;
      lastRead = -1;
    } else if (in->fail() || in->bad())
      throw new IOException("Error reading input");

    if (lastRead != '\n') // count chars that aren't newlines
      column++;
  }
}

Token::Type CssTokenizer::readNextToken(){
  if (in == NULL) {
    currentToken.type = Token::EOS;
    return Token::EOS;
  }

  currentToken.clear();

  if (lastRead == '@') {
    currentToken.type = Token::ATKEYWORD;
    currentToken.add(lastRead);
    readChar();
    if (!readIdent()) {
      currentToken.type = Token::OTHER;
    }
  } else if (lastRead == '#') {
    currentToken.type = Token::HASH;
    currentToken.add(lastRead);
    readChar();
    if (!readName()) {
      throw new ParseException(&lastRead,
                               "name following '#'");
    }
  } else if (readString()) {
    currentToken.type = Token::STRING;
  } else if (lastRead == '-') {
    currentToken.add(lastRead);
    readChar();
    if (readNum()) {
      currentToken.type = Token::NUMBER;
      if (lastRead == '%') {
        currentToken.type = Token::PERCENTAGE;
        currentToken.add(lastRead);
        readChar();
      } else if (readIdent())
        currentToken.type = Token::DIMENSION;
    } else if (readIdent()) {
      currentToken.type = Token::IDENTIFIER;
      if (lastRead == '(') {
        currentToken.add(lastRead);
        readChar();
        currentToken.type = Token::FUNCTION;
      }
    } else
      currentToken.type = Token::OTHER;
  } else if (readNum()) {
    currentToken.type = Token::NUMBER;
    if (lastRead == '%') {
      currentToken.type = Token::PERCENTAGE;
      currentToken.add(lastRead);
      readChar();
    } else if (readIdent())
      currentToken.type = Token::DIMENSION;

  } else if (readIdent()) {
    currentToken.type = Token::IDENTIFIER;

    if (currentToken.str == "url" && readUrl())
      currentToken.type = Token::URL;
    else if (currentToken.str == "u" && lastRead == '+') {
      currentToken.add(lastRead);
      readChar();
      currentToken.type = Token::UNICODE_RANGE;
      readUnicodeRange();
    } else if (lastRead == '(') {
      currentToken.add(lastRead);
      readChar();
      currentToken.type = Token::FUNCTION;
    }
  } else if (readWhitespace()) {
    currentToken.type = Token::WHITESPACE;
    while (readWhitespace()) {};
  } else if (lastRead == '~') {
    currentToken.add(lastRead);
    readChar();
    if (lastRead == '=') {
      currentToken.add(lastRead);
      readChar();
      currentToken.type = Token::INCLUDES;
    } else
      currentToken.type = Token::OTHER;
  } else if (lastRead == '|') {
    currentToken.add(lastRead);
    readChar();
    if (lastRead == '=') {
      currentToken.add(lastRead);
      readChar();
      currentToken.type = Token::DASHMATCH;
    } else
      currentToken.type = Token::OTHER;
  } else if (lastRead == '/') {
    currentToken.add(lastRead);
    readChar();
    if (readComment())
      currentToken.type = Token::COMMENT;
    else
      currentToken.type = Token::OTHER;
  } else {
    switch (lastRead) {
    case ';':
      currentToken.type = Token::DELIMITER;
      break;
    case ':':
      currentToken.type = Token::COLON;
      break;
    case '{':
      currentToken.type = Token::BRACKET_OPEN;
      break;
    case '}':
      currentToken.type = Token::BRACKET_CLOSED;
      break;
    case '(':
      currentToken.type = Token::PAREN_OPEN;
      break;
    case ')':
      currentToken.type = Token::PAREN_CLOSED;
      break;
    case '[':
      currentToken.type = Token::BRACE_OPEN;
      break;
    case ']':
      currentToken.type = Token::BRACE_CLOSED;
      break;
    }
    currentToken.add(lastRead);
    readChar();
  }
  return currentToken.type;
}

bool CssTokenizer::readIdent () {
  if (lastRead == '-') {
    currentToken.add(lastRead);
    readChar();
  }
  if (!readNMStart())
    return false;
  else
    while (readNMChar()) {}
  return true;
}

bool CssTokenizer::readName () {
  if (!readNMChar())
    return false;
  while (readNMChar()) {}
  return true;
}

bool CssTokenizer::readNMStart () {
  if (lastRead == '_' ||
      (lastRead >= 'a' && lastRead <= 'z') ||
      (lastRead >= 'A' && lastRead <= 'Z')) {
    currentToken.add(lastRead);
    readChar();
    return true;
  } else
    return (readNonAscii() || readEscape());
}
bool CssTokenizer::readNonAscii () {
  if (lastRead > 237) {
    currentToken.add(lastRead);
    readChar();
    return true;
  } else
    return false;
}
bool CssTokenizer::readEscape () {
  if (lastRead != '\\')
    return false;
  currentToken.add(lastRead);
  readChar();

  if (readUnicode())
    return true;
  else if (lastRead != '\n' ||
           lastRead != '\r' ||
           lastRead != '\f') {
    currentToken.add(lastRead);
    readChar();
    return true;
  } else
    return false;
}
bool CssTokenizer::readUnicode () {
  if (!isHex(lastRead))
    return false;

  // [0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?
  for (int i=0; i < 6; i++) {
    if (readWhitespace())
      break;
    currentToken.add(lastRead);
    readChar();
    if (!isHex(lastRead)) {
      /*throw new ParseException(&lastRead,
        "hex code(0-9a-f) in unicode character");*/
      /* Just ignore and assume the unicode stops here  */
      break;
    }
  }
  return true;
}

bool CssTokenizer::readNMChar () {
  if (lastRead == '_' ||
      (lastRead >= 'a' && lastRead <= 'z') ||
      (lastRead >= 'A' && lastRead <= 'Z') ||
      isdigit(lastRead) ||
      lastRead == '-') {
    currentToken.add(lastRead);
    readChar();
    return true;
  } else
    return (readNonAscii() || readEscape());
}

bool CssTokenizer::readNum () {
  if (!isdigit(lastRead) && lastRead != '.')
    return false;
  while (isdigit(lastRead)) {
    currentToken.add(lastRead);
    readChar();
  }
  if (lastRead == '.') {
    currentToken.add(lastRead);
    readChar();

    while (isdigit(lastRead)) {
      currentToken.add(lastRead);
      readChar();
    }
  }
  return true;
}

bool CssTokenizer::readString() {
  if (lastRead != '"' && lastRead != '\'')
    return false;
  char delim = lastRead;

  currentToken.add(lastRead);
  readChar();
  while (lastRead != -1) {
    if (lastRead == delim) {
      currentToken.add(lastRead);
      readChar();
      return true;
    } else if (lastRead == '\n' ||
        lastRead == '\r' ||
        lastRead == '\f') {
      throw new ParseException("end of line",
                               "end of string");
    } else if (lastRead == '\\')
      readEscape() || readNewline();
    else {
      currentToken.add(lastRead);
      readChar();
    }
  }
  throw new ParseException(&lastRead,
                           "end of string");
  return true;
}

bool CssTokenizer::readNewline () {
  if (lastRead == '\r') {
    currentToken.add(lastRead);
    readChar();
    if (lastRead == '\n') {
      currentToken.add(lastRead);
      readChar();
    }
    return true;
  } else if (lastRead == '\n' ||
             lastRead == '\f') {
    currentToken.add(lastRead);
    readChar();
    return true;
  } else
    return false;
}

bool CssTokenizer::readWhitespace () {
  if (lastRead != ' ' &&
      lastRead != '\t' &&
      lastRead != '\r' &&
      lastRead != '\n' &&
      lastRead != '\f')
    return false;

  currentToken.add(lastRead);
  readChar();
  return true;
}

bool CssTokenizer::readUrl() {
  string urlchars = "!#$%&*-[]-~";

  if (lastRead != '(')
    return false;
  currentToken.add(lastRead);
  readChar();
  while(readWhitespace()) {};

  if (readString()) {
    if (lastRead == ')') {
      currentToken.add(lastRead);
      readChar();
      return true;
    } else {
      throw new ParseException(&lastRead,
                               "end of url (')')");
    }
  }

  while (lastRead != -1) {
    if (readWhitespace() || lastRead == ')') {
      while (readWhitespace()) {};
      if (lastRead == ')') {
        currentToken.add(lastRead);
        readChar();
        return true;
      } else {
        throw new ParseException(&lastRead,
                                 "end of url (')')");
      }
    } else if (urlchars.find(lastRead)) {
      currentToken.add(lastRead);
      readChar();
    } else if (!readNonAscii() &&
               !readEscape()) {
      throw new ParseException(&lastRead,
                               "end of url (')')");
    }
  }
  throw new ParseException(&lastRead,
                           "end of url (')')");
  return true;
}

bool CssTokenizer::isHex(char c) {
  return isdigit(c) ||
    (c >= 'a' && c <= 'f') ||
    (c >= 'A' && c <= 'F');
}

bool CssTokenizer::readComment () {
  if (lastRead != '*')
    return false;
  currentToken.add(lastRead);
  readChar();
  while (in != NULL) {
    if (lastRead == '*') {
      currentToken.add(lastRead);
      readChar();

      if (lastRead == '/') {
        currentToken.add(lastRead);
        readChar();
        return true;
      }
    }
    currentToken.add(lastRead);
    readChar();
  }
  throw new ParseException(&lastRead,
                           "end of comment (*/)");
  return true;
}

bool CssTokenizer::readUnicodeRange () {
  for (int i=0; i < 6; i++) {
    if (isHex(lastRead))
      break;
    currentToken.add(lastRead);
    readChar();
  }
  if (lastRead != '-')
    return true;

  for (int i=0; i < 6; i++) {
    if (isHex(lastRead))
      break;
    currentToken.add(lastRead);
    readChar();
  }
  return true;
}

Token* CssTokenizer::getToken(){
  return &currentToken;
}
Token::Type CssTokenizer::getTokenType() {
  return currentToken.type;
}

unsigned int CssTokenizer::getLineNumber(){
  return line;
}
unsigned int CssTokenizer::getColumn(){
  return column;
}
<|endoftext|>


<commit_before>#if !defined(ASCII_TREE_GRAMMAR_H)
#define ASCII_TREE_GRAMMAR_H

#include <cctype>
#include <string>
#include <vector>

namespace ascii_tree
{
    struct token
    {
        enum toktype { root_node, named_node, edge_name, horizontal_edge, ascending_edge_part, descending_edge_part, vertical_edge_part };
        toktype type;
        std::string name;
    };

    inline bool operator==(const token& lhs, const token& rhs)
    {
        return lhs.type == rhs.type
            && lhs.name == rhs.name;
    }

    inline std::vector<token> tokenize(const std::string& s)
    {
        std::vector<token> tokens;
        enum {
            none, open_square_brace, close_square_brace, asterisk, dash,
            open_paren, close_paren, name_char, slash, backslash, pipe
        } prev_ch = none, prev_prev_ch = none;
        size_t marker = 0, marked_length = 0;

        for (size_t i = 0; i < s.size(); ++i)
        {
            auto ch = s[i];

            if (ch == '[')
            {
                prev_ch = open_square_brace;
            }
            else if (ch == ']')
            {
                if (prev_ch == asterisk)
                {
                    tokens.emplace_back(token { token::root_node, "" });
                }
                else
                {
                    tokens.emplace_back(token { token::named_node, s.substr(marker, marked_length) });
                }

                prev_ch = close_square_brace;
            }
            else if (ch == '*')
            {
                prev_ch = asterisk;
            }
            else if (ch == '-')
            {
                if (prev_ch == name_char)
                {
                    tokens.emplace_back(token { token::horizontal_edge, s.substr(marker, marked_length) });
                }

                prev_ch = dash;
            }
            else if (ch == '/')
            {
                tokens.emplace_back(token { token::ascending_edge_part, "" });
                prev_ch = slash;
            }
            else if (ch == '\\')
            {
                tokens.emplace_back(token { token::descending_edge_part, "" });
                prev_ch = backslash;
            }
            else if (ch == '|')
            {
                tokens.emplace_back(token { token::vertical_edge_part, "" });
                prev_ch = pipe;
            }
            else if (ch == '(')
            {
                if (prev_ch == dash) { prev_prev_ch = dash; }
                prev_ch = open_paren;
            }
            else if (ch == ')')
            {
                if (prev_prev_ch == dash)
                {
                    tokens.emplace_back(token { token::horizontal_edge, s.substr(marker, marked_length) });
                }
                else
                {
                    tokens.emplace_back(token { token::edge_name, s.substr(marker, marked_length) });
                }

                prev_ch = close_paren;
            }
            else if (isalnum(ch) || ch == '_')
            {
                if (prev_ch != name_char)
                {
                    marker = i;
                    marked_length = 0;
                }

                prev_ch = name_char;
                ++marked_length;
            }
        }

        return tokens;
    }
}

#endif // ASCII_TREE_GRAMMAR_H
<commit_msg>add ABNF grammar definition to header<commit_after>#if !defined(ASCII_TREE_GRAMMAR_H)
#define ASCII_TREE_GRAMMAR_H

#include <cctype>
#include <string>
#include <vector>

#if 0

GRAMMAR
========

tokens:           token
                  tokens token

token:            node
                  horizontal-edge
                  edge-part

node:             root-node
                  named-node

root-node:        '[' '*' ']'

named-node:       '[' node-name ']'

node-name:        name-chars

name-chars:       name-char
                  name-chars name-char

name-char:        alnum
                  '_'

alnum:            one of: [A-Za-z0-9]

horizontal-edge:  edge-chars edge-name edge-chars

edge-chars:       '-'
                  edge-chars '-'

edge-name:        '(' name-chars ')'

edge-part:        '\'
                  '|'
                  '/'
                  edge-name

#endif

namespace ascii_tree
{
    struct token
    {
        enum toktype { root_node, named_node, edge_name, horizontal_edge, ascending_edge_part, descending_edge_part, vertical_edge_part };
        toktype type;
        std::string name;
    };

    inline bool operator==(const token& lhs, const token& rhs)
    {
        return lhs.type == rhs.type
            && lhs.name == rhs.name;
    }

    inline std::vector<token> tokenize(const std::string& s)
    {
        std::vector<token> tokens;
        enum {
            none, open_square_brace, close_square_brace, asterisk, dash,
            open_paren, close_paren, name_char, slash, backslash, pipe
        } prev_ch = none, prev_prev_ch = none;
        size_t marker = 0, marked_length = 0;

        for (size_t i = 0; i < s.size(); ++i)
        {
            auto ch = s[i];

            if (ch == '[')
            {
                prev_ch = open_square_brace;
            }
            else if (ch == ']')
            {
                if (prev_ch == asterisk)
                {
                    tokens.emplace_back(token { token::root_node, "" });
                }
                else
                {
                    tokens.emplace_back(token { token::named_node, s.substr(marker, marked_length) });
                }

                prev_ch = close_square_brace;
            }
            else if (ch == '*')
            {
                prev_ch = asterisk;
            }
            else if (ch == '-')
            {
                if (prev_ch == name_char)
                {
                    tokens.emplace_back(token { token::horizontal_edge, s.substr(marker, marked_length) });
                }

                prev_ch = dash;
            }
            else if (ch == '/')
            {
                tokens.emplace_back(token { token::ascending_edge_part, "" });
                prev_ch = slash;
            }
            else if (ch == '\\')
            {
                tokens.emplace_back(token { token::descending_edge_part, "" });
                prev_ch = backslash;
            }
            else if (ch == '|')
            {
                tokens.emplace_back(token { token::vertical_edge_part, "" });
                prev_ch = pipe;
            }
            else if (ch == '(')
            {
                if (prev_ch == dash) { prev_prev_ch = dash; }
                prev_ch = open_paren;
            }
            else if (ch == ')')
            {
                if (prev_prev_ch == dash)
                {
                    tokens.emplace_back(token { token::horizontal_edge, s.substr(marker, marked_length) });
                }
                else
                {
                    tokens.emplace_back(token { token::edge_name, s.substr(marker, marked_length) });
                }

                prev_ch = close_paren;
            }
            else if (isalnum(ch) || ch == '_')
            {
                if (prev_ch != name_char)
                {
                    marker = i;
                    marked_length = 0;
                }

                prev_ch = name_char;
                ++marked_length;
            }
        }

        return tokens;
    }
}

#endif // ASCII_TREE_GRAMMAR_H
<|endoftext|>


<commit_before>#include <iostream>
#include <cassert>
#include <stdexcept>
#include "DataAnalysis.h"

#include "TRoot.h"
#include "TFile.h"
#include "TDirectory.h"
#include "TKey.h"
#include "TClass.h"

#include "RunConfig.h"
#include "DataFileHierarchy.h"

using namespace Analysis;
using namespace std;

//_____________________________________________________________________________
TFile* DataFile::OpenRootFile(const std::string filename, const std::string option)
{
   // -- Simply open a Root file with the given name and option and return pointer to it.
   cout << "-------------------------------------------" << endl;
   cout << "Loading Data File: " << filename << endl;
   TFile *file = NULL;
   file = TFile::Open(filename.c_str(), option.c_str());
   if (!file || file->IsZombie()) {
      cerr << "Error: Cannot open file - " << filename << endl;
      return NULL;
   }
   file->cd();
   cout << "-------------------------------------------" << endl;
   cout << "Successfully Loaded Data File: " << filename << endl;
   cout << "-------------------------------------------" << endl;
   return file;
}

//_____________________________________________________________________________
const RunConfig& DataFile::LoadRunConfig(TFile& file)
{
   // -- Attempt to navigate to the config file folder in supplied file and extract the runconfig
   // -- Throw an exception if this cannot be done.
   cout << "Attempting to load the RunConfig" << endl;
   // Navigate to Config Folder
   if (file.cd(Folders::config.c_str()) == false) {
      cerr << "No Folder named: " << Folders::config << " in data file" << endl;
      throw runtime_error("Cannot find config folder");
   }
   TDirectory* const configDir = gDirectory;
   // -- Loop over all objects in folder and extract latest RunConfig
   RunConfig* ptr_config = NULL;
   TKey *configKey;
   TIter configIter(configDir->GetListOfKeys());
   while ((configKey = dynamic_cast<TKey*>(configIter.Next()))) {
      const char *classname = configKey->GetClassName();
      TClass *cl = gROOT->GetClass(classname);
      if (!cl) continue;
      if (cl->InheritsFrom("RunConfig")) {
         ptr_config = dynamic_cast<RunConfig*>(configKey->ReadObj());
         break;
      }
   }
   cout << "-------------------------------------------" << endl;
   cout << "Successfully Loaded RunConfig" << endl;
   cout << "-------------------------------------------" << endl;
   return *ptr_config;
}

//_____________________________________________________________________________
bool DataFile::ValidateRootFile(const string filename)
{
   // -- Check that the filename supplied has a .root extension
   size_t found = filename.find_last_of(".");
   if (found == string::npos) return false;
   if (filename.substr(found) == ".root") return true;
   return false;
}
//_____________________________________________________________________________
bool DataFile::ValidateStateNames(const vector<string>& statenames)
{
   // -- Check that each statename in list is a valid state as defined
   // -- in DataFileHierarchy lvl 3 and is unique
   vector<string>::const_iterator iter;
   for (iter = statenames.begin(); iter != statenames.end(); iter++) {
      // Check state-name
      if (*iter != Folders::initial &&
          *iter != Folders::propagating &&
          *iter != Folders::absorbed &&
          *iter != Folders::lost &&
          *iter != Folders::decayed &&
          *iter != Folders::detected &&
          *iter != Folders::anomalous) {
         cerr << "Argument, " << *iter << " is not a valid statename" << endl;
         return false;
      }
      // Check for duplicates
      vector<string>::const_iterator second_iter;
      for (second_iter = iter+1; second_iter != statenames.end(); second_iter++) {
         if (*second_iter == *iter) {
            cerr << "Duplicate statenames given: " << *iter << endl;
            return false;
         }
      }
   }
   return true;
}
//_____________________________________________________________________________
bool DataFile::ValidateStateNames(const string statename)
{
   // -- Check that each statename in list is a valid state as defined
   // -- in DataFileHierarchy lvl 3 and is unique
   // Check state-name
   if (statename != Folders::initial &&
         statename != Folders::propagating &&
         statename != Folders::absorbed &&
         statename != Folders::lost &&
         statename != Folders::decayed &&
         statename != Folders::detected &&
         statename != Folders::anomalous) {
      cerr << "Argument, " << statename << " is not a valid statename" << endl;
      return false;
   }
   return true;
}
//_____________________________________________________________________________
void DataFile::CountParticles(TDirectory * const particleDir)
{
   // -- Given the particle state directory, count the number of particles
   // -- in each state subfolder
   if (particleDir->cd(Folders::initial.c_str()) == false) return;
   Int_t initial = gDirectory->GetNkeys();
   if (particleDir->cd(Folders::propagating.c_str()) == false) return;
   Int_t propagating = gDirectory->GetNkeys();
   if (particleDir->cd(Folders::absorbed.c_str()) == false) return;
   Int_t absorbed = gDirectory->GetNkeys();
   if (particleDir->cd(Folders::detected.c_str()) == false) return;
   Int_t detected = gDirectory->GetNkeys();
   if (particleDir->cd(Folders::decayed.c_str()) == false) return;
   Int_t decayed = gDirectory->GetNkeys();
   if (particleDir->cd(Folders::lost.c_str()) == false) return;
   Int_t lost = gDirectory->GetNkeys();
   if (particleDir->cd(Folders::anomalous.c_str()) == false) return;
   Int_t anomalous = gDirectory->GetNkeys();
   cout << "Initial Particles: " << initial << endl;
   cout << "Final Total: ";
   cout << propagating+detected+absorbed+decayed+lost+anomalous << endl;
   cout << "Propagating: " << propagating << endl;
   cout << "Detected: " << detected << endl;
   cout << "Absorbed: " << absorbed << endl;
   cout << "Decayed: " << decayed << endl;
   cout << "Lost: " << lost << endl;
   cout << "Anomalous: " << anomalous << endl;
   return;
}

<commit_msg>Add a check for null pointer in LoadRunConfig<commit_after>#include <iostream>
#include <cassert>
#include <stdexcept>
#include "DataAnalysis.h"

#include "TRoot.h"
#include "TFile.h"
#include "TDirectory.h"
#include "TKey.h"
#include "TClass.h"

#include "RunConfig.h"
#include "DataFileHierarchy.h"

using namespace Analysis;
using namespace std;

//_____________________________________________________________________________
TFile* DataFile::OpenRootFile(const std::string filename, const std::string option)
{
   // -- Simply open a Root file with the given name and option and return pointer to it.
   cout << "-------------------------------------------" << endl;
   cout << "Loading Data File: " << filename << endl;
   TFile *file = NULL;
   file = TFile::Open(filename.c_str(), option.c_str());
   if (!file || file->IsZombie()) {
      cerr << "Error: Cannot open file - " << filename << endl;
      return NULL;
   }
   file->cd();
   cout << "-------------------------------------------" << endl;
   cout << "Successfully Loaded Data File: " << filename << endl;
   cout << "-------------------------------------------" << endl;
   return file;
}

//_____________________________________________________________________________
const RunConfig& DataFile::LoadRunConfig(TFile& file)
{
   // -- Attempt to navigate to the config file folder in supplied file and extract the runconfig
   // -- Throw an exception if this cannot be done.
   cout << "Attempting to load the RunConfig" << endl;
   // Navigate to Config Folder
   if (file.cd(Folders::config.c_str()) == false) {
      cerr << "No Folder named: " << Folders::config << " in data file" << endl;
      throw runtime_error("Cannot find config folder");
   }
   TDirectory* const configDir = gDirectory;
   // -- Loop over all objects in folder and extract latest RunConfig
   RunConfig* ptr_config = NULL;
   TKey *configKey;
   TIter configIter(configDir->GetListOfKeys());
   while ((configKey = dynamic_cast<TKey*>(configIter.Next()))) {
      // Check if current item is of class RunConfig
      const char *classname = configKey->GetClassName();
      TClass *cl = gROOT->GetClass(classname);
      if (!cl) continue;
      if (cl->InheritsFrom("RunConfig")) {
         // Read RunConfig into memory when found
         ptr_config = dynamic_cast<RunConfig*>(configKey->ReadObj());
         break;
      }
   }
   // Throw exception if we failed to find any RunConfig in this folder
   if (ptr_config == NULL) {
      throw runtime_error("Unable to load RunConfig from config folder");
   }
   cout << "-------------------------------------------" << endl;
   cout << "Successfully Loaded RunConfig" << endl;
   cout << "-------------------------------------------" << endl;
   return *ptr_config;
}

//_____________________________________________________________________________
bool DataFile::ValidateRootFile(const string filename)
{
   // -- Check that the filename supplied has a .root extension
   size_t found = filename.find_last_of(".");
   if (found == string::npos) return false;
   if (filename.substr(found) == ".root") return true;
   return false;
}
//_____________________________________________________________________________
bool DataFile::ValidateStateNames(const vector<string>& statenames)
{
   // -- Check that each statename in list is a valid state as defined
   // -- in DataFileHierarchy lvl 3 and is unique
   vector<string>::const_iterator iter;
   for (iter = statenames.begin(); iter != statenames.end(); iter++) {
      // Check state-name
      if (*iter != Folders::initial &&
          *iter != Folders::propagating &&
          *iter != Folders::absorbed &&
          *iter != Folders::lost &&
          *iter != Folders::decayed &&
          *iter != Folders::detected &&
          *iter != Folders::anomalous) {
         cerr << "Argument, " << *iter << " is not a valid statename" << endl;
         return false;
      }
      // Check for duplicates
      vector<string>::const_iterator second_iter;
      for (second_iter = iter+1; second_iter != statenames.end(); second_iter++) {
         if (*second_iter == *iter) {
            cerr << "Duplicate statenames given: " << *iter << endl;
            return false;
         }
      }
   }
   return true;
}
//_____________________________________________________________________________
bool DataFile::ValidateStateNames(const string statename)
{
   // -- Check that each statename in list is a valid state as defined
   // -- in DataFileHierarchy lvl 3 and is unique
   // Check state-name
   if (statename != Folders::initial &&
         statename != Folders::propagating &&
         statename != Folders::absorbed &&
         statename != Folders::lost &&
         statename != Folders::decayed &&
         statename != Folders::detected &&
         statename != Folders::anomalous) {
      cerr << "Argument, " << statename << " is not a valid statename" << endl;
      return false;
   }
   return true;
}
//_____________________________________________________________________________
void DataFile::CountParticles(TDirectory * const particleDir)
{
   // -- Given the particle state directory, count the number of particles
   // -- in each state subfolder
   if (particleDir->cd(Folders::initial.c_str()) == false) return;
   Int_t initial = gDirectory->GetNkeys();
   if (particleDir->cd(Folders::propagating.c_str()) == false) return;
   Int_t propagating = gDirectory->GetNkeys();
   if (particleDir->cd(Folders::absorbed.c_str()) == false) return;
   Int_t absorbed = gDirectory->GetNkeys();
   if (particleDir->cd(Folders::detected.c_str()) == false) return;
   Int_t detected = gDirectory->GetNkeys();
   if (particleDir->cd(Folders::decayed.c_str()) == false) return;
   Int_t decayed = gDirectory->GetNkeys();
   if (particleDir->cd(Folders::lost.c_str()) == false) return;
   Int_t lost = gDirectory->GetNkeys();
   if (particleDir->cd(Folders::anomalous.c_str()) == false) return;
   Int_t anomalous = gDirectory->GetNkeys();
   cout << "Initial Particles: " << initial << endl;
   cout << "Final Total: ";
   cout << propagating+detected+absorbed+decayed+lost+anomalous << endl;
   cout << "Propagating: " << propagating << endl;
   cout << "Detected: " << detected << endl;
   cout << "Absorbed: " << absorbed << endl;
   cout << "Decayed: " << decayed << endl;
   cout << "Lost: " << lost << endl;
   cout << "Anomalous: " << anomalous << endl;
   return;
}

<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkDistributedGraphHelper.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
/*
 * Copyright (C) 2008 The Trustees of Indiana University.
 * Use, modification and distribution is subject to the Boost Software
 * License, Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt)
 */
// .NAME vtkDistributedGraphHelper.cxx - distributed graph helper for vtkGraph
//
// .SECTION Description
// Attach a subclass of this helper to a vtkGraph to turn it into a distributed graph
#include "vtkDistributedGraphHelper.h"
#include "vtkGraph.h"
#include "vtkInformation.h"
#include "vtkInformationIntegerKey.h"
#include "vtkStdString.h"
#include "vtkVariant.h"

#include <limits.h> // CHAR_BIT
#include <assert.h> // assert()

vtkInformationKeyMacro(vtkDistributedGraphHelper, DISTRIBUTEDVERTEXIDS, Integer);
vtkInformationKeyMacro(vtkDistributedGraphHelper, DISTRIBUTEDEDGEIDS, Integer);

//----------------------------------------------------------------------------
// class vtkDistributedGraphHelper
//----------------------------------------------------------------------------

//----------------------------------------------------------------------------
void vtkDistributedGraphHelper::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
  int numProcs
    = this->Graph->GetInformation()->Get(vtkDataObject::DATA_NUMBER_OF_PIECES());
  int myRank
    = this->Graph->GetInformation()->Get(vtkDataObject::DATA_PIECE_NUMBER());
  os << indent << "Processor: " << myRank << " of " << numProcs << endl;
}

//----------------------------------------------------------------------------
vtkDistributedGraphHelper::vtkDistributedGraphHelper()
{
  this->Graph = 0;
  this->VertexDistribution = 0;
}

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

//----------------------------------------------------------------------------
vtkIdType vtkDistributedGraphHelper::GetVertexOwner(vtkIdType v) const
{
  vtkIdType owner = v;
  int numProcs
    = this->Graph->GetInformation()->Get(vtkDataObject::DATA_NUMBER_OF_PIECES());

  if (numProcs > 1)
    {
    // An alternative to this obfuscated code is to provide
    // an 'unsigned' equivalent to vtkIdType.  Could then safely
    // do a logical right-shift of bits, e.g.:
    //   owner = (vtkIdTypeUnsigned) v >> this->indexBits;
    if (v & this->signBitMask)
      {
      owner ^= this->signBitMask;               // remove sign bit
      vtkIdType tmp = owner >> this->indexBits; // so can right-shift
      owner = tmp | this->highBitShiftMask;     // and append sign bit back
      }
    else
      {
      owner = v >> this->indexBits;
      }
    }
  else  // numProcs = 1
    {
    owner = 0;
    }

  return owner;
}

//----------------------------------------------------------------------------
vtkIdType vtkDistributedGraphHelper::GetVertexIndex(vtkIdType v) const
{
  vtkIdType index = v;
  int numProcs
    = this->Graph->GetInformation()->Get(vtkDataObject::DATA_NUMBER_OF_PIECES());

  if (numProcs > 1)
    {
    // Shift off the Owner bits.  (Would a mask be faster?)
    index = (v << this->procBits) >> this->procBits;
    }

  return index;
}

//----------------------------------------------------------------------------
vtkIdType vtkDistributedGraphHelper::GetEdgeOwner(vtkIdType e_id) const
{
  vtkIdType owner = e_id;
  int numProcs =
    this->Graph->GetInformation()->Get(vtkDataObject::DATA_NUMBER_OF_PIECES());

  if (numProcs > 1)
    {
    if (e_id & this->signBitMask)
      {
      owner ^= this->signBitMask;               // remove sign bit
      vtkIdType tmp = owner >> this->indexBits; // so can right-shift
      owner = tmp | this->highBitShiftMask;     // and append sign bit back
      }
    else
      {
      owner = e_id >> this->indexBits;
      }
    }
  else  // numProcs = 1
    {
    owner = 0;
    }

  return owner;
}

//----------------------------------------------------------------------------
vtkIdType vtkDistributedGraphHelper::GetEdgeIndex(vtkIdType e_id) const
{
  vtkIdType index = e_id;
  int numProcs
    = this->Graph->GetInformation()->Get(vtkDataObject::DATA_NUMBER_OF_PIECES());

  if (numProcs > 1)
    {
    // Shift off the Owner bits.  (Would a mask be faster?)
    index = (e_id << this->procBits) >> this->procBits;
    }

  return index;
}

//----------------------------------------------------------------------------
vtkIdType vtkDistributedGraphHelper::MakeDistributedId(int owner, vtkIdType local)
{
  int numProcs
    = this->Graph->GetInformation()->Get(vtkDataObject::DATA_NUMBER_OF_PIECES());

  if (numProcs > 1)
    {
    assert(owner >= 0 && owner < numProcs);
    return (static_cast<vtkIdType>(owner) << this->indexBits) | local;
    }

  return local;
}

//----------------------------------------------------------------------------
void vtkDistributedGraphHelper::AttachToGraph(vtkGraph *graph)
{
  this->Graph = graph;

  // Some factors and masks to help speed up encoding/decoding {owner,index}
  int numProcs
    = this->Graph->GetInformation()->Get(vtkDataObject::DATA_NUMBER_OF_PIECES());
  int tmp = numProcs - 1;
  // The following is integer arith equiv of ceil(log2(numProcs)):
  int numProcBits = 0;
  while( tmp != 0 )
    {
    tmp >>= 1;
    numProcBits++;
    }
  if (numProcs == 1)  numProcBits = 1;

  this->signBitMask = static_cast<vtkIdType>(1) << ((sizeof(vtkIdType) * CHAR_BIT) - 1);
  this->highBitShiftMask = static_cast<vtkIdType>(1) << numProcBits;
  this->procBits = numProcBits + 1;
  this->indexBits = (sizeof(vtkIdType) * CHAR_BIT) - (numProcBits + 1);
}

//----------------------------------------------------------------------------
void
vtkDistributedGraphHelper::
SetVertexPedigreeIdDistribution(vtkVertexPedigreeIdDistribution Func,
                                void *userData)
{
  this->VertexDistribution = Func;
  this->VertexDistributionUserData = userData;
}

//----------------------------------------------------------------------------
vtkIdType
vtkDistributedGraphHelper::
GetVertexOwnerByPedigreeId(const vtkVariant& pedigreeId)
{
  vtkIdType numProcs
    = this->Graph->GetInformation()->Get(vtkDataObject::DATA_NUMBER_OF_PIECES());
  if (this->VertexDistribution)
    {
    return (this->VertexDistribution(pedigreeId,
                                     this->VertexDistributionUserData)
            % numProcs);
    }

  // Hash the variant in a very lame way.
  double numericValue;
  vtkStdString stringValue;
  const unsigned char *charsStart, *charsEnd;
  if (pedigreeId.IsNumeric())
    {
    // Convert every numeric value into a double.
    numericValue = pedigreeId.ToDouble();

    // Hash the characters in the double.
    charsStart = reinterpret_cast<const unsigned char*>(&numericValue);
    charsEnd = charsStart + sizeof(double);
    }
  else if (pedigreeId.GetType() == VTK_STRING)
    {
    stringValue = pedigreeId.ToString();
    charsStart = reinterpret_cast<const unsigned char*>(stringValue.c_str());
    charsEnd = charsStart + stringValue.size();
    }
  else
    {
    vtkErrorMacro("Cannot hash vertex pedigree ID of type "
                  << pedigreeId.GetType());
    return 0;
    }

  unsigned long hash = 5381;
  for (; charsStart != charsEnd; ++charsStart)
    {
    hash = ((hash << 5) + hash) ^ *charsStart;
    }

  return hash % numProcs;
}
<commit_msg>Fixed -Wshift-sign-overflow warning<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkDistributedGraphHelper.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
/*
 * Copyright (C) 2008 The Trustees of Indiana University.
 * Use, modification and distribution is subject to the Boost Software
 * License, Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt)
 */
// .NAME vtkDistributedGraphHelper.cxx - distributed graph helper for vtkGraph
//
// .SECTION Description
// Attach a subclass of this helper to a vtkGraph to turn it into a distributed graph
#include "vtkDistributedGraphHelper.h"
#include "vtkGraph.h"
#include "vtkInformation.h"
#include "vtkInformationIntegerKey.h"
#include "vtkStdString.h"
#include "vtkVariant.h"

#include <limits.h> // CHAR_BIT
#include <assert.h> // assert()

vtkInformationKeyMacro(vtkDistributedGraphHelper, DISTRIBUTEDVERTEXIDS, Integer);
vtkInformationKeyMacro(vtkDistributedGraphHelper, DISTRIBUTEDEDGEIDS, Integer);

//----------------------------------------------------------------------------
// class vtkDistributedGraphHelper
//----------------------------------------------------------------------------

//----------------------------------------------------------------------------
void vtkDistributedGraphHelper::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
  int numProcs
    = this->Graph->GetInformation()->Get(vtkDataObject::DATA_NUMBER_OF_PIECES());
  int myRank
    = this->Graph->GetInformation()->Get(vtkDataObject::DATA_PIECE_NUMBER());
  os << indent << "Processor: " << myRank << " of " << numProcs << endl;
}

//----------------------------------------------------------------------------
vtkDistributedGraphHelper::vtkDistributedGraphHelper()
{
  this->Graph = 0;
  this->VertexDistribution = 0;
}

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

//----------------------------------------------------------------------------
vtkIdType vtkDistributedGraphHelper::GetVertexOwner(vtkIdType v) const
{
  vtkIdType owner = v;
  int numProcs
    = this->Graph->GetInformation()->Get(vtkDataObject::DATA_NUMBER_OF_PIECES());

  if (numProcs > 1)
    {
    // An alternative to this obfuscated code is to provide
    // an 'unsigned' equivalent to vtkIdType.  Could then safely
    // do a logical right-shift of bits, e.g.:
    //   owner = (vtkIdTypeUnsigned) v >> this->indexBits;
    if (v & this->signBitMask)
      {
      owner ^= this->signBitMask;               // remove sign bit
      vtkIdType tmp = owner >> this->indexBits; // so can right-shift
      owner = tmp | this->highBitShiftMask;     // and append sign bit back
      }
    else
      {
      owner = v >> this->indexBits;
      }
    }
  else  // numProcs = 1
    {
    owner = 0;
    }

  return owner;
}

//----------------------------------------------------------------------------
vtkIdType vtkDistributedGraphHelper::GetVertexIndex(vtkIdType v) const
{
  vtkIdType index = v;
  int numProcs
    = this->Graph->GetInformation()->Get(vtkDataObject::DATA_NUMBER_OF_PIECES());

  if (numProcs > 1)
    {
    // Shift off the Owner bits.  (Would a mask be faster?)
    index = (v << this->procBits) >> this->procBits;
    }

  return index;
}

//----------------------------------------------------------------------------
vtkIdType vtkDistributedGraphHelper::GetEdgeOwner(vtkIdType e_id) const
{
  vtkIdType owner = e_id;
  int numProcs =
    this->Graph->GetInformation()->Get(vtkDataObject::DATA_NUMBER_OF_PIECES());

  if (numProcs > 1)
    {
    if (e_id & this->signBitMask)
      {
      owner ^= this->signBitMask;               // remove sign bit
      vtkIdType tmp = owner >> this->indexBits; // so can right-shift
      owner = tmp | this->highBitShiftMask;     // and append sign bit back
      }
    else
      {
      owner = e_id >> this->indexBits;
      }
    }
  else  // numProcs = 1
    {
    owner = 0;
    }

  return owner;
}

//----------------------------------------------------------------------------
vtkIdType vtkDistributedGraphHelper::GetEdgeIndex(vtkIdType e_id) const
{
  vtkIdType index = e_id;
  int numProcs
    = this->Graph->GetInformation()->Get(vtkDataObject::DATA_NUMBER_OF_PIECES());

  if (numProcs > 1)
    {
    // Shift off the Owner bits.  (Would a mask be faster?)
    index = (e_id << this->procBits) >> this->procBits;
    }

  return index;
}

//----------------------------------------------------------------------------
vtkIdType vtkDistributedGraphHelper::MakeDistributedId(int owner, vtkIdType local)
{
  int numProcs
    = this->Graph->GetInformation()->Get(vtkDataObject::DATA_NUMBER_OF_PIECES());

  if (numProcs > 1)
    {
    assert(owner >= 0 && owner < numProcs);
    return (static_cast<vtkIdType>(owner) << this->indexBits) | local;
    }

  return local;
}

//----------------------------------------------------------------------------
void vtkDistributedGraphHelper::AttachToGraph(vtkGraph *graph)
{
  this->Graph = graph;

  // Some factors and masks to help speed up encoding/decoding {owner,index}
  int numProcs
    = this->Graph->GetInformation()->Get(vtkDataObject::DATA_NUMBER_OF_PIECES());
  int tmp = numProcs - 1;
  // The following is integer arith equiv of ceil(log2(numProcs)):
  int numProcBits = 0;
  while( tmp != 0 )
    {
    tmp >>= 1;
    numProcBits++;
    }
  if (numProcs == 1)  numProcBits = 1;

  this->signBitMask = VTK_ID_MIN;
  this->highBitShiftMask = static_cast<vtkIdType>(1) << numProcBits;
  this->procBits = numProcBits + 1;
  this->indexBits = (sizeof(vtkIdType) * CHAR_BIT) - (numProcBits + 1);
}

//----------------------------------------------------------------------------
void
vtkDistributedGraphHelper::
SetVertexPedigreeIdDistribution(vtkVertexPedigreeIdDistribution Func,
                                void *userData)
{
  this->VertexDistribution = Func;
  this->VertexDistributionUserData = userData;
}

//----------------------------------------------------------------------------
vtkIdType
vtkDistributedGraphHelper::
GetVertexOwnerByPedigreeId(const vtkVariant& pedigreeId)
{
  vtkIdType numProcs
    = this->Graph->GetInformation()->Get(vtkDataObject::DATA_NUMBER_OF_PIECES());
  if (this->VertexDistribution)
    {
    return (this->VertexDistribution(pedigreeId,
                                     this->VertexDistributionUserData)
            % numProcs);
    }

  // Hash the variant in a very lame way.
  double numericValue;
  vtkStdString stringValue;
  const unsigned char *charsStart, *charsEnd;
  if (pedigreeId.IsNumeric())
    {
    // Convert every numeric value into a double.
    numericValue = pedigreeId.ToDouble();

    // Hash the characters in the double.
    charsStart = reinterpret_cast<const unsigned char*>(&numericValue);
    charsEnd = charsStart + sizeof(double);
    }
  else if (pedigreeId.GetType() == VTK_STRING)
    {
    stringValue = pedigreeId.ToString();
    charsStart = reinterpret_cast<const unsigned char*>(stringValue.c_str());
    charsEnd = charsStart + stringValue.size();
    }
  else
    {
    vtkErrorMacro("Cannot hash vertex pedigree ID of type "
                  << pedigreeId.GetType());
    return 0;
    }

  unsigned long hash = 5381;
  for (; charsStart != charsEnd; ++charsStart)
    {
    hash = ((hash << 5) + hash) ^ *charsStart;
    }

  return hash % numProcs;
}
<|endoftext|>


<commit_before>/* Copyright (c) 2008-2020 the MRtrix3 contributors.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Covered Software is provided under this License on an "as is"
 * basis, without warranty of any kind, either expressed, implied, or
 * statutory, including, without limitation, warranties that the
 * Covered Software is free of defects, merchantable, fit for a
 * particular purpose or non-infringing.
 * See the Mozilla Public License v. 2.0 for more details.
 *
 * For more details, see http://www.mrtrix.org/.
 */

#include "command.h"
#include "image.h"
#include "image_helpers.h"
#include "mrtrix.h"
#include "transform.h"

#include "algo/loop.h"
#include "file/path.h"
#include "file/utils.h"
#include "interp/nearest.h"

#include "connectome/connectome.h"
#include "connectome/lut.h"

#include <string>

#define SPINE_NODE_NAME std::string("Spinal_column")

using namespace MR;
using namespace App;
using namespace MR::Connectome;
using MR::Connectome::node_t;

void usage ()
{

  AUTHOR = "Robert E. Smith (robert.smith@florey.edu.au)";

  SYNOPSIS = "Convert a connectome node image from one lookup table to another";

  DESCRIPTION
  + "Typical usage is to convert a parcellation image provided by some other software, based on "
    "the lookup table provided by that software, to conform to a new lookup table, particularly "
    "one where the node indices increment from 1, in preparation for connectome construction; "
    "examples of such target lookup table files are provided in share//mrtrix3//labelconvert//, "
    "but can be created by the user to provide the desired node set // ordering // colours.";

  EXAMPLES
  + Example ("Convert a Desikan-Killiany parcellation image as provided by FreeSurfer to have nodes incrementing from 1",
             "labelconvert aparc+aseg.mgz FreeSurferColorLUT.txt mrtrix3//share//mrtrix3//labelconvert//fs_default.txt nodes.mif",
             "Paths to the files in the example above would need to be revised according to their "
             "locations on the user's system.");

  ARGUMENTS
  + Argument ("path_in",   "the input image").type_image_in()
  + Argument ("lut_in",    "the connectome lookup table corresponding to the input image").type_file_in()
  + Argument ("lut_out",   "the target connectome lookup table for the output image").type_file_in()
  + Argument ("image_out", "the output image").type_image_out();

  OPTIONS
  + Option ("spine", "provide a manually-defined segmentation of the base of the spine where the streamlines terminate, so that "
                     "this can become a node in the connection matrix.")
    + Argument ("image").type_image_in();

}

void run ()
{

  // Open the input file
  auto H = Header::open (argument[0]);
  Connectome::check (H);
  auto in = H.get_image<node_t>();

  // Load the lookup tables
  LUT lut_in (argument[1]), lut_out (argument[2]);

  // Build the mapping from input to output indices
  const auto mapping = get_lut_mapping (lut_in, lut_out);

  // Modify the header for the output file
  H.datatype() = DataType::from<node_t>();
  add_line (H.keyval()["comments"], "LUT: " + Path::basename (argument[2]));

  // Create the output file
  auto out = Image<node_t>::create (argument[3], H);

  // Fill the output image with data
  bool user_warn = false;
  for (auto l = Loop (in) (in, out); l; ++l) {
    const node_t orig = in.value();
    if (orig < mapping.size())
      out.value() = mapping[orig];
    else
      user_warn = true;
  }
  if (user_warn)
    WARN ("Unexpected values detected in input image; suggest checking input image thoroughly");

  // Need to manually search through the output LUT to see if the
  //   'Spinal_column' node is in there, and appears only once
  node_t spine_index = 0;
  bool duplicates = false;
  for (const auto& i : lut_out) {
    if (i.second.get_name() == SPINE_NODE_NAME) {
      if (!spine_index)
        spine_index = i.first;
      else
        duplicates = true;
    }
  }

  // If the spine segment option has been provided, add this retrospectively
  auto opt = get_options ("spine");
  if (opt.size()) {

    if (duplicates) {
      WARN ("Could not add spine node: \"" + SPINE_NODE_NAME + "\" appears multiple times in output LUT");
    } else {

      auto in_spine = Image<bool>::open (opt[0][0]);
      if (dimensions_match (in_spine, out)) {

        for (auto l = Loop (in_spine) (in_spine, out); l; ++l) {
          if (in_spine.value())
            out.value() = spine_index;
        }

      } else {

        WARN ("Spine node is being created from the mask image provided using -spine option using nearest-neighbour interpolation;");
        WARN ("recommend using the parcellation image as the basis for this mask so that interpolation is not required");

        Transform transform (out);
        Interp::Nearest<decltype(in_spine)> nearest (in_spine);
        for (auto l = Loop (out) (out); l; ++l) {
          Eigen::Vector3 p (out.index (0), out.index (1), out.index (2));
          p = transform.voxel2scanner * p;
          if (nearest.scanner (p) && nearest.value())
            out.value() = spine_index;
        }

      }

    }

  } else if (spine_index) {
    WARN ("Config file includes \"" + SPINE_NODE_NAME + "\" node, but user has not provided the segmentation using -spine option");
  }

}

<commit_msg>labelconvert: Error if -spine used but absent from LUT<commit_after>/* Copyright (c) 2008-2020 the MRtrix3 contributors.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Covered Software is provided under this License on an "as is"
 * basis, without warranty of any kind, either expressed, implied, or
 * statutory, including, without limitation, warranties that the
 * Covered Software is free of defects, merchantable, fit for a
 * particular purpose or non-infringing.
 * See the Mozilla Public License v. 2.0 for more details.
 *
 * For more details, see http://www.mrtrix.org/.
 */

#include "command.h"
#include "image.h"
#include "image_helpers.h"
#include "mrtrix.h"
#include "transform.h"

#include "algo/loop.h"
#include "file/path.h"
#include "file/utils.h"
#include "interp/nearest.h"

#include "connectome/connectome.h"
#include "connectome/lut.h"

#include <string>

#define SPINE_NODE_NAME std::string("Spinal_column")

using namespace MR;
using namespace App;
using namespace MR::Connectome;
using MR::Connectome::node_t;

void usage ()
{

  AUTHOR = "Robert E. Smith (robert.smith@florey.edu.au)";

  SYNOPSIS = "Convert a connectome node image from one lookup table to another";

  DESCRIPTION
  + "Typical usage is to convert a parcellation image provided by some other software, based on "
    "the lookup table provided by that software, to conform to a new lookup table, particularly "
    "one where the node indices increment from 1, in preparation for connectome construction; "
    "examples of such target lookup table files are provided in share//mrtrix3//labelconvert//, "
    "but can be created by the user to provide the desired node set // ordering // colours.";

  EXAMPLES
  + Example ("Convert a Desikan-Killiany parcellation image as provided by FreeSurfer to have nodes incrementing from 1",
             "labelconvert aparc+aseg.mgz FreeSurferColorLUT.txt mrtrix3//share//mrtrix3//labelconvert//fs_default.txt nodes.mif",
             "Paths to the files in the example above would need to be revised according to their "
             "locations on the user's system.");

  ARGUMENTS
  + Argument ("path_in",   "the input image").type_image_in()
  + Argument ("lut_in",    "the connectome lookup table corresponding to the input image").type_file_in()
  + Argument ("lut_out",   "the target connectome lookup table for the output image").type_file_in()
  + Argument ("image_out", "the output image").type_image_out();

  OPTIONS
  + Option ("spine", "provide a manually-defined segmentation of the base of the spine where the streamlines terminate, so that "
                     "this can become a node in the connection matrix.")
    + Argument ("image").type_image_in();

}

void run ()
{

  // Open the input file
  auto H = Header::open (argument[0]);
  Connectome::check (H);
  auto in = H.get_image<node_t>();

  // Load the lookup tables
  LUT lut_in (argument[1]), lut_out (argument[2]);

  // Build the mapping from input to output indices
  const auto mapping = get_lut_mapping (lut_in, lut_out);

  // Modify the header for the output file
  H.datatype() = DataType::from<node_t>();
  add_line (H.keyval()["comments"], "LUT: " + Path::basename (argument[2]));

  // Create the output file
  auto out = Image<node_t>::create (argument[3], H);

  // Fill the output image with data
  bool user_warn = false;
  for (auto l = Loop (in) (in, out); l; ++l) {
    const node_t orig = in.value();
    if (orig < mapping.size())
      out.value() = mapping[orig];
    else
      user_warn = true;
  }
  if (user_warn)
    WARN ("Unexpected values detected in input image; suggest checking input image thoroughly");

  // Need to manually search through the output LUT to see if the
  //   'Spinal_column' node is in there, and appears only once
  node_t spine_index = 0;
  bool duplicates = false;
  for (const auto& i : lut_out) {
    if (i.second.get_name() == SPINE_NODE_NAME) {
      if (!spine_index)
        spine_index = i.first;
      else
        duplicates = true;
    }
  }

  // If the spine segment option has been provided, add this retrospectively
  auto opt = get_options ("spine");
  if (opt.size()) {

    if (duplicates)
      throw Exception ("Cannot add spine node: \"" + SPINE_NODE_NAME + "\" appears multiple times in output LUT");
    if (!spine_index)
      throw Exception ("Cannot add spine node: \"" + SPINE_NODE_NAME + "\" not present in output LUT");

    auto in_spine = Image<bool>::open (opt[0][0]);
    if (dimensions_match (in_spine, out)) {

      for (auto l = Loop (in_spine) (in_spine, out); l; ++l) {
        if (in_spine.value())
          out.value() = spine_index;
      }

    } else {

      WARN ("Spine node is being created from the mask image provided using -spine option using nearest-neighbour interpolation;");
      WARN ("recommend using the parcellation image as the basis for this mask so that interpolation is not required");

      Transform transform (out);
      Interp::Nearest<decltype(in_spine)> nearest (in_spine);
      for (auto l = Loop (out) (out); l; ++l) {
        Eigen::Vector3 p (out.index (0), out.index (1), out.index (2));
        p = transform.voxel2scanner * p;
        if (nearest.scanner (p) && nearest.value())
          out.value() = spine_index;
      }

    }

  } else if (spine_index) {
    WARN ("Config file includes \"" + SPINE_NODE_NAME + "\" node, but user has not provided the segmentation using -spine option");
  }

}

<|endoftext|>