<commit_before>// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//
// $Id: pyWidget.C,v 1.13 2003/11/12 12:31:49 amoll Exp $
//

// This include has to be first in order to avoid collisions.
#include <Python.h>

#include <BALL/VIEW/WIDGETS/pyWidget.h>
#include <BALL/VIEW/KERNEL/mainControl.h>
#include <BALL/VIEW/DIALOGS/pythonSettings.h>
#include <BALL/PYTHON/pyInterpreter.h>
#include <BALL/VIEW/DIALOGS/preferences.h>
#include <BALL/FORMAT/lineBasedFile.h>

#include <qscrollbar.h>
#include <qfiledialog.h>

namespace BALL
{
	namespace VIEW
	{

		PyWidgetData::PyWidgetData(QWidget* parent, const char* name)
			: QTextEdit(parent, name)
		{
			setWrapPolicy(QTextEdit::Anywhere);
		}

		PyWidgetData::PyWidgetData(const PyWidgetData& /*widget*/)
			:	QTextEdit()
		{
		}

		PyWidgetData::~PyWidgetData()
			throw()
		{
		}

		void PyWidgetData::stopInterpreter()
		{
			PyInterpreter::finalize();
		}

		void PyWidgetData::startInterpreter()
		{
			// initialize the interpreter
			PyInterpreter::initialize();

			// print the PyBALL version and clear
			// the widget's contents in case of a restart
			setText((String("BALL ") + VersionInfo::getVersion()).c_str());

			// print the first prompt
			multi_line_mode_ = false;
			newPrompt_();
			history_position_ = history_.size() + 1;
		}

		void PyWidgetData::retrieveHistoryLine_(Position index)
		{
			if (index > history_.size())
			{
				history_position_ = history_.size();
				return;
			}

			int row, col;
			getCursorPosition(&row, &col);

			if (index == history_.size())
			{
				history_position_ = history_.size();
				removeParagraph(row);
				insertParagraph(getPrompt_(), row);
				setCursorPosition(row, col);
				QScrollBar* sb = verticalScrollBar();
				if (sb != 0)
				{
					sb->setValue(sb->maxValue());
				}
				removeParagraph(row +1);
				return;
			}

			String line = getPrompt_()+ history_[index];

			// replace the line's contents
			removeParagraph(row);
			insertParagraph(line.c_str(), row);
			setCursorPosition(row, line.size());
			QScrollBar* sb = verticalScrollBar();
			if (sb != 0)
			{
				sb->setValue(sb->maxValue());
			}

			// update the history position
			history_position_ = index;
			removeParagraph(row +1);
		}

		void PyWidgetData::contentsMousePressEvent(QMouseEvent* /* m */)
		{
			setCursorPosition(lines() - 1, 4);
			// we ignore the mouse events!
			// they might place the cursor anywhere!
		}

		void PyWidgetData::mousePressEvent(QMouseEvent* /* m */)
		{
			setCursorPosition(lines() - 1, 4);
			// we ignore the mouse events!
			// they might place the cursor anywhere!
		}

		bool PyWidgetData::returnPressed()
		{
			// check for an empty line (respect the prompt)
			int row, col;
			getCursorPosition(&row, &col);
			current_line_ = getCurrentLine_();
			if (col < 5)
			{
				if (multi_line_mode_)
				{
					// in multi line mode: end of input - parse it!
					QTextEdit::returnPressed();
					parseLine_();
				}
				else
				{
					// return on an empty line is handled
					// as in the interactive interpreter: do nothing and
					// print another prompt
					QTextEdit::returnPressed();
					newPrompt_();
				}
			}
			else
			{
				// parse the line
				QTextEdit::returnPressed();
				parseLine_();
			}

			return false;
		}

		void PyWidgetData::parseLine_()
		{
			if (!Py_IsInitialized())
			{
				append("ERROR: no interpreter running!\n");
				return;
			}

			history_position_ = history_.size();

			String line = current_line_.getSubstring(4);
			line.trimRight();

			if (!multi_line_mode_)
			{
				if (line.isEmpty()) return;
				if ((line.hasPrefix("for ") 		||
						 line.hasPrefix("def ") 		||
						 line.hasPrefix("class ") 	||
						 line.hasPrefix("while ")	||
						 line.hasPrefix("if "))
						&& line.hasSuffix(":"))
				{
						multi_line_mode_ = true;
						multi_line_text_ = line;
						multi_line_text_.append("\n");
						multi_lines_ = 1;
						appendToHistory_(line);
						newPrompt_();
						return;
				}

				multi_lines_ = 0;
				appendToHistory_(line);
			}
			else // Multiline mode
			{
				multi_lines_ += 1;
				appendToHistory_(line);
				if (!line.isEmpty())
				{
					multi_line_text_ += line + "\n";
					newPrompt_();
					return;
				}

				line = multi_line_text_ + "\n";
			}

			bool state;
			String result = PyInterpreter::run(line, state);
			if (result != "") append(result.c_str());

			if (!multi_line_mode_)
			{
				results_.push_back(state);
			}
			else
			{
				for (Position p = 0; p <= multi_lines_ -1; p++) results_.push_back(state);
			}

			multi_line_mode_ = false;

			newPrompt_();
		}

		void PyWidgetData::appendToHistory_(const String& line)
		{
			history_.push_back(line);
			history_position_ = history_.size();
		}

		const char* PyWidgetData::getPrompt_() const
		{
			return (multi_line_mode_ ? "... " : ">>> ");
		}

		void PyWidgetData::newPrompt_()
		{
			append(getPrompt_());
			//scrollToBottom();
			setCursorPosition(lines() - 1, 4);
		}

		void PyWidgetData::keyPressEvent(QKeyEvent* e)
		{
			int row, col;
			getCursorPosition(&row, &col);

			if (e->key() == Key_Left || e->key() == Key_Backspace)
			{
				if (col <= 4) return;
			}
			else if (e->key() == Key_Right)
			{
				setCursorPosition(row, col+1);
				return;
			}
			else if (e->key() == Key_Up)
			{
				if (history_position_ != 0) retrieveHistoryLine_(history_position_ - 1);
				return;
			}
			else if (e->key() == Key_Down)
			{
				retrieveHistoryLine_(history_position_ + 1);
				return;
			}
			else if (e->key() == Key_Home)
			{
				setCursorPosition(row, 4);
				return;
			}
			else if (e->key() == Key_Return)
			{
				if (!returnPressed()) return;
			}
			else if (e->key() == Key_PageUp ||
							 e->key() == Key_PageDown)
			{
				return;
			}

			QTextEdit::keyPressEvent(e);
		}

		void PyWidgetData::dump(std::ostream& s, Size depth) const
			throw()
		{
			BALL_DUMP_STREAM_PREFIX(s);

			BALL_DUMP_HEADER(s, this, this);

			BALL_DUMP_DEPTH(s, depth);
			s << "multiline_mode : " << multi_line_mode_<< std::endl;

			BALL_DUMP_DEPTH(s, depth);
			s << "multi_line_text  : " << multi_line_text_<< std::endl;

			BALL_DUMP_DEPTH(s, depth);
			s << "history : "<< std::endl;

			for (Position i = 0; i < history_.size(); i++)
			{
				BALL_DUMP_DEPTH(s, depth);
				s << history_[i]<< std::endl;
			}

			BALL_DUMP_DEPTH(s, depth);
			s << "history_position : " << history_position_ << std::endl;

			BALL_DUMP_DEPTH(s, depth);
			s << "current_line : " << current_line_ << std::endl;

			BALL_DUMP_STREAM_SUFFIX(s);
		}

		String PyWidgetData::getCurrentLine_()
		{
			int row, col;
			getCursorPosition(&row, &col);
			return String(text(row).ascii());
		}

		void PyWidgetData::runFile(const String& filename)
		{
			append(String("> running File " + filename + "\n").c_str());
			bool result;
			String result_string;
			LineBasedFile file;
			try
			{
				file.open(filename);
			}
			catch(Exception::GeneralException e)
			{
				append(String("> Could not find file " + filename + "\n").c_str());
				newPrompt_();
				return;
			}

			while (file.readLine())
			{
				result_string = PyInterpreter::run(file.getLine(), result);
				if (!result)
				{
					result_string += "> Error in Line " + String(file.getLineNumber()) + " in file " + filename + "\n";
					append(result_string.c_str());
					newPrompt_();
					return;
				}

				append(result_string.c_str());
			}
			append("> finished...");
			newPrompt_();
		}

		void PyWidgetData::scriptDialog()
		{
			// no throw specifier because of that #$%@* moc
			QFileDialog *fd = new QFileDialog(this, "Run Python Script", true);
			fd->setMode(QFileDialog::ExistingFile);
			fd->addFilter("Python Scripts(*.py)");
			fd->setSelectedFilter(1);

			fd->setCaption("Run Python Script");
			fd->setViewMode(QFileDialog::Detail);
			fd->setGeometry(300, 150, 400, 400);

			int result_dialog = fd->exec();
			if (!result_dialog == QDialog::Accepted) return;

			String filename(fd->selectedFile().ascii());

			runFile(filename);
		}

		void PyWidgetData::exportHistory()
		{
			QFileDialog *fd = new QFileDialog(this, "Export History", true);
			fd->setMode(QFileDialog::AnyFile);
			fd->addFilter("Python Scripts(*.py)");
			fd->setSelectedFilter(1);

			fd->setCaption("Export History");
			fd->setViewMode(QFileDialog::Detail);
			fd->setGeometry(300, 150, 400, 400);

			int result_dialog = fd->exec();
			if (!result_dialog == QDialog::Accepted) return;

			String filename(fd->selectedFile().ascii());

			File file(filename, std::ios::out);
			if (!file.isOpen())
			{
				append(String("> Could not export history to file " + filename + "\n").c_str());
				newPrompt_();
				return;
			}

			for (Position p = 0; p < history_.size(); p++)
			{
				if (results_[p]) file << history_[p] << std::endl;
			}

			file.close();
		}

		PyWidget::PyWidget(QWidget *parent, const char *name)
			throw()
			: DockWidget(parent, name),
				text_edit_(new PyWidgetData(this))
		{
		#ifdef BALL_VIEW_DEBUG
			Log.error() << "new PyWidget " << this << std::endl;
		#endif
			default_visible_ = false;
			setGuest(*text_edit_);
		}

		void PyWidget::initializeWidget(MainControl& main_control)
			throw()
		{
			main_control.insertMenuEntry(MainControl::TOOLS_PYTHON, "Restart Python", text_edit_, SLOT(startInterpreter()));
			main_control.insertMenuEntry(MainControl::TOOLS_PYTHON, "Run Python Script", text_edit_, SLOT(scriptDialog()));
			main_control.insertMenuEntry(MainControl::TOOLS_PYTHON, "Export History", text_edit_, SLOT(exportHistory()));

			DockWidget::initializeWidget(main_control);
		}

		void PyWidget::finalizeWidget(MainControl& main_control)
			throw()
		{
			main_control.removeMenuEntry(MainControl::TOOLS_PYTHON, "Restart Python", text_edit_, SLOT(startInterpreter()));
			main_control.removeMenuEntry(MainControl::TOOLS_PYTHON, "Run Python Script", text_edit_, SLOT(scriptDialog()));
			main_control.removeMenuEntry(MainControl::TOOLS_PYTHON, "Export History", text_edit_, SLOT(exportHistory()));

			DockWidget::finalizeWidget(main_control);
		}

		void PyWidget::fetchPreferences(INIFile& inifile)
			throw()
		{
			DockWidget::fetchPreferences(inifile);

			if (!inifile.hasEntry("PYTHON", "StartupScript")) return;

			text_edit_->startup_script_ =	inifile.getValue("PYTHON", "StartupScript");
			text_edit_->python_settings_->setFilename(text_edit_->startup_script_);
			if (text_edit_->startup_script_ != "") text_edit_->runFile(text_edit_->startup_script_);
		}

		void PyWidget::writePreferences(INIFile& inifile)
			throw()
		{
			inifile.appendSection("PYTHON");
			inifile.insertValue("PYTHON", "StartupScript", text_edit_->startup_script_);

			DockWidget::writePreferences(inifile);
		}

		void PyWidget::initializePreferencesTab(Preferences &preferences)
			throw()
		{
			text_edit_->python_settings_= new PythonSettings(this);
			text_edit_->python_settings_->setFilename(text_edit_->startup_script_);
			preferences.insertTab(text_edit_->python_settings_, "Python");
		}

		void PyWidget::finalizePreferencesTab(Preferences &preferences)
			throw()
		{
			if (text_edit_->python_settings_ != 0)
			{
				preferences.removeTab(text_edit_->python_settings_);

				delete text_edit_->python_settings_;
				text_edit_->python_settings_ = 0;
			}
		}

		void PyWidget::applyPreferences(Preferences & /* preferences */)
			throw()
		{
			if (text_edit_->python_settings_ == 0) return;
			text_edit_->startup_script_ = text_edit_->python_settings_->getFilename();
		}

		void PyWidget::cancelPreferences(Preferences&)
			throw()
		{
			if (text_edit_->python_settings_ != 0)
			{
				text_edit_->python_settings_->setFilename(text_edit_->startup_script_);
			}
		}

		void PyWidget::startInterpreter()
		{
			text_edit_->startInterpreter();
		}

		void PyWidget::stopInterpreter()
		{
			text_edit_->stopInterpreter();
		}

	} // namespace VIEW
} // namespace BALL
<commit_msg>fixed problem with wraping<commit_after>// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//
// $Id: pyWidget.C,v 1.14 2003/11/13 15:01:57 amoll Exp $
//

// This include has to be first in order to avoid collisions.
#include <Python.h>

#include <BALL/VIEW/WIDGETS/pyWidget.h>
#include <BALL/VIEW/KERNEL/mainControl.h>
#include <BALL/VIEW/DIALOGS/pythonSettings.h>
#include <BALL/PYTHON/pyInterpreter.h>
#include <BALL/VIEW/DIALOGS/preferences.h>
#include <BALL/FORMAT/lineBasedFile.h>

#include <qscrollbar.h>
#include <qfiledialog.h>

namespace BALL
{
	namespace VIEW
	{

		PyWidgetData::PyWidgetData(QWidget* parent, const char* name)
			: QTextEdit(parent, name)
		{
			setWrapPolicy(QTextEdit::Anywhere);
		}

		PyWidgetData::PyWidgetData(const PyWidgetData& /*widget*/)
			:	QTextEdit()
		{
		}

		PyWidgetData::~PyWidgetData()
			throw()
		{
		}

		void PyWidgetData::stopInterpreter()
		{
			PyInterpreter::finalize();
		}

		void PyWidgetData::startInterpreter()
		{
			// initialize the interpreter
			PyInterpreter::initialize();

			// print the PyBALL version and clear
			// the widget's contents in case of a restart
			setText((String("BALL ") + VersionInfo::getVersion()).c_str());

			// print the first prompt
			multi_line_mode_ = false;
			newPrompt_();
			history_position_ = history_.size() + 1;
		}

		void PyWidgetData::retrieveHistoryLine_(Position index)
		{
			if (index > history_.size())
			{
				history_position_ = history_.size();
				return;
			}

			int row, col;
			getCursorPosition(&row, &col);

			if (index == history_.size())
			{
				history_position_ = history_.size();
				removeParagraph(row);
				insertParagraph(getPrompt_(), row);
				setCursorPosition(paragraphs()-1, col);
				QScrollBar* sb = verticalScrollBar();
				if (sb != 0)
				{
					sb->setValue(sb->maxValue());
				}
				removeParagraph(row +1);
				return;
			}

			String line = getPrompt_()+ history_[index];

			// replace the line's contents
			removeParagraph(row);
			insertParagraph(line.c_str(), row);
			setCursorPosition(row, line.size());
			QScrollBar* sb = verticalScrollBar();
			if (sb != 0)
			{
				sb->setValue(sb->maxValue());
			}

			// update the history position
			history_position_ = index;
			removeParagraph(row +1);
		}

		void PyWidgetData::contentsMousePressEvent(QMouseEvent* /* m */)
		{
			setCursorPosition(paragraphs() - 1, 4);
			// we ignore the mouse events!
			// they might place the cursor anywhere!
		}

		void PyWidgetData::mousePressEvent(QMouseEvent* /* m */)
		{
			setCursorPosition(paragraphs() - 1, 4);
			// we ignore the mouse events!
			// they might place the cursor anywhere!
		}

		bool PyWidgetData::returnPressed()
		{
			// check for an empty line (respect the prompt)
			int row, col;
			getCursorPosition(&row, &col);
			current_line_ = getCurrentLine_();
			if (col < 5)
			{
				if (multi_line_mode_)
				{
					// in multi line mode: end of input - parse it!
					QTextEdit::returnPressed();
					parseLine_();
				}
				else
				{
					// return on an empty line is handled
					// as in the interactive interpreter: do nothing and
					// print another prompt
					QTextEdit::returnPressed();
					newPrompt_();
				}
			}
			else
			{
				// parse the line
				QTextEdit::returnPressed();
				parseLine_();
			}

			return false;
		}

		void PyWidgetData::parseLine_()
		{
			if (!Py_IsInitialized())
			{
				append("ERROR: no interpreter running!\n");
				return;
			}

			history_position_ = history_.size();

			String line = current_line_.getSubstring(4);
			line.trimRight();

			if (!multi_line_mode_)
			{
				if (line.isEmpty()) return;
				if ((line.hasPrefix("for ") 		||
						 line.hasPrefix("def ") 		||
						 line.hasPrefix("class ") 	||
						 line.hasPrefix("while ")	||
						 line.hasPrefix("if "))
						&& line.hasSuffix(":"))
				{
						multi_line_mode_ = true;
						multi_line_text_ = line;
						multi_line_text_.append("\n");
						multi_lines_ = 1;
						appendToHistory_(line);
						newPrompt_();
						return;
				}

				multi_lines_ = 0;
				appendToHistory_(line);
			}
			else // Multiline mode
			{
				multi_lines_ += 1;
				appendToHistory_(line);
				if (!line.isEmpty())
				{
					multi_line_text_ += line + "\n";
					newPrompt_();
					return;
				}

				line = multi_line_text_ + "\n";
			}

			bool state;
			String result = PyInterpreter::run(line, state);
			if (result != "") append(result.c_str());

			if (!multi_line_mode_)
			{
				results_.push_back(state);
			}
			else
			{
				for (Position p = 0; p <= multi_lines_ -1; p++) results_.push_back(state);
			}

			multi_line_mode_ = false;

			newPrompt_();
		}

		void PyWidgetData::appendToHistory_(const String& line)
		{
			history_.push_back(line);
			history_position_ = history_.size();
		}

		const char* PyWidgetData::getPrompt_() const
		{
			return (multi_line_mode_ ? "... " : ">>> ");
		}

		void PyWidgetData::newPrompt_()
		{
			append(getPrompt_());
			setCursorPosition(paragraphs() - 1, 4);
		}

		void PyWidgetData::keyPressEvent(QKeyEvent* e)
		{
			int row, col;
			getCursorPosition(&row, &col);

			if (e->key() == Key_Left || e->key() == Key_Backspace)
			{
				if (col <= 4) return;
			}
			else if (e->key() == Key_Right)
			{
				setCursorPosition(paragraphs()-1, col+1);
				return;
			}
			else if (e->key() == Key_Up)
			{
				if (history_position_ != 0) retrieveHistoryLine_(history_position_ - 1);
				return;
			}
			else if (e->key() == Key_Down)
			{
				retrieveHistoryLine_(history_position_ + 1);
				return;
			}
			else if (e->key() == Key_Home)
			{
				setCursorPosition(row, 4);
				return;
			}
			else if (e->key() == Key_Return)
			{
				if (!returnPressed()) return;
			}
			else if (e->key() == Key_PageUp)
			{
				return;
			}
			else if (e->key() == Key_PageDown)
			{
				return;
			}

			QTextEdit::keyPressEvent(e);
		}

		void PyWidgetData::dump(std::ostream& s, Size depth) const
			throw()
		{
			BALL_DUMP_STREAM_PREFIX(s);

			BALL_DUMP_HEADER(s, this, this);

			BALL_DUMP_DEPTH(s, depth);
			s << "multiline_mode : " << multi_line_mode_<< std::endl;

			BALL_DUMP_DEPTH(s, depth);
			s << "multi_line_text  : " << multi_line_text_<< std::endl;

			BALL_DUMP_DEPTH(s, depth);
			s << "history : "<< std::endl;

			for (Position i = 0; i < history_.size(); i++)
			{
				BALL_DUMP_DEPTH(s, depth);
				s << history_[i]<< std::endl;
			}

			BALL_DUMP_DEPTH(s, depth);
			s << "history_position : " << history_position_ << std::endl;

			BALL_DUMP_DEPTH(s, depth);
			s << "current_line : " << current_line_ << std::endl;

			BALL_DUMP_STREAM_SUFFIX(s);
		}

		String PyWidgetData::getCurrentLine_()
		{
			int row, col;
			getCursorPosition(&row, &col);
			return String(text(row).ascii());
		}

		void PyWidgetData::runFile(const String& filename)
		{
			append(String("> running File " + filename + "\n").c_str());
			bool result;
			String result_string;
			LineBasedFile file;
			try
			{
				file.open(filename);
			}
			catch(Exception::GeneralException e)
			{
				append(String("> Could not find file " + filename + "\n").c_str());
				newPrompt_();
				return;
			}

			while (file.readLine())
			{
				result_string = PyInterpreter::run(file.getLine(), result);
				if (!result)
				{
					result_string += "> Error in Line " + String(file.getLineNumber()) + " in file " + filename + "\n";
					append(result_string.c_str());
					newPrompt_();
					return;
				}

				append(result_string.c_str());
			}
			append("> finished...");
			newPrompt_();
		}

		void PyWidgetData::scriptDialog()
		{
			// no throw specifier because of that #$%@* moc
			QFileDialog *fd = new QFileDialog(this, "Run Python Script", true);
			fd->setMode(QFileDialog::ExistingFile);
			fd->addFilter("Python Scripts(*.py)");
			fd->setSelectedFilter(1);

			fd->setCaption("Run Python Script");
			fd->setViewMode(QFileDialog::Detail);
			fd->setGeometry(300, 150, 400, 400);

			int result_dialog = fd->exec();
			if (!result_dialog == QDialog::Accepted) return;

			String filename(fd->selectedFile().ascii());

			runFile(filename);
		}

		void PyWidgetData::exportHistory()
		{
			QFileDialog *fd = new QFileDialog(this, "Export History", true);
			fd->setMode(QFileDialog::AnyFile);
			fd->addFilter("Python Scripts(*.py)");
			fd->setSelectedFilter(1);

			fd->setCaption("Export History");
			fd->setViewMode(QFileDialog::Detail);
			fd->setGeometry(300, 150, 400, 400);

			int result_dialog = fd->exec();
			if (!result_dialog == QDialog::Accepted) return;

			String filename(fd->selectedFile().ascii());

			File file(filename, std::ios::out);
			if (!file.isOpen())
			{
				append(String("> Could not export history to file " + filename + "\n").c_str());
				newPrompt_();
				return;
			}

			for (Position p = 0; p < history_.size(); p++)
			{
				if (results_[p]) file << history_[p] << std::endl;
			}

			file.close();
		}

		void PyWidgetData::cut()
		{
			QTextEdit::cut();
			newPrompt_();
		}

		void PyWidgetData::clear()
		{
			QTextEdit::clear();
			newPrompt_();
		}

// ######################################################################################################

		PyWidget::PyWidget(QWidget *parent, const char *name)
			throw()
			: DockWidget(parent, name),
				text_edit_(new PyWidgetData(this))
		{
		#ifdef BALL_VIEW_DEBUG
			Log.error() << "new PyWidget " << this << std::endl;
		#endif
			default_visible_ = false;
			setGuest(*text_edit_);
		}

		void PyWidget::initializeWidget(MainControl& main_control)
			throw()
		{
			main_control.insertMenuEntry(MainControl::TOOLS_PYTHON, "Restart Python", text_edit_, SLOT(startInterpreter()));
			main_control.insertMenuEntry(MainControl::TOOLS_PYTHON, "Run Python Script", text_edit_, SLOT(scriptDialog()));
			main_control.insertMenuEntry(MainControl::TOOLS_PYTHON, "Export History", text_edit_, SLOT(exportHistory()));

			DockWidget::initializeWidget(main_control);
		}

		void PyWidget::finalizeWidget(MainControl& main_control)
			throw()
		{
			main_control.removeMenuEntry(MainControl::TOOLS_PYTHON, "Restart Python", text_edit_, SLOT(startInterpreter()));
			main_control.removeMenuEntry(MainControl::TOOLS_PYTHON, "Run Python Script", text_edit_, SLOT(scriptDialog()));
			main_control.removeMenuEntry(MainControl::TOOLS_PYTHON, "Export History", text_edit_, SLOT(exportHistory()));

			DockWidget::finalizeWidget(main_control);
		}

		void PyWidget::fetchPreferences(INIFile& inifile)
			throw()
		{
			DockWidget::fetchPreferences(inifile);

			if (!inifile.hasEntry("PYTHON", "StartupScript")) return;

			text_edit_->startup_script_ =	inifile.getValue("PYTHON", "StartupScript");
			text_edit_->python_settings_->setFilename(text_edit_->startup_script_);
			if (text_edit_->startup_script_ != "") text_edit_->runFile(text_edit_->startup_script_);
		}

		void PyWidget::writePreferences(INIFile& inifile)
			throw()
		{
			inifile.appendSection("PYTHON");
			inifile.insertValue("PYTHON", "StartupScript", text_edit_->startup_script_);

			DockWidget::writePreferences(inifile);
		}

		void PyWidget::initializePreferencesTab(Preferences &preferences)
			throw()
		{
			text_edit_->python_settings_= new PythonSettings(this);
			text_edit_->python_settings_->setFilename(text_edit_->startup_script_);
			preferences.insertTab(text_edit_->python_settings_, "Python");
		}

		void PyWidget::finalizePreferencesTab(Preferences &preferences)
			throw()
		{
			if (text_edit_->python_settings_ != 0)
			{
				preferences.removeTab(text_edit_->python_settings_);

				delete text_edit_->python_settings_;
				text_edit_->python_settings_ = 0;
			}
		}

		void PyWidget::applyPreferences(Preferences & /* preferences */)
			throw()
		{
			if (text_edit_->python_settings_ == 0) return;
			text_edit_->startup_script_ = text_edit_->python_settings_->getFilename();
		}

		void PyWidget::cancelPreferences(Preferences&)
			throw()
		{
			if (text_edit_->python_settings_ != 0)
			{
				text_edit_->python_settings_->setFilename(text_edit_->startup_script_);
			}
		}

		void PyWidget::startInterpreter()
		{
			text_edit_->startInterpreter();
		}

		void PyWidget::stopInterpreter()
		{
			text_edit_->stopInterpreter();
		}

	} // namespace VIEW
} // namespace BALL
<|endoftext|>


<commit_before>#include "CUVElement.hpp"

/* Documentation at: http://www.metroid2002.com/retromodding/wiki/Particle_Script#UV_Elements */

namespace urde {

CUVEAnimTexture::CUVEAnimTexture(TToken<CTexture>&& tex, std::unique_ptr<CIntElement>&& tileW,
                                 std::unique_ptr<CIntElement>&& tileH, std::unique_ptr<CIntElement>&& strideW,
                                 std::unique_ptr<CIntElement>&& strideH, std::unique_ptr<CIntElement>&& cycleFrames,
                                 bool loop)
: x4_tex(std::move(tex)), x24_loop(loop), x28_cycleFrames(std::move(cycleFrames)) {
  tileW->GetValue(0, x10_tileW);
  tileH->GetValue(0, x14_tileH);
  strideW->GetValue(0, x18_strideW);
  strideH->GetValue(0, x1c_strideH);

  const int width = int(x4_tex.GetObj()->GetWidth());
  const int height = int(x4_tex.GetObj()->GetHeight());
  const float widthF = float(width);
  const float heightF = float(height);
  const int xTiles = std::max(1, width / x18_strideW);
  const int yTiles = std::max(1, height / x1c_strideH);

  x20_tiles = xTiles * yTiles;
  x2c_uvElems.reserve(x20_tiles);

  for (int y = yTiles - 1; y >= 0; --y) {
    for (int x = 0; x < xTiles; ++x) {
      const int px = x18_strideW * x;
      const int px2 = px + x10_tileW;
      const int py = x1c_strideH * y;
      const int py2 = py + x14_tileH;

      x2c_uvElems.push_back({
          float(px) / widthF,
          float(py) / heightF,
          float(px2) / widthF,
          float(py2) / heightF,
      });
    }
  }
}

void CUVEAnimTexture::GetValueUV(int frame, SUVElementSet& valOut) const {
  int cv;
  x28_cycleFrames->GetValue(frame, cv);
  float cvf = float(cv) / float(x20_tiles);
  cvf = float(frame) / cvf;

  int tile = int(cvf);
  if (x24_loop) {
    if (cvf >= float(x20_tiles)) {
      tile = int(cvf) % x20_tiles;
    }
  } else {
    if (cvf >= float(x20_tiles)) {
      tile = x20_tiles - 1;
    }
  }

  valOut = x2c_uvElems[tile];
}

} // namespace urde
<commit_msg>CUVElement: Provide initial value for cv in GetValueUV()<commit_after>#include "CUVElement.hpp"

/* Documentation at: http://www.metroid2002.com/retromodding/wiki/Particle_Script#UV_Elements */

namespace urde {

CUVEAnimTexture::CUVEAnimTexture(TToken<CTexture>&& tex, std::unique_ptr<CIntElement>&& tileW,
                                 std::unique_ptr<CIntElement>&& tileH, std::unique_ptr<CIntElement>&& strideW,
                                 std::unique_ptr<CIntElement>&& strideH, std::unique_ptr<CIntElement>&& cycleFrames,
                                 bool loop)
: x4_tex(std::move(tex)), x24_loop(loop), x28_cycleFrames(std::move(cycleFrames)) {
  tileW->GetValue(0, x10_tileW);
  tileH->GetValue(0, x14_tileH);
  strideW->GetValue(0, x18_strideW);
  strideH->GetValue(0, x1c_strideH);

  const int width = int(x4_tex.GetObj()->GetWidth());
  const int height = int(x4_tex.GetObj()->GetHeight());
  const float widthF = float(width);
  const float heightF = float(height);
  const int xTiles = std::max(1, width / x18_strideW);
  const int yTiles = std::max(1, height / x1c_strideH);

  x20_tiles = xTiles * yTiles;
  x2c_uvElems.reserve(x20_tiles);

  for (int y = yTiles - 1; y >= 0; --y) {
    for (int x = 0; x < xTiles; ++x) {
      const int px = x18_strideW * x;
      const int px2 = px + x10_tileW;
      const int py = x1c_strideH * y;
      const int py2 = py + x14_tileH;

      x2c_uvElems.push_back({
          float(px) / widthF,
          float(py) / heightF,
          float(px2) / widthF,
          float(py2) / heightF,
      });
    }
  }
}

void CUVEAnimTexture::GetValueUV(int frame, SUVElementSet& valOut) const {
  int cv = 1;
  x28_cycleFrames->GetValue(frame, cv);
  float cvf = float(cv) / float(x20_tiles);
  cvf = float(frame) / cvf;

  int tile = int(cvf);
  if (x24_loop) {
    if (cvf >= float(x20_tiles)) {
      tile = int(cvf) % x20_tiles;
    }
  } else {
    if (cvf >= float(x20_tiles)) {
      tile = x20_tiles - 1;
    }
  }

  valOut = x2c_uvElems[tile];
}

} // namespace urde
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef SC_ADIASYNC_HXX
#define SC_ADIASYNC_HXX

#include <svl/broadcast.hxx>
#include <set>

#include "callform.hxx"

extern "C" {
void CALLTYPE ScAddInAsyncCallBack( double& nHandle, void* pData );
}

class ScDocument;
class ScAddInDocs : public std::set<ScDocument*> {};

class String;

class ScAddInAsync : public SvtBroadcaster
{
private:
    union
    {
        double      nVal;               // current value
        String*     pStr;
    };
    ScAddInDocs*    pDocs;              // List of using documents
    FuncData*       mpFuncData;         // Pointer to files in collection
    sal_uLong       nHandle;            // is casted from double to sal_uLong
    ParamType       meType;             // result of type PTR_DOUBLE or PTR_STRING
    bool            bValid;             // is value valid?

public:
    // cTor only if ScAddInAsync::Get fails.
    // nIndex: Index from FunctionCollection
    ScAddInAsync(sal_uLong nHandle, FuncData* pFuncData, ScDocument* pDoc);
                    // default-cTor only for that single, global aSeekObj!
                    ScAddInAsync();
    virtual         ~ScAddInAsync();
    static ScAddInAsync*    Get( sal_uLong nHandle );
    static void     CallBack( sal_uLong nHandle, void* pData );
    static void     RemoveDocument( ScDocument* pDocument );
    bool            IsValid() const         { return bValid; }
    ParamType       GetType() const         { return meType; }
    double          GetValue() const        { return nVal; }
    const String&   GetString() const       { return *pStr; }
    bool            HasDocument( ScDocument* pDoc ) const
                        { return pDocs->find( pDoc ) != pDocs->end(); }
    void            AddDocument( ScDocument* pDoc ) { pDocs->insert( pDoc ); }

    // Comparators for PtrArrSort
    bool operator< ( const ScAddInAsync& r ) const { return nHandle <  r.nHandle; }
    bool operator==( const ScAddInAsync& r ) const { return nHandle == r.nHandle; }
};

struct CompareScAddInAsync
{
  bool operator()( ScAddInAsync* const& lhs, ScAddInAsync* const& rhs ) const { return (*lhs)<(*rhs); }
};
class ScAddInAsyncs : public std::set<ScAddInAsync*, CompareScAddInAsync> {};

extern ScAddInAsyncs theAddInAsyncTbl;  // in adiasync.cxx

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>fix errorin translation from german to english<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef SC_ADIASYNC_HXX
#define SC_ADIASYNC_HXX

#include <svl/broadcast.hxx>
#include <set>

#include "callform.hxx"

extern "C" {
void CALLTYPE ScAddInAsyncCallBack( double& nHandle, void* pData );
}

class ScDocument;
class ScAddInDocs : public std::set<ScDocument*> {};

class String;

class ScAddInAsync : public SvtBroadcaster
{
private:
    union
    {
        double      nVal;               // current value
        String*     pStr;
    };
    ScAddInDocs*    pDocs;              // List of using documents
    FuncData*       mpFuncData;         // Pointer to data in collection
    sal_uLong       nHandle;            // is casted from double to sal_uLong
    ParamType       meType;             // result of type PTR_DOUBLE or PTR_STRING
    bool            bValid;             // is value valid?

public:
    // cTor only if ScAddInAsync::Get fails.
    // nIndex: Index from FunctionCollection
    ScAddInAsync(sal_uLong nHandle, FuncData* pFuncData, ScDocument* pDoc);
                    // default-cTor only for that single, global aSeekObj!
                    ScAddInAsync();
    virtual         ~ScAddInAsync();
    static ScAddInAsync*    Get( sal_uLong nHandle );
    static void     CallBack( sal_uLong nHandle, void* pData );
    static void     RemoveDocument( ScDocument* pDocument );
    bool            IsValid() const         { return bValid; }
    ParamType       GetType() const         { return meType; }
    double          GetValue() const        { return nVal; }
    const String&   GetString() const       { return *pStr; }
    bool            HasDocument( ScDocument* pDoc ) const
                        { return pDocs->find( pDoc ) != pDocs->end(); }
    void            AddDocument( ScDocument* pDoc ) { pDocs->insert( pDoc ); }

    // Comparators for PtrArrSort
    bool operator< ( const ScAddInAsync& r ) const { return nHandle <  r.nHandle; }
    bool operator==( const ScAddInAsync& r ) const { return nHandle == r.nHandle; }
};

struct CompareScAddInAsync
{
  bool operator()( ScAddInAsync* const& lhs, ScAddInAsync* const& rhs ) const { return (*lhs)<(*rhs); }
};
class ScAddInAsyncs : public std::set<ScAddInAsync*, CompareScAddInAsync> {};

extern ScAddInAsyncs theAddInAsyncTbl;  // in adiasync.cxx

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>#ifndef _A_STAR_HPP_
#define _A_STAR_HPP_

#include <vector>

#include <boost/none.hpp>
#include <boost/optional.hpp>
#include <boost/pool/pool_alloc.hpp>
#include <boost/unordered_map.hpp>

#include "search/BucketPriorityQueue.hpp"
#include "util/PointerOps.hpp"

template <
  class Domain,
  class Node
  >
class AStar
{
private:
  typedef BucketPriorityQueue<Node> Open;
  typedef boost::unordered_map<
    Node *,
    boost::optional<typename Open::ItemPointer>,
    PointerHash<Node>,
    PointerEq<Node>
    , boost::fast_pool_allocator<
        std::pair<Node * const,
                  boost::optional<typename Open::ItemPointer> > >
    > Closed;

public:
  AStar(const Domain &domain)
    : open(*new Open())
    , closed(*new Closed(50000000))  // requested number of hash buckets
    , goal(NULL)
    , domain(domain)
    , num_expanded(0)
    , num_generated(0)
  {
  }

  ~AStar()
  {
    // I don't delete open or closed.  This appears to be acceptable,
    // due to my use of memory pools in key places.  Check for
    // yourself, with valgrind: no memory is leaked.
  }

  void search()
  {
    // TODO: the following check is buggy.  What if there is no goal,
    // and the search has been completed?
    if (goal != NULL)
      return;

    typename std::vector<Node *> succs;    // re-use a stack-allocated
                                           // vector for successor
                                           // nodes, thus avoiding
                                           // repeated heap
                                           // allocation.

    {
      assert(all_closed_item_ptrs_valid());
      Node *start_node = domain.create_start_node();
      boost::optional<typename Open::ItemPointer> open_ptr = open.push(start_node);
      assert(open_ptr);
      closed[start_node] = open_ptr;
      assert(closed.find(start_node) != closed.end());
      assert(open.size() == 1);
      assert(closed.size() == 1);
      assert(all_closed_item_ptrs_valid());
    }

    while (!open.empty())
    {
// #ifndef NDEBUG
//       std::cerr << "open size is " << open.size() << std::endl
//                 << "closed size is " << closed.size() << std::endl;
// #endif

      Node *n = open.top();
      open.pop();
      assert(closed.find(n) != closed.end());
      closed[n] = boost::none;
      assert(all_closed_item_ptrs_valid());

      if (domain.is_goal(n->get_state())) {
        goal = n;
        return;
      }

      domain.expand(*n, succs);
      num_expanded += 1;
      num_generated += succs.size();

      for (unsigned succ_i = 0; succ_i < succs.size(); succ_i += 1)
      {
        Node *succ = succs[succ_i];
        assert(open.size() <= closed.size());
        assert(all_closed_item_ptrs_valid());
        typename Closed::iterator closed_it = closed.find(succ);
        if (closed.find(succ) != closed.end()) {
          boost::optional<typename Open::ItemPointer> &open_ptr = closed_it->second;

          if ( open_ptr ) {
            Node *old_succ = open.lookup(*open_ptr);

            if ( succ->get_f() < old_succ->get_f() ) {
              // A worse copy of succ is in the open list.  Replace it!
              assert(old_succ->get_state() == succ->get_state());
              assert(*old_succ == *succ);

              domain.free_node(old_succ);    // get rid of the old copy
              open.erase(*open_ptr);
              closed.erase(succ);

              open_ptr = open.push(succ);    // insert the new copy
              closed[succ] = open_ptr;

              assert(all_closed_item_ptrs_valid());
            }
          }
          else {
            // succ is not in the open list, but is closed.  Drop it!
            domain.free_node(succ);
          }
        }
        else {
          // succ has not been generated before.
          boost::optional<typename Open::ItemPointer> open_ptr = open.push(succ);
          closed[succ] = open_ptr;
          assert(closed.find(open.lookup(*open_ptr)) != closed.end());
          assert(all_closed_item_ptrs_valid());
        }
      } /* end for */
    } /* end while */
  }

  const Node * get_goal() const
  {
#ifndef NDEBUG
    std::cerr << open.size() << " nodes in open at end of search" << std::endl
              << closed.size() << " nodes in closed at end of search" << std::endl;
#endif
    return goal;
  }

  const Domain & get_domain() const
  {
    return domain;
  }

  unsigned get_num_generated() const
  {
    return num_generated;
  }

  unsigned get_num_expanded() const
  {
    return num_expanded;
  }

private:
  bool all_closed_item_ptrs_valid() const
  {
    return true;
    std::cerr << "checking if item pointers are valid" << std::endl
              << "  " << closed.size() << " pointers to check" << std::endl;
    for (typename Closed::const_iterator closed_it = closed.begin();
         closed_it != closed.end();
         ++closed_it) {
      if ( closed_it->second && !open.valid_item_pointer(*closed_it->second) )
        return false;
    }
    return true;
  }

private:
  Open &open;
  Closed &closed;

  const Node * goal;
  const Domain &domain;

  unsigned num_expanded;
  unsigned num_generated;

private:
  AStar(const AStar<Domain, Node> &);
  AStar<Domain, Node> & operator =(const AStar<Domain, Node> &);
};

#endif /* !_A_STAR_HPP_ */
<commit_msg>Fixed a bug where search could be repeated if no goal exists.<commit_after>#ifndef _A_STAR_HPP_
#define _A_STAR_HPP_

#include <vector>

#include <boost/none.hpp>
#include <boost/optional.hpp>
#include <boost/pool/pool_alloc.hpp>
#include <boost/unordered_map.hpp>

#include "search/BucketPriorityQueue.hpp"
#include "util/PointerOps.hpp"

template <
  class Domain,
  class Node
  >
class AStar
{
private:
  typedef BucketPriorityQueue<Node> Open;
  typedef boost::unordered_map<
    Node *,
    boost::optional<typename Open::ItemPointer>,
    PointerHash<Node>,
    PointerEq<Node>
    , boost::fast_pool_allocator<
        std::pair<Node * const,
                  boost::optional<typename Open::ItemPointer> > >
    > Closed;

public:
  AStar(const Domain &domain)
    : open(*new Open())
    , closed(*new Closed(50000000))  // requested number of hash buckets
    , goal(NULL)
    , searched(false)
    , domain(domain)
    , num_expanded(0)
    , num_generated(0)
  {
  }

  ~AStar()
  {
    // I don't delete open or closed.  This appears to be acceptable,
    // due to my use of memory pools in key places.  Check for
    // yourself, with valgrind: no memory is leaked.
  }

  void search()
  {
    if (searched || goal != NULL)
      return;
    searched = true;

    typename std::vector<Node *> succs;    // re-use a stack-allocated
                                           // vector for successor
                                           // nodes, thus avoiding
                                           // repeated heap
                                           // allocation.

    {
      assert(all_closed_item_ptrs_valid());
      Node *start_node = domain.create_start_node();
      boost::optional<typename Open::ItemPointer> open_ptr = open.push(start_node);
      assert(open_ptr);
      closed[start_node] = open_ptr;
      assert(closed.find(start_node) != closed.end());
      assert(open.size() == 1);
      assert(closed.size() == 1);
      assert(all_closed_item_ptrs_valid());
    }

    while (!open.empty())
    {
// #ifndef NDEBUG
//       std::cerr << "open size is " << open.size() << std::endl
//                 << "closed size is " << closed.size() << std::endl;
// #endif

      Node *n = open.top();
      open.pop();
      assert(closed.find(n) != closed.end());
      closed[n] = boost::none;
      assert(all_closed_item_ptrs_valid());

      if (domain.is_goal(n->get_state())) {
        goal = n;
        return;
      }

      domain.expand(*n, succs);
      num_expanded += 1;
      num_generated += succs.size();

      for (unsigned succ_i = 0; succ_i < succs.size(); succ_i += 1)
      {
        Node *succ = succs[succ_i];
        assert(open.size() <= closed.size());
        assert(all_closed_item_ptrs_valid());
        typename Closed::iterator closed_it = closed.find(succ);
        if (closed.find(succ) != closed.end()) {
          boost::optional<typename Open::ItemPointer> &open_ptr = closed_it->second;

          if ( open_ptr ) {
            Node *old_succ = open.lookup(*open_ptr);

            if ( succ->get_f() < old_succ->get_f() ) {
              // A worse copy of succ is in the open list.  Replace it!
              assert(old_succ->get_state() == succ->get_state());
              assert(*old_succ == *succ);

              domain.free_node(old_succ);    // get rid of the old copy
              open.erase(*open_ptr);
              closed.erase(succ);

              open_ptr = open.push(succ);    // insert the new copy
              closed[succ] = open_ptr;

              assert(all_closed_item_ptrs_valid());
            }
          }
          else {
            // succ is not in the open list, but is closed.  Drop it!
            domain.free_node(succ);
          }
        }
        else {
          // succ has not been generated before.
          boost::optional<typename Open::ItemPointer> open_ptr = open.push(succ);
          closed[succ] = open_ptr;
          assert(closed.find(open.lookup(*open_ptr)) != closed.end());
          assert(all_closed_item_ptrs_valid());
        }
      } /* end for */
    } /* end while */
  }

  const Node * get_goal() const
  {
#ifndef NDEBUG
    std::cerr << open.size() << " nodes in open at end of search" << std::endl
              << closed.size() << " nodes in closed at end of search" << std::endl;
#endif
    return goal;
  }

  const Domain & get_domain() const
  {
    return domain;
  }

  unsigned get_num_generated() const
  {
    return num_generated;
  }

  unsigned get_num_expanded() const
  {
    return num_expanded;
  }

private:
  bool all_closed_item_ptrs_valid() const
  {
    return true;
    std::cerr << "checking if item pointers are valid" << std::endl
              << "  " << closed.size() << " pointers to check" << std::endl;
    for (typename Closed::const_iterator closed_it = closed.begin();
         closed_it != closed.end();
         ++closed_it) {
      if ( closed_it->second && !open.valid_item_pointer(*closed_it->second) )
        return false;
    }
    return true;
  }

private:
  Open &open;
  Closed &closed;

  const Node * goal;
  bool searched;

  const Domain &domain;

  unsigned num_expanded;
  unsigned num_generated;

private:
  AStar(const AStar<Domain, Node> &);
  AStar<Domain, Node> & operator =(const AStar<Domain, Node> &);
};

#endif /* !_A_STAR_HPP_ */
<|endoftext|>


<commit_before>/**
 * Licensed under Apache License v2. See LICENSE for more information.
 */
#include <CppUTest/TestHarness.h>
#include "CppUTest/CommandLineTestRunner.h"

extern "C" {
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include <ffi.h>

#include "dyn_common.h"
#include "dyn_type.h"
#include "json_serializer.h"

static void stdLog(void *handle, int level, const char *file, int line, const char *msg, ...) {
    va_list ap;
    const char *levels[5] = {"NIL", "ERROR", "WARNING", "INFO", "DEBUG"};
    fprintf(stderr, "%s: FILE:%s, LINE:%i, MSG:",levels[level], file, line);
    va_start(ap, msg);
    vfprintf(stderr, msg, ap);
    fprintf(stderr, "\n");
}

/*********** example 1 ************************/
/** struct type ******************************/
const char *example1_descriptor = "{DJISF a b c d e}";

const char *example1_input = "{ \
    \"a\" : 1.0, \
    \"b\" : 22, \
    \"c\" : 32, \
    \"d\" : 42, \
    \"e\" : 4.4 \
}";

struct example1 {
    double a;   //0
    int64_t b;  //1
    int32_t c;  //2
    int16_t d;  //3
    float e;    //4
};

static void check_example1(void *data) {
    struct example1 *ex = (struct example1 *)data;
    CHECK_EQUAL(1.0, ex->a);
    LONGS_EQUAL(22, ex->b);
    LONGS_EQUAL(32, ex->c);
    LONGS_EQUAL(42, ex->d);
    CHECK_EQUAL(4.4f, ex->e);
}

/*********** example 2 ************************/
const char *example2_descriptor = "{BJJDFD byte long1 long2 double1 float1 double2}";

const char *example2_input = "{ \
    \"byte\" : 42, \
    \"long1\" : 232, \
    \"long2\" : 242, \
    \"double1\" : 4.2, \
    \"float1\" : 3.2, \
    \"double2\" : 4.4 \
}";

struct example2 {
    char byte;      //0
    int64_t long1;     //1
    int64_t long2;     //2
    double double1; //3
    float float1;   //4
    double double2; //5
};

static void check_example2(void *data) {
    struct example2 *ex = (struct example2 *)data;
    CHECK_EQUAL(42, ex->byte);
    LONGS_EQUAL(232, ex->long1);
    LONGS_EQUAL(242, ex->long2);
    CHECK_EQUAL(4.2, ex->double1);
    CHECK_EQUAL(3.2f, ex->float1);
    CHECK_EQUAL(4.4, ex->double2);
}

/*********** example 3 ************************/
/** sequence with a simple type **************/
const char *example3_descriptor = "{[I numbers}";

const char *example3_input = "{ \
    \"numbers\" : [22,32,42] \
}";

struct example3 {
    struct {
        uint32_t cap;
        uint32_t len;
        int32_t *buf;
    } numbers;
};

static void check_example3(void *data) {
    struct example3 *ex = (struct example3 *)data;
    CHECK_EQUAL(3, ex->numbers.len);
    CHECK_EQUAL(22, ex->numbers.buf[0]);
    CHECK_EQUAL(32, ex->numbers.buf[1]);
    CHECK_EQUAL(42, ex->numbers.buf[2]);
}

/*********** example 4 ************************/
/** structs within a struct (by reference)*******/
const char *example4_descriptor = "{{IDD index val1 val2}{IDD index val1 val2} left right}";

static const char *example4_input =  "{ \
    \"left\" : {\"index\":1, \"val1\":1.0, \"val2\":2.0 }, \
    \"right\" : {\"index\":2, \"val1\":5.0, \"val2\":4.0 } \
}";

struct ex4_leaf {
    int32_t index;
    double val1;
    double val2;
};

struct example4 {
    struct ex4_leaf left;
    struct ex4_leaf right;
};

static void check_example4(void *data) {
    struct example4 *ex = (struct example4 *)data;
    CHECK_EQUAL(1, ex->left.index);
    CHECK_EQUAL(1.0, ex->left.val1);
    CHECK_EQUAL(2.0, ex->left.val2);
    CHECK_EQUAL(2, ex->right.index);
    CHECK_EQUAL(5.0, ex->right.val1);
    CHECK_EQUAL(4.0, ex->right.val2);
}

/*********** example 4 ************************/
/** structs within a struct (by reference)*******/
const char *example5_descriptor = "Tleaf={ts name age};Tnode={Lnode;Lnode;Lleaf; left right value};{Lnode; head}";

static const char *example5_input =  "{ \
    \"head\" : {\
        \"left\" : {\
            \"value\" : {\
                \"name\" : \"John\",\
                \"age\" : 44 \
            }\
        },\
        \"right\" : {\
            \"value\" : {\
                \"name\" : \"Peter\", \
                \"age\" : 55 \
            }\
        }\
    }\
}";

struct leaf {
    const char *name;
    uint16_t age;
};

struct node {
    struct node *left;
    struct node *right;
    struct leaf *value;
};

struct example5 {
    struct node *head;
};

static void check_example5(void *data) {
    struct example5 *ex = (struct example5 *)data;
    CHECK_TRUE(ex->head != NULL);

    CHECK(ex->head->left != NULL);
    CHECK(ex->head->left->value != NULL);
    STRCMP_EQUAL("John", ex->head->left->value->name);
    CHECK_EQUAL(44, ex->head->left->value->age);
    CHECK(ex->head->left->left == NULL);
    CHECK(ex->head->left->right == NULL);

    CHECK(ex->head->right != NULL);
    CHECK(ex->head->right->value != NULL);
    STRCMP_EQUAL("Peter", ex->head->right->value->name);
    CHECK_EQUAL(55, ex->head->right->value->age);
    CHECK(ex->head->right->left == NULL);
    CHECK(ex->head->right->right == NULL);
}

static const char *example6_descriptor = "Tsample={DD v1 v2};[lsample;";

static const char *example6_input = "[{\"v1\":0.1,\"v2\":0.2},{\"v1\":1.1,\"v2\":1.2},{\"v1\":2.1,\"v2\":2.2}]";

struct ex6_sample {
    double v1;
    double v2;
};

struct ex6_sequence {
    uint32_t cap;
    uint32_t len;
    struct ex6_sample *buf;
};

static void check_example6(struct ex6_sequence seq) {
    CHECK_EQUAL(3, seq.cap);
    CHECK_EQUAL(3, seq.len);
    CHECK_EQUAL(0.1, seq.buf[0].v1);
    CHECK_EQUAL(0.2, seq.buf[0].v2);
    CHECK_EQUAL(1.1, seq.buf[1].v1);
    CHECK_EQUAL(1.2, seq.buf[1].v2);
    CHECK_EQUAL(2.1, seq.buf[2].v1);
    CHECK_EQUAL(2.2, seq.buf[2].v2);
}

static void parseTests(void) {
    dyn_type *type;
    void *inst;
    int rc;

    type = NULL;
    inst = NULL;
    rc = dynType_parseWithStr(example1_descriptor, NULL, NULL, &type);
    CHECK_EQUAL(0, rc);
    rc = jsonSerializer_deserialize(type, example1_input, &inst);
    CHECK_EQUAL(0, rc);
    check_example1(inst);
    dynType_free(type, inst);
    dynType_destroy(type);

    type = NULL;
    inst = NULL;
    rc = dynType_parseWithStr(example2_descriptor, NULL, NULL, &type);
    CHECK_EQUAL(0, rc);
    rc = jsonSerializer_deserialize(type, example2_input, &inst);
    CHECK_EQUAL(0, rc);
    check_example2(inst);
    dynType_free(type, inst);
    dynType_destroy(type);

    type = NULL;
    inst = NULL;
    rc = dynType_parseWithStr(example3_descriptor, NULL, NULL, &type);
    CHECK_EQUAL(0, rc);
    rc = jsonSerializer_deserialize(type, example3_input, &inst);
    CHECK_EQUAL(0, rc);
    check_example3(inst);
    dynType_free(type, inst);
    dynType_destroy(type);

    type = NULL;
    inst = NULL;
    rc = dynType_parseWithStr(example4_descriptor, NULL, NULL, &type);
    CHECK_EQUAL(0, rc);
    rc = jsonSerializer_deserialize(type, example4_input, &inst);
    CHECK_EQUAL(0, rc);
    check_example4(inst);
    dynType_free(type, inst);
    dynType_destroy(type);

    type = NULL;
    inst = NULL;
    rc = dynType_parseWithStr(example5_descriptor, NULL, NULL, &type);
    CHECK_EQUAL(0, rc);
    rc = jsonSerializer_deserialize(type, example5_input, &inst);
    CHECK_EQUAL(0, rc);
    check_example5(inst);
    dynType_free(type, inst);
    dynType_destroy(type);

    type = NULL;
    struct ex6_sequence *seq;
    rc = dynType_parseWithStr(example6_descriptor, NULL, NULL, &type);
    CHECK_EQUAL(0, rc);
    rc = jsonSerializer_deserialize(type, example6_input, (void **)&seq);
    CHECK_EQUAL(0, rc);
    check_example6((*seq));
    dynType_free(type, seq);
    dynType_destroy(type);
}

const char *write_example1_descriptor = "{BSIJsijFDN a b c d e f g h i j}";

struct write_example1 {
    char a;
    int16_t b;
    int32_t c;
    int64_t d;
    uint16_t e;
    uint32_t f;
    uint64_t g;
    float h;
    double i;
    int j;
};

void writeTest1(void) {
    struct write_example1 ex1 = {.a=1, .b=2, .c=3, .d=4, .e=5, .f=6, .g=7, .h=8.8f, .i=9.9, .j=10};
    dyn_type *type = NULL;
    char *result = NULL;
    int rc = dynType_parseWithStr(write_example1_descriptor, "ex1", NULL, &type);
    CHECK_EQUAL(0, rc);
    rc = jsonSerializer_serialize(type, &ex1, &result);
    CHECK_EQUAL(0, rc);
    STRCMP_CONTAINS("\"a\":1", result);
    STRCMP_CONTAINS("\"b\":2", result);
    STRCMP_CONTAINS("\"c\":3", result);
    STRCMP_CONTAINS("\"d\":4", result);
    STRCMP_CONTAINS("\"e\":5", result);
    STRCMP_CONTAINS("\"f\":6", result);
    STRCMP_CONTAINS("\"g\":7", result);
    STRCMP_CONTAINS("\"h\":8.8", result);
    STRCMP_CONTAINS("\"i\":9.9", result);
    STRCMP_CONTAINS("\"j\":10", result);
    //printf("example 1 result: '%s'\n", result);
    dynType_destroy(type);
    free(result);
}

const char *write_example2_descriptor = "{*{JJ a b}{SS c d} sub1 sub2}";

struct write_example2_sub {
        int64_t a;
        int64_t b;
};

struct write_example2 {
    struct write_example2_sub *sub1;
    struct {
        int16_t c;
        int16_t d;
    } sub2;
};

void writeTest2(void) {
    struct write_example2_sub sub1 = { .a = 1, .b = 2 };
    struct write_example2 ex = { .sub1 = &sub1 };
    ex.sub2.c = 3;
    ex.sub2.d = 4;

    dyn_type *type = NULL;
    char *result = NULL;
    int rc = dynType_parseWithStr(write_example2_descriptor, "ex2", NULL, &type);
    CHECK_EQUAL(0, rc);
    rc = jsonSerializer_serialize(type, &ex, &result);
    CHECK_EQUAL(0, rc);
    STRCMP_CONTAINS("\"a\":1", result);
    STRCMP_CONTAINS("\"b\":2", result);
    STRCMP_CONTAINS("\"c\":3", result);
    STRCMP_CONTAINS("\"d\":4", result);
    //printf("example 2 result: '%s'\n", result);
    dynType_destroy(type);
    free(result);
}

const char *write_example3_descriptor = "Tperson={ti name age};[Lperson;";

struct write_example3_person {
    const char *name;
    uint32_t age;
};

struct write_example3 {
    uint32_t cap;
    uint32_t len;
    struct write_example3_person **buf;
};

void writeTest3(void) {
    struct write_example3_person p1 = {.name = "John", .age = 33};
    struct write_example3_person p2 = {.name = "Peter", .age = 44};
    struct write_example3_person p3 = {.name = "Carol", .age = 55};
    struct write_example3_person p4 = {.name = "Elton", .age = 66};
    struct write_example3 seq;
    seq.buf = (struct write_example3_person **) calloc(4, sizeof(void *));
    seq.len = seq.cap = 4;
    seq.buf[0] = &p1;
    seq.buf[1] = &p2;
    seq.buf[2] = &p3;
    seq.buf[3] = &p4;

    dyn_type *type = NULL;
    char *result = NULL;
    int rc = dynType_parseWithStr(write_example3_descriptor, "ex3", NULL, &type);
    CHECK_EQUAL(0, rc);
    rc = jsonSerializer_serialize(type, &seq, &result);
    CHECK_EQUAL(0, rc);
    STRCMP_CONTAINS("\"age\":33", result);
    STRCMP_CONTAINS("\"age\":44", result);
    STRCMP_CONTAINS("\"age\":55", result);
    STRCMP_CONTAINS("\"age\":66", result);
    //printf("example 3 result: '%s'\n", result);
    free(seq.buf);
    dynType_destroy(type);
    free(result);
}

}

TEST_GROUP(JsonSerializerTests) {
    void setup() {
        int lvl = 1;
        dynCommon_logSetup(stdLog, NULL, lvl);
        dynType_logSetup(stdLog, NULL,lvl);
        jsonSerializer_logSetup(stdLog, NULL, lvl);
    }
};

TEST(JsonSerializerTests, ParseTests) {
    //TODO split up
    parseTests();
}

TEST(JsonSerializerTests, WriteTest1) {
    writeTest1();
}

TEST(JsonSerializerTests, WriteTest2) {
    writeTest2();
}

TEST(JsonSerializerTests, WriteTest3) {
    writeTest3();
}
<commit_msg>CELIX-237: Changed intialization of test structs.<commit_after>/**
 * Licensed under Apache License v2. See LICENSE for more information.
 */
#include <CppUTest/TestHarness.h>
#include "CppUTest/CommandLineTestRunner.h"

extern "C" {
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include <ffi.h>

#include "dyn_common.h"
#include "dyn_type.h"
#include "json_serializer.h"

static void stdLog(void *handle, int level, const char *file, int line, const char *msg, ...) {
    va_list ap;
    const char *levels[5] = {"NIL", "ERROR", "WARNING", "INFO", "DEBUG"};
    fprintf(stderr, "%s: FILE:%s, LINE:%i, MSG:",levels[level], file, line);
    va_start(ap, msg);
    vfprintf(stderr, msg, ap);
    fprintf(stderr, "\n");
}

/*********** example 1 ************************/
/** struct type ******************************/
const char *example1_descriptor = "{DJISF a b c d e}";

const char *example1_input = "{ \
    \"a\" : 1.0, \
    \"b\" : 22, \
    \"c\" : 32, \
    \"d\" : 42, \
    \"e\" : 4.4 \
}";

struct example1 {
    double a;   //0
    int64_t b;  //1
    int32_t c;  //2
    int16_t d;  //3
    float e;    //4
};

static void check_example1(void *data) {
    struct example1 *ex = (struct example1 *)data;
    CHECK_EQUAL(1.0, ex->a);
    LONGS_EQUAL(22, ex->b);
    LONGS_EQUAL(32, ex->c);
    LONGS_EQUAL(42, ex->d);
    CHECK_EQUAL(4.4f, ex->e);
}

/*********** example 2 ************************/
const char *example2_descriptor = "{BJJDFD byte long1 long2 double1 float1 double2}";

const char *example2_input = "{ \
    \"byte\" : 42, \
    \"long1\" : 232, \
    \"long2\" : 242, \
    \"double1\" : 4.2, \
    \"float1\" : 3.2, \
    \"double2\" : 4.4 \
}";

struct example2 {
    char byte;      //0
    int64_t long1;     //1
    int64_t long2;     //2
    double double1; //3
    float float1;   //4
    double double2; //5
};

static void check_example2(void *data) {
    struct example2 *ex = (struct example2 *)data;
    CHECK_EQUAL(42, ex->byte);
    LONGS_EQUAL(232, ex->long1);
    LONGS_EQUAL(242, ex->long2);
    CHECK_EQUAL(4.2, ex->double1);
    CHECK_EQUAL(3.2f, ex->float1);
    CHECK_EQUAL(4.4, ex->double2);
}

/*********** example 3 ************************/
/** sequence with a simple type **************/
const char *example3_descriptor = "{[I numbers}";

const char *example3_input = "{ \
    \"numbers\" : [22,32,42] \
}";

struct example3 {
    struct {
        uint32_t cap;
        uint32_t len;
        int32_t *buf;
    } numbers;
};

static void check_example3(void *data) {
    struct example3 *ex = (struct example3 *)data;
    CHECK_EQUAL(3, ex->numbers.len);
    CHECK_EQUAL(22, ex->numbers.buf[0]);
    CHECK_EQUAL(32, ex->numbers.buf[1]);
    CHECK_EQUAL(42, ex->numbers.buf[2]);
}

/*********** example 4 ************************/
/** structs within a struct (by reference)*******/
const char *example4_descriptor = "{{IDD index val1 val2}{IDD index val1 val2} left right}";

static const char *example4_input =  "{ \
    \"left\" : {\"index\":1, \"val1\":1.0, \"val2\":2.0 }, \
    \"right\" : {\"index\":2, \"val1\":5.0, \"val2\":4.0 } \
}";

struct ex4_leaf {
    int32_t index;
    double val1;
    double val2;
};

struct example4 {
    struct ex4_leaf left;
    struct ex4_leaf right;
};

static void check_example4(void *data) {
    struct example4 *ex = (struct example4 *)data;
    CHECK_EQUAL(1, ex->left.index);
    CHECK_EQUAL(1.0, ex->left.val1);
    CHECK_EQUAL(2.0, ex->left.val2);
    CHECK_EQUAL(2, ex->right.index);
    CHECK_EQUAL(5.0, ex->right.val1);
    CHECK_EQUAL(4.0, ex->right.val2);
}

/*********** example 4 ************************/
/** structs within a struct (by reference)*******/
const char *example5_descriptor = "Tleaf={ts name age};Tnode={Lnode;Lnode;Lleaf; left right value};{Lnode; head}";

static const char *example5_input =  "{ \
    \"head\" : {\
        \"left\" : {\
            \"value\" : {\
                \"name\" : \"John\",\
                \"age\" : 44 \
            }\
        },\
        \"right\" : {\
            \"value\" : {\
                \"name\" : \"Peter\", \
                \"age\" : 55 \
            }\
        }\
    }\
}";

struct leaf {
    const char *name;
    uint16_t age;
};

struct node {
    struct node *left;
    struct node *right;
    struct leaf *value;
};

struct example5 {
    struct node *head;
};

static void check_example5(void *data) {
    struct example5 *ex = (struct example5 *)data;
    CHECK_TRUE(ex->head != NULL);

    CHECK(ex->head->left != NULL);
    CHECK(ex->head->left->value != NULL);
    STRCMP_EQUAL("John", ex->head->left->value->name);
    CHECK_EQUAL(44, ex->head->left->value->age);
    CHECK(ex->head->left->left == NULL);
    CHECK(ex->head->left->right == NULL);

    CHECK(ex->head->right != NULL);
    CHECK(ex->head->right->value != NULL);
    STRCMP_EQUAL("Peter", ex->head->right->value->name);
    CHECK_EQUAL(55, ex->head->right->value->age);
    CHECK(ex->head->right->left == NULL);
    CHECK(ex->head->right->right == NULL);
}

static const char *example6_descriptor = "Tsample={DD v1 v2};[lsample;";

static const char *example6_input = "[{\"v1\":0.1,\"v2\":0.2},{\"v1\":1.1,\"v2\":1.2},{\"v1\":2.1,\"v2\":2.2}]";

struct ex6_sample {
    double v1;
    double v2;
};

struct ex6_sequence {
    uint32_t cap;
    uint32_t len;
    struct ex6_sample *buf;
};

static void check_example6(struct ex6_sequence seq) {
    CHECK_EQUAL(3, seq.cap);
    CHECK_EQUAL(3, seq.len);
    CHECK_EQUAL(0.1, seq.buf[0].v1);
    CHECK_EQUAL(0.2, seq.buf[0].v2);
    CHECK_EQUAL(1.1, seq.buf[1].v1);
    CHECK_EQUAL(1.2, seq.buf[1].v2);
    CHECK_EQUAL(2.1, seq.buf[2].v1);
    CHECK_EQUAL(2.2, seq.buf[2].v2);
}

static void parseTests(void) {
    dyn_type *type;
    void *inst;
    int rc;

    type = NULL;
    inst = NULL;
    rc = dynType_parseWithStr(example1_descriptor, NULL, NULL, &type);
    CHECK_EQUAL(0, rc);
    rc = jsonSerializer_deserialize(type, example1_input, &inst);
    CHECK_EQUAL(0, rc);
    check_example1(inst);
    dynType_free(type, inst);
    dynType_destroy(type);

    type = NULL;
    inst = NULL;
    rc = dynType_parseWithStr(example2_descriptor, NULL, NULL, &type);
    CHECK_EQUAL(0, rc);
    rc = jsonSerializer_deserialize(type, example2_input, &inst);
    CHECK_EQUAL(0, rc);
    check_example2(inst);
    dynType_free(type, inst);
    dynType_destroy(type);

    type = NULL;
    inst = NULL;
    rc = dynType_parseWithStr(example3_descriptor, NULL, NULL, &type);
    CHECK_EQUAL(0, rc);
    rc = jsonSerializer_deserialize(type, example3_input, &inst);
    CHECK_EQUAL(0, rc);
    check_example3(inst);
    dynType_free(type, inst);
    dynType_destroy(type);

    type = NULL;
    inst = NULL;
    rc = dynType_parseWithStr(example4_descriptor, NULL, NULL, &type);
    CHECK_EQUAL(0, rc);
    rc = jsonSerializer_deserialize(type, example4_input, &inst);
    CHECK_EQUAL(0, rc);
    check_example4(inst);
    dynType_free(type, inst);
    dynType_destroy(type);

    type = NULL;
    inst = NULL;
    rc = dynType_parseWithStr(example5_descriptor, NULL, NULL, &type);
    CHECK_EQUAL(0, rc);
    rc = jsonSerializer_deserialize(type, example5_input, &inst);
    CHECK_EQUAL(0, rc);
    check_example5(inst);
    dynType_free(type, inst);
    dynType_destroy(type);

    type = NULL;
    struct ex6_sequence *seq;
    rc = dynType_parseWithStr(example6_descriptor, NULL, NULL, &type);
    CHECK_EQUAL(0, rc);
    rc = jsonSerializer_deserialize(type, example6_input, (void **)&seq);
    CHECK_EQUAL(0, rc);
    check_example6((*seq));
    dynType_free(type, seq);
    dynType_destroy(type);
}

const char *write_example1_descriptor = "{BSIJsijFDN a b c d e f g h i j}";

struct write_example1 {
    char a;
    int16_t b;
    int32_t c;
    int64_t d;
    uint16_t e;
    uint32_t f;
    uint64_t g;
    float h;
    double i;
    int j;
};

void writeTest1(void) {
    struct write_example1 ex1;
    ex1.a=1;
    ex1.b=2;
    ex1.c=3;
    ex1.d=4;
    ex1.e=5;
    ex1.f=6;
    ex1.g=7;
    ex1.h=8.8f;
    ex1.i=9.9;
    ex1.j=10;

    dyn_type *type = NULL;
    char *result = NULL;
    int rc = dynType_parseWithStr(write_example1_descriptor, "ex1", NULL, &type);
    CHECK_EQUAL(0, rc);
    rc = jsonSerializer_serialize(type, &ex1, &result);
    CHECK_EQUAL(0, rc);
    STRCMP_CONTAINS("\"a\":1", result);
    STRCMP_CONTAINS("\"b\":2", result);
    STRCMP_CONTAINS("\"c\":3", result);
    STRCMP_CONTAINS("\"d\":4", result);
    STRCMP_CONTAINS("\"e\":5", result);
    STRCMP_CONTAINS("\"f\":6", result);
    STRCMP_CONTAINS("\"g\":7", result);
    STRCMP_CONTAINS("\"h\":8.8", result);
    STRCMP_CONTAINS("\"i\":9.9", result);
    STRCMP_CONTAINS("\"j\":10", result);
    //printf("example 1 result: '%s'\n", result);
    dynType_destroy(type);
    free(result);
}

const char *write_example2_descriptor = "{*{JJ a b}{SS c d} sub1 sub2}";

struct write_example2_sub {
        int64_t a;
        int64_t b;
};

struct write_example2 {
    struct write_example2_sub *sub1;
    struct {
        int16_t c;
        int16_t d;
    } sub2;
};

void writeTest2(void) {
    struct write_example2_sub sub1;
    sub1.a = 1;
    sub1.b = 2;

    struct write_example2 ex;
    ex.sub1=&sub1;
    ex.sub2.c = 3;
    ex.sub2.d = 4;

    dyn_type *type = NULL;
    char *result = NULL;
    int rc = dynType_parseWithStr(write_example2_descriptor, "ex2", NULL, &type);
    CHECK_EQUAL(0, rc);
    rc = jsonSerializer_serialize(type, &ex, &result);
    CHECK_EQUAL(0, rc);
    STRCMP_CONTAINS("\"a\":1", result);
    STRCMP_CONTAINS("\"b\":2", result);
    STRCMP_CONTAINS("\"c\":3", result);
    STRCMP_CONTAINS("\"d\":4", result);
    //printf("example 2 result: '%s'\n", result);
    dynType_destroy(type);
    free(result);
}

const char *write_example3_descriptor = "Tperson={ti name age};[Lperson;";

struct write_example3_person {
    const char *name;
    uint32_t age;
};

struct write_example3 {
    uint32_t cap;
    uint32_t len;
    struct write_example3_person **buf;
};

void writeTest3(void) {
    struct write_example3_person p1;
    p1.name = "John";
    p1.age = 33;

    struct write_example3_person p2;
    p2.name = "Peter";
    p2.age = 44;

    struct write_example3_person p3;
    p3.name = "Carol";
    p3.age = 55;

    struct write_example3_person p4;
    p4.name = "Elton";
    p4.age = 66;

    struct write_example3 seq;
    seq.buf = (struct write_example3_person **) calloc(4, sizeof(void *));
    seq.len = seq.cap = 4;
    seq.buf[0] = &p1;
    seq.buf[1] = &p2;
    seq.buf[2] = &p3;
    seq.buf[3] = &p4;

    dyn_type *type = NULL;
    char *result = NULL;
    int rc = dynType_parseWithStr(write_example3_descriptor, "ex3", NULL, &type);
    CHECK_EQUAL(0, rc);
    rc = jsonSerializer_serialize(type, &seq, &result);
    CHECK_EQUAL(0, rc);
    STRCMP_CONTAINS("\"age\":33", result);
    STRCMP_CONTAINS("\"age\":44", result);
    STRCMP_CONTAINS("\"age\":55", result);
    STRCMP_CONTAINS("\"age\":66", result);
    //printf("example 3 result: '%s'\n", result);
    free(seq.buf);
    dynType_destroy(type);
    free(result);
}

}

TEST_GROUP(JsonSerializerTests) {
    void setup() {
        int lvl = 1;
        dynCommon_logSetup(stdLog, NULL, lvl);
        dynType_logSetup(stdLog, NULL,lvl);
        jsonSerializer_logSetup(stdLog, NULL, lvl);
    }
};

TEST(JsonSerializerTests, ParseTests) {
    //TODO split up
    parseTests();
}

TEST(JsonSerializerTests, WriteTest1) {
    writeTest1();
}

TEST(JsonSerializerTests, WriteTest2) {
    writeTest2();
}

TEST(JsonSerializerTests, WriteTest3) {
    writeTest3();
}
<|endoftext|>


<commit_before>/*
 * Copyright 2016, Masayoshi Mizutani, mizutani@sfc.wide.ad.jp
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 * * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <vector>
#include <string>

#include "./gtest.h"
#include "../argparse.hpp"

TEST(Parser, basic_usage) {
  argparse::Parser *psr = new argparse::Parser("test");
  argparse::Argv args = {"./test", "-a"};
  psr->add_argument("-a").action("store_true");

  argparse::Values val = psr->parse_args(args);
  EXPECT_TRUE(val.is_true("a"));

}

TEST(Parser, basic_argument) {
  argparse::Parser *psr = new argparse::Parser("test");
  argparse::Argv args = {"./test", "-a", "v"};
  psr->add_argument("-a");
  argparse::Values val = psr->parse_args(args);
  EXPECT_EQ("v", val.get("a"));
  EXPECT_EQ("v", val.get("a", 0));
  EXPECT_EQ("v", val["a"]); // ["x"] is same with get("x", 0)
}

TEST(Parser, nargs1) {
  argparse::Parser *psr = new argparse::Parser("test");
  psr->add_argument("-a").nargs(1);
  argparse::Argv args1 = {"./test", "-a", "v"};
  argparse::Argv args2 = {"./test", "-a", "v", "w"};

  argparse::Values val = psr->parse_args(args1);
  EXPECT_EQ(val.get("a"), "v");
  EXPECT_THROW(val.get("a", 1), argparse::exception::IndexError);

  EXPECT_THROW(psr->parse_args(args2), argparse::exception::ParseError);
}

TEST(Parser, nargs2) {
  argparse::Parser *psr = new argparse::Parser("test");
  psr->add_argument("-a").nargs(2);
  argparse::Argv args1 = {"./test", "-a", "v"};
  argparse::Argv args2 = {"./test", "-a", "v", "w"};
  argparse::Argv args3 = {"./test", "-a", "v", "w", "x"};

  argparse::Values val = psr->parse_args(args2);
  EXPECT_EQ(val.get("a"), "v");
  EXPECT_EQ(val.get("a", 0), "v");
  EXPECT_EQ(val.get("a", 1), "w");
  EXPECT_THROW(val.get("a", 2), argparse::exception::IndexError);

  EXPECT_THROW(psr->parse_args(args1), argparse::exception::ParseError);
  EXPECT_THROW(psr->parse_args(args3), argparse::exception::ParseError);
}

TEST(Parser, nargs_asterisk) {
  argparse::Parser *psr = new argparse::Parser("test");
  psr->add_argument("-a").nargs("*");
  psr->add_argument("-b");

  // Stop parsing by end of arguments.
  argparse::Argv ok1 = {"./test", "-a", "v1", "v2"};
  argparse::Values v1 = psr->parse_args(ok1);
  EXPECT_EQ(2, v1.size("a"));
  EXPECT_EQ("v1", v1.get("a", 0));
  EXPECT_EQ("v2", v1.get("a", 1));

  // Stop parsing by an other option.
  argparse::Argv ok2 = {"./test", "-a", "v1", "v2", "-b", "r1"};
  argparse::Values v2 = psr->parse_args(ok2);
  EXPECT_EQ(2, v2.size("a"));
  EXPECT_EQ("v1", v2.get("a", 0));
  EXPECT_EQ("v2", v2.get("a", 1));
  EXPECT_EQ(1, v2.size("b"));
  EXPECT_EQ("r1", v2.get("b"));

  // No option value.
  argparse::Argv ok3 = {"./test", "-a", "-b", "r1"};
  argparse::Values v3 = psr->parse_args(ok3);
  EXPECT_EQ(0, v3.size("a"));
  EXPECT_TRUE(v3.is_set("a"));
  EXPECT_EQ(1, v3.size("b"));
  EXPECT_EQ("r1", v3.get("b"));
}

class ParserNargsQuestion : public ::testing::Test {
public:
  argparse::Parser *psr;
  argparse::Argument *arg;
  virtual void SetUp() {
    psr = new argparse::Parser("test");
    arg = &(psr->add_argument("-a").nargs("?")); // 0 or 1 value
    psr->add_argument("-b");
  }

  virtual void TearDown() { delete psr; }
};

TEST_F(ParserNargsQuestion, ok0) {
  argparse::Argv seq = {"./test"};
  argparse::Values v = psr->parse_args(seq);
  EXPECT_FALSE(v.is_set("a"));
  EXPECT_EQ(0, v.size("a"));
  EXPECT_FALSE(v.is_set("b"));
}

TEST_F(ParserNargsQuestion, ok1) {
  argparse::Argv seq = {"./test", "-a"};
  argparse::Values v = psr->parse_args(seq);
  EXPECT_TRUE(v.is_set("a"));
  EXPECT_EQ(1, v.size("a"));
  EXPECT_FALSE(v.is_set("b"));
}

TEST_F(ParserNargsQuestion, ok2) {
  argparse::Argv seq = {"./test", "-a", "v1"};
  argparse::Values v = psr->parse_args(seq);
  EXPECT_TRUE(v.is_set("a"));
  EXPECT_EQ(1, v.size("a"));
  EXPECT_EQ("v1", v["a"]);
  EXPECT_FALSE(v.is_set("b"));
}

TEST_F(ParserNargsQuestion, ok3) {
  argparse::Argv seq = {"./test", "-a", "v1", "-b", "r1"};
  argparse::Values v = psr->parse_args(seq);
  EXPECT_TRUE(v.is_set("a"));
  EXPECT_EQ(1, v.size("a"));
  EXPECT_EQ("v1", v["a"]);
  EXPECT_TRUE(v.is_set("b"));
}

TEST_F(ParserNargsQuestion, with_default1) {
  arg->set_default("d");
  argparse::Argv seq = {"./test", "-a"};
  argparse::Values v = psr->parse_args(seq);
  EXPECT_TRUE(v.is_set("a"));
  EXPECT_EQ(1, v.size("a"));
  EXPECT_EQ("d", v["a"]);
}

TEST_F(ParserNargsQuestion, with_default2) {
  arg->set_default("d");
  argparse::Argv seq = {"./test"};
  argparse::Values v = psr->parse_args(seq);
  EXPECT_TRUE(v.is_set("a"));
  EXPECT_EQ(1, v.size("a"));
  EXPECT_EQ("d", v["a"]);
}

TEST_F(ParserNargsQuestion, with_const) {
  arg->set_const("c");
  argparse::Argv seq = {"./test", "-a"};
  argparse::Values v = psr->parse_args(seq);
  EXPECT_TRUE(v.is_set("a"));
  EXPECT_EQ(1, v.size("a"));
  EXPECT_EQ("c", v["a"]);
}

TEST(Parser, name2) {
  argparse::Parser *psr = new argparse::Parser("test");
  psr->add_argument("-a").name("--action");
  argparse::Argv ok1 = {"./test", "-a", "v"};
  argparse::Argv ok2 = {"./test", "--action", "v"};
  argparse::Argv ng1 = {"./test", "-a"}; // Not enough arguments
  argparse::Argv ng2 = {"./test", "--action"}; // Same as above

  argparse::Values v1 = psr->parse_args(ok1);
  argparse::Values v2 = psr->parse_args(ok2);
  EXPECT_EQ(v1.get("a"), "v"); // Using "name" instead of "dest".
  EXPECT_EQ(v2.get("a"), "v"); // Same if the option is set by 2nd name (--aciton)

  EXPECT_THROW(psr->parse_args(ng1), argparse::exception::ParseError);
  EXPECT_THROW(psr->parse_args(ng1), argparse::exception::ParseError);
}

<commit_msg>add test for ParserNargsQuestion with both of default and const<commit_after>/*
 * Copyright 2016, Masayoshi Mizutani, mizutani@sfc.wide.ad.jp
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 * * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <vector>
#include <string>

#include "./gtest.h"
#include "../argparse.hpp"

TEST(Parser, basic_usage) {
  argparse::Parser *psr = new argparse::Parser("test");
  argparse::Argv args = {"./test", "-a"};
  psr->add_argument("-a").action("store_true");

  argparse::Values val = psr->parse_args(args);
  EXPECT_TRUE(val.is_true("a"));

}

TEST(Parser, basic_argument) {
  argparse::Parser *psr = new argparse::Parser("test");
  argparse::Argv args = {"./test", "-a", "v"};
  psr->add_argument("-a");
  argparse::Values val = psr->parse_args(args);
  EXPECT_EQ("v", val.get("a"));
  EXPECT_EQ("v", val.get("a", 0));
  EXPECT_EQ("v", val["a"]); // ["x"] is same with get("x", 0)
}

TEST(Parser, nargs1) {
  argparse::Parser *psr = new argparse::Parser("test");
  psr->add_argument("-a").nargs(1);
  argparse::Argv args1 = {"./test", "-a", "v"};
  argparse::Argv args2 = {"./test", "-a", "v", "w"};

  argparse::Values val = psr->parse_args(args1);
  EXPECT_EQ(val.get("a"), "v");
  EXPECT_THROW(val.get("a", 1), argparse::exception::IndexError);

  EXPECT_THROW(psr->parse_args(args2), argparse::exception::ParseError);
}

TEST(Parser, nargs2) {
  argparse::Parser *psr = new argparse::Parser("test");
  psr->add_argument("-a").nargs(2);
  argparse::Argv args1 = {"./test", "-a", "v"};
  argparse::Argv args2 = {"./test", "-a", "v", "w"};
  argparse::Argv args3 = {"./test", "-a", "v", "w", "x"};

  argparse::Values val = psr->parse_args(args2);
  EXPECT_EQ(val.get("a"), "v");
  EXPECT_EQ(val.get("a", 0), "v");
  EXPECT_EQ(val.get("a", 1), "w");
  EXPECT_THROW(val.get("a", 2), argparse::exception::IndexError);

  EXPECT_THROW(psr->parse_args(args1), argparse::exception::ParseError);
  EXPECT_THROW(psr->parse_args(args3), argparse::exception::ParseError);
}

TEST(Parser, nargs_asterisk) {
  argparse::Parser *psr = new argparse::Parser("test");
  psr->add_argument("-a").nargs("*");
  psr->add_argument("-b");

  // Stop parsing by end of arguments.
  argparse::Argv ok1 = {"./test", "-a", "v1", "v2"};
  argparse::Values v1 = psr->parse_args(ok1);
  EXPECT_EQ(2, v1.size("a"));
  EXPECT_EQ("v1", v1.get("a", 0));
  EXPECT_EQ("v2", v1.get("a", 1));

  // Stop parsing by an other option.
  argparse::Argv ok2 = {"./test", "-a", "v1", "v2", "-b", "r1"};
  argparse::Values v2 = psr->parse_args(ok2);
  EXPECT_EQ(2, v2.size("a"));
  EXPECT_EQ("v1", v2.get("a", 0));
  EXPECT_EQ("v2", v2.get("a", 1));
  EXPECT_EQ(1, v2.size("b"));
  EXPECT_EQ("r1", v2.get("b"));

  // No option value.
  argparse::Argv ok3 = {"./test", "-a", "-b", "r1"};
  argparse::Values v3 = psr->parse_args(ok3);
  EXPECT_EQ(0, v3.size("a"));
  EXPECT_TRUE(v3.is_set("a"));
  EXPECT_EQ(1, v3.size("b"));
  EXPECT_EQ("r1", v3.get("b"));
}

class ParserNargsQuestion : public ::testing::Test {
public:
  argparse::Parser *psr;
  argparse::Argument *arg;
  virtual void SetUp() {
    psr = new argparse::Parser("test");
    arg = &(psr->add_argument("-a").nargs("?")); // 0 or 1 value
    psr->add_argument("-b");
  }

  virtual void TearDown() { delete psr; }
};

TEST_F(ParserNargsQuestion, ok0) {
  argparse::Argv seq = {"./test"};
  argparse::Values v = psr->parse_args(seq);
  EXPECT_FALSE(v.is_set("a"));
  EXPECT_EQ(0, v.size("a"));
  EXPECT_FALSE(v.is_set("b"));
}

TEST_F(ParserNargsQuestion, ok1) {
  argparse::Argv seq = {"./test", "-a"};
  argparse::Values v = psr->parse_args(seq);
  EXPECT_TRUE(v.is_set("a"));
  EXPECT_EQ(1, v.size("a"));
  EXPECT_FALSE(v.is_set("b"));
}

TEST_F(ParserNargsQuestion, ok2) {
  argparse::Argv seq = {"./test", "-a", "v1"};
  argparse::Values v = psr->parse_args(seq);
  EXPECT_TRUE(v.is_set("a"));
  EXPECT_EQ(1, v.size("a"));
  EXPECT_EQ("v1", v["a"]);
  EXPECT_FALSE(v.is_set("b"));
}

TEST_F(ParserNargsQuestion, ok3) {
  argparse::Argv seq = {"./test", "-a", "v1", "-b", "r1"};
  argparse::Values v = psr->parse_args(seq);
  EXPECT_TRUE(v.is_set("a"));
  EXPECT_EQ(1, v.size("a"));
  EXPECT_EQ("v1", v["a"]);
  EXPECT_TRUE(v.is_set("b"));
}

TEST_F(ParserNargsQuestion, with_default1) {
  arg->set_default("d");
  argparse::Argv seq = {"./test", "-a"};
  argparse::Values v = psr->parse_args(seq);
  EXPECT_TRUE(v.is_set("a"));
  EXPECT_EQ(1, v.size("a"));
  EXPECT_EQ("d", v["a"]);
}

TEST_F(ParserNargsQuestion, with_default2) {
  arg->set_default("d");
  argparse::Argv seq = {"./test"};
  argparse::Values v = psr->parse_args(seq);
  EXPECT_TRUE(v.is_set("a"));
  EXPECT_EQ(1, v.size("a"));
  EXPECT_EQ("d", v["a"]);
}

TEST_F(ParserNargsQuestion, with_const) {
  arg->set_const("c");
  argparse::Argv seq = {"./test", "-a"};
  argparse::Values v = psr->parse_args(seq);
  EXPECT_TRUE(v.is_set("a"));
  EXPECT_EQ(1, v.size("a"));
  EXPECT_EQ("c", v["a"]);
}

TEST_F(ParserNargsQuestion, with_default_and_const) {
  arg->set_const("c").set_default("d");
  argparse::Argv seq = {"./test", "-a"};
  argparse::Values v = psr->parse_args(seq);
  EXPECT_TRUE(v.is_set("a"));
  EXPECT_EQ(1, v.size("a"));
  // 'const' has priority over 'default'
  EXPECT_EQ("c", v["a"]);
}

TEST(Parser, name2) {
  argparse::Parser *psr = new argparse::Parser("test");
  psr->add_argument("-a").name("--action");
  argparse::Argv ok1 = {"./test", "-a", "v"};
  argparse::Argv ok2 = {"./test", "--action", "v"};
  argparse::Argv ng1 = {"./test", "-a"}; // Not enough arguments
  argparse::Argv ng2 = {"./test", "--action"}; // Same as above

  argparse::Values v1 = psr->parse_args(ok1);
  argparse::Values v2 = psr->parse_args(ok2);
  EXPECT_EQ(v1.get("a"), "v"); // Using "name" instead of "dest".
  EXPECT_EQ(v2.get("a"), "v"); // Same if the option is set by 2nd name (--aciton)

  EXPECT_THROW(psr->parse_args(ng1), argparse::exception::ParseError);
  EXPECT_THROW(psr->parse_args(ng1), argparse::exception::ParseError);
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: xlpage.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 19:37:34 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef SC_XLPAGE_HXX
#define SC_XLPAGE_HXX

#ifndef _GEN_HXX
#include <tools/gen.hxx>
#endif
#ifndef SC_XLTOOLS_HXX
#include "xltools.hxx"
#endif

// Constants and Enumerations =================================================

// (0x0014, 0x0015) HEADER, FOOTER --------------------------------------------

const sal_uInt16 EXC_ID_HEADER              = 0x0014;
const sal_uInt16 EXC_ID_FOOTER              = 0x0015;

// (0x001A, 0x001B) VERTICAL-, HORIZONTALPAGEBREAKS ---------------------------

const sal_uInt16 EXC_ID_VERPAGEBREAKS       = 0x001A;
const sal_uInt16 EXC_ID_HORPAGEBREAKS       = 0x001B;

// (0x0026, 0x0027, 0x0028, 0x0029) LEFT-, RIGHT-, TOP-, BOTTOMMARGIN ---------

const sal_uInt16 EXC_ID_LEFTMARGIN          = 0x0026;
const sal_uInt16 EXC_ID_RIGHTMARGIN         = 0x0027;
const sal_uInt16 EXC_ID_TOPMARGIN           = 0x0028;
const sal_uInt16 EXC_ID_BOTTOMMARGIN        = 0x0029;

const sal_Int32 EXC_MARGIN_DEFAULT_LR       = 1900;     /// Left/right default margin in 1/100mm.
const sal_Int32 EXC_MARGIN_DEFAULT_TB       = 2500;     /// Top/bottom default margin in 1/100mm.
const sal_Int32 EXC_MARGIN_DEFAULT_HF       = 1300;     /// Header/footer default margin in 1/100mm.
const sal_Int32 EXC_MARGIN_DEFAULT_HLR      = 1900;     /// Left/right header default margin in 1/100mm.
const sal_Int32 EXC_MARGIN_DEFAULT_FLR      = 1900;     /// Left/right footer default margin in 1/100mm.

// (0x002A, 0x002B) PRINTHEADERS, PRINTGRIDLINES ------------------------------

const sal_uInt16 EXC_ID_PRINTHEADERS        = 0x002A;
const sal_uInt16 EXC_ID_PRINTGRIDLINES      = 0x002B;

// (0x0082, 0x0083, 0x0084) GRIDSET, HCENTER, VCENTER -------------------------

const sal_uInt16 EXC_ID_GRIDSET             = 0x0082;
const sal_uInt16 EXC_ID_HCENTER             = 0x0083;
const sal_uInt16 EXC_ID_VCENTER             = 0x0084;

// (0x00A1) SETUP -------------------------------------------------------------

const sal_uInt16 EXC_ID_SETUP               = 0x00A1;

const sal_uInt16 EXC_SETUP_INROWS           = 0x0001;
const sal_uInt16 EXC_SETUP_PORTRAIT         = 0x0002;
const sal_uInt16 EXC_SETUP_INVALID          = 0x0004;
const sal_uInt16 EXC_SETUP_BLACKWHITE       = 0x0008;
const sal_uInt16 EXC_SETUP_DRAFT            = 0x0010;
const sal_uInt16 EXC_SETUP_PRINTNOTES       = 0x0020;
const sal_uInt16 EXC_SETUP_STARTPAGE        = 0x0080;
const sal_uInt16 EXC_SETUP_NOTES_END        = 0x0200;

const sal_uInt16 EXC_PAPERSIZE_DEFAULT      = 0;

// (0x00E9) BITMAP ------------------------------------------------------------

const sal_uInt16 EXC_ID_BITMAP              = 0x00E9;
const sal_uInt32 EXC_BITMAP_UNKNOWNID       = 0x00010009;
const sal_uInt32 EXC_BITMAP_MAXREC          = 0x201C;
const sal_uInt32 EXC_BITMAP_MAXCONT         = 0x2014;

// ============================================================================

// Page settings ==============================================================

class SvxBrushItem;
class SfxPrinter;

/** Contains all page (print) settings for a single sheet. */
struct XclPageData : ScfNoCopy
{
    typedef ::std::auto_ptr< SvxBrushItem > SvxBrushItemPtr;

    ScfUInt16Vec        maHorPageBreaks;    /// Horizontal page breaks.
    ScfUInt16Vec        maVerPageBreaks;    /// Vertical page breaks.
    SvxBrushItemPtr     mxBrushItem;        /// Background bitmap.
    String              maHeader;           /// Excel header string (empty = off).
    String              maFooter;           /// Excel footer string (empty = off).
    double              mfLeftMargin;       /// Left margin in inches.
    double              mfRightMargin;      /// Right margin in inches.
    double              mfTopMargin;        /// Top margin in inches.
    double              mfBottomMargin;     /// Bottom margin in inches.
    double              mfHeaderMargin;     /// Margin main page to header.
    double              mfFooterMargin;     /// Margin main page to footer.
    double              mfHdrLeftMargin;    /// Left margin to header.
    double              mfHdrRightMargin;   /// Right margin to header.
    double              mfFtrLeftMargin;    /// Left margin to footer.
    double              mfFtrRightMargin;   /// Right margin to footer.
    sal_uInt16          mnPaperSize;        /// Index into paper size table.
    sal_uInt16          mnCopies;           /// Number of copies.
    sal_uInt16          mnStartPage;        /// Start page number.
    sal_uInt16          mnScaling;          /// Scaling in percent.
    sal_uInt16          mnFitToWidth;       /// Fit to number of pages in width.
    sal_uInt16          mnFitToHeight;      /// Fit to number of pages in height.
    sal_uInt16          mnHorPrintRes;      /// Horizontal printing resolution.
    sal_uInt16          mnVerPrintRes;      /// Vertical printing resolution.
    bool                mbValid;            /// false = some of the values are not valid.
    bool                mbPortrait;         /// true = portrait; false = landscape.
    bool                mbPrintInRows;      /// true = in rows; false = in columns.
    bool                mbBlackWhite;       /// true = black/white; false = colors.
    bool                mbDraftQuality;     /// true = draft; false = default quality.
    bool                mbPrintNotes;       /// true = print notes.
    bool                mbManualStart;      /// true = mnStartPage valid; false = automatic.
    bool                mbFitToPages;       /// true = fit to pages; false = scale in percent.
    bool                mbHorCenter;        /// true = centered horizontally; false = left aligned.
    bool                mbVerCenter;        /// true = centered vertically; false = top aligned.
    bool                mbPrintHeadings;    /// true = print column and row headings.
    bool                mbPrintGrid;        /// true = print grid lines.

    explicit            XclPageData();
                        ~XclPageData();

    /** Sets Excel default page settings. */
    void                SetDefaults();

    /** Returns the real paper size (twips) from the paper size index and paper orientation. */
    Size                GetScPaperSize( SfxPrinter* pPrinter ) const;
    /** Sets the Excel paper size index and paper orientation from Calc paper size (twips). */
    void                SetScPaperSize( const Size& rSize, bool bPortrait );
};

// ============================================================================

#endif

<commit_msg>INTEGRATION: CWS chart2mst3 (1.5.26); FILE MERGED 2006/07/11 14:13:49 dr 1.5.26.1: #export of chart line and area formats<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: xlpage.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: vg $ $Date: 2007-05-22 19:59:39 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef SC_XLPAGE_HXX
#define SC_XLPAGE_HXX

#ifndef _GEN_HXX
#include <tools/gen.hxx>
#endif
#ifndef SC_XLTOOLS_HXX
#include "xltools.hxx"
#endif

// Constants and Enumerations =================================================

// (0x0014, 0x0015) HEADER, FOOTER --------------------------------------------

const sal_uInt16 EXC_ID_HEADER              = 0x0014;
const sal_uInt16 EXC_ID_FOOTER              = 0x0015;

// (0x001A, 0x001B) VERTICAL-, HORIZONTALPAGEBREAKS ---------------------------

const sal_uInt16 EXC_ID_VERPAGEBREAKS       = 0x001A;
const sal_uInt16 EXC_ID_HORPAGEBREAKS       = 0x001B;

// (0x0026, 0x0027, 0x0028, 0x0029) LEFT-, RIGHT-, TOP-, BOTTOMMARGIN ---------

const sal_uInt16 EXC_ID_LEFTMARGIN          = 0x0026;
const sal_uInt16 EXC_ID_RIGHTMARGIN         = 0x0027;
const sal_uInt16 EXC_ID_TOPMARGIN           = 0x0028;
const sal_uInt16 EXC_ID_BOTTOMMARGIN        = 0x0029;

const sal_Int32 EXC_MARGIN_DEFAULT_LR       = 1900;     /// Left/right default margin in 1/100mm.
const sal_Int32 EXC_MARGIN_DEFAULT_TB       = 2500;     /// Top/bottom default margin in 1/100mm.
const sal_Int32 EXC_MARGIN_DEFAULT_HF       = 1300;     /// Header/footer default margin in 1/100mm.
const sal_Int32 EXC_MARGIN_DEFAULT_HLR      = 1900;     /// Left/right header default margin in 1/100mm.
const sal_Int32 EXC_MARGIN_DEFAULT_FLR      = 1900;     /// Left/right footer default margin in 1/100mm.

// (0x002A, 0x002B) PRINTHEADERS, PRINTGRIDLINES ------------------------------

const sal_uInt16 EXC_ID_PRINTHEADERS        = 0x002A;
const sal_uInt16 EXC_ID_PRINTGRIDLINES      = 0x002B;

// (0x0033) PRINTSIZE ---------------------------------------------------------

const sal_uInt16 EXC_ID_PRINTSIZE           = 0x0033;

const sal_uInt16 EXC_PRINTSIZE_SCREEN       = 1;
const sal_uInt16 EXC_PRINTSIZE_PAGE         = 2;
const sal_uInt16 EXC_PRINTSIZE_FULL         = 3;

// (0x0082, 0x0083, 0x0084) GRIDSET, HCENTER, VCENTER -------------------------

const sal_uInt16 EXC_ID_GRIDSET             = 0x0082;
const sal_uInt16 EXC_ID_HCENTER             = 0x0083;
const sal_uInt16 EXC_ID_VCENTER             = 0x0084;

// (0x00A1) SETUP -------------------------------------------------------------

const sal_uInt16 EXC_ID_SETUP               = 0x00A1;

const sal_uInt16 EXC_SETUP_INROWS           = 0x0001;
const sal_uInt16 EXC_SETUP_PORTRAIT         = 0x0002;
const sal_uInt16 EXC_SETUP_INVALID          = 0x0004;
const sal_uInt16 EXC_SETUP_BLACKWHITE       = 0x0008;
const sal_uInt16 EXC_SETUP_DRAFT            = 0x0010;
const sal_uInt16 EXC_SETUP_PRINTNOTES       = 0x0020;
const sal_uInt16 EXC_SETUP_STARTPAGE        = 0x0080;
const sal_uInt16 EXC_SETUP_NOTES_END        = 0x0200;

const sal_uInt16 EXC_PAPERSIZE_DEFAULT      = 0;

// (0x00E9) BITMAP ------------------------------------------------------------

const sal_uInt16 EXC_ID_BITMAP              = 0x00E9;
const sal_uInt32 EXC_BITMAP_UNKNOWNID       = 0x00010009;
const sal_uInt32 EXC_BITMAP_MAXREC          = 0x201C;
const sal_uInt32 EXC_BITMAP_MAXCONT         = 0x2014;

// ============================================================================

// Page settings ==============================================================

class SvxBrushItem;
class SfxPrinter;

/** Contains all page (print) settings for a single sheet. */
struct XclPageData : ScfNoCopy
{
    typedef ::std::auto_ptr< SvxBrushItem > SvxBrushItemPtr;

    ScfUInt16Vec        maHorPageBreaks;    /// Horizontal page breaks.
    ScfUInt16Vec        maVerPageBreaks;    /// Vertical page breaks.
    SvxBrushItemPtr     mxBrushItem;        /// Background bitmap.
    String              maHeader;           /// Excel header string (empty = off).
    String              maFooter;           /// Excel footer string (empty = off).
    double              mfLeftMargin;       /// Left margin in inches.
    double              mfRightMargin;      /// Right margin in inches.
    double              mfTopMargin;        /// Top margin in inches.
    double              mfBottomMargin;     /// Bottom margin in inches.
    double              mfHeaderMargin;     /// Margin main page to header.
    double              mfFooterMargin;     /// Margin main page to footer.
    double              mfHdrLeftMargin;    /// Left margin to header.
    double              mfHdrRightMargin;   /// Right margin to header.
    double              mfFtrLeftMargin;    /// Left margin to footer.
    double              mfFtrRightMargin;   /// Right margin to footer.
    sal_uInt16          mnPaperSize;        /// Index into paper size table.
    sal_uInt16          mnCopies;           /// Number of copies.
    sal_uInt16          mnStartPage;        /// Start page number.
    sal_uInt16          mnScaling;          /// Scaling in percent.
    sal_uInt16          mnFitToWidth;       /// Fit to number of pages in width.
    sal_uInt16          mnFitToHeight;      /// Fit to number of pages in height.
    sal_uInt16          mnHorPrintRes;      /// Horizontal printing resolution.
    sal_uInt16          mnVerPrintRes;      /// Vertical printing resolution.
    bool                mbValid;            /// false = some of the values are not valid.
    bool                mbPortrait;         /// true = portrait; false = landscape.
    bool                mbPrintInRows;      /// true = in rows; false = in columns.
    bool                mbBlackWhite;       /// true = black/white; false = colors.
    bool                mbDraftQuality;     /// true = draft; false = default quality.
    bool                mbPrintNotes;       /// true = print notes.
    bool                mbManualStart;      /// true = mnStartPage valid; false = automatic.
    bool                mbFitToPages;       /// true = fit to pages; false = scale in percent.
    bool                mbHorCenter;        /// true = centered horizontally; false = left aligned.
    bool                mbVerCenter;        /// true = centered vertically; false = top aligned.
    bool                mbPrintHeadings;    /// true = print column and row headings.
    bool                mbPrintGrid;        /// true = print grid lines.

    explicit            XclPageData();
                        ~XclPageData();

    /** Sets Excel default page settings. */
    void                SetDefaults();

    /** Returns the real paper size (twips) from the paper size index and paper orientation. */
    Size                GetScPaperSize( SfxPrinter* pPrinter ) const;
    /** Sets the Excel paper size index and paper orientation from Calc paper size (twips). */
    void                SetScPaperSize( const Size& rSize, bool bPortrait );
};

// ============================================================================

#endif

<|endoftext|>