<commit_before>/*
 *  traywindow.cpp  -  the KDE system tray applet
 *  Program:  kalarm
 *  Copyright © 2002-2006 by David Jarvie <software@astrojar.org.uk>
 *
 *  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 <stdlib.h>

#include <QToolTip>
#include <QMouseEvent>
#include <QList>

#include <kapplication.h>
#include <klocale.h>
#include <kstdaction.h>
#include <kaboutdata.h>
#include <kmenu.h>
#include <kmessagebox.h>
#include <kstandarddirs.h>
#include <kstdaction.h>
#include <kstdguiitem.h>
#include <kconfig.h>
#include <kdebug.h>

#include "alarmcalendar.h"
#include "alarmlistview.h"
#include "alarmtext.h"
#include "daemon.h"
#include "functions.h"
#include "kalarmapp.h"
#include "mainwindow.h"
#include "messagewin.h"
#include "prefdlg.h"
#include "preferences.h"
#include "templatemenuaction.h"
#include "traywindow.moc"

struct TipItem
{
	QDateTime  dateTime;
	QString    text;
};

/*=============================================================================
= Class: TrayWindow
= The KDE system tray window.
=============================================================================*/

TrayWindow::TrayWindow(MainWindow* parent)
	: KSystemTray((theApp()->wantRunInSystemTray() ? parent : 0)),
	  mAssocMainWindow(parent)
{
	kDebug(5950) << "TrayWindow::TrayWindow()\n";
	// Set up GUI icons
	mPixmapEnabled  = loadIcon("kalarm");
	mPixmapDisabled = loadIcon("kalarm_disabled");
	if (mPixmapEnabled.isNull() || mPixmapDisabled.isNull())
		KMessageBox::sorry(this, i18n("Cannot load system tray icon."));
	setAcceptDrops(true);         // allow drag-and-drop onto this window

	// Set up the context menu
	KActionCollection* actcol = actionCollection();
	KAction* a = Daemon::createAlarmEnableAction(actcol);
	contextMenu()->addAction( a );
	connect(a, SIGNAL(switched(bool)), SLOT(setEnabledStatus(bool)));
	a = KAlarm::createNewAlarmAction(i18n("&New Alarm..."), actcol, QLatin1String("tNew"));
	contextMenu()->addAction( a );
	connect(a, SIGNAL(triggered(bool)), SLOT(slotNewAlarm()));
	a = KAlarm::createNewFromTemplateAction(i18n("New Alarm From &Template"), actcol, QLatin1String("tNewFromTempl"));
	contextMenu()->addAction( a );
	connect(a, SIGNAL(selected(const KAEvent&)), SLOT(slotNewFromTemplate(const KAEvent&)));
	contextMenu()->addAction( KStdAction::preferences(this, SLOT(slotPreferences()), actcol));

	// Replace the default handler for the Quit context menu item
	const char* quitName = KStdAction::name(KStdAction::Quit);
	delete actcol->action(quitName);
	KStdAction::quit(this, SLOT(slotQuit()), actcol);

	// Set icon to correspond with the alarms enabled menu status
	Daemon::checkStatus();
	setEnabledStatus(Daemon::monitoringAlarms());
}

TrayWindow::~TrayWindow()
{
	kDebug(5950) << "TrayWindow::~TrayWindow()\n";
	theApp()->removeWindow(this);
	emit deleted();
}

/******************************************************************************
* Called just before the context menu is displayed.
* Update the Alarms Enabled item status.
*/
void TrayWindow::contextMenuAboutToShow(KMenu*)
{
	Daemon::checkStatus();
}

/******************************************************************************
*  Called when the "New Alarm" menu item is selected to edit a new alarm.
*/
void TrayWindow::slotNewAlarm()
{
	MainWindow::executeNew();
}

/******************************************************************************
*  Called when the "New Alarm" menu item is selected to edit a new alarm.
*/
void TrayWindow::slotNewFromTemplate(const KAEvent& event)
{
	MainWindow::executeNew(event);
}

/******************************************************************************
*  Called when the "Configure KAlarm" menu item is selected.
*/
void TrayWindow::slotPreferences()
{
	KAlarmPrefDlg prefDlg;
	prefDlg.exec();
}

/******************************************************************************
* Called when the Quit context menu item is selected.
*/
void TrayWindow::slotQuit()
{
	theApp()->doQuit(this);
}

/******************************************************************************
* Called when the Alarms Enabled action status has changed.
* Updates the alarms enabled menu item check state, and the icon pixmap.
*/
void TrayWindow::setEnabledStatus(bool status)
{
	kDebug(5950) << "TrayWindow::setEnabledStatus(" << (int)status << ")\n";
	setPixmap(status ? mPixmapEnabled : mPixmapDisabled);
}

/******************************************************************************
*  Called when the mouse is clicked over the panel icon.
*  A left click displays the KAlarm main window.
*  A middle button click displays the New Alarm window.
*/
void TrayWindow::mousePressEvent(QMouseEvent* e)
{
	if (e->button() == Qt::LeftButton  &&  !theApp()->wantRunInSystemTray())
	{
		// Left click: display/hide the first main window
		mAssocMainWindow = MainWindow::toggleWindow(mAssocMainWindow);
	}
	else if (e->button() == Qt::MidButton)
		MainWindow::executeNew();    // display a New Alarm dialog
	else
		KSystemTray::mousePressEvent(e);
}

/******************************************************************************
*  Called when the mouse is released over the panel icon.
*  The main window (if not hidden) is raised and made the active window.
*  If this is done in mousePressEvent(), it doesn't work.
*/
void TrayWindow::mouseReleaseEvent(QMouseEvent* e)
{
	if (e->button() == Qt::LeftButton  &&  mAssocMainWindow  &&  mAssocMainWindow->isVisible())
	{
		mAssocMainWindow->raise();
		mAssocMainWindow->activateWindow();
	}
	else
		KSystemTray::mouseReleaseEvent(e);
}

/******************************************************************************
*  Called when the drag cursor enters the panel icon.
*/
void TrayWindow::dragEnterEvent(QDragEnterEvent* e)
{
	MainWindow::executeDragEnterEvent(e);
}

/******************************************************************************
*  Called when an object is dropped on the panel icon.
*  If the object is recognised, the edit alarm dialog is opened appropriately.
*/
void TrayWindow::dropEvent(QDropEvent* e)
{
	MainWindow::executeDropEvent(0, e);
}

/******************************************************************************
*  Called when any event occurs.
*  If it's a tooltip event, display the tooltip text showing alarms due in the
*  next 24 hours. The limit of 24 hours is because only times, not dates, are
*  displayed.
*/
bool TrayWindow::event(QEvent* e)
{
	if (e->type() != QEvent::ToolTip)
		return KSystemTray::event(e);
	QHelpEvent* he = (QHelpEvent*)e;
	QString text;
	if (Daemon::monitoringAlarms())
		text = kapp->aboutData()->programName();
	else
		text = i18n("%1 - disabled", kapp->aboutData()->programName());
	kDebug(5950) << "TrayWindow::event(): " << text << endl;
	if (Preferences::tooltipAlarmCount())
		tooltipAlarmText(text);
	QToolTip::showText(he->pos(), text);
	return true;
}

/******************************************************************************
*  Return the tooltip text showing alarms due in the next 24 hours.
*  The limit of 24 hours is because only times, not dates, are displayed.
*/
void TrayWindow::tooltipAlarmText(QString& text) const
{
	KAEvent event;
	const QString& prefix = Preferences::tooltipTimeToPrefix();
	int maxCount = Preferences::tooltipAlarmCount();
	QDateTime now = QDateTime::currentDateTime();

	// Get today's and tomorrow's alarms, sorted in time order
	QList<TipItem> items;
	KCal::Event::List events = AlarmCalendar::activeCalendar()->eventsWithAlarms(QDateTime(now.date()), now.addDays(1));
	for (KCal::Event::List::ConstIterator it = events.begin();  it != events.end();  ++it)
	{
		KCal::Event* kcalEvent = *it;
		event.set(*kcalEvent);
		if (event.enabled()  &&  !event.expired()  &&  event.action() == KAEvent::MESSAGE)
		{
			TipItem item;
			DateTime dateTime = event.nextDateTime(false);
			if (dateTime.date() > now.date())
			{
				// Ignore alarms after tomorrow at the current clock time
				if (dateTime.date() != now.date().addDays(1)
				||  dateTime.time() >= now.time())
					continue;
			}
			item.dateTime = dateTime.dateTime();

			// The alarm is due today, or early tomorrow
			bool space = false;
			if (Preferences::showTooltipAlarmTime())
			{
				item.text += KGlobal::locale()->formatTime(item.dateTime.time());
				item.text += QLatin1Char(' ');
				space = true;
			}
			if (Preferences::showTooltipTimeToAlarm())
			{
				int mins = (now.secsTo(item.dateTime) + 59) / 60;
				if (mins < 0)
					mins = 0;
				char minutes[3] = "00";
				minutes[0] = (mins%60) / 10 + '0';
				minutes[1] = (mins%60) % 10 + '0';
				if (Preferences::showTooltipAlarmTime())
					item.text += i18nc("prefix + hours:minutes", "(%1%2:%3)", prefix, mins/60, minutes);
				else
					item.text += i18nc("prefix + hours:minutes", "%1%2:%3", prefix, mins/60, minutes);
				item.text += QLatin1Char(' ');
				space = true;
			}
			if (space)
				item.text += QLatin1Char(' ');
			item.text += AlarmText::summary(event);

			// Insert the item into the list in time-sorted order
			int i = 0;
			for (int iend = items.count();  i < iend;  ++i)
			{
				if (item.dateTime <= items[i].dateTime)
					break;
			}
			items.insert(i, item);
		}
        }
	kDebug(5950) << "TrayWindow::tooltipAlarmText():\n";
	int count = 0;
	for (int i = 0, iend = items.count();  i < iend;  ++i)
	{
		kDebug(5950) << "-- " << (count+1) << ") " << items[i].text << endl;
		text += "\n";
		text += items[i].text;
		if (++count == maxCount)
			break;
	}
}

/******************************************************************************
* Called when the associated main window is closed.
*/
void TrayWindow::removeWindow(MainWindow* win)
{
	if (win == mAssocMainWindow)
		mAssocMainWindow = 0;
}

#if defined(HAVE_X11_HEADERS) && defined(Q_WS_X11)
	#include <X11/X.h>
	#include <X11/Xlib.h>
	#include <X11/Xutil.h>
#include <QX11Info>
#endif

/******************************************************************************
* Check whether the widget is in the system tray.
* Note that it is only sometime AFTER the show event that the system tray
* becomes the widget's parent. So for a definitive status, call this method
* only after waiting a bit...
* Reply = true if the widget is in the system tray, or its status can't be determined.
*       = false if it is not currently in the system tray.
*/
bool TrayWindow::inSystemTray() const
{
#if defined(HAVE_X11_HEADERS) && defined(Q_WS_X11)
	Window  xParent;    // receives parent window
	Window  root;
	Window* children = 0;
	unsigned int nchildren;
	// Find the X parent window of the widget. This is not the same as the Qt parent widget.
	if (!XQueryTree(QX11Info::display(), winId(), &root, &xParent, &children, &nchildren))
		return true;    // error determining its parent X window
	if (children)
		XFree(children);

	// If it is in the system tray, the system tray window will be its X parent.
	// Otherwise, the root window will be its X parent.
	return xParent != root;
#else
	return true;
#endif // HAVE_X11_HEADERS
}
<commit_msg>Fix coding style<commit_after>/*
 *  traywindow.cpp  -  the KDE system tray applet
 *  Program:  kalarm
 *  Copyright © 2002-2006 by David Jarvie <software@astrojar.org.uk>
 *
 *  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 <stdlib.h>

#include <QToolTip>
#include <QMouseEvent>
#include <QList>

#include <kapplication.h>
#include <klocale.h>
#include <kstdaction.h>
#include <kaboutdata.h>
#include <kmenu.h>
#include <kmessagebox.h>
#include <kstandarddirs.h>
#include <kstdaction.h>
#include <kstdguiitem.h>
#include <kconfig.h>
#include <kdebug.h>

#include "alarmcalendar.h"
#include "alarmlistview.h"
#include "alarmtext.h"
#include "daemon.h"
#include "functions.h"
#include "kalarmapp.h"
#include "mainwindow.h"
#include "messagewin.h"
#include "prefdlg.h"
#include "preferences.h"
#include "templatemenuaction.h"
#include "traywindow.moc"

struct TipItem
{
	QDateTime  dateTime;
	QString    text;
};

/*=============================================================================
= Class: TrayWindow
= The KDE system tray window.
=============================================================================*/

TrayWindow::TrayWindow(MainWindow* parent)
	: KSystemTray((theApp()->wantRunInSystemTray() ? parent : 0)),
	  mAssocMainWindow(parent)
{
	kDebug(5950) << "TrayWindow::TrayWindow()\n";
	// Set up GUI icons
	mPixmapEnabled  = loadIcon("kalarm");
	mPixmapDisabled = loadIcon("kalarm_disabled");
	if (mPixmapEnabled.isNull() || mPixmapDisabled.isNull())
		KMessageBox::sorry(this, i18n("Cannot load system tray icon."));
	setAcceptDrops(true);         // allow drag-and-drop onto this window

	// Set up the context menu
	KActionCollection* actcol = actionCollection();
	KAction* a = Daemon::createAlarmEnableAction(actcol);
	contextMenu()->addAction(a);
	connect(a, SIGNAL(switched(bool)), SLOT(setEnabledStatus(bool)));
	a = KAlarm::createNewAlarmAction(i18n("&New Alarm..."), actcol, QLatin1String("tNew"));
	contextMenu()->addAction(a);
	connect(a, SIGNAL(triggered(bool)), SLOT(slotNewAlarm()));
	a = KAlarm::createNewFromTemplateAction(i18n("New Alarm From &Template"), actcol, QLatin1String("tNewFromTempl"));
	contextMenu()->addAction(a);
	connect(a, SIGNAL(selected(const KAEvent&)), SLOT(slotNewFromTemplate(const KAEvent&)));
	contextMenu()->addAction(KStdAction::preferences(this, SLOT(slotPreferences()), actcol));

	// Replace the default handler for the Quit context menu item
	const char* quitName = KStdAction::name(KStdAction::Quit);
	delete actcol->action(quitName);
	KStdAction::quit(this, SLOT(slotQuit()), actcol);

	// Set icon to correspond with the alarms enabled menu status
	Daemon::checkStatus();
	setEnabledStatus(Daemon::monitoringAlarms());
}

TrayWindow::~TrayWindow()
{
	kDebug(5950) << "TrayWindow::~TrayWindow()\n";
	theApp()->removeWindow(this);
	emit deleted();
}

/******************************************************************************
* Called just before the context menu is displayed.
* Update the Alarms Enabled item status.
*/
void TrayWindow::contextMenuAboutToShow(KMenu*)
{
	Daemon::checkStatus();
}

/******************************************************************************
*  Called when the "New Alarm" menu item is selected to edit a new alarm.
*/
void TrayWindow::slotNewAlarm()
{
	MainWindow::executeNew();
}

/******************************************************************************
*  Called when the "New Alarm" menu item is selected to edit a new alarm.
*/
void TrayWindow::slotNewFromTemplate(const KAEvent& event)
{
	MainWindow::executeNew(event);
}

/******************************************************************************
*  Called when the "Configure KAlarm" menu item is selected.
*/
void TrayWindow::slotPreferences()
{
	KAlarmPrefDlg prefDlg;
	prefDlg.exec();
}

/******************************************************************************
* Called when the Quit context menu item is selected.
*/
void TrayWindow::slotQuit()
{
	theApp()->doQuit(this);
}

/******************************************************************************
* Called when the Alarms Enabled action status has changed.
* Updates the alarms enabled menu item check state, and the icon pixmap.
*/
void TrayWindow::setEnabledStatus(bool status)
{
	kDebug(5950) << "TrayWindow::setEnabledStatus(" << (int)status << ")\n";
	setPixmap(status ? mPixmapEnabled : mPixmapDisabled);
}

/******************************************************************************
*  Called when the mouse is clicked over the panel icon.
*  A left click displays the KAlarm main window.
*  A middle button click displays the New Alarm window.
*/
void TrayWindow::mousePressEvent(QMouseEvent* e)
{
	if (e->button() == Qt::LeftButton  &&  !theApp()->wantRunInSystemTray())
	{
		// Left click: display/hide the first main window
		mAssocMainWindow = MainWindow::toggleWindow(mAssocMainWindow);
	}
	else if (e->button() == Qt::MidButton)
		MainWindow::executeNew();    // display a New Alarm dialog
	else
		KSystemTray::mousePressEvent(e);
}

/******************************************************************************
*  Called when the mouse is released over the panel icon.
*  The main window (if not hidden) is raised and made the active window.
*  If this is done in mousePressEvent(), it doesn't work.
*/
void TrayWindow::mouseReleaseEvent(QMouseEvent* e)
{
	if (e->button() == Qt::LeftButton  &&  mAssocMainWindow  &&  mAssocMainWindow->isVisible())
	{
		mAssocMainWindow->raise();
		mAssocMainWindow->activateWindow();
	}
	else
		KSystemTray::mouseReleaseEvent(e);
}

/******************************************************************************
*  Called when the drag cursor enters the panel icon.
*/
void TrayWindow::dragEnterEvent(QDragEnterEvent* e)
{
	MainWindow::executeDragEnterEvent(e);
}

/******************************************************************************
*  Called when an object is dropped on the panel icon.
*  If the object is recognised, the edit alarm dialog is opened appropriately.
*/
void TrayWindow::dropEvent(QDropEvent* e)
{
	MainWindow::executeDropEvent(0, e);
}

/******************************************************************************
*  Called when any event occurs.
*  If it's a tooltip event, display the tooltip text showing alarms due in the
*  next 24 hours. The limit of 24 hours is because only times, not dates, are
*  displayed.
*/
bool TrayWindow::event(QEvent* e)
{
	if (e->type() != QEvent::ToolTip)
		return KSystemTray::event(e);
	QHelpEvent* he = (QHelpEvent*)e;
	QString text;
	if (Daemon::monitoringAlarms())
		text = kapp->aboutData()->programName();
	else
		text = i18n("%1 - disabled", kapp->aboutData()->programName());
	kDebug(5950) << "TrayWindow::event(): " << text << endl;
	if (Preferences::tooltipAlarmCount())
		tooltipAlarmText(text);
	QToolTip::showText(he->pos(), text);
	return true;
}

/******************************************************************************
*  Return the tooltip text showing alarms due in the next 24 hours.
*  The limit of 24 hours is because only times, not dates, are displayed.
*/
void TrayWindow::tooltipAlarmText(QString& text) const
{
	KAEvent event;
	const QString& prefix = Preferences::tooltipTimeToPrefix();
	int maxCount = Preferences::tooltipAlarmCount();
	QDateTime now = QDateTime::currentDateTime();

	// Get today's and tomorrow's alarms, sorted in time order
	QList<TipItem> items;
	KCal::Event::List events = AlarmCalendar::activeCalendar()->eventsWithAlarms(QDateTime(now.date()), now.addDays(1));
	for (KCal::Event::List::ConstIterator it = events.begin();  it != events.end();  ++it)
	{
		KCal::Event* kcalEvent = *it;
		event.set(*kcalEvent);
		if (event.enabled()  &&  !event.expired()  &&  event.action() == KAEvent::MESSAGE)
		{
			TipItem item;
			DateTime dateTime = event.nextDateTime(false);
			if (dateTime.date() > now.date())
			{
				// Ignore alarms after tomorrow at the current clock time
				if (dateTime.date() != now.date().addDays(1)
				||  dateTime.time() >= now.time())
					continue;
			}
			item.dateTime = dateTime.dateTime();

			// The alarm is due today, or early tomorrow
			bool space = false;
			if (Preferences::showTooltipAlarmTime())
			{
				item.text += KGlobal::locale()->formatTime(item.dateTime.time());
				item.text += QLatin1Char(' ');
				space = true;
			}
			if (Preferences::showTooltipTimeToAlarm())
			{
				int mins = (now.secsTo(item.dateTime) + 59) / 60;
				if (mins < 0)
					mins = 0;
				char minutes[3] = "00";
				minutes[0] = (mins%60) / 10 + '0';
				minutes[1] = (mins%60) % 10 + '0';
				if (Preferences::showTooltipAlarmTime())
					item.text += i18nc("prefix + hours:minutes", "(%1%2:%3)", prefix, mins/60, minutes);
				else
					item.text += i18nc("prefix + hours:minutes", "%1%2:%3", prefix, mins/60, minutes);
				item.text += QLatin1Char(' ');
				space = true;
			}
			if (space)
				item.text += QLatin1Char(' ');
			item.text += AlarmText::summary(event);

			// Insert the item into the list in time-sorted order
			int i = 0;
			for (int iend = items.count();  i < iend;  ++i)
			{
				if (item.dateTime <= items[i].dateTime)
					break;
			}
			items.insert(i, item);
		}
        }
	kDebug(5950) << "TrayWindow::tooltipAlarmText():\n";
	int count = 0;
	for (int i = 0, iend = items.count();  i < iend;  ++i)
	{
		kDebug(5950) << "-- " << (count+1) << ") " << items[i].text << endl;
		text += "\n";
		text += items[i].text;
		if (++count == maxCount)
			break;
	}
}

/******************************************************************************
* Called when the associated main window is closed.
*/
void TrayWindow::removeWindow(MainWindow* win)
{
	if (win == mAssocMainWindow)
		mAssocMainWindow = 0;
}

#if defined(HAVE_X11_HEADERS) && defined(Q_WS_X11)
	#include <X11/X.h>
	#include <X11/Xlib.h>
	#include <X11/Xutil.h>
#include <QX11Info>
#endif

/******************************************************************************
* Check whether the widget is in the system tray.
* Note that it is only sometime AFTER the show event that the system tray
* becomes the widget's parent. So for a definitive status, call this method
* only after waiting a bit...
* Reply = true if the widget is in the system tray, or its status can't be determined.
*       = false if it is not currently in the system tray.
*/
bool TrayWindow::inSystemTray() const
{
#if defined(HAVE_X11_HEADERS) && defined(Q_WS_X11)
	Window  xParent;    // receives parent window
	Window  root;
	Window* children = 0;
	unsigned int nchildren;
	// Find the X parent window of the widget. This is not the same as the Qt parent widget.
	if (!XQueryTree(QX11Info::display(), winId(), &root, &xParent, &children, &nchildren))
		return true;    // error determining its parent X window
	if (children)
		XFree(children);

	// If it is in the system tray, the system tray window will be its X parent.
	// Otherwise, the root window will be its X parent.
	return xParent != root;
#else
	return true;
#endif // HAVE_X11_HEADERS
}
<|endoftext|>


<commit_before>// Dak Washbrook - M10A

/*
 // Input
 The first three integers are in the range 0..100000.  They represent seconds taken to solve the first, second, and third problems, respectively.
 Zero seconds indicates that a problem has not been solved.  The last three integers are in the range 0..100, representing the attempts taken to
 solve the first, second, and third problems, respectively.

 // Output
 Each output line should begin with the line number (right justified in a 3 character field), followed by a colon and a space, the teams name
 (left justified in a 40 character field), followed by a single space, the number of solved problems (right justified in a 2 character field),
 a single space, and the total number of seconds including penalties it took for the solved problems (right justified in a 7 character field).
 */

// Includes
#include <iostream>
#include <string>
#include <iomanip>
#include <fstream>

// Namespace used.
using namespace std;

const int ZERO = 0, SOLVED = 1, NOT_SOLVED = 0, COLUMN1 = 3, COLUMN2 = 40, COLUMN3 = 2, COLUMN4 = 7; // Declaring Constants for zero, if solved, and the column lengths.
const string READ_FILE = "RawScore.dat", WRITE_FILE = "ComputedScore.dat"; // Declaring Constants for the filenames.

// Prototypes
int Solved(int score);
bool ReadInputRecord(ifstream &, int &, int &, int &, int &, int &, int &, string &);
bool WriteInputRecord(ofstream &, int, string, int, int);
int CountLines(string);

int main() {

    // Declaring all integer values.
    int numLines = ZERO, iteration = ZERO, score1, score2, score3, attempt1, attempt2, attempt3, numSolved, totalTime;

    // Declaring the fstreams for the read and writted files.
    ifstream filename;
    ofstream newFilename;

    string teamName; // Declaring the string for the team name column.

    numLines = CountLines(READ_FILE); // Counts the number of lines in a file.

    if (numLines > 0) {

        cout << "Opening " << READ_FILE << endl;

        filename.open(READ_FILE); // Open the READ_FILE and stream contents.

        if (filename) {

            cout << READ_FILE << " successfuly opened." << endl << endl;

            cout << "Opening " << WRITE_FILE << endl;

            // Open the WRITE_FILE and stream contents.
            newFilename.open(WRITE_FILE);

            if (newFilename) {

                cout << WRITE_FILE << " successfully opened." << endl << endl;

                // For each line, read contents, then convert to desired output and write.
                for (int i = ZERO; i < numLines; i++) {
                    cout << "Reading line." << endl;
                    // Read the contents of 'filename' and store it into the reference variables.
                    if (ReadInputRecord(filename, score1, score2, score3, attempt1, attempt2, attempt3, teamName)) {
                        cout << "Line successfully read" << endl; // Say the line is read if it didn't fail.
                        cout << "Team: " << teamName << " found." << endl; // Say the name of the team it found on the current line.
                        cout << "Calculating number of successfully solved problems by " << teamName << "." << endl;
                        numSolved = Solved(score1) + Solved(score2) + Solved(score3); // Find out how many were solved by the team.
                        cout << teamName << " solved " << numSolved << " problems." << endl; // Output number of solved problems by the team on the current line.
                        cout << "Calculating total time it took " << teamName << " to solve " << numSolved << " problems." << endl;
                        totalTime = score1 + score2 + score3; // Fine the total time that it took for them to solve all problems.
                        cout << teamName << " took " << totalTime << " seconds to solve " << numSolved << " problems." << endl; // Output the total time it took the team on the current line.
                        iteration++; // Iterate for the first column's number.
                        cout << "Writing data to " << WRITE_FILE << endl;
                        if (WriteInputRecord(newFilename, iteration, teamName, numSolved, totalTime)) { // Write the new output to 'newFilename'.
                            cout << "Data written to " << WRITE_FILE << endl << endl; // Output that the data was successfully written.
                        }
                        else {
                            cout << "Error writing data to file." << endl << endl; // If failed to write, output an error.
                            break; // Break the loop due to error.
                        }
                    }
                    else {
                        cout << "Error reading line." << endl << endl; // If failed to write, output an error.
                        break; // Break the loop due to error.
                    }
                }

                cout << "Closing " << WRITE_FILE << endl;
                newFilename.close(); // Close the WRITE_FILE;
                if (newFilename.is_open()) {
                    cout << "Error closing file." << endl << endl; // If failed to close, output an error.
                    return 0; // If failed to close, end program.
                }
                else {
                    cout << WRITE_FILE << " closed." << endl << endl;
                }
            }
            else {
                // If 'newFilename' failed to open, display an error message.
                cout << "Error Opening " << WRITE_FILE << endl << endl;
            }

            cout << "Closing " << READ_FILE << endl;
            filename.close(); // Close the READ_FILE.
            if (filename.is_open()) {
                cout << "Error closing file." << endl << endl; // If failed to close, output an error.
                return 0; // If failed to close, end program.
            }
            else {
                cout << READ_FILE << " closed." << endl << endl;
            }
        }
        else {
            // If 'filename' failed to open, display an error message.
            cout << "Error Opening " << READ_FILE << endl << endl;
        }
    }
    else {
        // If the file is empty then alert user.
        cout << READ_FILE << " is empty." << endl << endl;
    }

    return 0;

}

bool ReadInputRecord(ifstream &filename, int &score1, int &score2, int &score3, int &attempt1, int &attempt2, int &attempt3, string &teamName) {
    // Change the values of the reference variables to be the contents of the current line.
    if (filename >> score1 >> score2 >> score3 >> attempt1 >> attempt2 >> attempt3 >> teamName) {
        return true;
    }
    else {
        return false;
    }
}

bool WriteInputRecord(ofstream &newFilename, int iteration, string teamName, int numSolved, int totalTime) {
    // Write a new line to the 'newFilename' with the desired values and formatting. Also, sets the correct column widths for each column.
    if (newFilename << setw(COLUMN1) << iteration << ": " << setw(COLUMN2) << left << teamName << right << " " << setw(COLUMN3) << numSolved << " " << setw(COLUMN4) << totalTime << endl) {
        return true;
    }
    else {
        return false;
    }
}

int Solved(int score) {

    /* This function calculates if the problem was solved or not.
     Outputs SOLVED if it was, ZERO if it was not. Allowing
     the outputs to be added together to produce the total
     number of solved problems.
     */

    if (score > ZERO) { // Find if the problem was solved by seeing if their seconds were greater than 0.
        return SOLVED; // Return SOLVED if solved.
    }
    else {
        return NOT_SOLVED; // Return NOT_SOLVED if not solved.
    }
}

int CountLines(string file) {

    /* This function finds the number of lines that exist in a file and outputs that number. */

    int numLines = ZERO; // Initiate numLines.
    ifstream filename;
    string line;

    filename.open(file); // Open the filename that was passed into the function via a string.

    if (filename) {

        cout << "Counting number of lines in " << file << endl;

        while (getline(filename, line)) {
            // For each line, iterate numLines.
            numLines++;
        }

        cout << numLines << " line(s) counted." << endl << endl;

        filename.close(); // Close the file after done.

    }
    else {
        cout << file << " could not be opened." << endl << endl;
    }

    return numLines; // Return the number of lines that exist.
}
<commit_msg>Delete Assignment-3.cpp<commit_after><|endoftext|>


<commit_before>#include <igloo/igloo_alt.h>
using namespace igloo;

#include <Packet.h>
#include <AglVector3.h>
#include <AglQuaternion.h>

static const int TEST_PACKET_TYPE = 100;

Describe(a_packet)
{
	It(can_have_a_sender_id_defined_in_setSenderId_method)
	{
		Packet packet(TEST_PACKET_TYPE);
		packet.setSenderId(77);

		Assert::That(packet.getSenderId(), Equals(77));
	}

	It(can_contain_int_data)
	{
		Packet packet(TEST_PACKET_TYPE);

		int i_src = 1;
		packet << i_src;
		int i_dst;
		packet >> i_dst;

		Assert::That(i_dst, Equals(i_src));
	}

	It(can_contain_float_data)
	{
		Packet packet(TEST_PACKET_TYPE);
		float f_src = 13.37f;
		packet << f_src;
		float f_dst;
		packet >> f_dst;

		Assert::That(f_dst, Equals(f_src));
	}

	It(can_contain_bool_data)
	{
		Packet packet(TEST_PACKET_TYPE);
		bool b_src = true;
		packet << b_src;
		bool b_dst;
		packet >> b_dst;

		Assert::That(b_dst, Equals(b_src));
	}

	It(can_contain_char_data)
	{
		Packet packet(TEST_PACKET_TYPE);
		char c_src = 100;
		packet << c_src;
		char c_dst;
		packet >> c_dst;

		Assert::That(c_dst, Equals(c_src));
	}

	It(can_contain_short_data)
	{
		Packet packet(TEST_PACKET_TYPE);
		short s_src = 10000;
		packet << s_src;
		short s_dst;
		packet >> s_dst;

		Assert::That(s_dst, Equals(s_src));
	}

	It(can_contain_double_data)
	{
		Packet packet(TEST_PACKET_TYPE);
		double d_src = 1337.1435000000377;
		packet << d_src;
		double d_dst;
		packet >> d_dst;

		Assert::That(d_dst, Equals(d_src));
	}

	It(can_contain_vec3_data)
	{
		Packet packet(TEST_PACKET_TYPE);
		AglVector3 vec_src(1.0f, 2.0f, 3.0f);
		packet << vec_src;
		AglVector3 vec_dst;
		packet >> vec_dst;

		Assert::That(vec_dst.x, Equals(vec_src.x));
		Assert::That(vec_dst.y, Equals(vec_src.y));
		Assert::That(vec_dst.z, Equals(vec_src.z));
	}

	It(can_contain_quaternion_data)
	{
		Packet packet(TEST_PACKET_TYPE);
		AglQuaternion quaternion_src(1.0f, 2.0f, 3.0f, 4.5f);
		packet << quaternion_src;
		AglQuaternion quaternion_dst;
		packet >> quaternion_dst;

		Assert::That(quaternion_dst.u.x, Equals(quaternion_src.u.x));
		Assert::That(quaternion_dst.u.y, Equals(quaternion_src.u.y));
		Assert::That(quaternion_dst.u.z, Equals(quaternion_src.u.z));
		Assert::That(quaternion_dst.v, Equals(quaternion_src.v));
	}

	It(can_contain_multiple_int_data)
	{
		Packet packet(TEST_PACKET_TYPE);

		int i_src[] = { 1, 2, 3 };
		packet << i_src[0] << i_src[1] << i_src[2];
		int i_dst[3];
		packet >> i_dst[0] >> i_dst[1] >> i_dst[2];

		for (int i = 0; i <3; i++)
			Assert::That(i_dst[i], Equals(i_src[i]));
	}

	It(can_contain_multiple_types_of_data)
	{
		Packet packet(TEST_PACKET_TYPE);
		int i_src = 42;
		float f_src = 13.37f;
		packet << i_src << f_src;
		int i_dst;
		float f_dst;
		packet >> i_dst >> f_dst;

		Assert::That(i_dst, Equals(i_src));
		Assert::That(f_dst, Equals(f_src));
	}

	It(can_be_cleared)
	{
		Packet packet(TEST_PACKET_TYPE);
		packet << 10 << 10.0f;

		packet.clear();
		Assert::That(packet.isEmpty(), Equals(true));
	}

	It(can_return_data_size)
	{
		Packet packet(TEST_PACKET_TYPE);

		int i_src[] = { 1, 2, 3 };
		packet << i_src[0] << i_src[1] << i_src[2];

		Assert::That(packet.getDataSize(), Equals(sizeof(i_src) + Packet::HEADER_SIZE));
	}

	It(can_be_empty)
	{
		Packet packet(TEST_PACKET_TYPE);

		Assert::That(packet.isEmpty(), IsTrue());
	}

	It(throws_an_exception_if_trying_to_stream_out_an_empty_packet)
	{
		Packet packet(TEST_PACKET_TYPE);
		int i_dst;
		AssertThrows(std::out_of_range, (packet >> i_dst));
	}

	It(can_set_byte_data)
	{
		char* byteData = new char[4 + Packet::HEADER_SIZE];

		// Header
		byteData[0] = 4;
		byteData[1] = 0;
		byteData[2] = 0;
		byteData[3] = 0;
		byteData[4] = 0;
		byteData[5] = 0;

		// An int
		byteData[6] = 42;
		byteData[7] = 0;
		byteData[8] = 0;
		byteData[9] = 0;

		Packet packet(TEST_PACKET_TYPE);
		packet.setDataTest(byteData, 4 + Packet::HEADER_SIZE);

		int i_dst;
		packet >> i_dst;
		Assert::That(i_dst, Equals(42));

		delete[] byteData;
	}

	It(should_be_possible_to_copy_byte_data_from_a_packet_to_another)
	{
		int i_src = 5;
		float f_src = 6.9f;
		Packet packet_src(TEST_PACKET_TYPE);
		packet_src << i_src << f_src;

		unsigned int data_size = packet_src.getDataSize();
		char* data_src = packet_src.getDataPtr();

		Packet packet_dst(TEST_PACKET_TYPE);
		packet_dst.setDataTest(data_src, data_size);

		int i_dst;
		float f_dst;
		packet_dst >> i_dst >> f_dst;

		Assert::That(i_dst, Equals(i_src));
		Assert::That(f_dst, Equals(f_src));
	}

};<commit_msg>Added a test that makes sure packet size is ok. Passed.<commit_after>#include <igloo/igloo_alt.h>
using namespace igloo;

#include <Packet.h>
#include <AglVector3.h>
#include <AglQuaternion.h>

static const int TEST_PACKET_TYPE = 100;

Describe(a_packet)
{
	It(can_have_a_sender_id_defined_in_setSenderId_method)
	{
		Packet packet(TEST_PACKET_TYPE);
		packet.setSenderId(77);

		Assert::That(packet.getSenderId(), Equals(77));
	}

	It(can_contain_int_data)
	{
		Packet packet(TEST_PACKET_TYPE);

		int i_src = 1;
		packet << i_src;
		int i_dst;
		packet >> i_dst;

		Assert::That(i_dst, Equals(i_src));
	}

	It(can_contain_float_data)
	{
		Packet packet(TEST_PACKET_TYPE);
		float f_src = 13.37f;
		packet << f_src;
		float f_dst;
		packet >> f_dst;

		Assert::That(f_dst, Equals(f_src));
	}

	It(can_contain_bool_data)
	{
		Packet packet(TEST_PACKET_TYPE);
		bool b_src = true;
		packet << b_src;
		bool b_dst;
		packet >> b_dst;

		Assert::That(b_dst, Equals(b_src));
	}

	It(can_contain_char_data)
	{
		Packet packet(TEST_PACKET_TYPE);
		char c_src = 100;
		packet << c_src;
		char c_dst;
		packet >> c_dst;

		Assert::That(c_dst, Equals(c_src));
	}

	It(can_contain_short_data)
	{
		Packet packet(TEST_PACKET_TYPE);
		short s_src = 10000;
		packet << s_src;
		short s_dst;
		packet >> s_dst;

		Assert::That(s_dst, Equals(s_src));
	}

	It(can_contain_double_data)
	{
		Packet packet(TEST_PACKET_TYPE);
		double d_src = 1337.1435000000377;
		packet << d_src;
		double d_dst;
		packet >> d_dst;

		Assert::That(d_dst, Equals(d_src));
	}

	It(can_contain_vec3_data)
	{
		Packet packet(TEST_PACKET_TYPE);
		AglVector3 vec_src(1.0f, 2.0f, 3.0f);
		packet << vec_src;
		AglVector3 vec_dst;
		packet >> vec_dst;

		Assert::That(vec_dst.x, Equals(vec_src.x));
		Assert::That(vec_dst.y, Equals(vec_src.y));
		Assert::That(vec_dst.z, Equals(vec_src.z));
	}

	It(can_contain_quaternion_data)
	{
		Packet packet(TEST_PACKET_TYPE);
		AglQuaternion quaternion_src(1.0f, 2.0f, 3.0f, 4.5f);
		packet << quaternion_src;
		AglQuaternion quaternion_dst;
		packet >> quaternion_dst;

		Assert::That(quaternion_dst.u.x, Equals(quaternion_src.u.x));
		Assert::That(quaternion_dst.u.y, Equals(quaternion_src.u.y));
		Assert::That(quaternion_dst.u.z, Equals(quaternion_src.u.z));
		Assert::That(quaternion_dst.v, Equals(quaternion_src.v));
	}

	It(can_contain_multiple_int_data)
	{
		Packet packet(TEST_PACKET_TYPE);

		int i_src[] = { 1, 2, 3 };
		packet << i_src[0] << i_src[1] << i_src[2];
		int i_dst[3];
		packet >> i_dst[0] >> i_dst[1] >> i_dst[2];

		for (int i = 0; i <3; i++)
			Assert::That(i_dst[i], Equals(i_src[i]));
	}

	It(can_contain_multiple_types_of_data)
	{
		Packet packet(TEST_PACKET_TYPE);
		int i_src = 42;
		float f_src = 13.37f;
		packet << i_src << f_src;
		int i_dst;
		float f_dst;
		packet >> i_dst >> f_dst;

		Assert::That(i_dst, Equals(i_src));
		Assert::That(f_dst, Equals(f_src));
	}

	It(can_be_cleared)
	{
		Packet packet(TEST_PACKET_TYPE);
		packet << 10 << 10.0f;

		packet.clear();
		Assert::That(packet.isEmpty(), Equals(true));
	}

	It(can_return_data_size)
	{
		Packet packet(TEST_PACKET_TYPE);

		int i_src[] = { 1, 2, 3 };
		packet << i_src[0] << i_src[1] << i_src[2];

		Assert::That(packet.getDataSize(), Equals(sizeof(i_src) + Packet::HEADER_SIZE));
	}

	It(can_be_empty)
	{
		Packet packet(TEST_PACKET_TYPE);

		Assert::That(packet.isEmpty(), IsTrue());
	}

	It(throws_an_exception_if_trying_to_stream_out_an_empty_packet)
	{
		Packet packet(TEST_PACKET_TYPE);
		int i_dst;
		AssertThrows(std::out_of_range, (packet >> i_dst));
	}

	It(can_set_byte_data)
	{
		char* byteData = new char[4 + Packet::HEADER_SIZE];

		// Header
		byteData[0] = 4;
		byteData[1] = 0;
		byteData[2] = 0;
		byteData[3] = 0;
		byteData[4] = 0;
		byteData[5] = 0;

		// An int
		byteData[6] = 42;
		byteData[7] = 0;
		byteData[8] = 0;
		byteData[9] = 0;

		Packet packet(TEST_PACKET_TYPE);
		packet.setDataTest(byteData, 4 + Packet::HEADER_SIZE);

		int i_dst;
		packet >> i_dst;
		Assert::That(i_dst, Equals(42));

		delete[] byteData;
	}

	It(should_be_possible_to_copy_byte_data_from_a_packet_to_another)
	{
		int i_src = 5;
		float f_src = 6.9f;
		Packet packet_src(TEST_PACKET_TYPE);
		packet_src << i_src << f_src;

		unsigned int data_size = packet_src.getDataSize();
		char* data_src = packet_src.getDataPtr();

		Packet packet_dst(TEST_PACKET_TYPE);
		packet_dst.setDataTest(data_src, data_size);

		int i_dst;
		float f_dst;
		packet_dst >> i_dst >> f_dst;

		Assert::That(i_dst, Equals(i_src));
		Assert::That(f_dst, Equals(f_src));
	}

	It(can_return_the_packet_byte_size)
	{
		Packet packet(TEST_PACKET_TYPE);
		packet << 10 << 10.0f;
		Assert::That(packet.getDataSize(), Equals(14));

		int i_dst = 0;
		packet >> i_dst;
		Assert::That(packet.getDataSize(), Equals(14));
	}
};<|endoftext|>


<commit_before>/**
 *  For conditions of distribution and use, see copyright notice in license.txt
 *
 *  @file   AssetTreeWidget.cpp
 *  @brief  Tree widget showing all available assets.
 */

#include "StableHeaders.h"
#include "DebugOperatorNew.h"

#include "AssetTreeWidget.h"
#include "AddContentWindow.h"
#include "SupportedFileTypes.h"
#include "RequestNewAssetDialog.h"

#include "AssetAPI.h"
#include "IAsset.h"
#include "AssetCache.h"
#include "QtUtils.h"

#ifdef _WINDOWS
#include <windows.h>
#endif

#include "MemoryLeakCheck.h"

// AssetItem

AssetItem::AssetItem(const AssetPtr &asset, QTreeWidgetItem *parent) :
    QTreeWidgetItem(parent),
    assetPtr(asset)
{
    setText(0, asset->Name());
}

AssetPtr AssetItem::Asset() const
{
    return assetPtr.lock();
}

// AssetTreeWidget

AssetTreeWidget::AssetTreeWidget(Foundation::Framework *fw, QWidget *parent) :
    QTreeWidget(parent),
    framework(fw),
    contextMenu(0)
{
    setSelectionMode(QAbstractItemView::ExtendedSelection);
    setSelectionBehavior(QAbstractItemView::SelectItems);
    setDragDropMode(QAbstractItemView::DropOnly/*DragDrop*/);
    setDropIndicatorShown(true);
}

void AssetTreeWidget::contextMenuEvent(QContextMenuEvent *e)
{
    // Do mousePressEvent so that the right item gets selected before we show the menu
    // (right-click doesn't do this automatically).
    QMouseEvent mouseEvent(QEvent::MouseButtonPress, e->pos(), e->globalPos(),
        Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);

    mousePressEvent(&mouseEvent);

    // Create context menu and show it.
    SAFE_DELETE(contextMenu);
    contextMenu = new QMenu(this);

    AddAvailableActions(contextMenu);

    contextMenu->popup(e->globalPos());
}

void AssetTreeWidget::dragEnterEvent(QDragEnterEvent *e)
{
    const QMimeData *data = e->mimeData();
    if (data->hasUrls())
    {
        foreach(QUrl url, data->urls())
            if (!GetResourceTypeFromResourceFileName(url.path().toStdString().c_str()).isEmpty())
                e->acceptProposedAction();
    }
    else
        QTreeWidget::dropEvent(e);
}

void AssetTreeWidget::dragMoveEvent(QDragMoveEvent *e)
{
    const QMimeData *data = e->mimeData();
    if (data->hasUrls())
    {
        foreach(QUrl url, data->urls())
            if (!GetResourceTypeFromResourceFileName(url.path().toStdString().c_str()).isEmpty())
                e->acceptProposedAction();
    }
    else
        QTreeWidget::dragMoveEvent(e);
}

void AssetTreeWidget::dropEvent(QDropEvent *e)
{
    const QMimeData *data = e->mimeData();
    if (data->hasUrls())
    {
        QStringList filenames;
        foreach(QUrl url, data->urls())
            if (!GetResourceTypeFromResourceFileName(url.path().toStdString().c_str()).isEmpty())
            {
                QString filename = url.path();
#ifdef _WINDOWS
                // We have '/' as the first char on windows and the filename
                // is not identified as a file properly. But on other platforms the '/' is valid/required.
                filename = filename.mid(1);
#endif
                filenames << filename;
            }

        if (!filenames.isEmpty())
        {
            e->acceptProposedAction();
            Upload(filenames);
        }
    }
    else
        QTreeWidget::dropEvent(e);
}

void AssetTreeWidget::AddAvailableActions(QMenu *menu)
{
    QList<AssetItem *> items = GetSelection();
    if (!items.isEmpty())
    {
        QMenu *deleteMenu = new QMenu(tr("Delete"), menu);
        QAction *deleteSourceAction = new QAction(tr("Delete from source"), deleteMenu);
        deleteSourceAction->setDisabled(true);
        QAction *deleteCacheAction = new QAction(tr("Delete from cache"), deleteMenu);
        QAction *forgetAction = new QAction(tr("Forget asset"), deleteMenu);

        deleteMenu->addAction(deleteSourceAction);
        deleteMenu->addAction(deleteCacheAction);
        deleteMenu->addAction(forgetAction);
        menu->addMenu(deleteMenu);

        connect(deleteSourceAction, SIGNAL(triggered()), SLOT(DeleteFromSource()));
        connect(deleteCacheAction, SIGNAL(triggered()), SLOT(DeleteFromCache()));
        connect(forgetAction, SIGNAL(triggered()), SLOT(Forget()));

        QMenu *reloadMenu = new QMenu(tr("Reload"), menu);
        QAction *reloadFromSourceAction = new QAction(tr("Reload from source"), deleteMenu);
        QAction *reloadFromCacheAction = new QAction(tr("Reload from cache"), deleteMenu);
        QAction *unloadAction = new QAction(tr("Unload"), deleteMenu);

        // Reload from cache is not possible if asset's disk source is empty.
        foreach(AssetItem *item, items)
            if (item->Asset() && item->Asset()->DiskSource().trimmed().isEmpty())
            {
                reloadFromCacheAction->setDisabled(true);
                break;
            }

        reloadMenu->addAction(reloadFromSourceAction);
        reloadMenu->addAction(reloadFromCacheAction);
        reloadMenu->addAction(unloadAction);
        menu->addMenu(reloadMenu);

        connect(reloadFromSourceAction, SIGNAL(triggered()), SLOT(ReloadFromSource()));
        connect(reloadFromCacheAction, SIGNAL(triggered()), SLOT(ReloadFromCache()));
        connect(unloadAction, SIGNAL(triggered()), SLOT(Unload()));

        QAction *openFileLocationAction = new QAction(tr("Open file location"), menu);
#ifndef _WINDOWS
        openFileLocationAction->setDisabled(true);
#endif
        menu->addAction(openFileLocationAction);

        connect(openFileLocationAction, SIGNAL(triggered()), SLOT(OpenFileLocation()));

        menu->addSeparator();

        QAction *exportAction = new QAction(tr("Export..."), menu);
        menu->addAction(exportAction);
        connect(exportAction, SIGNAL(triggered()), SLOT(Export()));
    }

    QAction *importAction = new QAction(tr("Import..."), menu);
    connect(importAction, SIGNAL(triggered()), SLOT(Import()));
    menu->addAction(importAction);

    QAction *requestNewAssetAction = new QAction(tr("Request new asset..."), menu);
    connect(requestNewAssetAction, SIGNAL(triggered()), SLOT(RequestNewAsset()));
    menu->addAction(requestNewAssetAction);
}

QList<AssetItem *> AssetTreeWidget::GetSelection() const
{
    QList<AssetItem *> assetItems;
    foreach(QTreeWidgetItem *item, selectedItems())
    {
        // Omit top-level i.e. asset storage items
        AssetItem *aitem = dynamic_cast<AssetItem *>(item);
        if (aitem)
            assetItems << aitem;
    }

    return assetItems;
}

void AssetTreeWidget::DeleteFromSource()
{
/*
    foreach(AssetItem *item, GetSelection())
        framework->Asset()->ForgetAsset(asset, false);
*/
}

void AssetTreeWidget::DeleteFromCache()
{
    foreach(AssetItem *item, GetSelection())
        if (item->Asset())
            framework->Asset()->GetAssetCache()->DeleteAsset(item->Asset()->Name());
}

void AssetTreeWidget::Forget()
{
    foreach(AssetItem *item, GetSelection())
        if (item->Asset())
            framework->Asset()->ForgetAsset(item->Asset(), false);
}

void AssetTreeWidget::Unload()
{
    foreach(AssetItem *item, GetSelection())
        if (item->Asset())
        {
            item->Asset()->Unload();
            QTreeWidgetItem *parent = item->parent();
            parent->removeChild(item);
            SAFE_DELETE(item);
            ///\todo Preferably use the AssetDeleted() or similar signal from AssetAPI for deleting items.
        }
}

void AssetTreeWidget::ReloadFromCache()
{
    foreach(AssetItem *item, GetSelection())
        if (item->Asset())
            item->Asset()->LoadFromCache();
}

void AssetTreeWidget::ReloadFromSource()
{
    foreach(AssetItem *item, GetSelection())
        if (item->Asset())
        {
            QString assetRef = item->Asset()->Name();
            // The next line will delete IAsset from the system, so dereferencing item->Asset() after that would be invalid.
            framework->Asset()->ForgetAsset(item->Asset(), false);
            framework->Asset()->RequestAsset(assetRef);
        }
}

void AssetTreeWidget::Import()
{
    QtUtils::OpenFileDialogNonModal(cAllTypesFileFilter, tr("Import"), "", 0, this, SLOT(OpenFileDialogClosed(int)), true);
}

void AssetTreeWidget::OpenFileDialogClosed(int result)
{
    QFileDialog *dialog = dynamic_cast<QFileDialog *>(sender());
    assert(dialog);
    if (!dialog)
        return;

    if (result != QDialog::Accepted)
        return;

    if (dialog->selectedFiles().isEmpty())
        return;

    Upload(dialog->selectedFiles());
}

void AssetTreeWidget::RequestNewAsset()
{
    RequestNewAssetDialog *dialog = new RequestNewAssetDialog(framework->Asset(), this);
    connect(dialog, SIGNAL(finished(int)), SLOT(RequestNewAssetDialogClosed(int)));
    dialog->show();
}

void AssetTreeWidget::RequestNewAssetDialogClosed(int result)
{
    RequestNewAssetDialog *dialog = qobject_cast<RequestNewAssetDialog*>(sender());
    if (!dialog)
        return;

    if (result != QDialog::Accepted)
        return;

    framework->Asset()->RequestAsset(dialog->Source(), dialog->Type());
}

void AssetTreeWidget::Export()
{
    QList<AssetItem *> sel = GetSelection();
    if (sel.isEmpty())
        return;

    if (sel.size() == 1)
    {
        QString ref = sel.first()->Asset() ? sel.first()->Asset()->Name() : "";
        QString assetName= AssetAPI::ExtractFilenameFromAssetRef(ref);
        QtUtils::SaveFileDialogNonModal("", tr("Save Asset As"), assetName, 0, this, SLOT(SaveAssetDialogClosed(int)));
    }
    else
    {
        QtUtils::DirectoryDialogNonModal(tr("Select Directory"), "", 0, this, SLOT(SaveAssetDialogClosed(int)));
    }
}

void AssetTreeWidget::SaveAssetDialogClosed(int result)
{
    QFileDialog *dialog = dynamic_cast<QFileDialog *>(sender());
    assert(dialog);

    if (!dialog || result != QDialog::Accepted || dialog->selectedFiles().isEmpty())
        return;

    QStringList files = dialog->selectedFiles();

    QList<AssetItem *> sel = GetSelection();

    bool isDir = QDir(files[0]).exists();

    if ((sel.size() == 1 && isDir) || (sel.size() > 1 && !isDir))
    {
        // should not happen normally, so just log error. No prompt for user.
//        LogError("Could not save asset: no such directory.");
        return;
    }

    foreach(AssetItem *item, sel)
        if (item->Asset())
        {
            // if saving multiple assets, append filename to directory
            QString filename = files[0];
            if (isDir)
            {
                QString assetName = AssetAPI::ExtractFilenameFromAssetRef(item->Asset()->Name());
               //while(QFile::exists(filename))
                    //filename.append("_");
                filename += QDir::separator() + assetName;
            }

            QString param;
            if (item->Asset()->Type().contains("texture", Qt::CaseInsensitive))
                param = filename.right(filename.size() - filename.lastIndexOf('.') - 1);

            item->Asset()->SaveToFile(filename, param);
        }
}

void AssetTreeWidget::Upload(const QStringList &files)
{
    AddContentWindow *addContent = new AddContentWindow(framework, framework->GetDefaultWorldScene());
    addContent->AddFiles(files);
    addContent->show();
}

void AssetTreeWidget::OpenFileLocation()
{
    QList<AssetItem *> selection = GetSelection();
    if (selection.isEmpty() || selection.size() < 1)
        return;

    AssetItem *item = selection.first();
    if (item->Asset() && !item->Asset()->DiskSource().isEmpty())
    {
#ifdef _WINDOWS
        // Craft command line string
        QString path = boost::filesystem::path(item->Asset()->DiskSource().toStdString()).branch_path().string().c_str();
        WCHAR commandLineStr[256] = {};
        WCHAR wcharPath[256] = {};
        mbstowcs(wcharPath, QDir::toNativeSeparators(path).toStdString().c_str(), 254);
        wsprintf(commandLineStr, L"explorer.exe %s", wcharPath);

        STARTUPINFO startupInfo;
        memset(&startupInfo, 0, sizeof(STARTUPINFO));
        startupInfo.cb = sizeof(STARTUPINFO);
        PROCESS_INFORMATION processInfo;
        memset(&processInfo, 0, sizeof(PROCESS_INFORMATION));
        /*BOOL success = */CreateProcessW(NULL, commandLineStr, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS,
            NULL, NULL, &startupInfo, &processInfo);

        CloseHandle(processInfo.hProcess);
        CloseHandle(processInfo.hThread);
#endif
    }
}
<commit_msg>Assets window: "Delete from source" action<commit_after>/**
 *  For conditions of distribution and use, see copyright notice in license.txt
 *
 *  @file   AssetTreeWidget.cpp
 *  @brief  Tree widget showing all available assets.
 */

#include "StableHeaders.h"
#include "DebugOperatorNew.h"

#include "AssetTreeWidget.h"
#include "AddContentWindow.h"
#include "SupportedFileTypes.h"
#include "RequestNewAssetDialog.h"

#include "AssetAPI.h"
#include "IAsset.h"
#include "AssetCache.h"
#include "QtUtils.h"

#ifdef _WINDOWS
#include <windows.h>
#endif

#include "MemoryLeakCheck.h"

// AssetItem

AssetItem::AssetItem(const AssetPtr &asset, QTreeWidgetItem *parent) :
    QTreeWidgetItem(parent),
    assetPtr(asset)
{
    setText(0, asset->Name());
}

AssetPtr AssetItem::Asset() const
{
    return assetPtr.lock();
}

// AssetTreeWidget

AssetTreeWidget::AssetTreeWidget(Foundation::Framework *fw, QWidget *parent) :
    QTreeWidget(parent),
    framework(fw),
    contextMenu(0)
{
    setSelectionMode(QAbstractItemView::ExtendedSelection);
    setSelectionBehavior(QAbstractItemView::SelectItems);
    setDragDropMode(QAbstractItemView::DropOnly/*DragDrop*/);
    setDropIndicatorShown(true);
}

void AssetTreeWidget::contextMenuEvent(QContextMenuEvent *e)
{
    // Do mousePressEvent so that the right item gets selected before we show the menu
    // (right-click doesn't do this automatically).
    QMouseEvent mouseEvent(QEvent::MouseButtonPress, e->pos(), e->globalPos(),
        Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);

    mousePressEvent(&mouseEvent);

    // Create context menu and show it.
    SAFE_DELETE(contextMenu);
    contextMenu = new QMenu(this);

    AddAvailableActions(contextMenu);

    contextMenu->popup(e->globalPos());
}

void AssetTreeWidget::dragEnterEvent(QDragEnterEvent *e)
{
    const QMimeData *data = e->mimeData();
    if (data->hasUrls())
    {
        foreach(QUrl url, data->urls())
            if (!GetResourceTypeFromResourceFileName(url.path().toStdString().c_str()).isEmpty())
                e->acceptProposedAction();
    }
    else
        QTreeWidget::dropEvent(e);
}

void AssetTreeWidget::dragMoveEvent(QDragMoveEvent *e)
{
    const QMimeData *data = e->mimeData();
    if (data->hasUrls())
    {
        foreach(QUrl url, data->urls())
            if (!GetResourceTypeFromResourceFileName(url.path().toStdString().c_str()).isEmpty())
                e->acceptProposedAction();
    }
    else
        QTreeWidget::dragMoveEvent(e);
}

void AssetTreeWidget::dropEvent(QDropEvent *e)
{
    const QMimeData *data = e->mimeData();
    if (data->hasUrls())
    {
        QStringList filenames;
        foreach(QUrl url, data->urls())
            if (!GetResourceTypeFromResourceFileName(url.path().toStdString().c_str()).isEmpty())
            {
                QString filename = url.path();
#ifdef _WINDOWS
                // We have '/' as the first char on windows and the filename
                // is not identified as a file properly. But on other platforms the '/' is valid/required.
                filename = filename.mid(1);
#endif
                filenames << filename;
            }

        if (!filenames.isEmpty())
        {
            e->acceptProposedAction();
            Upload(filenames);
        }
    }
    else
        QTreeWidget::dropEvent(e);
}

void AssetTreeWidget::AddAvailableActions(QMenu *menu)
{
    QList<AssetItem *> items = GetSelection();
    if (!items.isEmpty())
    {
        QMenu *deleteMenu = new QMenu(tr("Delete"), menu);
        QAction *deleteSourceAction = new QAction(tr("Delete from source"), deleteMenu);
        QAction *deleteCacheAction = new QAction(tr("Delete from cache"), deleteMenu);
        QAction *forgetAction = new QAction(tr("Forget asset"), deleteMenu);

        deleteMenu->addAction(deleteSourceAction);
        deleteMenu->addAction(deleteCacheAction);
        deleteMenu->addAction(forgetAction);
        menu->addMenu(deleteMenu);

        connect(deleteSourceAction, SIGNAL(triggered()), SLOT(DeleteFromSource()));
        connect(deleteCacheAction, SIGNAL(triggered()), SLOT(DeleteFromCache()));
        connect(forgetAction, SIGNAL(triggered()), SLOT(Forget()));

        QMenu *reloadMenu = new QMenu(tr("Reload"), menu);
        QAction *reloadFromSourceAction = new QAction(tr("Reload from source"), deleteMenu);
        QAction *reloadFromCacheAction = new QAction(tr("Reload from cache"), deleteMenu);
        QAction *unloadAction = new QAction(tr("Unload"), deleteMenu);

        // Reload from cache is not possible if asset's disk source is empty.
        foreach(AssetItem *item, items)
            if (item->Asset() && item->Asset()->DiskSource().trimmed().isEmpty())
            {
                reloadFromCacheAction->setDisabled(true);
                break;
            }

        reloadMenu->addAction(reloadFromSourceAction);
        reloadMenu->addAction(reloadFromCacheAction);
        reloadMenu->addAction(unloadAction);
        menu->addMenu(reloadMenu);

        connect(reloadFromSourceAction, SIGNAL(triggered()), SLOT(ReloadFromSource()));
        connect(reloadFromCacheAction, SIGNAL(triggered()), SLOT(ReloadFromCache()));
        connect(unloadAction, SIGNAL(triggered()), SLOT(Unload()));

        QAction *openFileLocationAction = new QAction(tr("Open file location"), menu);
#ifndef _WINDOWS
        openFileLocationAction->setDisabled(true);
#endif
        menu->addAction(openFileLocationAction);

        connect(openFileLocationAction, SIGNAL(triggered()), SLOT(OpenFileLocation()));

        menu->addSeparator();

        QAction *exportAction = new QAction(tr("Export..."), menu);
        menu->addAction(exportAction);
        connect(exportAction, SIGNAL(triggered()), SLOT(Export()));
    }

    QAction *importAction = new QAction(tr("Import..."), menu);
    connect(importAction, SIGNAL(triggered()), SLOT(Import()));
    menu->addAction(importAction);

    QAction *requestNewAssetAction = new QAction(tr("Request new asset..."), menu);
    connect(requestNewAssetAction, SIGNAL(triggered()), SLOT(RequestNewAsset()));
    menu->addAction(requestNewAssetAction);
}

QList<AssetItem *> AssetTreeWidget::GetSelection() const
{
    QList<AssetItem *> assetItems;
    foreach(QTreeWidgetItem *item, selectedItems())
    {
        // Omit top-level i.e. asset storage items
        AssetItem *aitem = dynamic_cast<AssetItem *>(item);
        if (aitem)
            assetItems << aitem;
    }

    return assetItems;
}

void AssetTreeWidget::DeleteFromSource()
{
    int ret = QMessageBox::warning(
        this,
        tr("Delete From Source"),
        tr("Are you sure want to delete the selected asset(s) permanently from the source?"),
        QMessageBox::Ok | QMessageBox::Cancel,
        QMessageBox::Cancel);

    if (ret == QMessageBox::Ok)
    {
        // AssetAPI::DeleteAssetFromStorage() signals will start deletion of tree widget asset items:
        // Gather the asset refs to a separate list beforehand in order to prevent crash.
        QStringList assetRefs;
        foreach(AssetItem *item, GetSelection())
            if (item->Asset())
                assetRefs << item->Asset()->Name();

        foreach(QString ref, assetRefs)
            framework->Asset()->DeleteAssetFromStorage(ref);
    }
}

void AssetTreeWidget::DeleteFromCache()
{
    foreach(AssetItem *item, GetSelection())
        if (item->Asset())
            framework->Asset()->GetAssetCache()->DeleteAsset(item->Asset()->Name());
}

void AssetTreeWidget::Forget()
{
    foreach(AssetItem *item, GetSelection())
        if (item->Asset())
            framework->Asset()->ForgetAsset(item->Asset(), false);
}

void AssetTreeWidget::Unload()
{
    foreach(AssetItem *item, GetSelection())
        if (item->Asset())
        {
            item->Asset()->Unload();
            QTreeWidgetItem *parent = item->parent();
            parent->removeChild(item);
            SAFE_DELETE(item);
            ///\todo Preferably use the AssetDeleted() or similar signal from AssetAPI for deleting items.
        }
}

void AssetTreeWidget::ReloadFromCache()
{
    foreach(AssetItem *item, GetSelection())
        if (item->Asset())
            item->Asset()->LoadFromCache();
}

void AssetTreeWidget::ReloadFromSource()
{
    foreach(AssetItem *item, GetSelection())
        if (item->Asset())
        {
            QString assetRef = item->Asset()->Name();
            // The next line will delete IAsset from the system, so dereferencing item->Asset() after that would be invalid.
            framework->Asset()->ForgetAsset(item->Asset(), false);
            framework->Asset()->RequestAsset(assetRef);
        }
}

void AssetTreeWidget::Import()
{
    QtUtils::OpenFileDialogNonModal(cAllTypesFileFilter, tr("Import"), "", 0, this, SLOT(OpenFileDialogClosed(int)), true);
}

void AssetTreeWidget::OpenFileDialogClosed(int result)
{
    QFileDialog *dialog = dynamic_cast<QFileDialog *>(sender());
    assert(dialog);
    if (!dialog)
        return;

    if (result != QDialog::Accepted)
        return;

    if (dialog->selectedFiles().isEmpty())
        return;

    Upload(dialog->selectedFiles());
}

void AssetTreeWidget::RequestNewAsset()
{
    RequestNewAssetDialog *dialog = new RequestNewAssetDialog(framework->Asset(), this);
    connect(dialog, SIGNAL(finished(int)), SLOT(RequestNewAssetDialogClosed(int)));
    dialog->show();
}

void AssetTreeWidget::RequestNewAssetDialogClosed(int result)
{
    RequestNewAssetDialog *dialog = qobject_cast<RequestNewAssetDialog*>(sender());
    if (!dialog)
        return;

    if (result != QDialog::Accepted)
        return;

    framework->Asset()->RequestAsset(dialog->Source(), dialog->Type());
}

void AssetTreeWidget::Export()
{
    QList<AssetItem *> sel = GetSelection();
    if (sel.isEmpty())
        return;

    if (sel.size() == 1)
    {
        QString ref = sel.first()->Asset() ? sel.first()->Asset()->Name() : "";
        QString assetName= AssetAPI::ExtractFilenameFromAssetRef(ref);
        QtUtils::SaveFileDialogNonModal("", tr("Save Asset As"), assetName, 0, this, SLOT(SaveAssetDialogClosed(int)));
    }
    else
    {
        QtUtils::DirectoryDialogNonModal(tr("Select Directory"), "", 0, this, SLOT(SaveAssetDialogClosed(int)));
    }
}

void AssetTreeWidget::SaveAssetDialogClosed(int result)
{
    QFileDialog *dialog = dynamic_cast<QFileDialog *>(sender());
    assert(dialog);

    if (!dialog || result != QDialog::Accepted || dialog->selectedFiles().isEmpty())
        return;

    QStringList files = dialog->selectedFiles();

    QList<AssetItem *> sel = GetSelection();

    bool isDir = QDir(files[0]).exists();

    if ((sel.size() == 1 && isDir) || (sel.size() > 1 && !isDir))
    {
        // should not happen normally, so just log error. No prompt for user.
//        LogError("Could not save asset: no such directory.");
        return;
    }

    foreach(AssetItem *item, sel)
        if (item->Asset())
        {
            // if saving multiple assets, append filename to directory
            QString filename = files[0];
            if (isDir)
            {
                QString assetName = AssetAPI::ExtractFilenameFromAssetRef(item->Asset()->Name());
               //while(QFile::exists(filename))
                    //filename.append("_");
                filename += QDir::separator() + assetName;
            }

            QString param;
            if (item->Asset()->Type().contains("texture", Qt::CaseInsensitive))
                param = filename.right(filename.size() - filename.lastIndexOf('.') - 1);

            item->Asset()->SaveToFile(filename, param);
        }
}

void AssetTreeWidget::Upload(const QStringList &files)
{
    AddContentWindow *addContent = new AddContentWindow(framework, framework->GetDefaultWorldScene());
    addContent->AddFiles(files);
    addContent->show();
}

void AssetTreeWidget::OpenFileLocation()
{
    QList<AssetItem *> selection = GetSelection();
    if (selection.isEmpty() || selection.size() < 1)
        return;

    AssetItem *item = selection.first();
    if (item->Asset() && !item->Asset()->DiskSource().isEmpty())
    {
#ifdef _WINDOWS
        // Craft command line string
        QString path = boost::filesystem::path(item->Asset()->DiskSource().toStdString()).branch_path().string().c_str();
        WCHAR commandLineStr[256] = {};
        WCHAR wcharPath[256] = {};
        mbstowcs(wcharPath, QDir::toNativeSeparators(path).toStdString().c_str(), 254);
        wsprintf(commandLineStr, L"explorer.exe %s", wcharPath);

        STARTUPINFO startupInfo;
        memset(&startupInfo, 0, sizeof(STARTUPINFO));
        startupInfo.cb = sizeof(STARTUPINFO);
        PROCESS_INFORMATION processInfo;
        memset(&processInfo, 0, sizeof(PROCESS_INFORMATION));
        /*BOOL success = */CreateProcessW(NULL, commandLineStr, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS,
            NULL, NULL, &startupInfo, &processInfo);

        CloseHandle(processInfo.hProcess);
        CloseHandle(processInfo.hThread);
#endif
    }
}
<|endoftext|>


<commit_before>//-----------------------------------------------------------------------bl-
//--------------------------------------------------------------------------
//
// Antioch - A Gas Dynamics Thermochemistry Library
//
// Copyright (C) 2013 The PECOS Development Team
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the Version 2.1 GNU Lesser General
// Public License as published by the Free Software Foundation.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc. 51 Franklin Street, Fifth Floor,
// Boston, MA  02110-1301  USA
//
//-----------------------------------------------------------------------el-
//
// $Id$
//
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------

#include "antioch_config.h"

#include <valarray>

#ifdef ANTIOCH_HAVE_EIGEN
#include "Eigen/Dense"
#endif

#ifdef ANTIOCH_HAVE_METAPHYSICL
#include "metaphysicl/numberarray.h"
#endif

// C++
#include <limits>
#include <string>
#include <vector>

// This needs to precede any headers that might use their overloads
#include "antioch/eigen_utils.h"
#include "antioch/metaphysicl_utils.h"
#include "antioch/valarray_utils.h"
#include "antioch/vector_utils.h"

// Antioch
#include "antioch/antioch_asserts.h"
#include "antioch/chemical_species.h"
#include "antioch/chemical_mixture.h"
#include "antioch/reaction_set.h"
#include "antioch/read_reaction_set_data_xml.h"
#include "antioch/cea_thermo.h"
#include "antioch/kinetics_evaluator.h"

template <typename Scalar, typename PairScalars>
int vectester(const std::string& input_name, const PairScalars& example)
{
  std::vector<std::string> species_str_list;
  const unsigned int n_species = 5;
  species_str_list.reserve(n_species);
  species_str_list.push_back( "N2" );
  species_str_list.push_back( "O2" );
  species_str_list.push_back( "N" );
  species_str_list.push_back( "O" );
  species_str_list.push_back( "NO" );

  Antioch::ChemicalMixture<Scalar> chem_mixture( species_str_list );
  Antioch::ReactionSet<Scalar> reaction_set( chem_mixture );
  Antioch::CEAThermodynamics<Scalar> thermo( chem_mixture );

  Antioch::read_reaction_set_data_xml<Scalar>( input_name, true, reaction_set );

  PairScalars T = example;
  T[0] = 1500.0;
  T[1] = 1500.0;
  PairScalars P = example;
  P[0] = 1.0e5;
  P[1] = 1.0e5;

  // Mass fractions
  PairScalars massfrac = example;
  massfrac[0] = 0.2;
  massfrac[1] = 0.2;
  std::vector<PairScalars> Y(n_species,massfrac);

  const PairScalars R_mix = chem_mixture.R(Y);

  const PairScalars rho = P/(R_mix*T);

  std::vector<PairScalars> molar_densities(n_species, example);
  chem_mixture.molar_densities(rho,Y,molar_densities);

  std::vector<PairScalars> h_RT_minus_s_R(n_species, example);
  typedef typename Antioch::CEAThermodynamics<Scalar>::
    template Cache<PairScalars> Cache;
  thermo.h_RT_minus_s_R(Cache(T),h_RT_minus_s_R);

  Antioch::KineticsEvaluator<Scalar> kinetics( reaction_set );
  std::vector<PairScalars> omega_dot(n_species, example);

  kinetics.compute_mass_sources( T, rho, R_mix, Y, molar_densities, h_RT_minus_s_R, omega_dot );

  for( unsigned int s = 0; s < n_species; s++)
    {
      std::cout << std::scientific << std::setprecision(16)
		<< "omega_dot(" << chem_mixture.chemical_species()[s]->species() << ") = "
		<< omega_dot[s] << std::endl;
    }

  int return_flag = 0;

  std::vector<PairScalars> omega_dot_reg(n_species,example);
  omega_dot_reg[0][0] =  7.9004530802650654e+04;
  omega_dot_reg[1][0] = -3.4113853617637843e+05;
  omega_dot_reg[2][0] = -1.8898881857838202e+05;
  omega_dot_reg[3][0] =  2.1551399274321867e+05;
  omega_dot_reg[4][0] =  2.3560883120889112e+05;
  omega_dot_reg[0][1] = omega_dot_reg[0][0];
  omega_dot_reg[1][1] = omega_dot_reg[1][0];
  omega_dot_reg[2][1] = omega_dot_reg[2][0];
  omega_dot_reg[3][1] = omega_dot_reg[3][0];
  omega_dot_reg[4][1] = omega_dot_reg[4][0];

  const Scalar tol = std::numeric_limits<Scalar>::epsilon() * 100;
  for( unsigned int s = 0; s < n_species; s++)
    {
      // Break this expression up to workaround bugs in my Eigen
      // version - RHS
      const PairScalars rel_error =
        (omega_dot[s] - omega_dot_reg[s])/omega_dot_reg[s];
      const PairScalars abs_rel_error = std::abs(rel_error);

      if( Antioch::max(abs_rel_error) > tol )
	{
	  return_flag = 1;
	}
    }

  if( return_flag == 1 )
    {
      std::cerr << "Error: Mismatch between compute mass source terms and regression values." << std::endl;
      for( unsigned int s = 0; s < n_species; s++)
	{
	  std::cout << std::scientific << std::setprecision(16)
		    << "omega_dot(" << chem_mixture.chemical_species()[s]->species() << ") = " << omega_dot[s]
		    << ", omega_dot_reg(" << chem_mixture.chemical_species()[s]->species() << ") = " << omega_dot_reg[s]
		    << std::endl;
	}
    }

  return return_flag;
}

int main(int argc, char* argv[])
{
  // Check command line count.
  if( argc < 2 )
    {
      // TODO: Need more consistent error handling.
      std::cerr << "Error: Must specify reaction set XML input file." << std::endl;
      antioch_error();
    }

  int returnval = 0;

  returnval = returnval ||
    vectester<float, std::valarray<float> >
      (argv[1], std::valarray<float>(2));
  returnval = returnval ||
    vectester<double, std::valarray<double> >
      (argv[1], std::valarray<double>(2));
// We're not getting the full long double precision yet?
//  returnval = returnval ||
//    vectester<long double, std::valarray<long double> >
//      (argv[1], std::valarray<long double>(2));
#ifdef ANTIOCH_HAVE_EIGEN
  returnval = returnval ||
    vectester<float, Eigen::Array2f>
      (argv[1], Eigen::Array2f());
  returnval = returnval ||
    vectester<double, Eigen::Array2d>
      (argv[1], Eigen::Array2d());
// We're not getting the full long double precision yet?
//  returnval = returnval ||
//    vectester<long double, Eigen::Array<long double, 2, 1> >
//      (argv[1], Eigen::Array<long double, 2, 1>());
#endif
#ifdef ANTIOCH_HAVE_METAPHYSICL
  returnval = returnval ||
    vectester<float, MetaPhysicL::NumberArray<2, float> > (argv[1], 0);
  returnval = returnval ||
    vectester<double, MetaPhysicL::NumberArray<2, double> > (argv[1], 0);
//  returnval = returnval ||
//    vectester<long double, MetaPhysicL::NumberArray<2, long double> > (argv[1], 0);
#endif

  return returnval;
}
<commit_msg>Refactoring; beginning tests with Eigen::Arrays of StateTypes.<commit_after>//-----------------------------------------------------------------------bl-
//--------------------------------------------------------------------------
//
// Antioch - A Gas Dynamics Thermochemistry Library
//
// Copyright (C) 2013 The PECOS Development Team
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the Version 2.1 GNU Lesser General
// Public License as published by the Free Software Foundation.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc. 51 Franklin Street, Fifth Floor,
// Boston, MA  02110-1301  USA
//
//-----------------------------------------------------------------------el-
//
// $Id$
//
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------

#include "antioch_config.h"

#include <valarray>

#ifdef ANTIOCH_HAVE_EIGEN
#include "Eigen/Dense"
#endif

#ifdef ANTIOCH_HAVE_METAPHYSICL
#include "metaphysicl/numberarray.h"
#endif

// C++
#include <limits>
#include <string>
#include <vector>

// This needs to precede any headers that might use their overloads
#include "antioch/eigen_utils.h"
#include "antioch/metaphysicl_utils.h"
#include "antioch/valarray_utils.h"

// We don't use std::vector as a numeric vector, but we still need
// vector_utils to use it as a container in our container-templated
// functions
#include "antioch/vector_utils.h"

// Antioch
#include "antioch/antioch_asserts.h"
#include "antioch/chemical_species.h"
#include "antioch/chemical_mixture.h"
#include "antioch/reaction_set.h"
#include "antioch/read_reaction_set_data_xml.h"
#include "antioch/cea_thermo.h"
#include "antioch/kinetics_evaluator.h"

static const unsigned int n_species = 5;

template <typename SpeciesVector1, typename SpeciesVector2>
int species_vec_compare (const SpeciesVector1 &a, const SpeciesVector2 &b, const std::string &name)
{
  int found_errors = 0;

  typedef typename Antioch::value_type<SpeciesVector1>::type StateType;
  typedef typename Antioch::value_type<StateType>::type Scalar;

  for (unsigned int s=0; s != n_species; s++)
    {
      using std::abs;
      using std::max;

      const Scalar tol = std::numeric_limits<Scalar>::epsilon() * 100;

      // Break this expression up to workaround bugs in my Eigen
      // version - RHS
      const StateType rel_error = (a[s] - b[s])/max(a[s],b[s]);
      const StateType abs_rel_error = abs(rel_error);

      if( Antioch::max(abs_rel_error) > tol )
	{
	  found_errors++;
	}
    }

  if (found_errors)
    {
      std::cerr << "Error: Mismatch in vectors " << name << std::endl;
      for( unsigned int s = 0; s < n_species; s++)
	{
	  std::cout << std::scientific << std::setprecision(16)
		    << "a(" << s << ") = " << a[s]
		    << ", b(" << s << ") = " << b[s]
		    << ", a-b(" << s << ") = " << StateType(a[s]-b[s])
		    << std::endl;
	}
    }

  return found_errors;
}

template <typename Scalar, typename PairScalars>
int vectester(const std::string& input_name, const PairScalars& example)
{
  std::vector<std::string> species_str_list;
  species_str_list.reserve(n_species);
  species_str_list.push_back( "N2" );
  species_str_list.push_back( "O2" );
  species_str_list.push_back( "N" );
  species_str_list.push_back( "O" );
  species_str_list.push_back( "NO" );

  Antioch::ChemicalMixture<Scalar> chem_mixture( species_str_list );
  Antioch::ReactionSet<Scalar> reaction_set( chem_mixture );
  Antioch::CEAThermodynamics<Scalar> thermo( chem_mixture );

  Antioch::read_reaction_set_data_xml<Scalar>( input_name, true, reaction_set );

  PairScalars T = example;
  T[0] = 1500.0;
  T[1] = 1500.0;
  PairScalars P = example;
  P[0] = 1.0e5;
  P[1] = 1.0e5;

  // Mass fractions
  PairScalars massfrac = example;
  massfrac[0] = 0.2;
  massfrac[1] = 0.2;
  const std::vector<PairScalars> Y(n_species,massfrac);

  const PairScalars R_mix = chem_mixture.R(Y);

  const PairScalars rho = P/(R_mix*T);

  std::vector<PairScalars> molar_densities(n_species, example);
  chem_mixture.molar_densities(rho,Y,molar_densities);

  std::vector<PairScalars> h_RT_minus_s_R(n_species, example);
  typedef typename Antioch::CEAThermodynamics<Scalar>::
    template Cache<PairScalars> Cache;
  thermo.h_RT_minus_s_R(Cache(T),h_RT_minus_s_R);

  Antioch::KineticsEvaluator<Scalar> kinetics( reaction_set );
  std::vector<PairScalars> omega_dot(n_species, example);

  kinetics.compute_mass_sources( T, rho, R_mix, Y, molar_densities, h_RT_minus_s_R, omega_dot );

  int return_flag = 0;

#ifdef ANTIOCH_HAVE_EIGEN
  typedef Eigen::Array<PairScalars,n_species,1> SpeciesVecEigenType;
  SpeciesVecEigenType eigen_Y = SpeciesVecEigenType::Constant(massfrac);

  const PairScalars eigen_R = chem_mixture.R(eigen_Y);

  return_flag +=
    species_vec_compare(eigen_R,R_mix,"eigen_R");

  SpeciesVecEigenType eigen_molar_densities;

  chem_mixture.molar_densities(rho,eigen_Y,eigen_molar_densities);

  return_flag +=
    species_vec_compare(eigen_molar_densities, molar_densities,
                        "eigen_molar_densities");

  SpeciesVecEigenType eigen_h_RT_minus_s_R;

  thermo.h_RT_minus_s_R(Cache(T),eigen_h_RT_minus_s_R);

  return_flag +=
    species_vec_compare(eigen_h_RT_minus_s_R, h_RT_minus_s_R,
                        "eigen_h_RT_minus_s_R");
#endif // ANTIOCH_HAVE_EIGEN

  for( unsigned int s = 0; s < n_species; s++)
    {
      std::cout << std::scientific << std::setprecision(16)
		<< "omega_dot(" << chem_mixture.chemical_species()[s]->species() << ") = "
		<< omega_dot[s] << std::endl;
    }

  std::vector<PairScalars> omega_dot_reg(n_species,example);
  omega_dot_reg[0][0] =  7.9004530802650654e+04;
  omega_dot_reg[1][0] = -3.4113853617637843e+05;
  omega_dot_reg[2][0] = -1.8898881857838202e+05;
  omega_dot_reg[3][0] =  2.1551399274321867e+05;
  omega_dot_reg[4][0] =  2.3560883120889112e+05;
  omega_dot_reg[0][1] = omega_dot_reg[0][0];
  omega_dot_reg[1][1] = omega_dot_reg[1][0];
  omega_dot_reg[2][1] = omega_dot_reg[2][0];
  omega_dot_reg[3][1] = omega_dot_reg[3][0];
  omega_dot_reg[4][1] = omega_dot_reg[4][0];

  return_flag +=
    species_vec_compare(omega_dot, omega_dot_reg, "omega_dot");

  return return_flag;
}

int main(int argc, char* argv[])
{
  // Check command line count.
  if( argc < 2 )
    {
      // TODO: Need more consistent error handling.
      std::cerr << "Error: Must specify reaction set XML input file." << std::endl;
      antioch_error();
    }

  int returnval = 0;

  returnval +=
    vectester<float, std::valarray<float> >
      (argv[1], std::valarray<float>(2));
  returnval +=
    vectester<double, std::valarray<double> >
      (argv[1], std::valarray<double>(2));
// We're not getting the full long double precision yet?
//  returnval = returnval ||
//    vectester<long double, std::valarray<long double> >
//      (argv[1], std::valarray<long double>(2));
#ifdef ANTIOCH_HAVE_EIGEN
  returnval +=
    vectester<float, Eigen::Array2f>
      (argv[1], Eigen::Array2f());
  returnval +=
    vectester<double, Eigen::Array2d>
      (argv[1], Eigen::Array2d());
// We're not getting the full long double precision yet?
//  returnval = returnval ||
//    vectester<long double, Eigen::Array<long double, 2, 1> >
//      (argv[1], Eigen::Array<long double, 2, 1>());
#endif
#ifdef ANTIOCH_HAVE_METAPHYSICL
  returnval +=
    vectester<float, MetaPhysicL::NumberArray<2, float> > (argv[1], 0);
  returnval +=
    vectester<double, MetaPhysicL::NumberArray<2, double> > (argv[1], 0);
//  returnval = returnval ||
//    vectester<long double, MetaPhysicL::NumberArray<2, long double> > (argv[1], 0);
#endif

  std::cout << "Found " << returnval << " errors" << std::endl;

  return (returnval != 0) ? 1 : 0;
}
<|endoftext|>


<commit_before><commit_msg>Fixed timer duplication issue<commit_after><|endoftext|>


<commit_before>#include "memory_manager_base.h"
#include "pr_l1_pr_l2_dram_directory_msi/memory_manager.h"
#include "pr_l1_pr_l2_dram_directory_mosi/memory_manager.h"
#include "log.h"

MemoryManagerBase*
MemoryManagerBase::createMMU(std::string protocol_type,
      Core* core, Network* network, ShmemPerfModel* shmem_perf_model)
{
   CachingProtocol_t caching_protocol = parseProtocolType(protocol_type);

   switch (caching_protocol)
   {
      case PR_L1_PR_L2_DRAM_DIRECTORY_MSI:
         return new PrL1PrL2DramDirectoryMSI::MemoryManager(core, network, shmem_perf_model);

      case PR_L1_PR_L2_DRAM_DIRECTORY_MOSI:
         return new PrL1PrL2DramDirectoryMOSI::MemoryManager(core, network, shmem_perf_model);

      default:
         LOG_PRINT_ERROR("Unsupported Caching Protocol (%u)", caching_protocol);
         return NULL;
   }
}

MemoryManagerBase::CachingProtocol_t
MemoryManagerBase::parseProtocolType(std::string& protocol_type)
{
   if (protocol_type == "pr_l2_pr_l2_dram_directory_msi")
      return PR_L1_PR_L2_DRAM_DIRECTORY_MSI;
   else if (protocol_type == "pr_l1_pr_l2_dram_directory_mosi")
      return PR_L1_PR_L2_DRAM_DIRECTORY_MOSI;
   else
      return NUM_CACHING_PROTOCOL_TYPES;
}

void MemoryManagerNetworkCallback(void* obj, NetPacket packet)
{
   MemoryManagerBase *mm = (MemoryManagerBase*) obj;
   assert(mm != NULL);

   switch (packet.type)
   {
      case SHARED_MEM_1:
      case SHARED_MEM_2:
         mm->handleMsgFromNetwork(packet);
         break;

      default:
         LOG_PRINT_ERROR("Got unrecognized packet type(%u)", packet.type);
         break;
   }
}
<commit_msg>[misc] Minor bug<commit_after>#include "memory_manager_base.h"
#include "pr_l1_pr_l2_dram_directory_msi/memory_manager.h"
#include "pr_l1_pr_l2_dram_directory_mosi/memory_manager.h"
#include "log.h"

MemoryManagerBase*
MemoryManagerBase::createMMU(std::string protocol_type,
      Core* core, Network* network, ShmemPerfModel* shmem_perf_model)
{
   CachingProtocol_t caching_protocol = parseProtocolType(protocol_type);

   switch (caching_protocol)
   {
      case PR_L1_PR_L2_DRAM_DIRECTORY_MSI:
         return new PrL1PrL2DramDirectoryMSI::MemoryManager(core, network, shmem_perf_model);

      case PR_L1_PR_L2_DRAM_DIRECTORY_MOSI:
         return new PrL1PrL2DramDirectoryMOSI::MemoryManager(core, network, shmem_perf_model);

      default:
         LOG_PRINT_ERROR("Unsupported Caching Protocol (%u)", caching_protocol);
         return NULL;
   }
}

MemoryManagerBase::CachingProtocol_t
MemoryManagerBase::parseProtocolType(std::string& protocol_type)
{
   if (protocol_type == "pr_l1_pr_l2_dram_directory_msi")
      return PR_L1_PR_L2_DRAM_DIRECTORY_MSI;
   else if (protocol_type == "pr_l1_pr_l2_dram_directory_mosi")
      return PR_L1_PR_L2_DRAM_DIRECTORY_MOSI;
   else
      return NUM_CACHING_PROTOCOL_TYPES;
}

void MemoryManagerNetworkCallback(void* obj, NetPacket packet)
{
   MemoryManagerBase *mm = (MemoryManagerBase*) obj;
   assert(mm != NULL);

   switch (packet.type)
   {
      case SHARED_MEM_1:
      case SHARED_MEM_2:
         mm->handleMsgFromNetwork(packet);
         break;

      default:
         LOG_PRINT_ERROR("Got unrecognized packet type(%u)", packet.type);
         break;
   }
}
<|endoftext|>