Changeset - bacde69ee1b3
[Not reviewed]
default
2 3 1
Michael Guravage - 14 years ago 2011-01-13 13:36:54
michael.guravage@cwi.nl
Compile leaficon_small.xpm directly into canvas.cpp and revert changes that added a separate icon directory.

--
user: Michael Guravage <michael.guravage@cwi.nl>
branch 'default'
added src/leaficon_small.xpm
changed src/ChangeLog
changed src/VirtualLeaf-install-windows.nsi
changed src/canvas.cpp
removed icons/leaficon.png
removed icons/leaficon_small.png
6 files changed with 325 insertions and 15 deletions:
0 comments (0 inline, 0 general)
icons/leaficon.png
Show inline comments
 
deleted file
 
binary diff not shown
Show images
icons/leaficon_small.png
Show inline comments
 
deleted file
 
binary diff not shown
Show images
src/ChangeLog
Show inline comments
 
2011-01-13    <guravage@petitdru.sen.cwi.nl>
 

	
 
	* VirtualLeaf-install-windows.nsi: Remove previous change that added icon directory.
 

	
 
	* canvas.cpp: Instead of using a separate icon directory, compile
 
	leaficon_small.xpm directly into canvas.cpp.
 

	
 
	* VirtualLeaf-install-windows.nsi: Add new icons directory
 

	
 
	* canvas.cpp (about): Added virtual leaf logo to About message box.
 

	
 
2011-01-12    <guravage@petitdru.sen.cwi.nl>
 

	
 
	* transporterdialog.cpp (TransporterDialog): Add a proper title to
 
	the dialog, and place the cell and wall pairs in a seperate labe.
 

	
 
2011-01-10    <guravage@petitdru.sen.cwi.nl>
 

	
 
	* transporterdialog.cpp (TransporterDialog): Start numbering Transporter fields at zero.
 
	Resolves issue #1: http://code.google.com/p/virtualleaf/issues/detail?id=1.
 

	
 
	* wallitem.cpp (OnClick): Change dialog modality to Qt::WindowModal.
 
	Resolves issue #2: http://code.google.com/p/virtualleaf/issues/detail?id=2.
 

	
 
	* canvas.cpp (about): Add link to Plant Physiology paper.
 
	Resolves issue #3: http://code.google.com/p/virtualleaf/issues/detail?id=3.
 

	
 
2010-11-30    <guravage@petitdru.sen.cwi.nl>
 

	
 
	* canvas.cpp (snapshot): Preface each image format extension with
 
	an asterisk so files with those extensions to appear in the file
 
	dialogue.
 
	(snapshot): Forgot to add asterisk before our own pdf format.
 

	
 
	* VirtualLeaf-install-windows.nsi: Include imageformats folder
 
	alongside executable.
 

	
 
	* canvas.cpp (snapshot): PNG is the default image format.
 

	
 
2010-11-29    <guravage@petitdru.sen.cwi.nl>
 

	
 
	* canvas.cpp (snapshot): Query and display supported snapshot file
 
	formats.
 

	
 
	* VirtualLeaf-install-windows.nsi: To facilitate debugging I added
 
	the debug versions of all the windows DLLs.
 

	
 
2010-10-19    <guravage@caterpie.sen.cwi.nl>
 

	
 
	* mainbase.cpp (Save): Use format specified in function prototype.
 

	
 
	* VirtualLeaf.cpp (Plot): Render PNG instead of JPEG. Write image
 
	and XML files dependent only on getTime().
 

	
 
2010-10-18    <guravage@caterpie.sen.cwi.nl>
 

	
 
	* mainbase.cpp (Save): QDir::toNativeSeparators(fname). Invoke
 
	save with format argument set to zero to force QImage to guess the
 
	format by looking at fileName's suffix.
 

	
 
	* VirtualLeaf-install.nsi: Put uninstaller in top directory.
 

	
 
	* modelcatalogue.cpp (InstallModel): For all OS-es. Move from "bin" directory to root application folder.
 

	
 
	* VirtualLeaf.pro: MAXOSX, look for gpl3.txt in the ../doc directory.
 

	
 
	* Makefile (Makefile.libplugin): Removed -makefile qmake option.
 

	
 
	* VirtualLeaf.cpp (TIMESTEP): Removed getIterations().
 

	
 
	* mesh.h (Mesh): Removed {increment,get}Iterations().
 

	
 
	* canvas.cpp (TimeStepWrap): Replaced getIterations() with getTime().
 

	
 
2010-10-15    <guravage@caterpie.sen.cwi.nl>
 

	
 
	* mesh.h (Mesh): Added iterations. incrementIterations() and
 
	getIterations().
 

	
 
	* VirtualLeaf.cpp (Plot): Replaced local frame counter with
 
	mesh.incrementIterations().
 

	
 
	* canvas.cpp (TimeStepWrap): Replaced local counter with
 
	mesh.incrementIterations().
 

	
 
2010-10-14    <guravage@caterpie.sen.cwi.nl>
 

	
 
	* VirtualLeaf.pro: Turned debug off to make all profiles must be
 
	consistant.
 

	
 
	* VirtualLeaf-install.nsi: Tweaked paths to coincide with UNIX
 
	distribution, i.e. VirtualLeaf.exe, its libraries, models, and the
 
	uninstaller all go in the bin directory. And leaves directory
 
	placed under data directory.
 

	
 
	* canvas.cpp (exportCellData): Added a check to inquire before
 
	overwritting an existing file.
 

	
 

	
 
2010-10-14    <merks@cwi.nl>
 

	
 
	* mesh.cpp: In response to referees' comments, added new parameter
 
	"yield_threshold" instead of fixed parameter '4' for yield
 
	threshold.
 

	
 
	* wallitem.cpp: when clicking a wall, both the wall type was
 
	cycled and the transporterdialog popped up. Corrected this - for
 
	wall type cycling, hold the Control button while left
 
	clicking. TransporterDialog only pops up for left click. Also made
 
	sure the wall is redrawn after changing the transporter values.
 

	
 
	* cell.cpp (DivideWalls): accomodated for rename of Circumference -> WallCircumference
 

	
 
	* hull.h: added an operator< to sort Points
 

	
 
	* hull.cpp: added an operator< to sort Points
 

	
 
	* cellbase.cpp (ExactCircumference): I added a new function
 
	ExactCircumference, yielding the circumference of the cell along
 
	its wall_elements
 

	
 
	* VirtualLeaf.cpp: adjust info_string to accomodate for new name
 
	of function CellBase::Circumference -> CellBase::WallCircumference
 

	
 
	* mesh.cpp: corrected Mesh::Compactness, the boundary coordinates
 
	need to be sorted in x,y order for the convex hull algorithm
 
	(thanks Margriet!). I updated CSVExportCellData so it exports the
 
	circumferences of hull and boundary_polygon.
 

	
 

	
 
2010-10-14    <guravage@caterpie.sen.cwi.nl>
 

	
 
	* VirtualLeafpar.tmpl (export_fn_prefix): changed to 'cell.'
 

	
 
	* canvas.cpp (TimeStepWrap): Removed TimeStamp(). Cell data
 
	filename now incorporates iteration number.
 

	
 
	* canvas.h (MainBase): Removed TimeStamp().
 

	
 

	
 
2010-10-08    <guravage@caterpie.sen.cwi.nl>
 

	
 

	
 
	* pardialog.h:
 
	* pardialog.cpp:
 
	* parameter.h:
 
	* parameter.cpp: Regenerated to include export_interval and export_fn_prefix.
 

	
 
	* VirtualLeafpar.tmpl: Appended export_interval and export_fn_prefix.
 

	
 
	* canvas.h (MainBase): Declared polymorphic exportCellData() functions.
 

	
 
	* canvas.cpp:
 
	(TimeStamp): New private TimeStamp() function.
 
	(TimeStepWrap): Added invocation of exportCellData().
 
	(exportCellData): Created two polymorphic functions: one with a
 
	single QString argument, the other with no argument. The former is
 
	called from TimeStepWrap() while the latter is called from the
 
	"Export cell areas" item in the file menu.
 

	
 

	
 
2010-10-07    <guravage@caterpie.sen.cwi.nl>
 

	
 
	* canvas.cpp (exportCellData): Added a Q3FileDialog to inquire
 
	where to write the exportCellData.
 

	
 
2010-06-28    <guravage@caterpie.sen.cwi.nl>
 

	
 

	
 
	* VirtualLeaf-install.nsi: Grab gpl3.txt from doc directory.
 

	
 
	* canvas.cpp (gpl): gpl3.txt can be either in an ancestor doc
 
	directory (Linux) or a decedent doc directory (Windows, via the
 
	binary installer).
 

	
 
	* VirtualLeaf-install.nsi: Add VirtualLeaf doc directory.
 

	
 
2010-06-25    <guravage@caterpie.sen.cwi.nl>
 

	
 

	
 
	* gpl3.txt: Moved gpl3.txt from doc to src directory.
 

	
 
	* VirtualLeaf.pro: Added -Wno-write-strings and -Wno-unused-parameter to QMAKE_CXXFLAGS.
 

	
 
	* libplugin.pro: Ditto.
 

	
 
	* parameter.cpp: Result of adding datadir changes to make_parameter_source.pl.
 
	* parameter.h: Ditto.
 

	
 
	* output.h: Declared new function (AppendHomeDirIfPathRelative).
 

	
 
	* output.cpp (AppendHomeDirIfPathRelative): Added new function.
 

	
 
	* canvas.cpp (gpl): Moving gpl3.txt from doc to src obviates the need to docDir.cd("../doc").
 

	
 
	* VirtualLeaf-install.nsi: Grab gpl3.txt from src directory.
 
	Add missing libiconv/bin, libxml2bin and libz/bin directories.
 
	Copy libiconv-2.dll, libxml2.dll and zlib1.dll from relative paths.
 

	
src/VirtualLeaf-install-windows.nsi
Show inline comments
 
# $Id$
 

	
 
# appends \ to the path if missing
 
# example: !insertmacro GetCleanDir "c:\blabla"
 
# Pop $0 => "c:\blabla\"
 
!macro GetCleanDir INPUTDIR
 
  ; ATTENTION: USE ON YOUR OWN RISK!
 
  ; Please report bugs here: http://stefan.bertels.org/
 
  !define Index_GetCleanDir 'GetCleanDir_Line${__LINE__}'
 
  Push $R0
 
  Push $R1
 
  StrCpy $R0 "${INPUTDIR}"
 
  StrCmp $R0 "" ${Index_GetCleanDir}-finish
 
  StrCpy $R1 "$R0" "" -1
 
  StrCmp "$R1" "\" ${Index_GetCleanDir}-finish
 
  StrCpy $R0 "$R0\"
 
${Index_GetCleanDir}-finish:
 
  Pop $R1
 
  Exch $R0
 
  !undef Index_GetCleanDir
 
!macroend
 
 
 
# similar to "RMDIR /r DIRECTORY", but does not remove DIRECTORY itself
 
# example: !insertmacro RemoveFilesAndSubDirs "$INSTDIR"
 
!macro RemoveFilesAndSubDirs DIRECTORY
 
  # ATTENTION: USE ON YOUR OWN RISK!
 
  # Please report bugs here: http://stefan.bertels.org/
 
  !define Index_RemoveFilesAndSubDirs 'RemoveFilesAndSubDirs_${__LINE__}'
 
 
 
  Push $R0
 
  Push $R1
 
  Push $R2
 
 
 
  !insertmacro GetCleanDir "${DIRECTORY}"
 
  Pop $R2
 
  FindFirst $R0 $R1 "$R2*.*"
 
${Index_RemoveFilesAndSubDirs}-loop:
 
  StrCmp $R1 "" ${Index_RemoveFilesAndSubDirs}-done
 
  StrCmp $R1 "." ${Index_RemoveFilesAndSubDirs}-next
 
  StrCmp $R1 ".." ${Index_RemoveFilesAndSubDirs}-next
 
  IfFileExists "$R2$R1\*.*" ${Index_RemoveFilesAndSubDirs}-directory
 
  ; file
 
  Delete "$R2$R1"
 
  goto ${Index_RemoveFilesAndSubDirs}-next
 
${Index_RemoveFilesAndSubDirs}-directory:
 
  ; directory
 
  RMDir /r "$R2$R1"
 
${Index_RemoveFilesAndSubDirs}-next:
 
  FindNext $R0 $R1
 
  Goto ${Index_RemoveFilesAndSubDirs}-loop
 
${Index_RemoveFilesAndSubDirs}-done:
 
  FindClose $R0
 
 
 
  Pop $R2
 
  Pop $R1
 
  Pop $R0
 
  !undef Index_RemoveFilesAndSubDirs
 
!macroend
 

	
 
!define PRODUCT_NAME "The Virtual Leaf"
 
!define PRODUCT_VERSION "1.0"
 
!define PRODUCT_PUBLISHER "Center for Mathematics and Computer Science (CWI)"
 
!define PRODUCT_WEB_SITE "www.cwi.nl"
 
!define EXECUTABLE "VirtualLeaf.exe"
 
!define PROGICON "leaficon.ico"
 
!define SETUP_BITMAP "leaficon.ico"
 

	
 
# MUI 1.67 compatible ------
 
!include "MUI.nsh"
 
!include "EnvVarUpdate.nsh"
 

	
 
# MUI Settings
 
!define MUI_ABORTWARNING
 
!define MUI_ICON "leaficon.ico"
 
!define MUI_UNICON "leaficon.ico"
 

	
 
# Welcome page
 
!insertmacro MUI_PAGE_WELCOME
 

	
 
# License page
 
!insertmacro MUI_PAGE_LICENSE "..\doc\gpl3.txt"
 

	
 
# Components page
 
!insertmacro MUI_PAGE_COMPONENTS
 

	
 
# Directory page
 
!insertmacro MUI_PAGE_DIRECTORY
 

	
 
# Instfiles page
 
!insertmacro MUI_PAGE_INSTFILES
 

	
 
# Finish page
 
!insertmacro MUI_PAGE_FINISH
 

	
 
# Uninstaller pages
 
!insertmacro MUI_UNPAGE_CONFIRM
 
!insertmacro MUI_UNPAGE_INSTFILES
 
!insertmacro MUI_UNPAGE_FINISH
 

	
 
# Language files
 
!insertmacro MUI_LANGUAGE "English"
 

	
 
# MUI end ------
 

	
 
# set the name of the installer
 
outfile "VirtualLeaf-install.exe"
 
Name "${PRODUCT_NAME} ${PRODUCT_VERSION}"
 
ShowInstDetails show
 
ShowUnInstDetails show
 
 
 
# define the directory to install to
 
installDir C:\VirtualLeaf
 

	
 
# Request application privileges
 
RequestExecutionLevel user
 

	
 
section "Virtual Leaf executable"
 
  #sectionIn RO
 
  # define the output path for the Virtual Leaf executable
 
  setOutPath $INSTDIR\bin
 
  writeUninstaller $INSTDIR\uninstaller.exe
 
  file ..\bin\VirtualLeaf.exe
 

	
 
  # Required DLLs
 
  setOutPath $INSTDIR\bin
 

	
 
  file ..\lib\libiconv\bin\libiconv-2.dll
 
  file ..\lib\libxml2\lib\libxml2.dll
 
  file ..\lib\libz\bin\zlib1.dll
 

	
 
  # Is the pegging of these DLLs to a specific QT version a problem?
 
  file C:\Qt\2010.02.1\mingw\bin\mingwm10.dll
 
  file C:\Qt\2010.02.1\mingw\bin\libgcc_s_dw2-1.dll
 
  file C:\Qt\2010.02.1\qt\bin\Qt3Support4.dll
 
  file C:\Qt\2010.02.1\qt\bin\QtCore4.dll
 
  file C:\Qt\2010.02.1\qt\bin\QtGui4.dll
 
  file C:\Qt\2010.02.1\qt\bin\QtNetwork4.dll
 
  file C:\Qt\2010.02.1\qt\bin\QtSql4.dll
 
  file C:\Qt\2010.02.1\qt\bin\QtXml4.dll
 

	
 
  # Prepend the Virtual Leaf bin directory to the installers PATH
 
  ${EnvVarUpdate} $0 "PATH" "P" "HKCU" "$INSTDIR\bin"  
 

	
 
  # create a shortcut named "VirtualLeaf" in the start menu programs directory
 
  # point the new shortcut at the program VirtualLeaf
 
  createShortCut "$SMPROGRAMS\VirtualLeaf.lnk" "$INSTDIR\bin\VirtualLeaf.exe"
 

	
 
  # Icons
 
  setOutPath $INSTDIR\icons
 
  file ..\icons\*
 
sectionEnd
 

	
 
section "Image Formats"
 
  # define the output path for the Qt Image Formats
 
  setOutPath $INSTDIR\bin\imageformats
 
  file C:\Qt\2010.02.1\qt\plugins\imageformats\qgif4.dll
 
  file C:\Qt\2010.02.1\qt\plugins\imageformats\qico4.dll
 
  file C:\Qt\2010.02.1\qt\plugins\imageformats\qjpeg4.dll
 
  file C:\Qt\2010.02.1\qt\plugins\imageformats\qmng4.dll
 
  file C:\Qt\2010.02.1\qt\plugins\imageformats\qsvg4.dll
 
  file C:\Qt\2010.02.1\qt\plugins\imageformats\qtiff4.dll
 
sectionEnd
 

	
 

	
 
section "Virtual Leaf plugins"
 
  # define the output path for the Virtual Leaf models
 
  setOutPath $INSTDIR\bin\models
 
  file ..\bin\models\*
 
sectionEnd
 

	
 
section "Virtual Leaf data"
 
  # define the output path for the Virtual Leaf models
 
  setOutPath $INSTDIR\data\leaves
 
  file ..\data\leaves\*
 
sectionEnd
 

	
 
section "Virtual Leaf docs"
 
  # define the output path for the Virtual Leaf documentation
 
  setOutPath $INSTDIR\doc
 
  file ..\doc\*
 
sectionEnd
 

	
 
# create a section to define what the uninstaller does.
 
# the section will always be named "Uninstall"
 
section "Uninstall"
 

	
 
  # Always delete uninstaller first
 
  delete $INSTDIR\uninstaller.exe
 
 
 
  # Now delete installed file
 
  !insertmacro RemoveFilesAndSubDirs "$INSTDIR"
 

	
 
  # Delete shortcut from start menu
 
  delete "$SMPROGRAMS\VirtualLeaf.lnk"
 

	
 
  # Last but not least - delete the path  
 
  ${un.EnvVarUpdate} $0 "PATH" "R" "HKCU" "$INSTDIR\bin"
 
sectionEnd
 

	
 
# finis
src/canvas.cpp
Show inline comments
 
/*
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#include <time.h>
 
#include <string>
 
#include <fstream>
 
#include <streambuf>
 
#include <QGraphicsScene>
 
#include <QGraphicsView>
 
#include <qdatetime.h>
 
#include <q3mainwindow.h>
 
#include <qstatusbar.h>
 
#include <qmessagebox.h>
 
#include <qmenubar.h>
 
#include <qapplication.h>
 
#include <qpainter.h>
 
#include <qprinter.h>
 
#include <qlabel.h>
 
#include <qimage.h>
 
#include <q3progressdialog.h>
 
#include <qtimer.h>
 
#include <qslider.h>
 
#include <qpixmap.h>
 
#include <qfile.h>
 
#include <qdir.h>
 
#include <q3filedialog.h>
 
#include <QGraphicsItem>
 
#include <QList>
 
#include <QDir>
 
#include <QFileInfo>
 
#include <QDebug>
 
#include <QImageWriter>
 

	
 
#include <set>
 

	
 
//Added by qt3to4:
 
#include <Q3ValueList>
 
#include <Q3PopupMenu>
 
#include <QMouseEvent>
 
#include <typeinfo>
 
#include <cstring>
 
#include <q3process.h>
 
#include <qlayout.h>
 
#include <qspinbox.h>
 
#include <fstream>
 
#include <sstream>
 
#include "pardialog.h"
 
#include "parameter.h"
 
#include "canvas.h"
 
#include "node.h"
 
#include "nodeset.h"
 
#include "nodeitem.h"
 
#include "cellitem.h"
 
#include "wallitem.h"
 
#include "mesh.h"
 
#include "xmlwrite.h"
 
#include "OptionFileDialog.h"
 
#include <cstdlib>
 
#include <cstdio>
 
#include "modelcatalogue.h"
 

	
 
#include <algorithm>
 

	
 
// Include VIB and PSB logos
 
// Include PSB, CWI and vleaf logos
 
#include "psb.xpm"
 
#include "cwi.xpm"
 
#include "leaficon_small.xpm"
 

	
 
static const std::string _module_id("$Id$");
 

	
 
using namespace std;
 

	
 
// We use a global variable to save memory - all the brushes and pens in
 
// the mesh are shared.
 

	
 
#define FNAMESIZE 100
 
#define QUOTE_ME(s) QUOTE_ME_2NDLEV(s)
 
#define QUOTE_ME_2NDLEV(s) #s
 

	
 
static QColor dark_red("darkRed");
 

	
 

	
 
static const int imageRTTI = 984376;
 
extern Parameter par;
 
const QString Main::caption("Virtual leaf");
 
const QString Main::caption_with_file("Virtual leaf: %1");
 

	
 
FigureEditor::FigureEditor(
 
			   QGraphicsScene& c, Mesh &m, QWidget* parent,
 
			   const char* name, Qt::WindowFlags f) :
 
  QGraphicsView(&c,parent), mesh(m)
 
{
 
  intersection_line = 0;
 
  //angle_line = 0;
 
  setInteractive(true);
 
  moving = 0;  
 
  rotation_mode = false;
 
}
 

	
 

	
 
void FigureEditor::clear()
 
{
 
  QList<QGraphicsItem *> list = scene()->items();
 
  QList<QGraphicsItem *>::Iterator it = list.begin();
 
  for (; it != list.end(); ++it) {
 
    delete *it;
 
  }
 
}
 

	
 
void FigureEditor::wheelEvent(QWheelEvent *event)
 
{
 
  scaleView(pow((double)2, -event->delta() / 240.0));
 
}
 

	
 

	
 
void FigureEditor::scaleView (qreal scaleFactor)
 
{
 
  qreal factor = matrix().scale(scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)). width();
 
  if (factor < 0.07 || factor > 100) return;
 
  scale (scaleFactor, scaleFactor);
 
}
 

	
 
void FigureEditor::Save(const char *fname, const char *format, int sizex, int sizey)
 
{
 

	
 
  QImage *image = new QImage(sizex, sizey, QImage::Format_RGB32);
 
  image->fill(QColor(Qt::white).rgb());
 
  QPainter *painter=new QPainter(image);
 

	
 
  render(painter);
 

	
 
  image->save(QString(fname),format);
 
  delete painter;
 
  delete image;
 
}
 

	
 
void FigureEditor::mousePressEvent(QMouseEvent* e)
 
{
 
  static QList<Node*> selected;
 
  emit MousePressed();
 

	
 
  //QPointF p = matrix().inverted().map(e->pos());
 
  QPointF p = mapToScene(e->pos());
 

	
 
#ifdef QDEBUG  
 
  qDebug() << endl << "MousePressEvent location: (" << p.x() << "," << p.y() << ")." << endl;
 
  qDebug() << "Magnification:  " << Cell::Magnification() << endl;
 
  qDebug() << "Offsets:  " << Cell::Offset() << endl;
 
#endif
 

	
 

	
 
  QList<QGraphicsItem *> l=scene()->items(p);
 

	
 
#ifdef QDEBUG  
 
  qDebug() << "MousePressEvents, items: " << l.size() << endl;
 
  qDebug() << "Mouse button modifier: " << e->modifiers() << endl;
 
#endif
 

	
 
  if (e->button()==Qt::RightButton || l.size()==0) {
 

	
 
    //cerr << "Drawing an intersection line from " << p.x() << ", " << p.y() << endl;
 
    intersection_line = new QGraphicsLineItem( 0, scene() );
 
    intersection_line->setPen( QPen( QColor("red"), 3, Qt::DashLine ) );
 
    intersection_line->setLine( QLineF(p,p) );
 
    intersection_line->setZValue( 100 );
 
    intersection_line->show();
 
  }
 

	
 
  for (QList<QGraphicsItem *>::Iterator it=l.begin(); it!=l.end(); ++it) {
 
#ifdef QDEBUG
 
    qDebug() << typeid(**it).name() << endl;
 
#endif
 

	
 
    if ( !strcmp(typeid(**it).name(),"8NodeItem")) {
 

	
 
      stringstream data_strstream;
 
      data_strstream << (dynamic_cast<NodeItem*>(*it))->getNode();
 
      dynamic_cast<Main *>(parent())->UserMessage(QString(data_strstream.str().c_str()));
 

	
 
      (dynamic_cast<NodeItem*>(*it))->OnClick(e->button());
 
    }
 
    else 
 
      if ( !strcmp(typeid(**it).name(),"8CellItem") ) {
 

	
 
	Cell &c=((dynamic_cast<CellItem *>(*it))->getCell());      
 
	// OnClick to be defined in end-user code
 
	c.OnClick(e);
 
      } else {
 
	if ( !strcmp(typeid(**it).name(),"8WallItem") ) {
 
	  (dynamic_cast<WallItem *>(*it))->OnClick(e);
 
	} 
 
      }
 
  }
 

	
 
  FullRedraw();
 
  moving = 0;
 
}
 

	
 
void FigureEditor::mouseMoveEvent(QMouseEvent* e)
 
{
 

	
 
  // User chooses "rotation mode" and we can rotate the object around its center of mass
 
  if (dynamic_cast<Main *>(parent())->RotationModeP()) {
 

	
 
    QPointF p = mapToScene(e->pos());
 
    p.setX(p.x() / Cell::Magnification());
 
    p.setY(p.y() / Cell::Magnification());
 

	
 

	
 
    // get object's center of mass
 
    QPointF rotation_midpoint = mesh.Centroid()*Cell::Factor() - Cell::Offset();
 

	
 

	
 
    // calculate rotation angle
 
    double dy = (rotation_midpoint.y() - p.y());
 
    double dx = (rotation_midpoint.x() - p.x());
 
    double new_rot_angle = atan2(dx, dy);
 
    double d_alpha = new_rot_angle - rot_angle;
 
    rot_angle = new_rot_angle;
 

	
 
    mesh.Rotate(d_alpha, ( Vector(rotation_midpoint) + Cell::Offset() ) / Cell::Factor() );
 

	
 
    dynamic_cast<Main *>(parent())->Plot(0);
 
    FullRedraw();
 
    return;
 
  }
 
 
 
  
 
  if ( moving ) {
 

	
 
    QPointF p = mapToScene(e->pos());
 
    moving->userMove(p.x() - moving_start.x(),
 
		     p.y() - moving_start.y());
 
    moving_start = p;
 
    scene()->update();
 

	
 
  }
 

	
 
  //cerr << "event";
 

	
 
  // keep track of intersection line to interactively cut a growing leaf
 

	
 
  if ( intersection_line ) {
 

	
 
    QPointF sp = intersection_line -> line().p1(); // startpoint
 
    QPointF ep = mapToScene(e->pos()); // endpoint
 
    intersection_line -> setLine( QLineF(sp, ep) ); 
 
    scene()->update();
 
    // Need this for Mac
 
    FullRedraw();
 
  }
 
}
 

	
 
//void FigureEditor::contentsMouseReleaseEvent(QMouseEvent* e)
 
void FigureEditor::mouseReleaseEvent(QMouseEvent* e)
 
{
 

	
 
  emit MouseReleased();
 
  // intersection line for leaf was finished now.
 
@@ -867,394 +868,385 @@ int Main::readStateXML(const char *filen
 

	
 

	
 
void Main::readNextStateXML()
 
{
 

	
 
  // if we have already read a file, read the next file
 
  if (!currentFile.isEmpty() && working_dir) {
 
    QString next_file;
 

	
 
    QStringList xml_files = working_dir->entryList("*.xml");
 
    QString currentFile_nopath = currentFile.section( '/', -1 );
 
    QString currentFile_path = currentFile.section( '/', 0, -2 );
 

	
 

	
 
    QList<QString>::iterator f = xml_files.find( currentFile_nopath );
 

	
 
    if (f == xml_files.end()) {
 
      return;
 
    }
 

	
 
    ++f;
 
    if (f==xml_files.end()) {
 
      QMessageBox mb( "Read next leaf",
 
		      "No more files",
 
		      QMessageBox::Information,
 
		      QMessageBox::Ok | QMessageBox::Default,
 
		      QMessageBox::NoButton,
 
		      QMessageBox::NoButton);
 
      mb.exec();
 
      return;
 
    }
 
    next_file = *f;
 
    next_file = currentFile_path+"/"+next_file;
 

	
 
    readStateXML((const char*)next_file);
 
  }
 
}
 

	
 
void Main::readLastStateXML()
 
{
 

	
 
  // if we have already read a file, read the next file
 
  if (!currentFile.isEmpty() && working_dir) {
 
    QString next_file;
 

	
 
    QStringList xml_files = working_dir->entryList("*.xml");
 
    QString currentFile_nopath = currentFile.section( '/', -1 );
 
    QString currentFile_path = currentFile.section( '/', 0, -2 );
 

	
 

	
 
    next_file = xml_files.back();
 

	
 
    next_file = currentFile_path+"/"+next_file;
 

	
 
    readStateXML((const char*)next_file);
 
  }
 
}
 

	
 

	
 
void Main::readFirstStateXML()
 
{
 

	
 
  // if we have already read a file, read the next file
 
  if (!currentFile.isEmpty() && working_dir) {
 
    QString next_file;
 

	
 
    QStringList xml_files = working_dir->entryList("*.xml");
 
    QString currentFile_nopath = currentFile.section( '/', -1 );
 
    QString currentFile_path = currentFile.section( '/', 0, -2 );
 

	
 

	
 
    next_file = xml_files.front();
 

	
 
    next_file = currentFile_path+"/"+next_file;
 

	
 
    readStateXML((const char*)next_file);
 
  }
 
}
 

	
 
QDir Main::GetLeafDir(void) {
 
   
 
  QDir LeafDir(QApplication::applicationDirPath()); 
 
  QStringList plugin_filters; // filter for plugins, i.e "*.dll", "*.dylib"
 
  
 
  
 
#if defined(Q_OS_WIN) 
 
  if (LeafDir.dirName().toLower() =="debug" 
 
      ||LeafDir.dirName().toLower() =="release") 
 
    LeafDir.cdUp(); 
 
  //plugin_filters << "*.dll";
 
#elif defined(Q_OS_MAC) 
 
  if (LeafDir.dirName() =="MacOS"){ 
 
    LeafDir.cdUp(); 
 
    LeafDir.cdUp(); 
 
    LeafDir.cdUp(); 
 
  }
 
  
 
#endif
 
  // for all OS-es. Move from "bin" directory to root application folder.
 
  if (LeafDir.dirName() == "bin") {
 
    LeafDir.cdUp();
 
  }
 

	
 
  LeafDir.cd("data/leaves");
 
  /* if (!LeafDir.cd("data/leaves")) {
 
    QString status_message = QString("No directory data/leaves");
 
    statusBar()->showMessage(status_message);
 
    
 
    return LeafDir;
 
  } 
 
  */
 
  return LeafDir;
 
      
 
}
 
 
 

	
 
void Main::readStateXML()
 
{
 

	
 
  //  extern Mesh mesh;
 

	
 
  stopSimulation();
 
#ifdef QDEBUG
 
  qDebug() << "Trying to open an OptionFileDialog" << endl;
 
#endif
 
  OptionFileDialog *fd = new OptionFileDialog( this, "read dialog", TRUE );
 
  fd->setMode( OptionFileDialog::ExistingFile );
 
  fd->setFilter( "LeafML files (*.xml)");
 
  if (working_dir) {
 
    fd->setDir(*working_dir);
 
  } else {
 
    fd->setDir(par.datadir);
 
  }
 
  QString fileName;
 
  if ( fd->exec() == QDialog::Accepted ) {
 

	
 
    fileName = fd->selectedFile();
 
    if (working_dir) {
 
      delete working_dir;
 
    }
 
    working_dir = fd->dir();
 

	
 
    if (readStateXML((const char *)fileName,fd->readGeometryP(), fd->readParametersP()) )
 
      return readStateXML(); // user can try again
 
  }
 
}
 

	
 

	
 
void Main::clear()
 
{
 
  editor->clear();
 
}
 

	
 
void Main::about()
 
{
 
  static QMessageBox* about = new QMessageBox
 
    ( "VirtualLeaf V1.0",
 
      "<h3>VirtualLeaf V1.0</h3>\
 
       <p>\
 
         An Open Source framework for cell-based modeling of plant\
 
         tissue growth and development.\
 
       </p>\
 
       <p>(c) 2005-2008, Roeland Merks <i>et al.</i>\
 
         <a href=\"http://www.psb.vib-ugent.be\">VIB Department Plant Systems Biology</a>,\
 
         Ghent, Belgium.\
 
       </p>\
 
       <p>(c) 2008-2010,\
 
         <a href=\"http://www.cwi.nl/~merks\">Roeland Merks <i>et al.</i></a>\
 
         <a href=\"http://www.cwi.nl\">Centrum Wiskunde & Informatica (CWI)</a> and\
 
         <a href=\"http://www.ncsb.nl\"> Netherlands Consortium for Systems Biology (NCSB)</a>,\
 
         Amsterdam, the Netherlands.\
 
       </p>\
 
       <p>\
 
         VirtualLeaf is free software: you can redistribute it and/or\
 
         modify it under the terms of the GNU General Public License as\
 
         published by the Free Software Foundation, either version 3 of the\
 
         License, or (at your option) any later version.\
 
       </p>\
 
       <p>\
 
         If you use this code for your projects, please cite our paper in\
 
         <a href=\"http://www.plantphysiol.org\">Plant Physiology</a>, &lsquo;\
 
         Roeland M. H. Merks, Michael Guravage, Dirk Inze, and Gerrit T.S. Beemster,\
 
         <a href=\"http://www.plantphysiol.org/cgi/content/short/pp.110.167619?keytype=ref&ijkey=YTmfxrHG5QCsa8k\">\
 
         VirtualLeaf: an Open Source framework for cell-based modeling of plant tissue growth and development</a>,<br>\
 
         Plant Physiology 2011: pp.110.167619v1-pp.110.167619.\
 
       </p>\
 
       <p>\
 
         Please share your model plugins and extensions at\
 
         <a href=\"http://virtualleaf.googlecode.com\">http://virtualleaf.googlecode.com</a>.\
 
       </p>",
 
      QMessageBox::Information, 1, 0, 0, this, 0, FALSE );
 
  about->setButtonText( 1, "Dismiss" );
 

	
 
  // Locate and set the message box's icon
 
  QDir iconDir(QApplication::applicationDirPath()); 
 
  if (iconDir.cd("../icons")) {
 
    QString iconFile = iconDir.filePath("leaficon_small.png");
 
    QFile icon(iconFile);
 
    if (icon.exists()){
 
      about->setIconPixmap(QPixmap(iconFile));
 
    }
 
  }
 
  about->setIconPixmap(QPixmap( leaficon_small ));
 
  about->show();
 
}
 

	
 

	
 
void Main::gpl()
 
{
 
  static QMessageBox* gpl = new QMessageBox ( "GPL License", "", 
 
      QMessageBox::Information, 1, 0, 0, this, 0, FALSE );
 

	
 
  QDir docDir(QApplication::applicationDirPath());
 
  docDir.cd("../doc"); // Where Linux expects gpl3.txt
 
  QString path = docDir.filePath("gpl3.txt");
 
  if (!docDir.exists("gpl3.txt")){
 
    docDir = QApplication::applicationDirPath();
 
    docDir.cd("doc"); // Where Windows expects gpl3.txt
 
    path = docDir.filePath("gpl3.txt");
 
  }
 

	
 
  // At this point path points either to the linux variant, which
 
  // exists, or the windows variant, which may exist. Testing the
 
  // ifstream object will determine whether we've found gpl3.txt.
 

	
 
  std::ifstream file(path.toStdString().c_str());
 
  std::string str;
 

	
 
  if (file) {
 
    file.seekg(0, std::ios::end);   
 
    str.reserve(file.tellg());
 
    file.seekg(0, std::ios::beg);
 

	
 
    str.assign((std::istreambuf_iterator<char>(file)),
 
	       std::istreambuf_iterator<char>());
 

	
 
    gpl->setDetailedText(QString(str.c_str()));
 
  }
 

	
 
  gpl->setText(QString( "<h3>GNU GENERAL PUBLIC LICENSE</h3>"
 
			"<p>Version 3, 29 June 2007</p>"
 
			"<p>Copyright &copy; 2007 Free Software Foundation, Inc. "
 
			"&lt;<a href=\"http://fsf.org/\">http://fsf.org/</a>&gt;</p><p>"
 
			"Everyone is permitted to copy and distribute verbatim copies "
 
			"of this license document, but changing it is not allowed.</p>"
 
			"<h2>GNU GENERAL PUBLIC LICENSE</h2>"));
 

	
 
  gpl->setButtonText( 1, "Dismiss" );
 
  gpl->show();
 
}
 

	
 
void Main::aboutQt(){
 
  QMessageBox::aboutQt( this, "Virtual Leaf" );
 
}
 

	
 
void Main::toggleShowCellCenters()
 
{
 
  Plot();
 
}
 

	
 
void Main::toggleShowWalls()
 
{
 
  Plot();
 
}
 

	
 
void Main::toggleShowApoplasts()
 
{
 
  Plot();
 
}
 

	
 
void Main::toggleShowNodes()
 
{
 
  Plot();
 
}
 

	
 
void Main::toggleNodeNumbers(void)
 
{
 
  Plot();
 
}
 

	
 
void Main::toggleCellNumbers(void)
 
{
 
  Plot();
 
}
 

	
 
void Main::toggleCellAxes(void)
 
{
 
  Plot();
 
}
 

	
 
void Main::toggleCellStrain(void)
 
{
 
  Plot();
 
}
 

	
 
void Main::toggleShowFluxes(void)
 
{
 
  Plot();
 
}
 

	
 
void Main::toggleShowBorderCells()
 
{
 
  Plot();
 
}
 

	
 
void Main::toggleHideCells(void)
 
{
 
  Plot();
 
  editor->FullRedraw();
 
}
 

	
 
void Main::toggleMovieFrames(){}
 

	
 
void Main::toggleLeafBoundary(){}
 

	
 
void Main::toggleDynCells() {}
 

	
 
void Main::startSimulation(void)
 
{
 
  timer->start( 0 );
 
  statusBar()->message("Simulation started");
 
  running = true;
 
}
 

	
 
void Main::stopSimulation(void)
 
{
 
  timer->stop();
 
  cerr << "Stopping simulation" << endl;
 
  statusBar()->message("Simulation paused");
 
  running = false;
 
}
 

	
 
void Main::togglePaused()
 
{
 
  bool s = run->isItemChecked(paused_id);
 
  if (s) {
 
    cerr << "Calling start simulation" << endl;
 
    startSimulation();
 
  } else {
 
    cerr << "Calling stop simulation" << endl;
 
    stopSimulation();
 
  }
 
}
 

	
 
void Main::setFluxArrowSize(int size)
 
{
 
  flux_arrow_size = size/100.;
 
}
 

	
 

	
 
void Main::enlarge()
 
{
 
  canvas.setSceneRect( QRectF( 0,0, canvas.width()*4./3., canvas.height()*4./3.) );
 
}
 

	
 
void Main::shrink()
 
{
 
  canvas.setSceneRect( QRectF( 0,0, canvas.width()*3/4, canvas.height()*3/4) );
 
}
 

	
 

	
 
void Main::scale(double factor)
 
{
 
  QMatrix m = editor->matrix();
 
  m.scale(factor, factor);
 
  editor->setMatrix( m );
 
}
 

	
 
void Main::zoomIn()
 
{
 
  QMatrix m = editor->matrix();
 
  m.scale( 1.1, 1.1 );
 
  editor->setMatrix( m );
 
}
 

	
 
void Main::zoomOut()
 
{
 
  QMatrix m = editor->matrix();
 
  m.scale( 0.9, 0.9 );
 
  editor->setMatrix( m );
 
}
 

	
 

	
 
void Main::print()
 
{
 
  if ( !printer ) printer = new QPrinter;
 

	
 
  if ( printer->setup(this) ) {
 

	
 
    //    extern Mesh mesh;
 
    Vector bbll,bbur;
 
    mesh.BoundingBox(bbll,bbur);
 

	
 
#ifdef QDEBUG
 
    qDebug() << "bbll = " << bbll << endl;
src/leaficon_small.xpm
Show inline comments
 
new file 100644
 
/* XPM */
 
static char *leaficon_small[] = {
 
/* columns rows colors chars-per-pixel */
 
"55 55 256 2 ",
 
"   c #020C02",
 
".  c #070602",
 
"X  c #140301",
 
"o  c #1B0301",
 
"O  c #130C02",
 
"+  c #1C0C03",
 
"@  c #160C0A",
 
"#  c #041304",
 
"$  c #0B1305",
 
"%  c #041C03",
 
"&  c #0B150A",
 
"*  c #0C1B0B",
 
"=  c #081A06",
 
"-  c #151505",
 
";  c #1C1404",
 
":  c #1B1A02",
 
">  c #151509",
 
",  c #1A140A",
 
"<  c #141B0B",
 
"1  c #1B1C0A",
 
"2  c #141C06",
 
"3  c #121D11",
 
"4  c #1C1F15",
 
"5  c #180F14",
 
"6  c #230401",
 
"7  c #2B0300",
 
"8  c #240B02",
 
"9  c #2B0B02",
 
"0  c #26080A",
 
"q  c #330400",
 
"w  c #3A0501",
 
"e  c #340B02",
 
"r  c #3C0B02",
 
"t  c #340B09",
 
"y  c #231305",
 
"u  c #2C1302",
 
"i  c #241C00",
 
"p  c #251C0B",
 
"a  c #281708",
 
"s  c #331305",
 
"d  c #381609",
 
"f  c #2B0316",
 
"g  c #37031C",
 
"h  c #331811",
 
"j  c #042302",
 
"k  c #0C240B",
 
"l  c #0C2B0A",
 
"z  c #082805",
 
"x  c #14230D",
 
"c  c #1B220D",
 
"v  c #132B0D",
 
"b  c #19280C",
 
"n  c #053202",
 
"m  c #0B3305",
 
"M  c #023C02",
 
"N  c #0D330B",
 
"B  c #093B07",
 
"V  c #14340D",
 
"C  c #13390B",
 
"Z  c #133B05",
 
"A  c #142313",
 
"S  c #1B2412",
 
"D  c #142B13",
 
"F  c #1B2C12",
 
"G  c #1B261A",
 
"H  c #153314",
 
"J  c #1A3214",
 
"K  c #1A3C12",
 
"L  c #1B341A",
 
"P  c #1C3C1B",
 
"I  c #133C13",
 
"U  c #0F3913",
 
"Y  c #242302",
 
"T  c #2C2401",
 
"R  c #26250A",
 
"E  c #352807",
 
"W  c #3A3209",
 
"Q  c #232913",
 
"!  c #282714",
 
"~  c #253516",
 
"^  c #39361A",
 
"/  c #352813",
 
"(  c #380421",
 
")  c #371526",
 
"_  c #3A1D3A",
 
"`  c #263625",
 
"'  c #35302F",
 
"]  c #430A03",
 
"[  c #490701",
 
"{  c #580801",
 
"}  c #441609",
 
"|  c #571608",
 
" . c #471913",
 
".. c #620B01",
 
"X. c #791A04",
 
"o. c #64170F",
 
"O. c #493A06",
 
"+. c #573A03",
 
"@. c #472416",
 
"#. c #433414",
 
"$. c #4D250A",
 
"%. c #762600",
 
"&. c #6F2D09",
 
"*. c #48032B",
 
"=. c #480932",
 
"-. c #520835",
 
";. c #481631",
 
":. c #60123E",
 
">. c #492822",
 
",. c #523231",
 
"<. c #692F2B",
 
"1. c #054903",
 
"2. c #154809",
 
"3. c #035300",
 
"4. c #0D5606",
 
"5. c #195609",
 
"6. c #154314",
 
"7. c #1A4816",
 
"8. c #145412",
 
"9. c #1C5517",
 
"0. c #0F4110",
 
"q. c #22560E",
 
"w. c #274A18",
 
"e. c #255718",
 
"r. c #314511",
 
"t. c #0A6705",
 
"y. c #186506",
 
"u. c #077502",
 
"i. c #197706",
 
"p. c #1B6915",
 
"a. c #187710",
 
"s. c #256A09",
 
"d. c #257706",
 
"f. c #267616",
 
"g. c #2E6B17",
 
"h. c #254523",
 
"j. c #3B4639",
 
"k. c #31522A",
 
"l. c #356F2C",
 
"z. c #5C4200",
 
"x. c #4B4C19",
 
"c. c #654A07",
 
"v. c #6C5519",
 
"b. c #5A6914",
 
"n. c #4C4D34",
 
"m. c #64443D",
 
"M. c #714124",
 
"N. c #497133",
 
"B. c #716530",
 
"V. c #626617",
 
"C. c #5B1443",
 
"Z. c #563349",
 
"A. c #692A53",
 
"S. c #4C5D4C",
 
"D. c #475846",
 
"F. c #4C4E49",
 
"G. c #6F504C",
 
"H. c #4A7B45",
 
"J. c #566456",
 
"K. c #5C7454",
 
"L. c #6C6C53",
 
"P. c #785668",
 
"I. c #744C64",
 
"U. c #72766F",
 
"Y. c #852E04",
 
"T. c #8A4B26",
 
"R. c #88743F",
 
"E. c #8D544F",
 
"W. c #A57052",
 
"Q. c #855275",
 
"!. c #866A65",
 
"~. c #917876",
 
"^. c #8B625F",
 
"/. c #098604",
 
"(. c #168905",
 
"). c #0A9702",
 
"_. c #189506",
 
"`. c #1B8F15",
 
"'. c #278507",
 
"]. c #32860C",
 
"[. c #269705",
 
"{. c #2E8E16",
 
"}. c #18A805",
 
"|. c #17B302",
 
" X c #0EAA08",
 
".X c #2BA706",
 
"XX c #23B808",
 
"oX c #2EAE16",
 
"OX c #37922D",
 
"+X c #31BA2A",
 
"@X c #478E1C",
 
"#X c #74890F",
 
"$X c #4DA216",
 
"%X c #4B8F33",
 
"&X c #49B832",
 
"*X c #4DA037",
 
"=X c #6AAF3B",
 
"-X c #27C30F",
 
";X c #30C128",
 
":X c #5CCD14",
 
">X c #65D816",
 
",X c #5DF900",
 
"<X c #63F802",
 
"1X c #71F312",
 
"2X c #7DF026",
 
"3X c #589248",
 
"4X c #53B44B",
 
"5X c #6DB251",
 
"6X c #769272",
 
"7X c #7CAD6D",
 
"8X c #63915A",
 
"9X c #55C849",
 
"0X c #76D46A",
 
"qX c #8BA918",
 
"wX c #9EAC14",
 
"eX c #AFD017",
 
"rX c #BDF200",
 
"tX c #BAE80D",
 
"yX c #85F339",
 
"uX c #B0D526",
 
"iX c #C6DB15",
 
"pX c #C6F806",
 
"aX c #CBF610",
 
"sX c #CAE828",
 
"dX c #8A8A75",
 
"fX c #92F44B",
 
"gX c #8AD07B",
 
"hX c #A0F760",
 
"jX c #D9F752",
 
"kX c #D6F368",
 
"lX c #A37698",
 
"zX c #957789",
 
"xX c #909189",
 
"cX c #AC8D8B",
 
"vX c #97B090",
 
"bX c #B5A983",
 
"nX c #AD8EA6",
 
"mX c #ABACAA",
 
"MX c #A3A5A3",
 
"NX c #B3B2AF",
 
"BX c #B3B4B3",
 
"VX c #BAB9B9",
 
"CX c #B2AFB0",
 
"ZX c #C2BABD",
 
"AX c #A2CE92",
 
"SX c #C3C8B9",
 
"DX c #D7BBD4",
 
"FX c #E0BFDB",
 
"GX c #CAC9C7",
 
"HX c #D8D5D8",
 
"JX c #D2D0CF",
 
"KX c #E1D8DE",
 
"LX c #DAE3D8",
 
"PX c #E8E7E8",
 
"IX c #ECEEEB",
 
"UX c None",
 
/* pixels */
 
"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
 
"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
 
"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
 
"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
 
"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXIXSXJXLXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
 
"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXHXxXZ.;.,.C.P.nXnXGXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
 
"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXVXU.P.;.=.*.=.=.( ( f 5 ) ;.C.Q.cXJXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
 
"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXSX~.Q.Q.g 5 o 6 o X / 0 X 9 o < , 0 g -.=.=.xXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
 
"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXGXZ.g *.*.6 o b , 6 t 7 ,.!.] ] w A a w 6 0 ) C.-.I.PXUXUXUXUXUXUXUXUXUXUXUXUXUX",
 
"UXUXUXUXUXUXUXUXUXUXUXUXUXUXNX,.:.A.f 6 t w , $ h q 7  .xX>.7 t A 7 [ ] t ,.6 ( *.P.PXUXUXUXUXUXUXUXUXUXUXUXUX",
 
"UXUXUXUXUXUXUXUXUXUXUXUXUXGX-.-. .,.t r ] 9 A @ > , 0 7 t r w 0 < 6 [ w cX^.q 7 0 f Z.BXUXUXUXUXUXUXUXUXUXUXUX",
 
"UXUXUXUXUXUXUXUXUXUXUXUXGXA.g 0 o ,.cX .7 Q 1 7 6 6 o 8 y 6 6 R > p u q G.] ] ] 6 c . _ DXUXUXUXUXUXUXUXUXUXUX",
 
"UXUXUXUXUXUXUXUXUXUXUXnX_ o 6 e ] } Z.w a A 6 ] ,.q 9 6 , , 1 p w 0 / / 8 w ] 7 R c o X C.nXUXUXUXUXUXUXUXUXUX",
 
"UXUXUXUXUXUXUXUXUXIXlXf # c 7 d t a a + 2 , w r G.@.] t 7 + < { ..{ w + ^ R 6 4 A 6 r 9 o C.ZXUXUXUXUXUXUXUXUX",
 
"UXUXUXUXUXUXUXUXHXQ.f 6 8 x $ x < S G S & + ] w  .cX<.r ] p p ....{ X.<.w y > - o w q 7 h ) A.HXUXUXUXUXUXUXUX",
 
"UXUXUXUXUXUXUXVXA.( 8 r w O < . O X X X 1 1 7 ]  .G. .7 e h 0 ....<.E.<...[ > p q w ~.G.,.a f lXUXUXUXUXUXUXUX",
 
"UXUXUXUXUXUXLXC.( + 7 w w a x o u O 8 8 + S a w 7 6 ] @.T + d { o.cXE.{ ..{ a p 7 t !.<.d q + =.KXUXUXUXUXUXUX",
 
"UXUXUXUXUXUXQ.g a G.G.G.w y k X 8 G.' a o b y 9 @.@.d d $.$./ | ..o.o.....{ , S X 6 6 0 q w 7 . P.IXUXUXUXUXUX",
 
"UXUXUXUXUXnXg o r t G.!.w t 3 X y y P.dXo o , R s | M.T.%.Y.d E } r { { { s Q X G ! 1 + 0 7 ; < @ lXUXUXUXUXUX",
 
"UXUXUXUXnX( o t r w q w e y $ - o X ,.,.o 8 < } &.%.T.T.%.&.| p d ^ ^ E 8 1 y 9 9 O 1 ! 4 $ F ; . -.DXUXUXUXUX",
 
"UXUXUXFX_ # 0 8 7 w r 9 y c O x F + o 8 o s 4 &.Y.%.W.W.%.%.$.#.+.O.E T - Q 9 e 9 e s 6 O * 6 r t 0 C.ZXUXUXUX",
 
"UXUXUXnXX + + o + 0 + 1 - ; y + 1 F c o 8 d a X.Y.X.W.W.%.$.@.+.c.c.c.c.#.~ o h >.9 6 q p x q r w X ( Q.PXUXUX",
 
"UXUXUXI.X s q 9 8 X & < + u u u o : b @ 1 r.O.r { X.X.Y...#.$.c.B.B.R.c.O.Q X G.dXG.m.7 1 Q 7 >.,.<.) *.mXUXUX",
 
"UXUXFX;.o r e e e 6 A ; u T ,.,.G.a + ; ~ qXtXeX#XO.} | $.} +.v.bXR.v.c.+.S p d >.@.h 9 & ! 7 cX!.@.y f Q.IXUX",
 
"UXUXnXX h G.G.~.} 7 b > 8 E n.G.~.#.u 0 b.tXpXpXsXtXuXwXW } c.c.v.c.+.+.+.1 Q 7 9 9 7 8 # + t d  .r q + A.IXUX",
 
"UXUXI.o d q >.!. .o A # , y y d u u s 8 N.pXpXrXjXpXpXpX#X^ &.+.+.O.O.~ x > c o e 9 + x 3 > o 6 0 w ] + f CXUX",
 
"UXHX_ . e r ] w 6 b $ : ~ x p ; u u ; + J qXaXpXsXkXaXpXtXx.e W Q m V r.w.Z l F o , D F + : - , + y 8 , 4 F.UX",
 
"UXVX. 4 , 6 r q c J T W : Q D A , 2 v x b q.#XpXaXkXpXrXpXx.1 F w.w.q.s.d.].s.D & S 2 : E T T ; p <   F 4 F.UX",
 
"UXxX. 3 c F o , J : T E E T i Q $ = e.'.d.q.w.b.iXsXiXiXeXx.b s.t.5XgXd.'.'.s.z x # i T u u i i i - c E W 5 JX",
 
"KX~ - : Y x < * : Y n.L.B.n.W ; A 7.[..X[.].q.c x.V.V.V.#.Q ~ ].'.*X3X3X@Xd.2.6.# K : Y n.L.L.^ i 1 w.x.W ' dX",
 
"ZX$ 2 : Y : 2 * : W W W !.dX; Q b '.}.&X0X.X{.A & 5.5.y.2.b Z d.d.d.i.].'.q.K K q.m v : E R dXL.i $ j.bXn.R N.",
 
"N.- c Q x.W Y x Q Y T T E T i x e..XoX5X5X.X'.e.r.2X2X1X2X].w.b 5.q.q.q.q.V 6.2.y.2.V x i i / T i $ < L.#.T n.",
 
"k.@ ! n.dXL.Y c x - R R R Y c J d..X&X$X_.XX5.e.@X,XyXfX,X1Xk A 7.7.6.I # k B f.l.s.Z C ; T T T k x % b Y T F.",
 
"H.. , : n.x.Y b * k l % z * # C .X.XoX[..X[.2.L :X<XfXhX,X1XI N (.u.u.a.0.P m %XgX%X5.v V y T - w.w.%Xk.K < 4 ",
 
"NX, 1 Y Y Y Y 3 6.y.y.y.y.q.6.D 4.y.y.5.e.9.J F 1X<X2XfX,X:X9.2.-X+X-XXX[.h.m f.g.N.@X2.v $ 2 3 r.=XAX$X2.2 U.",
 
"UXj.- Y : $ * L 5.[.'.*X%X[.y.J & U 6.n B B j D :X<X1X2X<X$Xp.8.-XgX9X}.}.V e.2.5.s.f.5.* k # * R $X=X=Xg.j.PX",
 
"UXS.. k G b = l 2.[.i.gX5X(.s.2.k p.`.`.`. X8.9.g.>X1X<X1Xg.7.p.|.&X&X9X|.p.7.Z d.5.5.5.D K N.w.k.Z %XN.2.VXUX",
 
"UXxX* v 2.q.e.P 2.(.*X*X{._.y.I 7.). X}.`.oX}.U * 1.{.:X>Xq.3 B a._.|.|.|.`.& l Z Z Z % D 4.4XAXq.w.Z 2.K.PXUX",
 
"UXJX` 5.].7X%XA 5.[.OX'._.d.V k k `. X).AX9Xu.7.# 9.6.1.b K m 7.7.6.f.(.|.p.< A K P P & P s.@X*X].4.F & mXUXUX",
 
"UXUXdXB N.5XN.3 C i.'.(.d.m N * N 2. X9X&X-Xp.p.9.).u.6.b m (.u.4.9.U 8.8.V I n M 1.M N D B s.N.d.s.A 6XIXUXUX",
 
"UXUXJXk.e.d.Z * D 2.d.a.m l n 1.N z f.+X).|.4.8.a. X+Xt.U 8./.).`.u.8.7.& k B l.p.3.4.B # % l P 7.k D.HXUXUXUX",
 
"UXUXUXxXj 9.C j j P C z V n l.8X1.l m ). X|.4.P `.9X0Xu.9.4.`.AX`.). Xn P n 8.7X3X1.3.l k ' D.# & # xXUXUXUXUX",
 
"UXUXUXPXN.$ P n 8XJ.= & N 4.OX6Xa.n U 8.|.).p.l  X4X-Xa.8.8./.4X4X/./.7.D 4.3.H.l.3.4.D k 6XK.# = U.UXUXUXUXUX",
 
"UXUXUXUXxX& % 8.H.3Xk * 4.t.t.OXp.3.z I (.(.p.6. X9X Xa.8.8./.).OX+X1.9.n 3.1.p.l.1.l P   h.`   j.UXUXUXUXUXUX",
 
"UXUXUXUXUXxXL m l.4.m L l 1.3.l.f.t.0.* 7.9.0.7././. Xt.9.8.u.u.u.u.B k B 3.4.1.B 0.* = % k * j.KXUXUXUXUXUXUX",
 
"UXUXUXUXUXUXGXD.= n H * * U 6.6.n 1.n * k #   l 8.9.p.6.I H 8.8.8.U k * U N M h.L k * &   * J.KXUXUXUXUXUXUXUX",
 
"UXUXUXUXUXUXUXIXxXh.  & * D L L l U A & % j L D.k.7.U k # # l H D.` * * j # k G j.* .   3 U.UXUXUXUXUXUXUXUXUX",
 
"UXUXUXUXUXUXUXUXUXGXJ.  .   ` ' # 3 # * * n A K.U j z * A = # # j.`   # 3 & & & j.3 . 3 xXUXUXUXUXUXUXUXUXUXUX",
 
"UXUXUXUXUXUXUXUXUXUXUXVXj.j 3 G       #   = # ` % % j #   # & # A A     *     & G * ` VXUXUXUXUXUXUXUXUXUXUXUX",
 
"UXUXUXUXUXUXUXUXUXUXUXUXPXMXK.J.S.S.J.j.G S.D.J.S.D.S.D.3 F.S.D.J.J.D.j.` S.S.D.D.D.JXUXUXUXUXUXUXUXUXUXUXUXUX",
 
"UXUXUXUXUXUXUXUXUXUXUXUXUXUXGXVXVXVXBXVXVXBXBXmXBXNXNXBXBXmXmXmXmXmXmXCXBXmXmXmXMXJXUXUXUXUXUXUXUXUXUXUXUXUXUX",
 
"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
 
"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
 
"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
 
"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX"
 
};
0 comments (0 inline, 0 general)