[
  {
    "path": ".github/workflows/build.yml",
    "content": "name: build\n\non:\n  push:\n    branches:\n    - master\n  pull_request:\n    branches:\n    - master\n\njobs:\n  build:\n    runs-on: ubuntu-20.04\n    steps:\n    - uses: actions/checkout@v1\n    - name: Install dependencies\n      run: >\n        sudo apt-get install meson mono-devel libgtk2.0-cil-dev\n        libnunit-cil-dev nunit-console xsltproc docbook-xsl\n    - name: Setup\n      run: meson setup build\n    - name: Build\n      run: ninja -C build\n    - name: Run tests\n      run: meson test -v -C build\n    - name: Install\n      run: DESTDIR=/tmp/bless-install ninja -C build install\n"
  },
  {
    "path": ".gitignore",
    "content": "**/*~\npo/**\n!po/LINGUAS\n!po/Makevars\n!po/POTFILES.in\n"
  },
  {
    "path": "AUTHORS",
    "content": "Main development team\n=====================\n\n* Alexandros Frantzis <alf82 [at] freemail [dot] gr>\n\nContributors\n============\nMany thanks to:\n\n* Jeremy Messenger <mezz7 [at] cox [dot] net>\n  Bug fixes, FreeBSD port    \n  \n* Ioannis Ramfos <isr81 [at] freemail [dot] gr>\n  Bug hunting (QA), Bug fixes\n  \n* Michael Iatrou <m_iatrou [at] freemail [dot] gr>\n  Bless logo in About Dialog.  \n\n* Mike Hearn <mike [at] navi [dot] cx>\n  Code patches\n  \n* Mirco \"MacSlow\" Müller <macslow [at] bangang [dot] de>\n  RPM packaging and .spec file\n\n* Thomas Liebetraut <thomas [at] tommie-lie [dot] de>\n  Exceptional bug hunting and fixes\n    \n* Saleem Abdulrasool <compnerd [at] gentoo [dot] org>\n  Support for DESTDIR in Makefiles\n\n* Mike Auty <mike.auty [at] gmail [dot] com>\n  Bug fixes\n\n* Marek Cernocký<marek [at] manet [dot] cz>\n  Czech translation and i18n related bug fixes.\n\n... if I have forgotten someone please remind me!\n"
  },
  {
    "path": "COPYING",
    "content": "\t\t    GNU GENERAL PUBLIC LICENSE\n\t\t       Version 2, June 1991\n\n Copyright (C) 1989, 1991 Free Software Foundation, Inc.\n                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n\t\t\t    Preamble\n\n  The licenses for most software are designed to take away your\nfreedom to share and change it.  By contrast, the GNU General Public\nLicense is intended to guarantee your freedom to share and change free\nsoftware--to make sure the software is free for all its users.  This\nGeneral Public License applies to most of the Free Software\nFoundation's software and to any other program whose authors commit to\nusing it.  (Some other Free Software Foundation software is covered by\nthe GNU Library General Public License instead.)  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthis service if you wish), that you receive source code or can get it\nif you want it, that you can change the software or use pieces of it\nin new free programs; and that you know you can do these things.\n\n  To protect your rights, we need to make restrictions that forbid\nanyone to deny you these rights or to ask you to surrender the rights.\nThese restrictions translate to certain responsibilities for you if you\ndistribute copies of the software, or if you modify it.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must give the recipients all the rights that\nyou have.  You must make sure that they, too, receive or can get the\nsource code.  And you must show them these terms so they know their\nrights.\n\n  We protect your rights with two steps: (1) copyright the software, and\n(2) offer you this license which gives you legal permission to copy,\ndistribute and/or modify the software.\n\n  Also, for each author's protection and ours, we want to make certain\nthat everyone understands that there is no warranty for this free\nsoftware.  If the software is modified by someone else and passed on, we\nwant its recipients to know that what they have is not the original, so\nthat any problems introduced by others will not reflect on the original\nauthors' reputations.\n\n  Finally, any free program is threatened constantly by software\npatents.  We wish to avoid the danger that redistributors of a free\nprogram will individually obtain patent licenses, in effect making the\nprogram proprietary.  To prevent this, we have made it clear that any\npatent must be licensed for everyone's free use or not licensed at all.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\f\n\t\t    GNU GENERAL PUBLIC LICENSE\n   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\n  0. This License applies to any program or other work which contains\na notice placed by the copyright holder saying it may be distributed\nunder the terms of this General Public License.  The \"Program\", below,\nrefers to any such program or work, and a \"work based on the Program\"\nmeans either the Program or any derivative work under copyright law:\nthat is to say, a work containing the Program or a portion of it,\neither verbatim or with modifications and/or translated into another\nlanguage.  (Hereinafter, translation is included without limitation in\nthe term \"modification\".)  Each licensee is addressed as \"you\".\n\nActivities other than copying, distribution and modification are not\ncovered by this License; they are outside its scope.  The act of\nrunning the Program is not restricted, and the output from the Program\nis covered only if its contents constitute a work based on the\nProgram (independent of having been made by running the Program).\nWhether that is true depends on what the Program does.\n\n  1. You may copy and distribute verbatim copies of the Program's\nsource code as you receive it, in any medium, provided that you\nconspicuously and appropriately publish on each copy an appropriate\ncopyright notice and disclaimer of warranty; keep intact all the\nnotices that refer to this License and to the absence of any warranty;\nand give any other recipients of the Program a copy of this License\nalong with the Program.\n\nYou may charge a fee for the physical act of transferring a copy, and\nyou may at your option offer warranty protection in exchange for a fee.\n\n  2. You may modify your copy or copies of the Program or any portion\nof it, thus forming a work based on the Program, and copy and\ndistribute such modifications or work under the terms of Section 1\nabove, provided that you also meet all of these conditions:\n\n    a) You must cause the modified files to carry prominent notices\n    stating that you changed the files and the date of any change.\n\n    b) You must cause any work that you distribute or publish, that in\n    whole or in part contains or is derived from the Program or any\n    part thereof, to be licensed as a whole at no charge to all third\n    parties under the terms of this License.\n\n    c) If the modified program normally reads commands interactively\n    when run, you must cause it, when started running for such\n    interactive use in the most ordinary way, to print or display an\n    announcement including an appropriate copyright notice and a\n    notice that there is no warranty (or else, saying that you provide\n    a warranty) and that users may redistribute the program under\n    these conditions, and telling the user how to view a copy of this\n    License.  (Exception: if the Program itself is interactive but\n    does not normally print such an announcement, your work based on\n    the Program is not required to print an announcement.)\n\f\nThese requirements apply to the modified work as a whole.  If\nidentifiable sections of that work are not derived from the Program,\nand can be reasonably considered independent and separate works in\nthemselves, then this License, and its terms, do not apply to those\nsections when you distribute them as separate works.  But when you\ndistribute the same sections as part of a whole which is a work based\non the Program, the distribution of the whole must be on the terms of\nthis License, whose permissions for other licensees extend to the\nentire whole, and thus to each and every part regardless of who wrote it.\n\nThus, it is not the intent of this section to claim rights or contest\nyour rights to work written entirely by you; rather, the intent is to\nexercise the right to control the distribution of derivative or\ncollective works based on the Program.\n\nIn addition, mere aggregation of another work not based on the Program\nwith the Program (or with a work based on the Program) on a volume of\na storage or distribution medium does not bring the other work under\nthe scope of this License.\n\n  3. You may copy and distribute the Program (or a work based on it,\nunder Section 2) in object code or executable form under the terms of\nSections 1 and 2 above provided that you also do one of the following:\n\n    a) Accompany it with the complete corresponding machine-readable\n    source code, which must be distributed under the terms of Sections\n    1 and 2 above on a medium customarily used for software interchange; or,\n\n    b) Accompany it with a written offer, valid for at least three\n    years, to give any third party, for a charge no more than your\n    cost of physically performing source distribution, a complete\n    machine-readable copy of the corresponding source code, to be\n    distributed under the terms of Sections 1 and 2 above on a medium\n    customarily used for software interchange; or,\n\n    c) Accompany it with the information you received as to the offer\n    to distribute corresponding source code.  (This alternative is\n    allowed only for noncommercial distribution and only if you\n    received the program in object code or executable form with such\n    an offer, in accord with Subsection b above.)\n\nThe source code for a work means the preferred form of the work for\nmaking modifications to it.  For an executable work, complete source\ncode means all the source code for all modules it contains, plus any\nassociated interface definition files, plus the scripts used to\ncontrol compilation and installation of the executable.  However, as a\nspecial exception, the source code distributed need not include\nanything that is normally distributed (in either source or binary\nform) with the major components (compiler, kernel, and so on) of the\noperating system on which the executable runs, unless that component\nitself accompanies the executable.\n\nIf distribution of executable or object code is made by offering\naccess to copy from a designated place, then offering equivalent\naccess to copy the source code from the same place counts as\ndistribution of the source code, even though third parties are not\ncompelled to copy the source along with the object code.\n\f\n  4. You may not copy, modify, sublicense, or distribute the Program\nexcept as expressly provided under this License.  Any attempt\notherwise to copy, modify, sublicense or distribute the Program is\nvoid, and will automatically terminate your rights under this License.\nHowever, parties who have received copies, or rights, from you under\nthis License will not have their licenses terminated so long as such\nparties remain in full compliance.\n\n  5. You are not required to accept this License, since you have not\nsigned it.  However, nothing else grants you permission to modify or\ndistribute the Program or its derivative works.  These actions are\nprohibited by law if you do not accept this License.  Therefore, by\nmodifying or distributing the Program (or any work based on the\nProgram), you indicate your acceptance of this License to do so, and\nall its terms and conditions for copying, distributing or modifying\nthe Program or works based on it.\n\n  6. Each time you redistribute the Program (or any work based on the\nProgram), the recipient automatically receives a license from the\noriginal licensor to copy, distribute or modify the Program subject to\nthese terms and conditions.  You may not impose any further\nrestrictions on the recipients' exercise of the rights granted herein.\nYou are not responsible for enforcing compliance by third parties to\nthis License.\n\n  7. If, as a consequence of a court judgment or allegation of patent\ninfringement or for any other reason (not limited to patent issues),\nconditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot\ndistribute so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you\nmay not distribute the Program at all.  For example, if a patent\nlicense would not permit royalty-free redistribution of the Program by\nall those who receive copies directly or indirectly through you, then\nthe only way you could satisfy both it and this License would be to\nrefrain entirely from distribution of the Program.\n\nIf any portion of this section is held invalid or unenforceable under\nany particular circumstance, the balance of the section is intended to\napply and the section as a whole is intended to apply in other\ncircumstances.\n\nIt is not the purpose of this section to induce you to infringe any\npatents or other property right claims or to contest validity of any\nsuch claims; this section has the sole purpose of protecting the\nintegrity of the free software distribution system, which is\nimplemented by public license practices.  Many people have made\ngenerous contributions to the wide range of software distributed\nthrough that system in reliance on consistent application of that\nsystem; it is up to the author/donor to decide if he or she is willing\nto distribute software through any other system and a licensee cannot\nimpose that choice.\n\nThis section is intended to make thoroughly clear what is believed to\nbe a consequence of the rest of this License.\n\f\n  8. If the distribution and/or use of the Program is restricted in\ncertain countries either by patents or by copyrighted interfaces, the\noriginal copyright holder who places the Program under this License\nmay add an explicit geographical distribution limitation excluding\nthose countries, so that distribution is permitted only in or among\ncountries not thus excluded.  In such case, this License incorporates\nthe limitation as if written in the body of this License.\n\n  9. The Free Software Foundation may publish revised and/or new versions\nof the General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\nEach version is given a distinguishing version number.  If the Program\nspecifies a version number of this License which applies to it and \"any\nlater version\", you have the option of following the terms and conditions\neither of that version or of any later version published by the Free\nSoftware Foundation.  If the Program does not specify a version number of\nthis License, you may choose any version ever published by the Free Software\nFoundation.\n\n  10. If you wish to incorporate parts of the Program into other free\nprograms whose distribution conditions are different, write to the author\nto ask for permission.  For software which is copyrighted by the Free\nSoftware Foundation, write to the Free Software Foundation; we sometimes\nmake exceptions for this.  Our decision will be guided by the two goals\nof preserving the free status of all derivatives of our free software and\nof promoting the sharing and reuse of software generally.\n\n\t\t\t    NO WARRANTY\n\n  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\nFOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN\nOTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\nPROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\nOR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS\nTO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE\nPROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\nREPAIR OR CORRECTION.\n\n  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\nREDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\nINCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\nOUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\nTO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\nYOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\nPROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGES.\n\n\t\t     END OF TERMS AND CONDITIONS\n\f\n\t    How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nconvey the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software; you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation; either version 2 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program; if not, write to the Free Software\n    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n\nAlso add information on how to contact you by electronic and paper mail.\n\nIf the program is interactive, make it output a short notice like this\nwhen it starts in an interactive mode:\n\n    Gnomovision version 69, Copyright (C) year name of author\n    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, the commands you use may\nbe called something other than `show w' and `show c'; they could even be\nmouse-clicks or menu items--whatever suits your program.\n\nYou should also get your employer (if you work as a programmer) or your\nschool, if any, to sign a \"copyright disclaimer\" for the program, if\nnecessary.  Here is a sample; alter the names:\n\n  Yoyodyne, Inc., hereby disclaims all copyright interest in the program\n  `Gnomovision' (which makes passes at compilers) written by James Hacker.\n\n  <signature of Ty Coon>, 1 April 1989\n  Ty Coon, President of Vice\n\nThis General Public License does not permit incorporating your program into\nproprietary programs.  If your program is a subroutine library, you may\nconsider it more useful to permit linking proprietary applications with the\nlibrary.  If this is what you want to do, use the GNU Library General\nPublic License instead of this License.\n"
  },
  {
    "path": "NEWS",
    "content": "Bless v0.6.3 20201011\n---------------------\n\n* Add plugin to allow copying the current offset to clipboard (gh #15).\n* Fix display of Courier font glyphs (gh #25).\n* Use Gtk.Builder for UI loading, drop libglade (gh #2).\n* Move to the meson build system, drop autotools.\n* Fix crash when plugins directory path is a file (gh #32).\n* Add binary+ASCII layout file (gh #23).\n* Fix issue with statusbar not showing all information (gh #14).\n\nBless v0.6.2 20190418\n---------------------\n\n* Fix rendering with monospace fonts with ligatures (gh #1).\n* Fix crash when searching (gh #3).\n* Fix incorrect notifications for file content changes (gh #7).\n* Fix crash when trying to save a file in-place.\n* Fix (harmless) Gtk-CRITICAL errors for file content change notifications.\n* Fix installation with newer autotools (gh #8).\n\nBless v0.6.1 20180919 - Better late than never\n----------------------------------------------\n\n* Use 'mcs' compiler by default, and allow proper overriding during configure.\n* Fix problem saving when the tempdir config entry hasn't been specified.\n* Fix reading and writing to XML config files.\n* Fix crash when trying to save a file without write permissions.\n* Fix various compilation warnings.\n* Moved to new home: https://github.com/afrantzis/bless\n\nBless v0.6.0 20080814\n---------------------\n\n* Read/Write support for block devices.\n* Saving speed improvements.\n* Rendering speed improvements.\n* Various bug fixes (gna.org #9660, #10378, #11397, #10601)\n* A lot of internal changes that pave the way for exciting features...\n\nBless v0.5.2 20070831\n---------------------\n\n* Pluginified Areas subsystem.\n* Bless is now installed in a more standard location.\n* Various bug fixes (gna.org #9313, #9543, #9664, #9659)\n\nBless v0.5.1 20070602\n---------------------\n\n* New Select All action.\n* Plugin to perform bitwise operations on data.\n* Added right-click popup menus.\n* Workaround for Mono 1.1.x bug that caused incomplete gui (gna.org #8975)\n* Various bug fixes (gna.org #8916, #9084, #9094)\n\nBless v0.5.0 20070330\n---------------------\n\n* Brand new plugin architecture (GUI and export).\n* Export functionality (text and html, others with plugins).\n* Reduced memory usage.\n* Fixed garbled display issue (thanks to Thomas Liebetraut).\n* Localization support.\n* New ways to select data ranges.\n\nBless v0.4.1 20060803                                                  \n---------------------\n                     \n* Fixed compilation problems with newer versions of Mono.\n* Added a work-around for the long standing garbled display issue (See README). \n\nBless v0.4.0 20051009\n---------------------\n\n* Upgraded widgets to Gtk# 2 (Gtk+ 2.4).\n* Added a toolbar.\n* Added highlighting of patterns matching the current selection.\n* Added the ability to open files by dragging and dropping them into Bless.\n* Improved build system (for packagers).\n* Many bugfixes and usability improvements.\n\nBless v0.3.6.1 20050827\n-----------------------\n\n* Fixed build system problems\n\nBless v0.3.6 20050725\n---------------------\n\n* Added Preferences (undo limit, session loading options, default layout etc)\n* Added the ability to change the statusbar information (offset, selection) \n  number base by clicking on it.\n* Reduced memory consumption for heavily modified files.\n* Improved Find/Replace and Goto Offset UI (bars instead of dialogs).\n* Misc usability improvements.\n\nBless v0.3.5 20050519\n---------------------\nThis is mainly a bugfix release\n\n* Fixed crash when saving a new file in 0.3.4.\n* Fixed subtle Gtk+ threading problems.\n* Made save as operation more robust.\n* Fixed problem with Notebook arrows.\n* Fixed dialog focusing problems.\n* Fixed crash with find/replace.\n* New <bytes> tag in layout files, allows you to set the number of bytes\n  each offset in the offset area will have.\n* You can now change the edit mode by clicking on the OVR/INS statusbar.\n\n\nBless v0.3.4 20050509\n---------------------\n\n* Added recent file support.\n* Added session support (Bless saves its state when you quit and tries to \n  reload it when you start).\n* Reduced memory consumption by sharing common resources.\n* Added notification when a file changes outside Bless.\n* Better help integration with scrollkeeper and GNOME.\n* Changed user configuration directory to adhere to XDG specification\n  (usually $HOME/.config/bless).\n\nBless v0.3.3 20050412\n---------------------\n\n* Added full copy/paste support.\n* Increased speed and gui responsiveness by moving find/replace and save \n  operations in separate threads.\n* Added new docbook manual.\n* Changed build system to use autotools.\n* When installing, an entry is added to the menu of freedesktop compliant\n  desktop enviroments (eg GNOME). \n\nBless v0.3.2 20050311\n---------------------\n\n* Increased search speed by using a boyer-moore based algorithm.\n* Greatly improved performance of replace all operation.\n* Added a Conversion Table (converts the data at the cursor to various formats).\n* Find and Replace dialogs can now parse numbers in all major bases.\n* New <bpr> tag in layout files allows setting the bytes per row of an area\n  to a fixed value.\n* The default values of some colors (eg selection) are now set from the theme. \n* Fixed compilation errors/warnings with Mono 1.1.4 and removed the dependency\n  of the main program on the NUnit framework.\n\nBless v0.3.1 20050214\n---------------------\n\n* Added replace functionality.\n* Find and Replace dialogs get their search pattern from the current selection.\n* You can now revert a file to its previous saved state.\n* Added Backspace key support for deletion.\n* Improved statusbar handling (View->Statusbar).\n\nBless v0.3.0 20050205\n---------------------\n\n* Bless now features multiple tabs!\n* Added support for finding bytes in hexadecimal and text.\n* You can go to a specified offset within the file.\n* Reduced memory usage.\n* Improved UI, especially when confirming file saves.\n\nBless v0.2.3 20041213\n---------------------\n\n* Support for inserting bytes.\n* Saving files is much quicker now.\n* Undo/redo behaviour has been improved.\n* A progress dialog is shown if a save lasts for more than 1 second.\n* The window title is marked with an asterisk if the file has been modified.\n\nBless v0.2.2 20041127\n---------------------\nThis release contains many bug fixes and enhancements. The most\nimportant ones are:\n\n* mouse wheel scrolling \n* improved memory handling (smaller footprint)\n* ability to create new files/append to existing ones\n* proper mouse and keyboard selection behaviour\n* more robust handling of files\n"
  },
  {
    "path": "README",
    "content": "Bless - Gtk# Hex Editor v0.6.3\n==============================\nCopyright (c) 2004-2020, Alexandros Frantzis\n\nThank you for using ( or at least trying out :) ) Bless!\n\nContents\n\n1. Description\n2. Project Web Site and contact info\n3. Requirements\n4. Installation\n5. Running\n6. Documentation\n7. Known Issues\n\n\n--------------\n1. Description\n--------------\n\nBless is a binary (hex) editor, a program that enables you to edit files as\na sequence of bytes. It is written in C# and uses the Gtk# bindings for the \nGTK+ toolkit.\n\nBless is distributed under the terms of the GNU General Public License\n(GPL-2.0-or-later).  See the file COPYING for more information.\n\nMain Features\n-------------\n  * Efficient editing of large data files. \n  * Raw disk editing.\n  * Multilevel undo - redo operations.\n  * Customizable data views.\n  * Fast data rendering on screen.\n  * Multiple Tabs.\n  * Fast Find and Replace operations.\n  * Conversion Table.\n  * Advanced Copy/Paste capabilities.\n  * Multi-threaded search and save operations.\n  * Export to text and html (others with plugins).\n  * Extensibility with Plugins.\n  \nPlanned Features\n----------------\n  * Scripting language for binary file manipulation.\n\n------------------------------------\n2. Project Web Site and contact info\n------------------------------------\n\nMore information, bug reports and the latest releases can be found at: \n  https://github.com/afrantzis/bless\n\nI can be contacted at: alf82 [at] freemail [dot] gr.\n\n---------------\n3. Requirements\n---------------\n\nThe main target platform for bless is GNU/Linux. However, all the libraries it\nuses are cross-platform, so bless should be able to run without problems \non all the major platforms (GNU/Linux, *BSD, Solaris, Win32).\n\nTo build and run the current version of bless you need:\n    * GTK+ >= 2.8.x (Included in all modern GNU/Linux distributions, http://www.gtk.org)\n    * mono/.NET runtime and C# compiler >= 1.1.14 (http://www.mono-project.com)\n    * Gtk# bindings >= 2.8 for GTK+ (http://gtk-sharp.sourceforge.net)\n    * pkg-config (Included in all modern GNU/Linux distributions)\n    * meson >= 0.46\n    * nunit and nunit-console, if you want to build and run tests\n    * xsltproc and docbook stylesheet, if you want to produce HTML documentation\n    \nDevelopment is done using the latest stable versions of the above libraries. \nAlthough using an older version may be OK, there is no guarantee that there \nwill not be problems.\n\n---------------\n4. Installation\n---------------\nQuick: \n    git clone https://github.com/afrantzis/bless\n    meson setup build (-Dopt=val --buildtype=type ...)\n    ninja -C build\n    (ninja -C build install)\n\nDetailed:\n\nStep 1: Get the source\n---------------------------------\nTo get the latest source:\n    git clone https://github.com/afrantzis/bless\n\nFor a compressed tarball use:\n    tar -xf bless-a.b.c.tar.gz\n\nStep 2: Configure the build\n-----------------------------\nEnter the directory created in the previous step (bless or bless-a.b.c). To\nconfigure the build and check that your system has all the required libraries\nuse: \n\n    $ meson setup build (-Dopt=val --buildtype=type ...)\n\nUse the \"-Dprefix=PREFIX\" option to set the installation directory prefix.  By\ndefault the prefix is '/usr/local'.\n\nYou can use the \"--buildtype=release\" option to build bless in release mode,\nby default the debug mode is built.\n\nStep 3: Build the program\n-----------------------------\nType 'ninja -C build'. This will create 'bless.exe' and the necessary library\nfiles in the build/src directory. You can also type 'ninja -C build test' to\nrun some tests on various bless components. Note that running the tests\nrequires the 'nunit-console' binary.\n\nStep 4: Install the program (optional)\n--------------------------------------\nBecome root and type 'ninja -C build install'.\n\n\n----------\n5. Running\n----------\nIf you chose to install the program, just type 'bless'. In any case you can\nrun the program by typing 'mono build/src/bless.exe' from within the top source\ndirectory.  Enjoy!\n\n----------------\n6. Documentation\n----------------\n\nThe doc/ directory contains documentation directed both at the user and at the \ndeveloper who wants to explore Bless. The doc/user/ subdirectory contains \ninformation about using bless whereas doc/developer/ contains developer \ninformation (bless api etc). \nNote: The developer documentation is almost non-existent.\n\n---------------\n7. Known Issues\n---------------\n\n* To be able to save a file under the same name (File->Save command) you need\n  to have (temporarily) enough disk space to hold both the original and the\n  new file. This happens because the new file is created in the /tmp \n  directory and then moved to its proper position. For example if you have a \n  20MB file and edit it so that it becomes 21MB and the new file is supposed to\n  be saved in the same storage device as /tmp, you need to have 20+21=41MB free\n  space in that storage device to be able to save it. After a successful save, \n  the original file is deleted, in this case freeing 20MB.\n      Although this can be a problem (when there is not enough disk space), it \n  can also be seen as a safety measure in case something goes wrong when saving.\n\n  A notable exception to the above is when the size of the file to be saved has \n  not been changed. In that case the file is saved in-place.\n"
  },
  {
    "path": "README.packaging",
    "content": "Bless - Gtk# Hex Editor Packaging Notes\n=======================================\n\nThis document is aimed at people trying to package Bless\nfor a specific distribution.\n\nBless can easily be packaged using the following method:\n\nmeson setup build -Dprefix=/usr\nninja -C build\nDESTDIR=/tmp-pkg-path ninja -C build install\n\nThe contents of the /tmp-pkg-path can then be compressed and\ndistributed as a package. \n"
  },
  {
    "path": "bless.mdp",
    "content": "<Project name=\"bless\" fileversion=\"2.0\" language=\"C#\" clr-version=\"Net_1_1\" ctype=\"DotNetProject\">\n  <Configurations active=\"Debug\">\n    <Configuration name=\"Debug\" ctype=\"DotNetProjectConfiguration\">\n      <Output directory=\"bin/Debug\" assembly=\"bless\" />\n      <Build debugmode=\"True\" target=\"Exe\" />\n      <Execution runwithwarnings=\"False\" consolepause=\"True\" runtime=\"MsNet\" clr-version=\"Net_1_1\" />\n      <CodeGeneration compiler=\"Csc\" warninglevel=\"4\" optimize=\"True\" unsafecodeallowed=\"False\" generateoverflowchecks=\"True\" mainclass=\"\" generatexmldocumentation=\"False\" ctype=\"CSharpCompilerParameters\" />\n    </Configuration>\n    <Configuration name=\"Release\" ctype=\"DotNetProjectConfiguration\">\n      <Output directory=\"bin/Release\" assembly=\"bless\" />\n      <Build debugmode=\"True\" target=\"Exe\" />\n      <Execution runwithwarnings=\"False\" consolepause=\"True\" runtime=\"MsNet\" clr-version=\"Net_1_1\" />\n      <CodeGeneration compiler=\"Csc\" warninglevel=\"4\" optimize=\"True\" unsafecodeallowed=\"False\" generateoverflowchecks=\"True\" mainclass=\"\" generatexmldocumentation=\"False\" ctype=\"CSharpCompilerParameters\" />\n    </Configuration>\n  </Configurations>\n  <Contents>\n    <File name=\"src/gui/DataView.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/MainWindow.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/Layout.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/dialogs\" subtype=\"Directory\" buildaction=\"Compile\" />\n    <File name=\"src/gui/dialogs/LayoutSelectionDialog.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/areas\" subtype=\"Directory\" buildaction=\"Compile\" />\n    <File name=\"src/gui/areas/AsciiArea.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/areas/BinaryArea.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/areas/DecimalArea.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/areas/HexArea.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/areas/OctalArea.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/areas/OffsetArea.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/areas/SeparatorArea.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/drawers/AsciiDrawer.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/drawers/BinaryDrawer.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/drawers/DecimalDrawer.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/drawers/HexDrawer.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/drawers/OctalDrawer.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/drawers/Drawer.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/areas/GroupedArea.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/dialogs/Alert.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/dialogs/ErrorAlert.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/util\" subtype=\"Directory\" buildaction=\"Compile\" />\n    <File name=\"src/util/Range.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/util/List.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/dialogs/SaveConfirmationAlert.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/util/TempFile.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/dialogs/FileOverwriteAlert.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/DataViewControl.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/DataBook.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/dialogs/SaveConfirmationMultiAlert.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/tools\" subtype=\"Directory\" buildaction=\"Compile\" />\n    <File name=\"src/gui/DataViewDisplay.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/util/ByteArray.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/tools/find/IFindStrategy.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/tools/find/SimpleFindStrategy.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/tools/find/IFinder.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/dialogs/AboutDialog.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/dialogs/InformationAlert.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/dialogs/RevertConfirmationAlert.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/tools/find/BMFindStrategy.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/util/BaseConverter.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"tests\" subtype=\"Directory\" buildaction=\"Compile\" />\n    <File name=\"src/util/FileResourcePath.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/dialogs/ProgressDialog.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"tests/util/BaseConverterTests.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"tests/util/ByteArrayTests.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"tests/util/ListTests.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"tests/util/RangeTests.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/util/ProgressCallback.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/tools/find/FindAsyncResult.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/util/ThreadedAsyncOperation.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/tools/find/FindOperations.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/tools/Session.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/tools/History.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/FileChangedBar.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/dialogs/WarningAlert.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/tools/Preferences.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/dialogs/PreferencesDialog.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/util/Deque.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"tests/util/DequeTests.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/util/RangeCollection.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/WidgetGroup.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/plugins\" subtype=\"Directory\" buildaction=\"Compile\" />\n    <File name=\"src/plugins/Plugin.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/plugins/PluginManager.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/plugins\" subtype=\"Directory\" buildaction=\"Compile\" />\n    <File name=\"src/plugins/GuiPlugin.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/plugins/FindReplacePlugin.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/plugins/GotoOffsetPlugin.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/plugins/FileOperationsPlugin.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/FileService.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/Services.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/SessionService.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/plugins/EditOperationsPlugin.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/plugins/ConversionTablePlugin.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/plugins/InfobarPlugin.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/plugins/HelpOperationsPlugin.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/plugins/SelectLayoutPlugin.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/plugins/StatisticsPlugin.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/tools/export\" subtype=\"Directory\" buildaction=\"Compile\" />\n    <File name=\"src/tools/export/IExporter.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/buffers/ByteBuffer.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/buffers/ByteBufferAction.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/buffers/FileBuffer.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/buffers/IBuffer.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/buffers/SaveAsOperation.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/buffers/SaveOperation.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/buffers/Segment.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/buffers/SegmentCollection.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/buffers/SimpleBuffer.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/tools/export/IExportBuilder.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/tools/export/InterpretedPatternExporter.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/tools/export/IPatternExporter.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"tests/buffers/ByteBufferTests.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"tests/buffers/FileBufferTests.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"tests/buffers/SegmentCollectionTests.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"tests/buffers/SegmentTests.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"tests/tools/export/ExporterTests.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"builder/Main.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"builder/Module.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"builder/ModuleBuilder.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"builder/ModuleTree.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/plugins/ExportPlugin.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/tools/export/plugins/TextExportBuilder.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/tools/export/plugins/TextExportPlugin.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/dialogs/ExportDialog.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/plugins/FileExportPlugin.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/tools/export/ExporterOperation.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/tools/export/plugins/HTMLExportBuilder.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/tools/export/plugins/HTMLExportPlugin.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/plugins/SelectRangePlugin.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/plugins/HistoryPlugin.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/drawers/PixmapManager.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/DataBookFinder.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/UIService.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/plugins/ProgressDisplayPlugin.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/plugins/BitwiseOperationsPlugin.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/plugins/AreaPlugin.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/areas/Area.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/util/ConfigureDefines.cs.tmpl.in\" subtype=\"Code\" buildaction=\"Nothing\" />\n    <File name=\"src/buffers/SaveInPlaceOperation.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/buffers/ISaveState.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"tests/buffers/SimpleBufferTests.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/util/RedBlackTree.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"tests/util/RedBlackTreeTests.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/util/IntervalTree.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"tests/util/IntervalTreeTests.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/areas/AreaGroup.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/areas/Highlight.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n    <File name=\"src/gui/plugins/PatternMatchHighlightPlugin.cs\" subtype=\"Code\" buildaction=\"Compile\" />\n  </Contents>\n  <DeploymentInformation strategy=\"File\">\n    <excludeFiles />\n  </DeploymentInformation>\n</Project>"
  },
  {
    "path": "bless.mds",
    "content": "<Combine name=\"bless\" fileversion=\"2.0\">\n  <Configurations active=\"Debug\">\n    <Configuration name=\"Release\" ctype=\"CombineConfiguration\">\n      <Entry build=\"False\" name=\"bless\" configuration=\"Release\" />\n    </Configuration>\n    <Configuration name=\"Debug\" ctype=\"CombineConfiguration\">\n      <Entry build=\"False\" name=\"bless\" configuration=\"Debug\" />\n    </Configuration>\n  </Configurations>\n  <StartMode startupentry=\"bless\" single=\"True\">\n    <Execute type=\"None\" entry=\"bless\" />\n  </StartMode>\n  <Entries>\n    <Entry filename=\"bless.mdp\" />\n  </Entries>\n</Combine>"
  },
  {
    "path": "data/README.bless-courier",
    "content": "bless-courier.ttf is a ttf version of the IBM Courier font as shipped by\ntexlive at:\n\nhttps://www.tug.org/texlive/Contents/live/texmf-dist/fonts/type1/adobe/courier/pcrr8a.pfb\n\nThe rendering of the original Type 1 version of the font is problematic on some\nsystems. See at https://github.com/afrantzis/bless/issues/25 for more\ninformation.\n\nWe ship a TTF version here to ensure we have a nice looking default Courier\nfont even on systems that don't ship one, or on which the Courier font is\nproblematic.\n\nThe font name of bless-courier.ttf is 'BlessCourier', to allow using the\n'Courier' font name for system-wide Courier font if needed.\n"
  },
  {
    "path": "data/bless-16-bytes-per-row.layout",
    "content": "<layout>\n    <area type=\"offset\">\n\t<display>\n\t    <evenrow>\n\t\t<evencolumn>\n\t\t    <foreground>dark red</foreground>\n\t\t    <background>white</background>\n\t\t</evencolumn>\n\t    </evenrow>\n\t    <oddrow>\n\t\t<evencolumn>\n\t\t    <foreground>dark red</foreground>\n\t\t    <background>white</background>\n\t\t</evencolumn>\n\t    </oddrow>    \n\t</display>\n    </area>\n    \n    <area type=\"separator\">\n    \t<display>\n\t    <evenrow>\n\t\t<evencolumn>\n\t\t    <foreground>dark green</foreground>\n\t\t    <background>white</background>\n\t\t</evencolumn>\n\t    </evenrow>    \n\t</display>\n\n    </area>\n    \n    <area type=\"hexadecimal\">\n\t<bpr>16</bpr>\n\t<case>upper</case>\n    </area>\n\n    <area type=\"separator\">\n\t<display>\n\t    <evenrow>\n\t\t<evencolumn>\n\t\t    <foreground>dark green</foreground>\n\t\t    <background>white</background>\n\t\t</evencolumn>\n\t    </evenrow>    \n\t</display>\n\n    </area>\n    \n    <area type=\"ascii\">\n    </area>\n</layout>"
  },
  {
    "path": "data/bless-all-number-bases.layout",
    "content": "<layout>\n    <area type=\"offset\">\n        <display>\n            <evenrow>\n                <evencolumn>\n                    <foreground>dark red</foreground>\n                </evencolumn>\n            </evenrow>\n            <oddrow>\n                <evencolumn>\n                    <background>#eeeeee</background>\n\t\t    <foreground>dark red</foreground>\n                </evencolumn>\n            </oddrow>    \n        </display>                        \n    </area>\n    \n    <area type=\"separator\">\n        <display>\n            <evenrow>\n                <evencolumn>\n                    <foreground>dark green</foreground>\n                    <background>white</background>\n                </evencolumn>\n            </evenrow>\n        </display>                        \n    </area>\n    \n    <area type=\"hexadecimal\">\n        <case>upper</case>\n        <display>\n            <evenrow>\n                <selectedcolumn>\n                    <foreground>white</foreground>\n                    <background>#8faec8</background>\n                </selectedcolumn>\n            </evenrow>    \n            <oddrow>\n                <evencolumn>\n                    <background>#eeeeee</background>\n                </evencolumn>\n                <oddcolumn>\n                    <background>#eeeeee</background>\n                </oddcolumn>\n                <selectedcolumn>\n                    <foreground>white</foreground>\n                    <background>#7b96ac</background>\n                </selectedcolumn>\n            </oddrow>    \n        </display>    \n    </area>\n\n    <area type=\"separator\">\n        <display>\n            <evenrow>\n                <evencolumn>\n                    <foreground>dark green</foreground>\n                    <background>white</background>\n                </evencolumn>\n            </evenrow>\n        </display>                        \n    </area>\n    \n    <area type=\"decimal\">\n        <display>\n            <evenrow>\n                <selectedcolumn>\n                    <foreground>white</foreground>\n                    <background>#8faec8</background>\n                </selectedcolumn>\n            </evenrow>    \n            <oddrow>\n                <evencolumn>\n                    <background>#eeeeee</background>\n                </evencolumn>\n                <oddcolumn>\n                    <background>#eeeeee</background>\n                </oddcolumn>\n                <selectedcolumn>\n                    <foreground>white</foreground>\n                    <background>#7b96ac</background>\n                </selectedcolumn>\n            </oddrow>    \n        </display>    \n    </area>\n\n    <area type=\"separator\">\n        <display>\n            <evenrow>\n                <evencolumn>\n                    <foreground>dark green</foreground>\n                    <background>white</background>\n                </evencolumn>\n            </evenrow>\n        </display>                        \n    </area>\n\n    <area type=\"octal\">\n        <case>upper</case>\n        <display>\n            <evenrow>\n                <selectedcolumn>\n                    <foreground>white</foreground>\n                    <background>#8faec8</background>\n                </selectedcolumn>\n            </evenrow>    \n            <oddrow>\n                <evencolumn>\n                    <background>#eeeeee</background>\n                </evencolumn>\n                <oddcolumn>\n                    <background>#eeeeee</background>\n                </oddcolumn>\n                <selectedcolumn>\n                    <foreground>white</foreground>\n                    <background>#7b96ac</background>\n                </selectedcolumn>\n            </oddrow>    \n        </display>    \n    </area>\n\n    <area type=\"separator\">\n        <display>\n            <evenrow>\n                <evencolumn>\n                    <foreground>dark green</foreground>\n                    <background>white</background>\n                </evencolumn>\n            </evenrow>\n        </display>                        \n    </area>\n\n    <area type=\"binary\">\n        <display>\n            <evenrow>\n                <selectedcolumn>\n                    <foreground>white</foreground>\n                    <background>#8faec8</background>\n                </selectedcolumn>\n            </evenrow>    \n            <oddrow>\n                <evencolumn>\n                    <background>#eeeeee</background>\n                </evencolumn>\n                <oddcolumn>\n                    <background>#eeeeee</background>\n                </oddcolumn>\n                <selectedcolumn>\n                    <foreground>white</foreground>\n                    <background>#7b96ac</background>\n                </selectedcolumn>\n            </oddrow>    \n        </display>    \n    </area>\n\n\n</layout>\n\n"
  },
  {
    "path": "data/bless-binary-ascii.layout",
    "content": "<layout>\n    <area type=\"offset\">\n\t<display>\n\t    <evenrow>\n\t\t<evencolumn>\n\t\t    <foreground>dark red</foreground>\n\t\t    <background>white</background>\n\t\t</evencolumn>\n\t    </evenrow>\n\t    <oddrow>\n\t\t<evencolumn>\n\t\t    <foreground>dark red</foreground>\n\t\t    <background>white</background>\n\t\t</evencolumn>\n\t    </oddrow>    \n\t</display>\n    </area>\n    \n    <area type=\"separator\">\n    \t<display>\n\t    <evenrow>\n\t\t<evencolumn>\n\t\t    <foreground>dark green</foreground>\n\t\t    <background>white</background>\n\t\t</evencolumn>\n\t    </evenrow>    \n\t</display>\n\n    </area>\n    \n    <area type=\"binary\">\n    </area>\n\n    <area type=\"separator\">\n\t<display>\n\t    <evenrow>\n\t\t<evencolumn>\n\t\t    <foreground>dark green</foreground>\n\t\t    <background>white</background>\n\t\t</evencolumn>\n\t    </evenrow>    \n\t</display>\n\n    </area>\n    \n    <area type=\"ascii\">\n    </area>\n</layout>\n"
  },
  {
    "path": "data/bless-default.layout",
    "content": "<layout>\n    <area type=\"offset\">\n\t<display>\n\t    <evenrow>\n\t\t<evencolumn>\n\t\t    <foreground>dark red</foreground>\n\t\t    <background>white</background>\n\t\t</evencolumn>\n\t    </evenrow>\n\t    <oddrow>\n\t\t<evencolumn>\n\t\t    <foreground>dark red</foreground>\n\t\t    <background>white</background>\n\t\t</evencolumn>\n\t    </oddrow>    \n\t</display>\n    </area>\n    \n    <area type=\"separator\">\n    \t<display>\n\t    <evenrow>\n\t\t<evencolumn>\n\t\t    <foreground>dark green</foreground>\n\t\t    <background>white</background>\n\t\t</evencolumn>\n\t    </evenrow>    \n\t</display>\n\n    </area>\n    \n    <area type=\"hexadecimal\">\n\t<case>upper</case>\n    </area>\n\n    <area type=\"separator\">\n\t<display>\n\t    <evenrow>\n\t\t<evencolumn>\n\t\t    <foreground>dark green</foreground>\n\t\t    <background>white</background>\n\t\t</evencolumn>\n\t    </evenrow>    \n\t</display>\n\n    </area>\n    \n    <area type=\"ascii\">\n    </area>\n</layout>"
  },
  {
    "path": "data/bless.desktop",
    "content": "[Desktop Entry]\nVersion=1.0\nName=Bless Hex Editor\nGenericName=Hex Editor\nExec=bless %F\nComment=Edit binary files\nTerminal=false\nType=Application\nCategories=GTK;Development;\nIcon=bless\nGenericName[en_US]=Hex Editor\n"
  },
  {
    "path": "data/default-preferences.xml",
    "content": "<preferences>\n\t<pref name=\"Session.RememberCursorPosition\">True</pref>\n\t<pref name=\"Tools.ConversionTable.LEDecoding\">False</pref>\n\t<pref name=\"Default.EditMode\">Insert</pref>\n\t<pref name=\"Tools.ConversionTable.Show\">True</pref>\n\t<pref name=\"Tools.Statistics.Show\">False</pref>\n\t<pref name=\"Session.RememberWindowGeometry\">True</pref>\n\t<pref name=\"Highlight.PatternMatch\">True</pref>\t\n\t<pref name=\"Undo.KeepAfterSave\">Memory</pref>\n\t<pref name=\"View.Toolbar.Show\">True</pref>\n\t<pref name=\"Default.NumberBase\">Hexadecimal</pref>\n\t<pref name=\"View.Statusbar.Offset\">True</pref>\n\t<pref name=\"Default.Layout.File\"></pref>\n\t<pref name=\"View.Statusbar.Show\">True</pref>\n\t<pref name=\"Undo.Limited\">False</pref>\n\t<pref name=\"Default.Layout.UseCurrent\">False</pref>\n\t<pref name=\"Session.LoadPrevious\">True</pref>\n\t<pref name=\"View.Statusbar.Overwrite\">True</pref>\n\t<pref name=\"Session.AskBeforeLoading\">False</pref>\n\t<pref name=\"Undo.Actions\">100</pref>\n\t<pref name=\"View.Statusbar.Selection\">True</pref>\n\t<pref name=\"ByteBuffer.TempDir\"></pref>\n</preferences>\n"
  },
  {
    "path": "data/help_script.sh",
    "content": "#!/bin/sh\n\nbase_dir=\"$1\"\ndocbook_help=\"$base_dir/index.docbook\"\nhtml_help=\"$base_dir/index.html\"\n\n# try to get default browsers from GConf\nGCONFTOOL=$(which gconftool-2 2> /dev/null)\n\nif [ -n \"$GCONFTOOL\" ];\nthen\n    help_browser=$(\"$GCONFTOOL\" --get \"/desktop/gnome/url-handlers/ghelp/command\")\n    help_browser=$(echo \"$help_browser\" | sed s/\\\"//g)\n    http_browser=$(\"$GCONFTOOL\" --get \"/desktop/gnome/url-handlers/http/command\")\n    http_browser=$(echo \"$http_browser\" | sed s/\\\"//g)\nfi\n\n# some other browsers\nyelp_browser=$(which yelp 2> /dev/null)\nfirefox_browser=$(which firefox 2> /dev/null)\n\n([ -n \"$help_browser\" ] && $(printf \"$help_browser\" \"$docbook_help\")) ||\n([ -n \"$yelp_browser\" ] && \"$yelp_browser\" \"$docbook_help\") ||\n([ -n \"$http_browser\" ] && $(printf \"$http_browser\" \"$html_help\")) ||\n([ -n \"$firefox_browser\" ] && \"$firefox_browser\" \"$html_help\")\n"
  },
  {
    "path": "data/meson.build",
    "content": "install_subdir(\n    'ui',\n    install_dir: join_paths(get_option('datadir'), meson.project_name()),\n)\n\ninstall_data(\n    files(\n        'bless-16-bytes-per-row.layout',\n        'bless-48x48.png',\n        'bless-about.png',\n        'bless-all-number-bases.layout',\n        'bless-binary-ascii.layout',\n        'bless-courier.ttf',\n        'bless-default.layout',\n        'default-preferences.xml',\n        'help_script.sh',\n    )\n)\n\ninstall_data(\n    'bless.desktop',\n    install_dir: join_paths(get_option('datadir'), 'applications'),\n)\n\ninstall_data(\n    'bless-48x48.png',\n    rename: 'bless.png',\n    install_dir: join_paths(get_option('datadir'), 'icons', 'hicolor', '48x48', 'apps'),\n)\n"
  },
  {
    "path": "data/ui/BitwiseOperationsPlugin.ui",
    "content": "<?xml version=\"1.0\"?>\n<interface>\n  <object class=\"GtkListStore\" id=\"model3\">\n    <columns>\n      <column type=\"gchararray\"/>\n    </columns>\n    <data>\n      <row>\n        <col id=\"0\" translatable=\"yes\">AND</col>\n      </row>\n      <row>\n        <col id=\"0\" translatable=\"yes\">OR</col>\n      </row>\n      <row>\n        <col id=\"0\" translatable=\"yes\">XOR</col>\n      </row>\n      <row>\n        <col id=\"0\" translatable=\"yes\">NOT</col>\n      </row>\n    </data>\n  </object>\n  <object class=\"GtkListStore\" id=\"model4\">\n    <columns>\n      <column type=\"gchararray\"/>\n    </columns>\n    <data>\n      <row>\n        <col id=\"0\" translatable=\"yes\">Hexadecimal</col>\n      </row>\n      <row>\n        <col id=\"0\" translatable=\"yes\">Decimal</col>\n      </row>\n      <row>\n        <col id=\"0\" translatable=\"yes\">Octal</col>\n      </row>\n      <row>\n        <col id=\"0\" translatable=\"yes\">Binary</col>\n      </row>\n      <row>\n        <col id=\"0\" translatable=\"yes\">Text</col>\n      </row>\n    </data>\n  </object>\n  <object class=\"GtkHBox\" id=\"BitwiseOperationsHBox\">\n    <property name=\"visible\">True</property>\n    <property name=\"border_width\">6</property>\n    <property name=\"spacing\">6</property>\n    <child>\n      <object class=\"GtkEventBox\" id=\"SourceLabelEB\">\n        <property name=\"visible\">True</property>\n        <signal handler=\"OnSourceLabelButtonPress\" name=\"button_press_event\"/>\n        <child>\n          <object class=\"GtkLabel\" id=\"SourceLabel\">\n            <property name=\"visible\">True</property>\n            <property name=\"xalign\">0</property>\n            <property name=\"use_markup\">True</property>\n          </object>\n        </child>\n      </object>\n      <packing>\n        <property name=\"expand\">False</property>\n        <property name=\"fill\">False</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkComboBox\" id=\"OperationComboBox\">\n        <property name=\"visible\">True</property>\n        <signal handler=\"OnOperationComboBoxChanged\" name=\"changed\"/>\n        <property name=\"model\">model3</property>\n        <child>\n          <object class=\"GtkCellRendererText\" id=\"renderer3\"/>\n          <attributes>\n            <attribute name=\"text\">0</attribute>\n          </attributes>\n        </child>\n      </object>\n      <packing>\n        <property name=\"expand\">False</property>\n        <property name=\"fill\">False</property>\n        <property name=\"position\">1</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkEntry\" id=\"OperandEntry\">\n        <property name=\"visible\">True</property>\n        <signal handler=\"OnOperandEntryChanged\" name=\"changed\"/>\n        <signal handler=\"OnOperandEntryActivated\" name=\"activate\"/>\n      </object>\n      <packing>\n        <property name=\"position\">2</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkLabel\" id=\"label8\">\n        <property name=\"visible\">True</property>\n        <property name=\"label\" translatable=\"yes\">as</property>\n      </object>\n      <packing>\n        <property name=\"expand\">False</property>\n        <property name=\"fill\">False</property>\n        <property name=\"position\">3</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkComboBox\" id=\"OperandAsComboBox\">\n        <property name=\"visible\">True</property>\n        <property name=\"model\">model4</property>\n        <child>\n          <object class=\"GtkCellRendererText\" id=\"renderer4\"/>\n          <attributes>\n            <attribute name=\"text\">0</attribute>\n          </attributes>\n        </child>\n      </object>\n      <packing>\n        <property name=\"position\">4</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkButton\" id=\"DoOperationButton\">\n        <property name=\"visible\">True</property>\n        <property name=\"label\" translatable=\"no\">gtk-execute</property>\n        <property name=\"use_stock\">True</property>\n        <signal handler=\"OnDoOperationClicked\" name=\"clicked\"/>\n      </object>\n      <packing>\n        <property name=\"expand\">False</property>\n        <property name=\"fill\">False</property>\n        <property name=\"position\">5</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkButton\" id=\"CloseButton\">\n        <property name=\"visible\">True</property>\n        <property name=\"can_focus\">True</property>\n        <property name=\"relief\">GTK_RELIEF_NONE</property>\n        <property name=\"focus_on_click\">False</property>\n        <signal handler=\"OnCloseButtonClicked\" name=\"clicked\"/>\n        <child>\n          <object class=\"GtkImage\" id=\"image8\">\n            <property name=\"visible\">True</property>\n            <property name=\"stock\">gtk-close</property>\n            <property name=\"icon_size\">1</property>\n          </object>\n        </child>\n      </object>\n      <packing>\n        <property name=\"expand\">False</property>\n        <property name=\"fill\">False</property>\n        <property name=\"position\">6</property>\n      </packing>\n    </child>\n  </object>\n</interface>\n"
  },
  {
    "path": "data/ui/ConversionTablePlugin.ui",
    "content": "<?xml version=\"1.0\"?>\n<interface>\n  <object class=\"GtkTable\" id=\"ConversionTableWidget\">\n    <property name=\"visible\">True</property>\n    <property name=\"border_width\">6</property>\n    <property name=\"n_rows\">7</property>\n    <property name=\"n_columns\">7</property>\n    <child>\n      <placeholder/>\n    </child>\n    <child>\n      <placeholder/>\n    </child>\n    <child>\n      <placeholder/>\n    </child>\n    <child>\n      <placeholder/>\n    </child>\n    <child>\n      <object class=\"GtkButton\" id=\"CloseButton\">\n        <property name=\"visible\">True</property>\n        <property name=\"can_focus\">True</property>\n        <property name=\"relief\">GTK_RELIEF_NONE</property>\n        <property name=\"focus_on_click\">False</property>\n        <signal handler=\"OnCloseButtonClicked\" name=\"clicked\"/>\n        <child>\n          <object class=\"GtkImage\" id=\"image1332\">\n            <property name=\"visible\">True</property>\n            <property name=\"stock\">gtk-close</property>\n            <property name=\"icon_size\">1</property>\n          </object>\n        </child>\n      </object>\n      <packing>\n        <property name=\"left_attach\">6</property>\n        <property name=\"right_attach\">7</property>\n        <property name=\"x_options\">GTK_FILL</property>\n        <property name=\"y_options\"/>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkAlignment\" id=\"alignment46\">\n        <property name=\"visible\">True</property>\n        <property name=\"xalign\">0</property>\n        <property name=\"xscale\">0</property>\n        <child>\n          <object class=\"GtkEntry\" id=\"AsciiEntry\">\n            <property name=\"visible\">True</property>\n            <property name=\"editable\">False</property>\n            <property name=\"width_chars\">8</property>\n          </object>\n        </child>\n      </object>\n      <packing>\n        <property name=\"left_attach\">5</property>\n        <property name=\"right_attach\">6</property>\n        <property name=\"top_attach\">4</property>\n        <property name=\"bottom_attach\">5</property>\n        <property name=\"y_options\"/>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkAlignment\" id=\"alignment45\">\n        <property name=\"visible\">True</property>\n        <property name=\"xalign\">0</property>\n        <property name=\"xscale\">0</property>\n        <child>\n          <object class=\"GtkEntry\" id=\"OctalEntry\">\n            <property name=\"visible\">True</property>\n            <property name=\"editable\">False</property>\n            <property name=\"width_chars\">16</property>\n          </object>\n        </child>\n      </object>\n      <packing>\n        <property name=\"left_attach\">5</property>\n        <property name=\"right_attach\">6</property>\n        <property name=\"top_attach\">2</property>\n        <property name=\"bottom_attach\">3</property>\n        <property name=\"y_options\"/>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkAlignment\" id=\"alignment44\">\n        <property name=\"visible\">True</property>\n        <property name=\"xalign\">0</property>\n        <property name=\"xscale\">0</property>\n        <child>\n          <object class=\"GtkEntry\" id=\"DecimalEntry\">\n            <property name=\"visible\">True</property>\n            <property name=\"editable\">False</property>\n            <property name=\"width_chars\">16</property>\n          </object>\n        </child>\n      </object>\n      <packing>\n        <property name=\"left_attach\">5</property>\n        <property name=\"right_attach\">6</property>\n        <property name=\"top_attach\">1</property>\n        <property name=\"bottom_attach\">2</property>\n        <property name=\"y_options\"/>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkAlignment\" id=\"alignment43\">\n        <property name=\"visible\">True</property>\n        <property name=\"xalign\">0</property>\n        <property name=\"xscale\">0</property>\n        <child>\n          <object class=\"GtkEntry\" id=\"HexadecimalEntry\">\n            <property name=\"visible\">True</property>\n            <property name=\"editable\">False</property>\n            <property name=\"width_chars\">16</property>\n          </object>\n        </child>\n      </object>\n      <packing>\n        <property name=\"left_attach\">5</property>\n        <property name=\"right_attach\">6</property>\n        <property name=\"y_options\"/>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkEntry\" id=\"BinaryEntry\">\n        <property name=\"visible\">True</property>\n        <property name=\"editable\">False</property>\n      </object>\n      <packing>\n        <property name=\"left_attach\">5</property>\n        <property name=\"right_attach\">6</property>\n        <property name=\"top_attach\">3</property>\n        <property name=\"bottom_attach\">4</property>\n        <property name=\"y_options\"/>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkLabel\" id=\"label42\">\n        <property name=\"visible\">True</property>\n        <property name=\"xalign\">1</property>\n        <property name=\"label\" translatable=\"yes\">ASCII Text:</property>\n      </object>\n      <packing>\n        <property name=\"left_attach\">4</property>\n        <property name=\"right_attach\">5</property>\n        <property name=\"top_attach\">4</property>\n        <property name=\"bottom_attach\">5</property>\n        <property name=\"x_options\">GTK_FILL</property>\n        <property name=\"y_options\"/>\n        <property name=\"x_padding\">6</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkAlignment\" id=\"alignment42\">\n        <property name=\"visible\">True</property>\n        <property name=\"xscale\">0</property>\n        <child>\n          <object class=\"GtkCheckButton\" id=\"UnsignedAsHexCheckButton\">\n            <property name=\"visible\">True</property>\n            <property name=\"label\" translatable=\"yes\">Show unsigned as hexadecimal</property>\n            <property name=\"use_underline\">True</property>\n            <property name=\"draw_indicator\">True</property>\n            <signal handler=\"OnUnsignedAsHexToggled\" name=\"toggled\"/>\n          </object>\n        </child>\n      </object>\n      <packing>\n        <property name=\"left_attach\">2</property>\n        <property name=\"right_attach\">4</property>\n        <property name=\"top_attach\">6</property>\n        <property name=\"bottom_attach\">7</property>\n        <property name=\"x_options\">GTK_FILL</property>\n        <property name=\"y_options\"/>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkAlignment\" id=\"alignment41\">\n        <property name=\"visible\">True</property>\n        <property name=\"xscale\">0</property>\n        <child>\n          <object class=\"GtkCheckButton\" id=\"LittleEndianCheckButton\">\n            <property name=\"visible\">True</property>\n            <property name=\"label\" translatable=\"yes\">Show little endian decoding</property>\n            <property name=\"use_underline\">True</property>\n            <property name=\"active\">True</property>\n            <property name=\"draw_indicator\">True</property>\n            <signal handler=\"OnLittleEndianToggled\" name=\"toggled\"/>\n          </object>\n        </child>\n      </object>\n      <packing>\n        <property name=\"right_attach\">2</property>\n        <property name=\"top_attach\">6</property>\n        <property name=\"bottom_attach\">7</property>\n        <property name=\"y_options\"/>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkAlignment\" id=\"alignment36\">\n        <property name=\"visible\">True</property>\n        <property name=\"xalign\">0</property>\n        <property name=\"xscale\">0</property>\n        <child>\n          <object class=\"GtkEntry\" id=\"Float64bitEntry\">\n            <property name=\"visible\">True</property>\n            <property name=\"editable\">False</property>\n            <property name=\"width_chars\">22</property>\n          </object>\n        </child>\n      </object>\n      <packing>\n        <property name=\"left_attach\">3</property>\n        <property name=\"right_attach\">4</property>\n        <property name=\"top_attach\">3</property>\n        <property name=\"bottom_attach\">4</property>\n        <property name=\"y_options\"/>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkAlignment\" id=\"alignment35\">\n        <property name=\"visible\">True</property>\n        <property name=\"xalign\">0</property>\n        <property name=\"xscale\">0</property>\n        <child>\n          <object class=\"GtkEntry\" id=\"Float32bitEntry\">\n            <property name=\"visible\">True</property>\n            <property name=\"editable\">False</property>\n            <property name=\"width_chars\">16</property>\n          </object>\n        </child>\n      </object>\n      <packing>\n        <property name=\"left_attach\">3</property>\n        <property name=\"right_attach\">4</property>\n        <property name=\"top_attach\">2</property>\n        <property name=\"bottom_attach\">3</property>\n        <property name=\"y_options\"/>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkAlignment\" id=\"alignment48\">\n        <property name=\"visible\">True</property>\n        <property name=\"xalign\">0</property>\n        <property name=\"xscale\">0</property>\n        <child>\n          <object class=\"GtkEntry\" id=\"Unsigned64bitEntry\">\n            <property name=\"visible\">True</property>\n            <property name=\"editable\">False</property>\n            <property name=\"width_chars\">22</property>\n          </object>\n        </child>\n      </object>\n      <packing>\n        <property name=\"left_attach\">3</property>\n        <property name=\"right_attach\">4</property>\n        <property name=\"top_attach\">1</property>\n        <property name=\"bottom_attach\">2</property>\n        <property name=\"y_options\"/>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkAlignment\" id=\"alignment47\">\n        <property name=\"visible\">True</property>\n        <property name=\"xalign\">0</property>\n        <property name=\"xscale\">0</property>\n        <child>\n          <object class=\"GtkEntry\" id=\"Signed64bitEntry\">\n            <property name=\"visible\">True</property>\n            <property name=\"editable\">False</property>\n            <property name=\"width_chars\">22</property>\n          </object>\n        </child>\n      </object>\n      <packing>\n        <property name=\"left_attach\">3</property>\n        <property name=\"right_attach\">4</property>\n        <property name=\"y_options\"/>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkAlignment\" id=\"alignment34\">\n        <property name=\"visible\">True</property>\n        <property name=\"xalign\">0</property>\n        <property name=\"xscale\">0</property>\n        <child>\n          <object class=\"GtkEntry\" id=\"Unsigned32bitEntry\">\n            <property name=\"visible\">True</property>\n            <property name=\"editable\">False</property>\n            <property name=\"width_chars\">12</property>\n          </object>\n        </child>\n      </object>\n      <packing>\n        <property name=\"left_attach\">1</property>\n        <property name=\"right_attach\">2</property>\n        <property name=\"top_attach\">5</property>\n        <property name=\"bottom_attach\">6</property>\n        <property name=\"y_options\"/>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkAlignment\" id=\"alignment33\">\n        <property name=\"visible\">True</property>\n        <property name=\"xalign\">0</property>\n        <property name=\"xscale\">0</property>\n        <child>\n          <object class=\"GtkEntry\" id=\"Signed32bitEntry\">\n            <property name=\"visible\">True</property>\n            <property name=\"editable\">False</property>\n            <property name=\"width_chars\">12</property>\n          </object>\n        </child>\n      </object>\n      <packing>\n        <property name=\"left_attach\">1</property>\n        <property name=\"right_attach\">2</property>\n        <property name=\"top_attach\">4</property>\n        <property name=\"bottom_attach\">5</property>\n        <property name=\"y_options\"/>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkAlignment\" id=\"alignment32\">\n        <property name=\"visible\">True</property>\n        <property name=\"xalign\">0</property>\n        <property name=\"xscale\">0</property>\n        <child>\n          <object class=\"GtkEntry\" id=\"Signed16bitEntry\">\n            <property name=\"visible\">True</property>\n            <property name=\"editable\">False</property>\n            <property name=\"width_chars\">8</property>\n          </object>\n        </child>\n      </object>\n      <packing>\n        <property name=\"left_attach\">1</property>\n        <property name=\"right_attach\">2</property>\n        <property name=\"top_attach\">2</property>\n        <property name=\"bottom_attach\">3</property>\n        <property name=\"y_options\"/>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkAlignment\" id=\"alignment31\">\n        <property name=\"visible\">True</property>\n        <property name=\"xalign\">0</property>\n        <property name=\"xscale\">0</property>\n        <child>\n          <object class=\"GtkEntry\" id=\"Unsigned8bitEntry\">\n            <property name=\"visible\">True</property>\n            <property name=\"editable\">False</property>\n            <property name=\"width_chars\">8</property>\n          </object>\n        </child>\n      </object>\n      <packing>\n        <property name=\"left_attach\">1</property>\n        <property name=\"right_attach\">2</property>\n        <property name=\"top_attach\">1</property>\n        <property name=\"bottom_attach\">2</property>\n        <property name=\"y_options\"/>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkAlignment\" id=\"alignment30\">\n        <property name=\"visible\">True</property>\n        <property name=\"xalign\">0</property>\n        <property name=\"xscale\">0</property>\n        <child>\n          <object class=\"GtkEntry\" id=\"Signed8bitEntry\">\n            <property name=\"visible\">True</property>\n            <property name=\"editable\">False</property>\n            <property name=\"width_chars\">8</property>\n          </object>\n        </child>\n      </object>\n      <packing>\n        <property name=\"left_attach\">1</property>\n        <property name=\"right_attach\">2</property>\n        <property name=\"y_options\"/>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkAlignment\" id=\"alignment29\">\n        <property name=\"visible\">True</property>\n        <property name=\"xalign\">0</property>\n        <property name=\"xscale\">0</property>\n        <child>\n          <object class=\"GtkEntry\" id=\"Unsigned16bitEntry\">\n            <property name=\"visible\">True</property>\n            <property name=\"editable\">False</property>\n            <property name=\"width_chars\">8</property>\n          </object>\n        </child>\n      </object>\n      <packing>\n        <property name=\"left_attach\">1</property>\n        <property name=\"right_attach\">2</property>\n        <property name=\"top_attach\">3</property>\n        <property name=\"bottom_attach\">4</property>\n        <property name=\"y_options\"/>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkLabel\" id=\"label41\">\n        <property name=\"visible\">True</property>\n        <property name=\"xalign\">1</property>\n        <property name=\"label\" translatable=\"yes\">Binary:</property>\n      </object>\n      <packing>\n        <property name=\"left_attach\">4</property>\n        <property name=\"right_attach\">5</property>\n        <property name=\"top_attach\">3</property>\n        <property name=\"bottom_attach\">4</property>\n        <property name=\"x_options\">GTK_FILL</property>\n        <property name=\"y_options\"/>\n        <property name=\"x_padding\">6</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkLabel\" id=\"label40\">\n        <property name=\"visible\">True</property>\n        <property name=\"xalign\">1</property>\n        <property name=\"label\" translatable=\"yes\">Octal:</property>\n      </object>\n      <packing>\n        <property name=\"left_attach\">4</property>\n        <property name=\"right_attach\">5</property>\n        <property name=\"top_attach\">2</property>\n        <property name=\"bottom_attach\">3</property>\n        <property name=\"x_options\">GTK_FILL</property>\n        <property name=\"y_options\"/>\n        <property name=\"x_padding\">6</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkLabel\" id=\"label39\">\n        <property name=\"visible\">True</property>\n        <property name=\"xalign\">1</property>\n        <property name=\"label\" translatable=\"yes\">Decimal:</property>\n      </object>\n      <packing>\n        <property name=\"left_attach\">4</property>\n        <property name=\"right_attach\">5</property>\n        <property name=\"top_attach\">1</property>\n        <property name=\"bottom_attach\">2</property>\n        <property name=\"x_options\">GTK_FILL</property>\n        <property name=\"y_options\"/>\n        <property name=\"x_padding\">6</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkLabel\" id=\"label38\">\n        <property name=\"visible\">True</property>\n        <property name=\"xalign\">1</property>\n        <property name=\"label\" translatable=\"yes\">Hexadecimal:</property>\n      </object>\n      <packing>\n        <property name=\"left_attach\">4</property>\n        <property name=\"right_attach\">5</property>\n        <property name=\"x_options\">GTK_FILL</property>\n        <property name=\"y_options\"/>\n        <property name=\"x_padding\">6</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkLabel\" id=\"label37\">\n        <property name=\"visible\">True</property>\n        <property name=\"xalign\">1</property>\n        <property name=\"label\" translatable=\"yes\">Float 64 bit:</property>\n      </object>\n      <packing>\n        <property name=\"left_attach\">2</property>\n        <property name=\"right_attach\">3</property>\n        <property name=\"top_attach\">3</property>\n        <property name=\"bottom_attach\">4</property>\n        <property name=\"x_options\">GTK_FILL</property>\n        <property name=\"y_options\"/>\n        <property name=\"x_padding\">6</property>\n        <property name=\"y_padding\">6</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkLabel\" id=\"label36\">\n        <property name=\"visible\">True</property>\n        <property name=\"xalign\">1</property>\n        <property name=\"label\" translatable=\"yes\">Float 32 bit:</property>\n      </object>\n      <packing>\n        <property name=\"left_attach\">2</property>\n        <property name=\"right_attach\">3</property>\n        <property name=\"top_attach\">2</property>\n        <property name=\"bottom_attach\">3</property>\n        <property name=\"x_options\">GTK_FILL</property>\n        <property name=\"y_options\"/>\n        <property name=\"x_padding\">6</property>\n        <property name=\"y_padding\">6</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkLabel\" id=\"label44\">\n        <property name=\"visible\">True</property>\n        <property name=\"xalign\">1</property>\n        <property name=\"label\" translatable=\"yes\">Unsigned 64 bit:</property>\n      </object>\n      <packing>\n        <property name=\"left_attach\">2</property>\n        <property name=\"right_attach\">3</property>\n        <property name=\"top_attach\">1</property>\n        <property name=\"bottom_attach\">2</property>\n        <property name=\"x_options\">GTK_FILL</property>\n        <property name=\"y_options\"/>\n        <property name=\"x_padding\">6</property>\n        <property name=\"y_padding\">6</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkLabel\" id=\"label43\">\n        <property name=\"visible\">True</property>\n        <property name=\"xalign\">1</property>\n        <property name=\"label\" translatable=\"yes\">Signed 64 bit:</property>\n      </object>\n      <packing>\n        <property name=\"left_attach\">2</property>\n        <property name=\"right_attach\">3</property>\n        <property name=\"x_options\">GTK_FILL</property>\n        <property name=\"y_options\"/>\n        <property name=\"x_padding\">6</property>\n        <property name=\"y_padding\">6</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkLabel\" id=\"label35\">\n        <property name=\"visible\">True</property>\n        <property name=\"xalign\">1</property>\n        <property name=\"label\" translatable=\"yes\">Unsigned 32 bit:</property>\n      </object>\n      <packing>\n        <property name=\"top_attach\">5</property>\n        <property name=\"bottom_attach\">6</property>\n        <property name=\"x_options\">GTK_FILL</property>\n        <property name=\"y_options\"/>\n        <property name=\"x_padding\">6</property>\n        <property name=\"y_padding\">6</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkLabel\" id=\"label34\">\n        <property name=\"visible\">True</property>\n        <property name=\"xalign\">1</property>\n        <property name=\"label\" translatable=\"yes\">Signed 32 bit:</property>\n      </object>\n      <packing>\n        <property name=\"top_attach\">4</property>\n        <property name=\"bottom_attach\">5</property>\n        <property name=\"x_options\">GTK_FILL</property>\n        <property name=\"y_options\"/>\n        <property name=\"x_padding\">6</property>\n        <property name=\"y_padding\">6</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkLabel\" id=\"label33\">\n        <property name=\"visible\">True</property>\n        <property name=\"xalign\">1</property>\n        <property name=\"label\" translatable=\"yes\">Unsigned 16 bit:</property>\n      </object>\n      <packing>\n        <property name=\"top_attach\">3</property>\n        <property name=\"bottom_attach\">4</property>\n        <property name=\"x_options\">GTK_FILL</property>\n        <property name=\"y_options\"/>\n        <property name=\"x_padding\">6</property>\n        <property name=\"y_padding\">6</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkLabel\" id=\"label32\">\n        <property name=\"visible\">True</property>\n        <property name=\"xalign\">1</property>\n        <property name=\"label\" translatable=\"yes\">Signed 16 bit:</property>\n      </object>\n      <packing>\n        <property name=\"top_attach\">2</property>\n        <property name=\"bottom_attach\">3</property>\n        <property name=\"x_options\">GTK_FILL</property>\n        <property name=\"y_options\"/>\n        <property name=\"x_padding\">6</property>\n        <property name=\"y_padding\">6</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkLabel\" id=\"label31\">\n        <property name=\"visible\">True</property>\n        <property name=\"xalign\">1</property>\n        <property name=\"label\" translatable=\"yes\">Unsigned 8 bit:</property>\n      </object>\n      <packing>\n        <property name=\"top_attach\">1</property>\n        <property name=\"bottom_attach\">2</property>\n        <property name=\"x_options\">GTK_FILL</property>\n        <property name=\"y_options\"/>\n        <property name=\"x_padding\">6</property>\n        <property name=\"y_padding\">6</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkLabel\" id=\"label30\">\n        <property name=\"visible\">True</property>\n        <property name=\"xalign\">1</property>\n        <property name=\"label\" translatable=\"yes\">Signed 8 bit:</property>\n      </object>\n      <packing>\n        <property name=\"x_options\">GTK_FILL</property>\n        <property name=\"y_options\"/>\n        <property name=\"x_padding\">6</property>\n        <property name=\"y_padding\">6</property>\n      </packing>\n    </child>\n  </object>\n</interface>\n"
  },
  {
    "path": "data/ui/ExportDialog.ui",
    "content": "<?xml version=\"1.0\"?>\n<interface>\n  <object class=\"GtkVBox\" id=\"ExportDialogVBox\">\n    <property name=\"visible\">True</property>\n    <property name=\"spacing\">6</property>\n    <child>\n      <object class=\"GtkTable\" id=\"table3\">\n        <property name=\"visible\">True</property>\n        <property name=\"n_rows\">3</property>\n        <property name=\"n_columns\">2</property>\n        <property name=\"column_spacing\">6</property>\n        <property name=\"row_spacing\">6</property>\n        <child>\n          <object class=\"GtkHBox\" id=\"hbox7\">\n            <property name=\"visible\">True</property>\n            <property name=\"spacing\">6</property>\n            <child>\n              <object class=\"GtkComboBoxEntry\" id=\"ExportPatternComboEntry\">\n                <property name=\"visible\">True</property>\n                <child internal-child=\"entry\">\n                  <object class=\"GtkEntry\" id=\"comboboxentry-entry1\">\n                    <property name=\"visible\">True</property>\n                  </object>\n                </child>\n              </object>\n            </child>\n            <child>\n              <object class=\"GtkButton\" id=\"SavePatternButton\">\n                <property name=\"visible\">True</property>\n                <property name=\"tooltip-text\" translatable=\"yes\">Save Pattern</property>\n                <signal handler=\"OnSavePatternButtonClicked\" name=\"clicked\"/>\n                <child>\n                  <object class=\"GtkImage\" id=\"image4\">\n                    <property name=\"visible\">True</property>\n                    <property name=\"stock\">gtk-save</property>\n                  </object>\n                </child>\n              </object>\n              <packing>\n                <property name=\"expand\">False</property>\n                <property name=\"fill\">False</property>\n                <property name=\"position\">1</property>\n              </packing>\n            </child>\n            <child>\n              <object class=\"GtkButton\" id=\"DeletePatternButton\">\n                <property name=\"visible\">True</property>\n                <signal handler=\"OnDeletePatternButtonClicked\" name=\"clicked\"/>\n                <child>\n                  <object class=\"GtkImage\" id=\"image5\">\n                    <property name=\"visible\">True</property>\n                    <property name=\"stock\">gtk-delete</property>\n                  </object>\n                </child>\n              </object>\n              <packing>\n                <property name=\"expand\">False</property>\n                <property name=\"fill\">False</property>\n                <property name=\"position\">2</property>\n              </packing>\n            </child>\n          </object>\n          <packing>\n            <property name=\"left_attach\">1</property>\n            <property name=\"right_attach\">2</property>\n            <property name=\"top_attach\">2</property>\n            <property name=\"bottom_attach\">3</property>\n            <property name=\"y_options\"/>\n          </packing>\n        </child>\n        <child>\n          <object class=\"GtkAlignment\" id=\"alignment1\">\n            <property name=\"visible\">True</property>\n            <property name=\"xalign\">0</property>\n            <property name=\"xscale\">0</property>\n            <child>\n              <object class=\"GtkComboBox\" id=\"ExportAsCombo\">\n                <property name=\"visible\">True</property>\n              </object>\n            </child>\n          </object>\n          <packing>\n            <property name=\"left_attach\">1</property>\n            <property name=\"right_attach\">2</property>\n            <property name=\"top_attach\">1</property>\n            <property name=\"bottom_attach\">2</property>\n          </packing>\n        </child>\n        <child>\n          <object class=\"GtkLabel\" id=\"label6\">\n            <property name=\"visible\">True</property>\n            <property name=\"xalign\">0</property>\n            <property name=\"label\" translatable=\"yes\">Export _pattern:</property>\n            <property name=\"use_underline\">True</property>\n          </object>\n          <packing>\n            <property name=\"top_attach\">2</property>\n            <property name=\"bottom_attach\">3</property>\n            <property name=\"x_options\">GTK_FILL</property>\n          </packing>\n        </child>\n        <child>\n          <object class=\"GtkHBox\" id=\"hbox2\">\n            <property name=\"visible\">True</property>\n            <property name=\"spacing\">6</property>\n            <child>\n              <object class=\"GtkEntry\" id=\"ExportFileEntry\">\n                <property name=\"visible\">True</property>\n              </object>\n            </child>\n            <child>\n              <object class=\"GtkButton\" id=\"SelectFileButton\">\n                <property name=\"visible\">True</property>\n                <signal handler=\"OnSelectFileButtonClicked\" name=\"clicked\"/>\n                <child>\n                  <object class=\"GtkImage\" id=\"image2\">\n                    <property name=\"visible\">True</property>\n                    <property name=\"stock\">gtk-open</property>\n                  </object>\n                </child>\n              </object>\n              <packing>\n                <property name=\"expand\">False</property>\n                <property name=\"position\">1</property>\n              </packing>\n            </child>\n          </object>\n          <packing>\n            <property name=\"left_attach\">1</property>\n            <property name=\"right_attach\">2</property>\n          </packing>\n        </child>\n        <child>\n          <object class=\"GtkLabel\" id=\"label5\">\n            <property name=\"visible\">True</property>\n            <property name=\"xalign\">0</property>\n            <property name=\"label\" translatable=\"yes\">Export _type:</property>\n            <property name=\"use_underline\">True</property>\n          </object>\n          <packing>\n            <property name=\"top_attach\">1</property>\n            <property name=\"bottom_attach\">2</property>\n            <property name=\"x_options\">GTK_FILL</property>\n          </packing>\n        </child>\n        <child>\n          <object class=\"GtkLabel\" id=\"label4\">\n            <property name=\"visible\">True</property>\n            <property name=\"xalign\">0</property>\n            <property name=\"label\" translatable=\"yes\">Export to _file:</property>\n            <property name=\"use_underline\">True</property>\n          </object>\n          <packing>\n            <property name=\"x_options\">GTK_FILL</property>\n          </packing>\n        </child>\n      </object>\n      <packing>\n        <property name=\"expand\">False</property>\n        <property name=\"fill\">False</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkLabel\" id=\"label11\">\n        <property name=\"visible\">True</property>\n        <property name=\"xalign\">0</property>\n        <property name=\"label\" translatable=\"yes\">&lt;b&gt;Range&lt;/b&gt;</property>\n        <property name=\"use_markup\">True</property>\n      </object>\n      <packing>\n        <property name=\"position\">1</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkHBox\" id=\"hbox3\">\n        <property name=\"visible\">True</property>\n        <child>\n          <object class=\"GtkLabel\" id=\"label9\">\n            <property name=\"visible\">True</property>\n            <property name=\"label\" translatable=\"yes\">    </property>\n          </object>\n        </child>\n        <child>\n          <object class=\"GtkVBox\" id=\"vbox2\">\n            <property name=\"visible\">True</property>\n            <child>\n              <object class=\"GtkRadioButton\" id=\"WholeFileRadio\">\n                <property name=\"visible\">True</property>\n                <property name=\"label\" translatable=\"yes\">_Whole file</property>\n                <property name=\"use_underline\">True</property>\n                <property name=\"active\">True</property>\n                <property name=\"draw_indicator\">True</property>\n              </object>\n              <packing>\n                <property name=\"expand\">False</property>\n                <property name=\"fill\">False</property>\n              </packing>\n            </child>\n            <child>\n              <object class=\"GtkRadioButton\" id=\"CurrentSelectionRadio\">\n                <property name=\"visible\">True</property>\n                <property name=\"label\" translatable=\"yes\">Current _selection</property>\n                <property name=\"use_underline\">True</property>\n                <property name=\"active\">True</property>\n                <property name=\"draw_indicator\">True</property>\n                <property name=\"group\">WholeFileRadio</property>\n              </object>\n              <packing>\n                <property name=\"position\">1</property>\n              </packing>\n            </child>\n            <child>\n              <object class=\"GtkHBox\" id=\"hbox6\">\n                <property name=\"visible\">True</property>\n                <property name=\"spacing\">6</property>\n                <child>\n                  <object class=\"GtkRadioButton\" id=\"RangeRadio\">\n                    <property name=\"visible\">True</property>\n                    <property name=\"label\" translatable=\"yes\">F_rom</property>\n                    <property name=\"use_underline\">True</property>\n                    <property name=\"draw_indicator\">True</property>\n                    <property name=\"group\">WholeFileRadio</property>\n                    <signal handler=\"OnRangeRadioToggled\" name=\"toggled\"/>\n                  </object>\n                </child>\n                <child>\n                  <object class=\"GtkEntry\" id=\"RangeFromEntry\">\n                    <property name=\"visible\">True</property>\n                    <property name=\"sensitive\">False</property>\n                  </object>\n                  <packing>\n                    <property name=\"expand\">False</property>\n                    <property name=\"fill\">False</property>\n                    <property name=\"position\">1</property>\n                  </packing>\n                </child>\n                <child>\n                  <object class=\"GtkLabel\" id=\"label10\">\n                    <property name=\"visible\">True</property>\n                    <property name=\"label\" translatable=\"yes\">to</property>\n                  </object>\n                  <packing>\n                    <property name=\"position\">2</property>\n                  </packing>\n                </child>\n                <child>\n                  <object class=\"GtkEntry\" id=\"RangeToEntry\">\n                    <property name=\"visible\">True</property>\n                    <property name=\"sensitive\">False</property>\n                  </object>\n                  <packing>\n                    <property name=\"expand\">False</property>\n                    <property name=\"fill\">False</property>\n                    <property name=\"position\">3</property>\n                  </packing>\n                </child>\n              </object>\n              <packing>\n                <property name=\"position\">2</property>\n              </packing>\n            </child>\n          </object>\n          <packing>\n            <property name=\"position\">1</property>\n          </packing>\n        </child>\n      </object>\n      <packing>\n        <property name=\"position\">2</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkHBox\" id=\"ProgressHBox\">\n        <property name=\"visible\">True</property>\n        <property name=\"spacing\">6</property>\n        <child>\n          <object class=\"GtkProgressBar\" id=\"ExportProgressBar\">\n            <property name=\"visible\">True</property>\n          </object>\n        </child>\n        <child>\n          <object class=\"GtkButton\" id=\"CancelButton\">\n            <property name=\"visible\">True</property>\n            <property name=\"label\" translatable=\"no\">gtk-cancel</property>\n            <property name=\"use_stock\">True</property>\n            <signal handler=\"OnExportCancelClicked\" name=\"clicked\"/>\n          </object>\n          <packing>\n            <property name=\"expand\">False</property>\n            <property name=\"fill\">False</property>\n            <property name=\"position\">1</property>\n          </packing>\n        </child>\n      </object>\n      <packing>\n        <property name=\"position\">3</property>\n      </packing>\n    </child>\n  </object>\n</interface>\n"
  },
  {
    "path": "data/ui/FindReplacePlugin.ui",
    "content": "<?xml version=\"1.0\"?>\n<interface>\n  <object class=\"GtkListStore\" id=\"model1\">\n    <columns>\n      <column type=\"gchararray\"/>\n    </columns>\n    <data>\n      <row>\n        <col id=\"0\" translatable=\"yes\">Hexadecimal</col>\n      </row>\n      <row>\n        <col id=\"0\" translatable=\"yes\">Decimal</col>\n      </row>\n      <row>\n        <col id=\"0\" translatable=\"yes\">Octal</col>\n      </row>\n      <row>\n        <col id=\"0\" translatable=\"yes\">Binary</col>\n      </row>\n      <row>\n        <col id=\"0\" translatable=\"yes\">Text</col>\n      </row>\n    </data>\n  </object>\n  <object class=\"GtkTable\" id=\"FindReplaceTable\">\n    <property name=\"visible\">True</property>\n    <property name=\"border_width\">6</property>\n    <property name=\"n_rows\">2</property>\n    <property name=\"n_columns\">7</property>\n    <property name=\"column_spacing\">6</property>\n    <property name=\"row_spacing\">6</property>\n    <child>\n      <placeholder/>\n    </child>\n    <child>\n      <object class=\"GtkComboBox\" id=\"ReplaceAsComboBox\">\n        <property name=\"visible\">True</property>\n        <property name=\"focus_on_click\">False</property>\n        <signal handler=\"OnReplaceAsComboBoxChanged\" name=\"changed\"/>\n        <property name=\"model\">model1</property>\n        <child>\n          <object class=\"GtkCellRendererText\" id=\"renderer1\"/>\n          <attributes>\n            <attribute name=\"text\">0</attribute>\n          </attributes>\n        </child>\n      </object>\n      <packing>\n        <property name=\"left_attach\">3</property>\n        <property name=\"right_attach\">4</property>\n        <property name=\"top_attach\">1</property>\n        <property name=\"bottom_attach\">2</property>\n        <property name=\"x_options\">GTK_FILL</property>\n        <property name=\"y_options\">GTK_FILL</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkComboBox\" id=\"SearchAsComboBox\">\n        <property name=\"visible\">True</property>\n        <property name=\"focus_on_click\">False</property>\n        <signal handler=\"OnSearchAsComboBoxChanged\" name=\"changed\"/>\n        <property name=\"model\">model1</property>\n        <child>\n          <object class=\"GtkCellRendererText\" id=\"renderer2\"/>\n          <attributes>\n            <attribute name=\"text\">0</attribute>\n          </attributes>\n        </child>\n      </object>\n      <packing>\n        <property name=\"left_attach\">3</property>\n        <property name=\"right_attach\">4</property>\n        <property name=\"x_options\">GTK_FILL</property>\n        <property name=\"y_options\">GTK_FILL</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkButton\" id=\"FindNextButton\">\n        <property name=\"visible\">True</property>\n        <property name=\"sensitive\">False</property>\n        <property name=\"can_focus\">True</property>\n        <property name=\"relief\">GTK_RELIEF_NONE</property>\n        <property name=\"focus_on_click\">False</property>\n        <signal handler=\"OnFindNextButtonClicked\" name=\"clicked\"/>\n        <child>\n          <object class=\"GtkAlignment\" id=\"alignment51\">\n            <property name=\"visible\">True</property>\n            <property name=\"xscale\">0</property>\n            <property name=\"yscale\">0</property>\n            <child>\n              <object class=\"GtkHBox\" id=\"hbox30\">\n                <property name=\"visible\">True</property>\n                <property name=\"spacing\">2</property>\n                <child>\n                  <object class=\"GtkImage\" id=\"image1329\">\n                    <property name=\"visible\">True</property>\n                    <property name=\"stock\">gtk-go-down</property>\n                  </object>\n                  <packing>\n                    <property name=\"expand\">False</property>\n                    <property name=\"fill\">False</property>\n                  </packing>\n                </child>\n                <child>\n                  <object class=\"GtkLabel\" id=\"label77\">\n                    <property name=\"visible\">True</property>\n                    <property name=\"label\" translatable=\"yes\">Find Next</property>\n                    <property name=\"use_underline\">True</property>\n                  </object>\n                  <packing>\n                    <property name=\"expand\">False</property>\n                    <property name=\"fill\">False</property>\n                    <property name=\"position\">1</property>\n                  </packing>\n                </child>\n              </object>\n            </child>\n          </object>\n        </child>\n      </object>\n      <packing>\n        <property name=\"left_attach\">4</property>\n        <property name=\"right_attach\">5</property>\n        <property name=\"x_options\"/>\n        <property name=\"y_options\"/>\n        <property name=\"x_padding\">6</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkButton\" id=\"ReplaceButton\">\n        <property name=\"visible\">True</property>\n        <property name=\"sensitive\">False</property>\n        <property name=\"can_focus\">True</property>\n        <property name=\"relief\">GTK_RELIEF_NONE</property>\n        <property name=\"focus_on_click\">False</property>\n        <signal handler=\"OnReplaceButtonClicked\" name=\"clicked\"/>\n        <child>\n          <object class=\"GtkAlignment\" id=\"alignment53\">\n            <property name=\"visible\">True</property>\n            <property name=\"xscale\">0</property>\n            <property name=\"yscale\">0</property>\n            <child>\n              <object class=\"GtkHBox\" id=\"hbox32\">\n                <property name=\"visible\">True</property>\n                <property name=\"spacing\">2</property>\n                <child>\n                  <object class=\"GtkImage\" id=\"image1331\">\n                    <property name=\"visible\">True</property>\n                    <property name=\"stock\">gtk-find-and-replace</property>\n                  </object>\n                  <packing>\n                    <property name=\"expand\">False</property>\n                    <property name=\"fill\">False</property>\n                  </packing>\n                </child>\n                <child>\n                  <object class=\"GtkLabel\" id=\"label79\">\n                    <property name=\"visible\">True</property>\n                    <property name=\"label\" translatable=\"yes\">Replace</property>\n                    <property name=\"use_underline\">True</property>\n                  </object>\n                  <packing>\n                    <property name=\"expand\">False</property>\n                    <property name=\"fill\">False</property>\n                    <property name=\"position\">1</property>\n                  </packing>\n                </child>\n              </object>\n            </child>\n          </object>\n        </child>\n      </object>\n      <packing>\n        <property name=\"left_attach\">4</property>\n        <property name=\"right_attach\">5</property>\n        <property name=\"top_attach\">1</property>\n        <property name=\"bottom_attach\">2</property>\n        <property name=\"x_options\">GTK_FILL</property>\n        <property name=\"y_options\"/>\n        <property name=\"x_padding\">6</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkLabel\" id=\"ReplaceAsLabel\">\n        <property name=\"visible\">True</property>\n        <property name=\"label\" translatable=\"yes\">as</property>\n      </object>\n      <packing>\n        <property name=\"left_attach\">2</property>\n        <property name=\"right_attach\">3</property>\n        <property name=\"top_attach\">1</property>\n        <property name=\"bottom_attach\">2</property>\n        <property name=\"x_options\">GTK_FILL</property>\n        <property name=\"y_options\"/>\n        <property name=\"x_padding\">6</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkLabel\" id=\"SearchAsLabel\">\n        <property name=\"visible\">True</property>\n        <property name=\"label\" translatable=\"yes\">as</property>\n      </object>\n      <packing>\n        <property name=\"left_attach\">2</property>\n        <property name=\"right_attach\">3</property>\n        <property name=\"x_options\">GTK_FILL</property>\n        <property name=\"y_options\"/>\n        <property name=\"x_padding\">6</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkButton\" id=\"ReplaceAllButton\">\n        <property name=\"visible\">True</property>\n        <property name=\"sensitive\">False</property>\n        <property name=\"can_focus\">True</property>\n        <property name=\"label\" translatable=\"yes\">Replace All</property>\n        <property name=\"relief\">GTK_RELIEF_NONE</property>\n        <property name=\"use_underline\">True</property>\n        <property name=\"focus_on_click\">False</property>\n        <signal handler=\"OnReplaceAllButtonClicked\" name=\"clicked\"/>\n      </object>\n      <packing>\n        <property name=\"left_attach\">5</property>\n        <property name=\"right_attach\">6</property>\n        <property name=\"top_attach\">1</property>\n        <property name=\"bottom_attach\">2</property>\n        <property name=\"x_options\">GTK_FILL</property>\n        <property name=\"y_options\"/>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkButton\" id=\"FindPreviousButton\">\n        <property name=\"visible\">True</property>\n        <property name=\"sensitive\">False</property>\n        <property name=\"can_focus\">True</property>\n        <property name=\"relief\">GTK_RELIEF_NONE</property>\n        <property name=\"focus_on_click\">False</property>\n        <signal handler=\"OnFindPreviousButtonClicked\" name=\"clicked\"/>\n        <child>\n          <object class=\"GtkAlignment\" id=\"alignment52\">\n            <property name=\"visible\">True</property>\n            <property name=\"xscale\">0</property>\n            <property name=\"yscale\">0</property>\n            <child>\n              <object class=\"GtkHBox\" id=\"hbox31\">\n                <property name=\"visible\">True</property>\n                <property name=\"spacing\">2</property>\n                <child>\n                  <object class=\"GtkImage\" id=\"image1330\">\n                    <property name=\"visible\">True</property>\n                    <property name=\"stock\">gtk-go-up</property>\n                  </object>\n                  <packing>\n                    <property name=\"expand\">False</property>\n                    <property name=\"fill\">False</property>\n                  </packing>\n                </child>\n                <child>\n                  <object class=\"GtkLabel\" id=\"label78\">\n                    <property name=\"visible\">True</property>\n                    <property name=\"label\" translatable=\"yes\">Find Previous</property>\n                    <property name=\"use_underline\">True</property>\n                    <property name=\"width_chars\">10</property>\n                  </object>\n                  <packing>\n                    <property name=\"expand\">False</property>\n                    <property name=\"fill\">False</property>\n                    <property name=\"position\">1</property>\n                  </packing>\n                </child>\n              </object>\n            </child>\n          </object>\n        </child>\n      </object>\n      <packing>\n        <property name=\"left_attach\">5</property>\n        <property name=\"right_attach\">6</property>\n        <property name=\"x_options\">GTK_FILL</property>\n        <property name=\"y_options\"/>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkEntry\" id=\"ReplacePatternEntry\">\n        <property name=\"visible\">True</property>\n        <property name=\"can_focus\">True</property>\n        <property name=\"activates_default\">True</property>\n        <signal handler=\"OnReplacePatternEntryChanged\" name=\"changed\"/>\n      </object>\n      <packing>\n        <property name=\"left_attach\">1</property>\n        <property name=\"right_attach\">2</property>\n        <property name=\"top_attach\">1</property>\n        <property name=\"bottom_attach\">2</property>\n        <property name=\"y_options\"/>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkEntry\" id=\"SearchPatternEntry\">\n        <property name=\"visible\">True</property>\n        <property name=\"can_focus\">True</property>\n        <property name=\"activates_default\">True</property>\n        <signal handler=\"OnSearchPatternEntryChanged\" name=\"changed\"/>\n      </object>\n      <packing>\n        <property name=\"left_attach\">1</property>\n        <property name=\"right_attach\">2</property>\n        <property name=\"y_options\"/>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkLabel\" id=\"ReplaceLabel\">\n        <property name=\"visible\">True</property>\n        <property name=\"xalign\">0</property>\n        <property name=\"label\" translatable=\"yes\">Replace with:</property>\n        <property name=\"use_markup\">True</property>\n      </object>\n      <packing>\n        <property name=\"top_attach\">1</property>\n        <property name=\"bottom_attach\">2</property>\n        <property name=\"x_options\">GTK_FILL</property>\n        <property name=\"y_options\"/>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkLabel\" id=\"SearchLabel\">\n        <property name=\"visible\">True</property>\n        <property name=\"xalign\">0</property>\n        <property name=\"label\" translatable=\"yes\">Search for:</property>\n        <property name=\"use_markup\">True</property>\n      </object>\n      <packing>\n        <property name=\"x_options\">GTK_FILL</property>\n        <property name=\"y_options\"/>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkButton\" id=\"CloseButton\">\n        <property name=\"visible\">True</property>\n        <property name=\"relief\">GTK_RELIEF_NONE</property>\n        <signal handler=\"OnCloseButtonClicked\" name=\"clicked\"/>\n        <child>\n          <object class=\"GtkImage\" id=\"image3\">\n            <property name=\"visible\">True</property>\n            <property name=\"stock\">gtk-close</property>\n            <property name=\"icon_size\">1</property>\n          </object>\n        </child>\n      </object>\n      <packing>\n        <property name=\"left_attach\">6</property>\n        <property name=\"right_attach\">7</property>\n        <property name=\"x_options\">GTK_FILL</property>\n        <property name=\"y_options\">GTK_FILL</property>\n      </packing>\n    </child>\n  </object>\n</interface>\n"
  },
  {
    "path": "data/ui/GotoOffsetPlugin.ui",
    "content": "<?xml version=\"1.0\"?>\n<interface>\n  <object class=\"GtkHBox\" id=\"GotoOffsetHBox\">\n    <property name=\"visible\">True</property>\n    <property name=\"border_width\">6</property>\n    <property name=\"spacing\">6</property>\n    <child>\n      <object class=\"GtkLabel\" id=\"label80\">\n        <property name=\"visible\">True</property>\n        <property name=\"xalign\">0</property>\n        <property name=\"label\" translatable=\"yes\">Offset:</property>\n        <property name=\"use_markup\">True</property>\n      </object>\n      <packing>\n        <property name=\"expand\">False</property>\n        <property name=\"fill\">False</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkEntry\" id=\"OffsetEntry\">\n        <property name=\"visible\">True</property>\n        <property name=\"can_focus\">True</property>\n        <signal handler=\"OnOffsetEntryChanged\" name=\"changed\"/>\n        <signal handler=\"OnOffsetEntryActivated\" name=\"activate\"/>\n      </object>\n      <packing>\n        <property name=\"position\">1</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkButton\" id=\"GotoOffsetButton\">\n        <property name=\"visible\">True</property>\n        <property name=\"can_focus\">True</property>\n        <property name=\"relief\">GTK_RELIEF_NONE</property>\n        <property name=\"focus_on_click\">False</property>\n        <signal handler=\"OnGotoOffsetClicked\" name=\"clicked\"/>\n        <child>\n          <object class=\"GtkAlignment\" id=\"alignment54\">\n            <property name=\"visible\">True</property>\n            <property name=\"xscale\">0</property>\n            <property name=\"yscale\">0</property>\n            <child>\n              <object class=\"GtkHBox\" id=\"hbox34\">\n                <property name=\"visible\">True</property>\n                <property name=\"spacing\">2</property>\n                <child>\n                  <object class=\"GtkImage\" id=\"image1333\">\n                    <property name=\"visible\">True</property>\n                    <property name=\"stock\">gtk-jump-to</property>\n                  </object>\n                  <packing>\n                    <property name=\"expand\">False</property>\n                    <property name=\"fill\">False</property>\n                  </packing>\n                </child>\n                <child>\n                  <object class=\"GtkLabel\" id=\"label81\">\n                    <property name=\"visible\">True</property>\n                    <property name=\"label\" translatable=\"yes\">Go to Offset</property>\n                    <property name=\"use_underline\">True</property>\n                  </object>\n                  <packing>\n                    <property name=\"expand\">False</property>\n                    <property name=\"fill\">False</property>\n                    <property name=\"position\">1</property>\n                  </packing>\n                </child>\n              </object>\n            </child>\n          </object>\n        </child>\n      </object>\n      <packing>\n        <property name=\"expand\">False</property>\n        <property name=\"fill\">False</property>\n        <property name=\"padding\">6</property>\n        <property name=\"position\">2</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkButton\" id=\"CloseButton\">\n        <property name=\"visible\">True</property>\n        <property name=\"can_focus\">True</property>\n        <property name=\"relief\">GTK_RELIEF_NONE</property>\n        <property name=\"focus_on_click\">False</property>\n        <signal handler=\"OnCloseButtonClicked\" name=\"clicked\"/>\n        <child>\n          <object class=\"GtkImage\" id=\"image1334\">\n            <property name=\"visible\">True</property>\n            <property name=\"stock\">gtk-close</property>\n            <property name=\"icon_size\">1</property>\n          </object>\n        </child>\n      </object>\n      <packing>\n        <property name=\"expand\">False</property>\n        <property name=\"position\">3</property>\n      </packing>\n    </child>\n  </object>\n</interface>\n"
  },
  {
    "path": "data/ui/LayoutSelectionDialog.ui",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<interface>\n  <object class=\"GtkHPaned\" id=\"LayoutSelectionPaned\">\n    <property name=\"visible\">True</property>\n    <property name=\"can_focus\">True</property>\n    <child>\n      <object class=\"GtkFrame\" id=\"frame2\">\n        <property name=\"visible\">True</property>\n        <property name=\"label_xalign\">0</property>\n        <child>\n          <object class=\"GtkScrolledWindow\" id=\"scrolledwindow1\">\n            <property name=\"visible\">True</property>\n            <property name=\"can_focus\">True</property>\n            <property name=\"hscrollbar_policy\">GTK_POLICY_NEVER</property>\n            <property name=\"vscrollbar_policy\">GTK_POLICY_AUTOMATIC</property>\n            <child>\n              <object class=\"GtkTreeView\" id=\"LayoutList\">\n                <property name=\"visible\">True</property>\n                <property name=\"can_focus\">True</property>\n                <property name=\"headers_visible\">False</property>\n                <property name=\"rules_hint\">True</property>\n              </object>\n            </child>\n          </object>\n        </child>\n        <child type=\"label\">\n          <object class=\"GtkLabel\" id=\"label2\">\n            <property name=\"visible\">True</property>\n            <property name=\"label\" translatable=\"yes\">Available Layouts</property>\n          </object>\n        </child>\n      </object>\n      <packing>\n        <property name=\"resize\">False</property>\n        <property name=\"shrink\">False</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkFrame\" id=\"PreviewFrame\">\n        <property name=\"visible\">True</property>\n        <property name=\"label_xalign\">0</property>\n        <child>\n          <placeholder/>\n        </child>\n        <child type=\"label\">\n          <object class=\"GtkLabel\" id=\"label3\">\n            <property name=\"visible\">True</property>\n            <property name=\"label\" translatable=\"yes\">Preview</property>\n          </object>\n        </child>\n      </object>\n      <packing>\n        <property name=\"resize\">True</property>\n        <property name=\"shrink\">True</property>\n      </packing>\n    </child>\n  </object>\n</interface>\n"
  },
  {
    "path": "data/ui/MainWindow.ui",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<interface>\n  <object class=\"GtkWindow\" id=\"MainWindow\">\n    <property name=\"visible\">True</property>\n    <property name=\"title\">Bless - Gtk# Hex Editor</property>\n    <property name=\"default_width\">400</property>\n    <property name=\"default_height\">400</property>\n    <signal handler=\"OnMainWindowDeleteEvent\" name=\"delete_event\"/>\n    <child>\n      <object class=\"GtkVBox\" id=\"MainVBox\">\n        <property name=\"visible\">True</property>\n        <child>\n          <placeholder/>\n        </child>\n        <child>\n          <placeholder/>\n        </child>\n        <child>\n          <object class=\"GtkHBox\" id=\"DataViewBox\">\n            <property name=\"visible\">True</property>\n            <child>\n              <placeholder/>\n            </child>\n            <child>\n              <placeholder/>\n            </child>\n            <child>\n              <placeholder/>\n            </child>\n          </object>\n          <packing>\n            <property name=\"position\">2</property>\n          </packing>\n        </child>\n        <child>\n          <placeholder/>\n        </child>\n      </object>\n    </child>\n  </object>\n</interface>\n"
  },
  {
    "path": "data/ui/PreferencesDialog.ui",
    "content": "<?xml version=\"1.0\"?>\n<interface>\n  <object class=\"GtkAdjustment\" id=\"adjustment1\">\n    <property name=\"upper\">1000</property>\n    <property name=\"lower\">0</property>\n    <property name=\"page_increment\">10</property>\n    <property name=\"step_increment\">1</property>\n    <property name=\"value\">99</property>\n  </object>\n  <object class=\"GtkListStore\" id=\"model1\">\n    <columns>\n      <column type=\"gchararray\"/>\n    </columns>\n    <data>\n      <row>\n        <col id=\"0\" translatable=\"yes\">Hexadecimal</col>\n      </row>\n      <row>\n        <col id=\"0\" translatable=\"yes\">Decimal</col>\n      </row>\n      <row>\n        <col id=\"0\" translatable=\"yes\">Octal</col>\n      </row>\n      <row>\n        <col id=\"0\" translatable=\"yes\">Binary</col>\n      </row>\n      <row>\n        <col id=\"0\" translatable=\"yes\">Text</col>\n      </row>\n    </data>\n  </object>\n  <object class=\"GtkListStore\" id=\"model5\">\n    <columns>\n      <column type=\"gchararray\"/>\n    </columns>\n    <data>\n      <row>\n        <col id=\"0\" translatable=\"yes\">Insert</col>\n      </row>\n      <row>\n        <col id=\"0\" translatable=\"yes\">Overwrite</col>\n      </row>\n    </data>\n  </object>\n  <object class=\"GtkHPaned\" id=\"PreferencesPaned\">\n    <property name=\"visible\">True</property>\n    <property name=\"can_focus\">True</property>\n    <child>\n      <object class=\"GtkTreeView\" id=\"PreferencesTreeView\">\n        <property name=\"visible\">True</property>\n        <property name=\"can_focus\">True</property>\n        <property name=\"border_width\">6</property>\n        <property name=\"headers_clickable\">True</property>\n      </object>\n      <packing>\n        <property name=\"resize\">True</property>\n        <property name=\"shrink\">False</property>\n      </packing>\n    </child>\n    <child>\n      <placeholder/>\n    </child>\n  </object>\n  <object class=\"GtkVBox\" id=\"GeneralPreferencesVBox\">\n    <property name=\"visible\">True</property>\n    <property name=\"border_width\">12</property>\n    <property name=\"spacing\">12</property>\n    <child>\n      <object class=\"GtkVBox\" id=\"vbox13\">\n        <property name=\"visible\">True</property>\n        <property name=\"spacing\">6</property>\n        <child>\n          <object class=\"GtkLabel\" id=\"label47\">\n            <property name=\"visible\">True</property>\n            <property name=\"xalign\">0</property>\n            <property name=\"label\" translatable=\"yes\">&lt;b&gt;Default Layout&lt;/b&gt;</property>\n            <property name=\"use_markup\">True</property>\n          </object>\n          <packing>\n            <property name=\"expand\">False</property>\n            <property name=\"fill\">False</property>\n          </packing>\n        </child>\n        <child>\n          <object class=\"GtkHBox\" id=\"hbox20\">\n            <property name=\"visible\">True</property>\n            <child>\n              <object class=\"GtkLabel\" id=\"label48\">\n                <property name=\"visible\">True</property>\n                <property name=\"label\" translatable=\"yes\">    </property>\n              </object>\n              <packing>\n                <property name=\"expand\">False</property>\n                <property name=\"fill\">False</property>\n              </packing>\n            </child>\n            <child>\n              <object class=\"GtkVBox\" id=\"vbox14\">\n                <property name=\"visible\">True</property>\n                <property name=\"spacing\">6</property>\n                <child>\n                  <object class=\"GtkHBox\" id=\"hbox21\">\n                    <property name=\"visible\">True</property>\n                    <property name=\"spacing\">6</property>\n                    <child>\n                      <object class=\"GtkLabel\" id=\"label49\">\n                        <property name=\"visible\">True</property>\n                        <property name=\"label\" translatable=\"yes\">Layout _File:</property>\n                        <property name=\"use_underline\">True</property>\n                        <property name=\"mnemonic_widget\">LayoutFileEntry</property>\n                      </object>\n                      <packing>\n                        <property name=\"expand\">False</property>\n                        <property name=\"fill\">False</property>\n                      </packing>\n                    </child>\n                    <child>\n                      <object class=\"GtkEntry\" id=\"LayoutFileEntry\">\n                        <property name=\"visible\">True</property>\n                        <property name=\"can_focus\">True</property>\n                      </object>\n                      <packing>\n                        <property name=\"position\">1</property>\n                      </packing>\n                    </child>\n                    <child>\n                      <object class=\"GtkButton\" id=\"SelectLayoutButton\">\n                        <property name=\"visible\">True</property>\n                        <property name=\"can_focus\">True</property>\n                        <child>\n                          <object class=\"GtkAlignment\" id=\"alignment50\">\n                            <property name=\"visible\">True</property>\n                            <property name=\"xscale\">0</property>\n                            <property name=\"yscale\">0</property>\n                            <child>\n                              <object class=\"GtkHBox\" id=\"hbox27\">\n                                <property name=\"visible\">True</property>\n                                <property name=\"spacing\">2</property>\n                                <child>\n                                  <object class=\"GtkImage\" id=\"image1238\">\n                                    <property name=\"visible\">True</property>\n                                    <property name=\"stock\">gtk-open</property>\n                                  </object>\n                                  <packing>\n                                    <property name=\"expand\">False</property>\n                                    <property name=\"fill\">False</property>\n                                  </packing>\n                                </child>\n                                <child>\n                                  <object class=\"GtkLabel\" id=\"label60\">\n                                    <property name=\"visible\">True</property>\n                                    <property name=\"label\" translatable=\"yes\">_Select Layout</property>\n                                    <property name=\"use_underline\">True</property>\n                                  </object>\n                                  <packing>\n                                    <property name=\"expand\">False</property>\n                                    <property name=\"fill\">False</property>\n                                    <property name=\"position\">1</property>\n                                  </packing>\n                                </child>\n                              </object>\n                            </child>\n                          </object>\n                        </child>\n                      </object>\n                      <packing>\n                        <property name=\"expand\">False</property>\n                        <property name=\"fill\">False</property>\n                        <property name=\"position\">2</property>\n                      </packing>\n                    </child>\n                  </object>\n                  <packing>\n                    <property name=\"expand\">False</property>\n                    <property name=\"fill\">False</property>\n                  </packing>\n                </child>\n                <child>\n                  <object class=\"GtkCheckButton\" id=\"UseCurrentLayoutCheckButton\">\n                    <property name=\"visible\">True</property>\n                    <property name=\"can_focus\">True</property>\n                    <property name=\"label\" translatable=\"yes\">Use layout of currently active _tab if any</property>\n                    <property name=\"use_underline\">True</property>\n                    <property name=\"draw_indicator\">True</property>\n                  </object>\n                  <packing>\n                    <property name=\"expand\">False</property>\n                    <property name=\"fill\">False</property>\n                    <property name=\"position\">1</property>\n                  </packing>\n                </child>\n              </object>\n              <packing>\n                <property name=\"expand\">False</property>\n                <property name=\"fill\">False</property>\n                <property name=\"position\">1</property>\n              </packing>\n            </child>\n          </object>\n          <packing>\n            <property name=\"expand\">False</property>\n            <property name=\"fill\">False</property>\n            <property name=\"position\">1</property>\n          </packing>\n        </child>\n      </object>\n      <packing>\n        <property name=\"expand\">False</property>\n        <property name=\"fill\">False</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkVBox\" id=\"vbox17\">\n        <property name=\"visible\">True</property>\n        <property name=\"spacing\">6</property>\n        <child>\n          <object class=\"GtkLabel\" id=\"label53\">\n            <property name=\"visible\">True</property>\n            <property name=\"xalign\">0</property>\n            <property name=\"label\" translatable=\"yes\">&lt;b&gt;Misc&lt;/b&gt;</property>\n            <property name=\"use_markup\">True</property>\n          </object>\n          <packing>\n            <property name=\"expand\">False</property>\n            <property name=\"fill\">False</property>\n          </packing>\n        </child>\n        <child>\n          <object class=\"GtkHBox\" id=\"hbox25\">\n            <property name=\"visible\">True</property>\n            <child>\n              <object class=\"GtkLabel\" id=\"label55\">\n                <property name=\"visible\">True</property>\n                <property name=\"label\" translatable=\"yes\">    </property>\n              </object>\n              <packing>\n                <property name=\"expand\">False</property>\n                <property name=\"fill\">False</property>\n              </packing>\n            </child>\n            <child>\n              <object class=\"GtkTable\" id=\"table2\">\n                <property name=\"visible\">True</property>\n                <property name=\"n_rows\">2</property>\n                <property name=\"n_columns\">2</property>\n                <property name=\"column_spacing\">6</property>\n                <property name=\"row_spacing\">6</property>\n                <child>\n                  <object class=\"GtkHBox\" id=\"hbox4\">\n                    <property name=\"visible\">True</property>\n                    <child>\n                      <object class=\"GtkEntry\" id=\"TempDirEntry\">\n                        <property name=\"visible\">True</property>\n                      </object>\n                    </child>\n                    <child>\n                      <object class=\"GtkButton\" id=\"SelectTempDirButton\">\n                        <property name=\"visible\">True</property>\n                        <child>\n                          <object class=\"GtkImage\" id=\"image7\">\n                            <property name=\"visible\">True</property>\n                            <property name=\"stock\">gtk-open</property>\n                          </object>\n                        </child>\n                      </object>\n                      <packing>\n                        <property name=\"expand\">False</property>\n                        <property name=\"position\">1</property>\n                      </packing>\n                    </child>\n                  </object>\n                  <packing>\n                    <property name=\"left_attach\">1</property>\n                    <property name=\"right_attach\">2</property>\n                    <property name=\"top_attach\">1</property>\n                    <property name=\"bottom_attach\">2</property>\n                  </packing>\n                </child>\n                <child>\n                  <object class=\"GtkLabel\" id=\"label7\">\n                    <property name=\"visible\">True</property>\n                    <property name=\"xalign\">0</property>\n                    <property name=\"label\" translatable=\"yes\">Temporary Directory:</property>\n                  </object>\n                  <packing>\n                    <property name=\"top_attach\">1</property>\n                    <property name=\"bottom_attach\">2</property>\n                  </packing>\n                </child>\n                <child>\n                  <object class=\"GtkLabel\" id=\"label58\">\n                    <property name=\"visible\">True</property>\n                    <property name=\"xalign\">0</property>\n                    <property name=\"label\" translatable=\"yes\">Default _edit mode:</property>\n                    <property name=\"use_underline\">True</property>\n                  </object>\n                  <packing>\n                    <property name=\"x_options\">GTK_FILL</property>\n                    <property name=\"y_options\"/>\n                  </packing>\n                </child>\n                <child>\n                  <object class=\"GtkComboBox\" id=\"DefaultEditModeComboBox\">\n                    <property name=\"visible\">True</property>\n                    <property name=\"model\">model5</property>\n                    <child>\n                      <object class=\"GtkCellRendererText\" id=\"renderer5\"/>\n                      <attributes>\n                        <attribute name=\"text\">0</attribute>\n                      </attributes>\n                    </child>\n                  </object>\n                  <packing>\n                    <property name=\"left_attach\">1</property>\n                    <property name=\"right_attach\">2</property>\n                    <property name=\"x_options\">GTK_FILL</property>\n                    <property name=\"y_options\">GTK_FILL</property>\n                  </packing>\n                </child>\n              </object>\n              <packing>\n                <property name=\"expand\">False</property>\n                <property name=\"fill\">False</property>\n                <property name=\"position\">1</property>\n              </packing>\n            </child>\n          </object>\n          <packing>\n            <property name=\"expand\">False</property>\n            <property name=\"fill\">False</property>\n            <property name=\"position\">1</property>\n          </packing>\n        </child>\n      </object>\n      <packing>\n        <property name=\"expand\">False</property>\n        <property name=\"fill\">False</property>\n        <property name=\"position\">1</property>\n      </packing>\n    </child>\n  </object>\n  <object class=\"GtkVBox\" id=\"SessionPreferencesVBox\">\n    <property name=\"visible\">True</property>\n    <property name=\"border_width\">12</property>\n    <property name=\"spacing\">6</property>\n    <child>\n      <object class=\"GtkCheckButton\" id=\"LoadPreviousSessionCheckButton\">\n        <property name=\"visible\">True</property>\n        <property name=\"can_focus\">True</property>\n        <property name=\"label\" translatable=\"yes\">_Load previous session on startup</property>\n        <property name=\"use_underline\">True</property>\n        <property name=\"draw_indicator\">True</property>\n      </object>\n      <packing>\n        <property name=\"expand\">False</property>\n        <property name=\"fill\">False</property>\n        <property name=\"padding\">2</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkHBox\" id=\"hbox19\">\n        <property name=\"visible\">True</property>\n        <child>\n          <object class=\"GtkLabel\" id=\"label46\">\n            <property name=\"visible\">True</property>\n            <property name=\"label\" translatable=\"yes\">    </property>\n          </object>\n          <packing>\n            <property name=\"expand\">False</property>\n            <property name=\"fill\">False</property>\n          </packing>\n        </child>\n        <child>\n          <object class=\"GtkVBox\" id=\"vbox11\">\n            <property name=\"visible\">True</property>\n            <property name=\"spacing\">6</property>\n            <child>\n              <object class=\"GtkCheckButton\" id=\"AskBeforeLoadingSessionCheckButton\">\n                <property name=\"visible\">True</property>\n                <property name=\"sensitive\">False</property>\n                <property name=\"can_focus\">True</property>\n                <property name=\"label\" translatable=\"yes\">_Ask before loading session </property>\n                <property name=\"use_underline\">True</property>\n                <property name=\"draw_indicator\">True</property>\n              </object>\n              <packing>\n                <property name=\"expand\">False</property>\n                <property name=\"fill\">False</property>\n              </packing>\n            </child>\n            <child>\n              <object class=\"GtkCheckButton\" id=\"RememberCursorPositionCheckButton\">\n                <property name=\"visible\">True</property>\n                <property name=\"sensitive\">False</property>\n                <property name=\"can_focus\">True</property>\n                <property name=\"label\" translatable=\"yes\">Remember cursor _position</property>\n                <property name=\"use_underline\">True</property>\n                <property name=\"draw_indicator\">True</property>\n              </object>\n              <packing>\n                <property name=\"expand\">False</property>\n                <property name=\"fill\">False</property>\n                <property name=\"position\">1</property>\n              </packing>\n            </child>\n            <child>\n              <object class=\"GtkCheckButton\" id=\"RememberWindowGeometryCheckButton\">\n                <property name=\"visible\">True</property>\n                <property name=\"sensitive\">False</property>\n                <property name=\"can_focus\">True</property>\n                <property name=\"label\" translatable=\"yes\">Remember _window geometry</property>\n                <property name=\"use_underline\">True</property>\n                <property name=\"draw_indicator\">True</property>\n              </object>\n              <packing>\n                <property name=\"expand\">False</property>\n                <property name=\"fill\">False</property>\n                <property name=\"position\">2</property>\n              </packing>\n            </child>\n          </object>\n          <packing>\n            <property name=\"expand\">False</property>\n            <property name=\"fill\">False</property>\n            <property name=\"position\">1</property>\n          </packing>\n        </child>\n      </object>\n      <packing>\n        <property name=\"expand\">False</property>\n        <property name=\"position\">1</property>\n      </packing>\n    </child>\n  </object>\n  <object class=\"GtkVBox\" id=\"UndoPreferencesVBox\">\n    <property name=\"visible\">True</property>\n    <property name=\"border_width\">12</property>\n    <property name=\"spacing\">12</property>\n    <child>\n      <object class=\"GtkVBox\" id=\"vbox15\">\n        <property name=\"visible\">True</property>\n        <property name=\"spacing\">6</property>\n        <child>\n          <object class=\"GtkLabel\" id=\"label50\">\n            <property name=\"visible\">True</property>\n            <property name=\"xalign\">0</property>\n            <property name=\"label\" translatable=\"yes\">&lt;b&gt;Undo Limit&lt;/b&gt;</property>\n            <property name=\"use_markup\">True</property>\n          </object>\n          <packing>\n            <property name=\"expand\">False</property>\n            <property name=\"fill\">False</property>\n          </packing>\n        </child>\n        <child>\n          <object class=\"GtkHBox\" id=\"hbox22\">\n            <property name=\"visible\">True</property>\n            <child>\n              <object class=\"GtkLabel\" id=\"label51\">\n                <property name=\"visible\">True</property>\n                <property name=\"label\" translatable=\"yes\">    </property>\n              </object>\n              <packing>\n                <property name=\"expand\">False</property>\n                <property name=\"fill\">False</property>\n              </packing>\n            </child>\n            <child>\n              <object class=\"GtkVBox\" id=\"vbox16\">\n                <property name=\"visible\">True</property>\n                <property name=\"spacing\">6</property>\n                <child>\n                  <object class=\"GtkHBox\" id=\"hbox23\">\n                    <property name=\"visible\">True</property>\n                    <property name=\"spacing\">6</property>\n                    <child>\n                      <object class=\"GtkRadioButton\" id=\"UndoLimitedRadioButton\">\n                        <property name=\"visible\">True</property>\n                        <property name=\"can_focus\">True</property>\n                        <property name=\"label\" translatable=\"yes\">_Limit to</property>\n                        <property name=\"use_underline\">True</property>\n                        <property name=\"draw_indicator\">True</property>\n                      </object>\n                      <packing>\n                        <property name=\"expand\">False</property>\n                        <property name=\"fill\">False</property>\n                      </packing>\n                    </child>\n                    <child>\n                      <object class=\"GtkSpinButton\" id=\"UndoActionsSpinButton\">\n                        <property name=\"visible\">True</property>\n                        <property name=\"can_focus\">True</property>\n                        <property name=\"adjustment\">adjustment1</property>\n                        <property name=\"climb_rate\">1</property>\n                        <property name=\"numeric\">True</property>\n                        <property name=\"update_policy\">GTK_UPDATE_IF_VALID</property>\n                      </object>\n                      <packing>\n                        <property name=\"expand\">False</property>\n                        <property name=\"fill\">False</property>\n                        <property name=\"position\">1</property>\n                      </packing>\n                    </child>\n                    <child>\n                      <object class=\"GtkLabel\" id=\"label52\">\n                        <property name=\"visible\">True</property>\n                        <property name=\"label\" translatable=\"yes\">actions</property>\n                      </object>\n                      <packing>\n                        <property name=\"expand\">False</property>\n                        <property name=\"fill\">False</property>\n                        <property name=\"position\">2</property>\n                      </packing>\n                    </child>\n                  </object>\n                  <packing>\n                    <property name=\"expand\">False</property>\n                    <property name=\"fill\">False</property>\n                  </packing>\n                </child>\n                <child>\n                  <object class=\"GtkRadioButton\" id=\"UndoUnlimitedRadioButton\">\n                    <property name=\"visible\">True</property>\n                    <property name=\"can_focus\">True</property>\n                    <property name=\"label\" translatable=\"yes\">_Unlimited Undo</property>\n                    <property name=\"use_underline\">True</property>\n                    <property name=\"draw_indicator\">True</property>\n                    <property name=\"group\">UndoLimitedRadioButton</property>\n                  </object>\n                  <packing>\n                    <property name=\"expand\">False</property>\n                    <property name=\"fill\">False</property>\n                    <property name=\"position\">1</property>\n                  </packing>\n                </child>\n              </object>\n              <packing>\n                <property name=\"expand\">False</property>\n                <property name=\"fill\">False</property>\n                <property name=\"position\">1</property>\n              </packing>\n            </child>\n          </object>\n          <packing>\n            <property name=\"expand\">False</property>\n            <property name=\"fill\">False</property>\n            <property name=\"position\">1</property>\n          </packing>\n        </child>\n      </object>\n      <packing>\n        <property name=\"expand\">False</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkVBox\" id=\"vbox3\">\n        <property name=\"visible\">True</property>\n        <property name=\"spacing\">6</property>\n        <child>\n          <object class=\"GtkLabel\" id=\"label12\">\n            <property name=\"visible\">True</property>\n            <property name=\"xalign\">0</property>\n            <property name=\"label\" translatable=\"yes\">&lt;b&gt;Keep Undo History After Save&lt;/b&gt;</property>\n            <property name=\"use_markup\">True</property>\n          </object>\n          <packing>\n            <property name=\"expand\">False</property>\n            <property name=\"fill\">False</property>\n          </packing>\n        </child>\n        <child>\n          <object class=\"GtkHBox\" id=\"hbox5\">\n            <property name=\"visible\">True</property>\n            <child>\n              <object class=\"GtkLabel\" id=\"label13\">\n                <property name=\"visible\">True</property>\n                <property name=\"label\" translatable=\"yes\">    </property>\n              </object>\n              <packing>\n                <property name=\"expand\">False</property>\n                <property name=\"fill\">False</property>\n              </packing>\n            </child>\n            <child>\n              <object class=\"GtkVBox\" id=\"vbox4\">\n                <property name=\"visible\">True</property>\n                <property name=\"spacing\">6</property>\n                <child>\n                  <object class=\"GtkRadioButton\" id=\"KeepUndoAlwaysRadioButton\">\n                    <property name=\"visible\">True</property>\n                    <property name=\"can_focus\">True</property>\n                    <property name=\"label\" translatable=\"yes\">Always</property>\n                    <property name=\"draw_indicator\">True</property>\n                  </object>\n                </child>\n                <child>\n                  <object class=\"GtkRadioButton\" id=\"KeepUndoMemoryRadioButton\">\n                    <property name=\"visible\">True</property>\n                    <property name=\"can_focus\">True</property>\n                    <property name=\"label\" translatable=\"yes\">What fits in main memory</property>\n                    <property name=\"active\">True</property>\n                    <property name=\"draw_indicator\">True</property>\n                    <property name=\"group\">KeepUndoAlwaysRadioButton</property>\n                  </object>\n                  <packing>\n                    <property name=\"position\">1</property>\n                  </packing>\n                </child>\n                <child>\n                  <object class=\"GtkRadioButton\" id=\"KeepUndoNeverRadioButton\">\n                    <property name=\"visible\">True</property>\n                    <property name=\"can_focus\">True</property>\n                    <property name=\"label\" translatable=\"yes\">Never</property>\n                    <property name=\"draw_indicator\">True</property>\n                    <property name=\"group\">KeepUndoAlwaysRadioButton</property>\n                  </object>\n                  <packing>\n                    <property name=\"position\">2</property>\n                  </packing>\n                </child>\n              </object>\n              <packing>\n                <property name=\"expand\">False</property>\n                <property name=\"fill\">False</property>\n                <property name=\"position\">1</property>\n              </packing>\n            </child>\n          </object>\n          <packing>\n            <property name=\"expand\">False</property>\n            <property name=\"fill\">False</property>\n            <property name=\"position\">1</property>\n          </packing>\n        </child>\n      </object>\n      <packing>\n        <property name=\"expand\">False</property>\n        <property name=\"position\">1</property>\n      </packing>\n    </child>\n  </object>\n</interface>\n"
  },
  {
    "path": "data/ui/ProgressDialog.ui",
    "content": "<?xml version=\"1.0\"?>\n<interface>\n  <object class=\"GtkVBox\" id=\"ProgressVBox\">\n    <property name=\"visible\">True</property>\n    <property name=\"border_width\">7</property>\n    <property name=\"spacing\">12</property>\n    <child>\n      <object class=\"GtkLabel\" id=\"MessageLabel\">\n        <property name=\"visible\">True</property>\n        <property name=\"yalign\">0</property>\n        <property name=\"label\" translatable=\"no\">label4</property>\n      </object>\n      <packing>\n        <property name=\"expand\">False</property>\n        <property name=\"fill\">False</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkLabel\" id=\"DetailsLabel\">\n        <property name=\"visible\">True</property>\n        <property name=\"wrap\">True</property>\n      </object>\n      <packing>\n        <property name=\"expand\">False</property>\n        <property name=\"fill\">False</property>\n        <property name=\"position\">1</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkProgressBar\" id=\"ProgressBar\">\n        <property name=\"visible\">True</property>\n        <property name=\"pulse_step\">0.10000000149011612</property>\n      </object>\n      <packing>\n        <property name=\"expand\">False</property>\n        <property name=\"fill\">False</property>\n        <property name=\"position\">2</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkHButtonBox\" id=\"hbuttonbox9\">\n        <property name=\"visible\">True</property>\n        <property name=\"layout_style\">GTK_BUTTONBOX_END</property>\n        <child>\n          <object class=\"GtkButton\" id=\"button2\">\n            <property name=\"visible\">True</property>\n            <property name=\"can_focus\">True</property>\n            <property name=\"label\" translatable=\"yes\">Cancel</property>\n            <property name=\"use_underline\">True</property>\n            <signal handler=\"OnCancelButtonClicked\" name=\"clicked\"/>\n          </object>\n        </child>\n      </object>\n      <packing>\n        <property name=\"expand\">False</property>\n        <property name=\"fill\">False</property>\n        <property name=\"position\">3</property>\n      </packing>\n    </child>\n  </object>\n</interface>\n"
  },
  {
    "path": "data/ui/ProgressDisplayPlugin.ui",
    "content": "<?xml version=\"1.0\"?>\n<interface>\n  <object class=\"GtkHBox\" id=\"ProgressBarHBox\">\n    <property name=\"visible\">True</property>\n    <property name=\"border_width\">6</property>\n    <property name=\"spacing\">6</property>\n    <child>\n      <object class=\"GtkProgressBar\" id=\"ProgressBar\">\n        <property name=\"visible\">True</property>\n        <property name=\"show_text\">True</property>\n      </object>\n    </child>\n    <child>\n      <object class=\"GtkButton\" id=\"CancelButton\">\n        <property name=\"visible\">True</property>\n        <property name=\"label\" translatable=\"no\">gtk-cancel</property>\n        <property name=\"use_stock\">True</property>\n        <signal handler=\"OnCancelButtonClicked\" name=\"clicked\"/>\n      </object>\n      <packing>\n        <property name=\"expand\">False</property>\n        <property name=\"fill\">False</property>\n        <property name=\"position\">1</property>\n      </packing>\n    </child>\n  </object>\n</interface>\n"
  },
  {
    "path": "data/ui/SelectRangePlugin.ui",
    "content": "<?xml version=\"1.0\"?>\n<interface>\n  <object class=\"GtkHBox\" id=\"SelectRangeHBox\">\n    <property name=\"visible\">True</property>\n    <property name=\"border_width\">6</property>\n    <property name=\"spacing\">6</property>\n    <child>\n      <object class=\"GtkLabel\" id=\"label82\">\n        <property name=\"visible\">True</property>\n        <property name=\"label\" translatable=\"yes\">Select range from:</property>\n      </object>\n      <packing>\n        <property name=\"expand\">False</property>\n        <property name=\"fill\">False</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkEntry\" id=\"FromEntry\">\n        <property name=\"visible\">True</property>\n        <property name=\"can_focus\">True</property>\n        <signal handler=\"OnEntryChanged\" name=\"changed\"/>\n        <signal handler=\"OnEntryActivated\" name=\"activate\"/>\n      </object>\n      <packing>\n        <property name=\"position\">1</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkLabel\" id=\"label83\">\n        <property name=\"visible\">True</property>\n        <property name=\"label\" translatable=\"yes\">to/&#xB1;length</property>\n      </object>\n      <packing>\n        <property name=\"expand\">False</property>\n        <property name=\"fill\">False</property>\n        <property name=\"position\">2</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkEntry\" id=\"ToEntry\">\n        <property name=\"visible\">True</property>\n        <property name=\"can_focus\">True</property>\n        <property name=\"tooltip-text\">Use +/- to specify selection length instead of the absolute ending offset</property>\n        <signal handler=\"OnEntryChanged\" name=\"changed\"/>\n        <signal handler=\"OnEntryActivated\" name=\"activate\"/>\n      </object>\n      <packing>\n        <property name=\"position\">3</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkButton\" id=\"SelectButton\">\n        <property name=\"visible\">True</property>\n        <property name=\"can_focus\">True</property>\n        <property name=\"relief\">GTK_RELIEF_NONE</property>\n        <property name=\"focus_on_click\">False</property>\n        <signal handler=\"OnSelectButtonClicked\" name=\"clicked\"/>\n        <child>\n          <object class=\"GtkAlignment\" id=\"alignment55\">\n            <property name=\"visible\">True</property>\n            <property name=\"xscale\">0</property>\n            <property name=\"yscale\">0</property>\n            <child>\n              <object class=\"GtkHBox\" id=\"hbox36\">\n                <property name=\"visible\">True</property>\n                <property name=\"spacing\">2</property>\n                <child>\n                  <object class=\"GtkImage\" id=\"image1642\">\n                    <property name=\"visible\">True</property>\n                    <property name=\"stock\">gtk-apply</property>\n                  </object>\n                  <packing>\n                    <property name=\"expand\">False</property>\n                    <property name=\"fill\">False</property>\n                  </packing>\n                </child>\n                <child>\n                  <object class=\"GtkLabel\" id=\"label84\">\n                    <property name=\"visible\">True</property>\n                    <property name=\"label\" translatable=\"yes\">Select</property>\n                    <property name=\"use_underline\">True</property>\n                  </object>\n                  <packing>\n                    <property name=\"expand\">False</property>\n                    <property name=\"fill\">False</property>\n                    <property name=\"position\">1</property>\n                  </packing>\n                </child>\n              </object>\n            </child>\n          </object>\n        </child>\n      </object>\n      <packing>\n        <property name=\"expand\">False</property>\n        <property name=\"fill\">False</property>\n        <property name=\"position\">4</property>\n      </packing>\n    </child>\n    <child>\n      <object class=\"GtkButton\" id=\"CloseButton\">\n        <property name=\"visible\">True</property>\n        <property name=\"can_focus\">True</property>\n        <property name=\"relief\">GTK_RELIEF_NONE</property>\n        <property name=\"focus_on_click\">False</property>\n        <signal handler=\"OnCloseButtonClicked\" name=\"clicked\"/>\n        <child>\n          <object class=\"GtkImage\" id=\"image1643\">\n            <property name=\"visible\">True</property>\n            <property name=\"stock\">gtk-close</property>\n            <property name=\"icon_size\">1</property>\n          </object>\n        </child>\n      </object>\n      <packing>\n        <property name=\"expand\">False</property>\n        <property name=\"fill\">False</property>\n        <property name=\"position\">5</property>\n      </packing>\n    </child>\n  </object>\n</interface>\n"
  },
  {
    "path": "doc/developer/bless-docs.source",
    "content": "<?xml version=\"1.0\"?>\n<monodoc>\n    <source provider=\"ecma\" basefile=\"bless-docs\" path=\"classlib-bless\" />\n</monodoc>"
  },
  {
    "path": "doc/developer/en/Bless.Buffers/ByteBuffer+ChangedHandler.xml",
    "content": "<Type Name=\"ByteBuffer+ChangedHandler\" FullName=\"Bless.Buffers.ByteBuffer+ChangedHandler\">\n  <TypeSignature Language=\"C#\" Value=\"public delegate void ByteBuffer.ChangedHandler(ByteBuffer bb);\" />\n  <AssemblyInfo>\n    <AssemblyName>Bless.Buffers</AssemblyName>\n    <AssemblyVersion>0.0.0.0</AssemblyVersion>\n  </AssemblyInfo>\n  <Base>\n    <BaseTypeName>System.Delegate</BaseTypeName>\n  </Base>\n  <Parameters>\n    <Parameter Name=\"bb\" Type=\"Bless.Buffers.ByteBuffer\" />\n  </Parameters>\n  <ReturnValue>\n    <ReturnType>System.Void</ReturnType>\n  </ReturnValue>\n  <Docs>\n    <param name=\"bb\">To be added.</param>\n    <summary>Handler for <see cref=\"T:Bless.Buffers.ByteBuffer\" /> events.</summary>\n    <remarks>To be added.</remarks>\n  </Docs>\n</Type>\n"
  },
  {
    "path": "doc/developer/en/Bless.Buffers/ByteBuffer.xml",
    "content": "<Type Name=\"ByteBuffer\" FullName=\"Bless.Buffers.ByteBuffer\">\n  <TypeSignature Language=\"C#\" Value=\"public class ByteBuffer : Bless.Buffers.IBuffer\" />\n  <AssemblyInfo>\n    <AssemblyName>Bless.Buffers</AssemblyName>\n    <AssemblyVersion>0.0.0.0</AssemblyVersion>\n  </AssemblyInfo>\n  <Base>\n    <BaseTypeName>System.Object</BaseTypeName>\n  </Base>\n  <Interfaces>\n    <Interface>\n      <InterfaceName>Bless.Buffers.IBuffer</InterfaceName>\n    </Interface>\n  </Interfaces>\n  <Attributes>\n    <Attribute>\n      <AttributeName>System.Reflection.DefaultMember(\"Item\")</AttributeName>\n    </Attribute>\n  </Attributes>\n  <Members>\n    <Member MemberName=\".ctor\">\n      <MemberSignature Language=\"C#\" Value=\"public ByteBuffer ();\" />\n      <MemberType>Constructor</MemberType>\n      <Parameters />\n      <Docs><summary>Create a new empty <see cref=\"T:Bless.Buffers.ByteBuffer\" />.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\".ctor\">\n      <MemberSignature Language=\"C#\" Value=\"public ByteBuffer (string filename);\" />\n      <MemberType>Constructor</MemberType>\n      <Parameters><Parameter Name=\"filename\" Type=\"System.String\" /></Parameters>\n      <Docs><param name=\"filename\">The filename of this <see cref=\"T:Bless.Buffers.ByteBuffer\" />.</param><summary>Create a new  <see cref=\"T:Bless.Buffers.ByteBuffer\" /> with a name.</summary><remarks>  <para>\nThis doesn't load a file into the <see cref=\"T:Bless.Buffers.ByteBuffer\" />. It just gives it the specified name.\n  </para>\n  <para>\nTo create a <see cref=\"T:Bless.Buffers.ByteBuffer\" /> from a file use  <see cref=\"M:Bless.Buffers.ByteBuffer.FromFile(string)\" />.\n  </para></remarks></Docs>\n    </Member>\n    <Member MemberName=\"ActionChaining\">\n      <MemberSignature Language=\"C#\" Value=\"public bool ActionChaining { get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>System.Boolean</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Append\">\n      <MemberSignature Language=\"C#\" Value=\"public void Append (byte b);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"b\" Type=\"System.Byte\" /></Parameters>\n      <Docs><param name=\"b\">The <see cref=\"T:byte\" /> to append.</param><summary>Appends a byte to this <see cref=\"T:Bless.Buffers.ByteBuffer\" />.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Append\">\n      <MemberSignature Language=\"C#\" Value=\"public void Append (byte[] data);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"data\" Type=\"System.Byte[]\" /></Parameters>\n      <Docs><param name=\"data\">The array of bytes to append.</param><summary>Appends an array of bytes to this <see cref=\"T:Bless.Buffers.ByteBuffer\" />.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Append\">\n      <MemberSignature Language=\"C#\" Value=\"public void Append (byte[] data, long index, long length);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"data\" Type=\"System.Byte[]\" /><Parameter Name=\"index\" Type=\"System.Int64\" /><Parameter Name=\"length\" Type=\"System.Int64\" /></Parameters>\n      <Docs><param name=\"data\">The array of bytes to get the data from.</param><param name=\"index\">The starting index in the array <paramref name=\"data\" /> of the sub-array to append.</param><param name=\"length\">The length of the sub-array to append.</param><summary>Appends to this <see cref=\"T:Bless.Buffers.ByteBuffer\" /> a sub-array of bytes contained in a byte array.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"BeginActionChaining\">\n      <MemberSignature Language=\"C#\" Value=\"public void BeginActionChaining ();\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters />\n      <Docs><summary>Treat subsequent actions in this <see cref=\"T:Bless.Buffers.ByteBuffer\" /> as a single one.</summary><remarks>See also <see cref=\"M:Bless.Buffers.ByteBuffer.EndActionChaining()\" />.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"BeginSave\">\n      <MemberSignature Language=\"C#\" Value=\"public IAsyncResult BeginSave (Bless.Util.ProgressCallback progressCallback, AsyncCallback ac);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.IAsyncResult</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"progressCallback\" Type=\"Bless.Util.ProgressCallback\" /><Parameter Name=\"ac\" Type=\"System.AsyncCallback\" /></Parameters>\n      <Docs><param name=\"progressCallback\">A callback used to report progress.</param><param name=\"ac\">A callback called when the save operation has finished (successfully or not).</param><summary>Saves this <see cref=\"T:Bless.Buffers.ByteBuffer\" /> under the same filename.</summary><returns>An object used to represent the state of the asynchronous save operation. It can be used to wait for the operation to complete.</returns><remarks><para>\nDuring the save operation no read, modify or file operations are allowed on this <see cref=\"T:Bless.Buffers.ByteBuffer\" />.\n</para>\n\n<para>\nWhen saving (under the same filename), the <see cref=\"T:Bless.Buffers.ByteBuffer\" /> is first saved to a temporary file in the  <see cref=\"P:Bless.Buffers.ByteBuffer.TempDir\" /> directory and then moved over to its final location.\n</para>\n\n<para>\nThe <see cref=\"P:IAsyncResult.AsyncState\" /> returned by the method and also passed in  the <paramref name=\"ac\" /> callback is a <see cref=\"T:Bless.Buffers.SaveOperation\" /> object.\n</para>\n\n<example>\n  <code lang=\"C#\">bool doSaveProgressCallback(object o, ProgressAction action)\n{\n\t...\n}\n\nvoid doSaveFinishedCallback(IAsyncResult ar)\n{\n\tSaveOperation so = (SaveOperation)ar.AsyncState;\n\n\tif (so.Result == SaveOperation.OperationResult.Finished) { // save went ok\n\t\tSystem.Console.WriteLine(\"Save went OK!\");\n\t}\n\telse if (so.Result == SaveOperation.OperationResult.Cancelled) { // save cancelled\n\t\tSystem.Console.WriteLine(\"Save was cancelled\");\n\t}\n\telse if (so.Result == SaveOperation.OperationResult.CaughtException) {\n\t\tSystem.Console.WriteLine(\"Save caught exception: {0}\", so.ThreadException.Message);\n\t}\n}\n\nvoid doSave()\n{\n\tByteBuffer bb = new ByteBuffer(\"test.txt\");\n\tbb[10] = 0xff;\n\t\n\tbb.BeginSave(doSaveProgressCallback, doSaveFinishedCallback);\n}</code>\n</example></remarks></Docs>\n    </Member>\n    <Member MemberName=\"BeginSaveAs\">\n      <MemberSignature Language=\"C#\" Value=\"public IAsyncResult BeginSaveAs (string filename, Bless.Util.ProgressCallback progressCallback, AsyncCallback ac);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.IAsyncResult</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"filename\" Type=\"System.String\" /><Parameter Name=\"progressCallback\" Type=\"Bless.Util.ProgressCallback\" /><Parameter Name=\"ac\" Type=\"System.AsyncCallback\" /></Parameters>\n      <Docs><param name=\"filename\">The filename of the file to save this <see cref=\"T:Bless.Buffers.ByteBuffer\" /> to.</param><param name=\"progressCallback\">A callback used to report progress.</param><param name=\"ac\">A callback called when the save as operation has finished (successfully or not).</param><summary>Saves this <see cref=\"T:Bless.Buffers.ByteBuffer\" /> under the specified filename.</summary><returns>An object used to represent the state of the asynchronous save operation. It can be used to wait for the operation to complete.</returns><remarks><para>\nDuring the save as operation no read, modify or file operations are allowed on this <see cref=\"T:Bless.Buffers.ByteBuffer\" />.\n</para>\n\n<para>\nThe <see cref=\"P:IAsyncResult.AsyncState\" /> returned by the method and also passed in  the <paramref name=\"ac\" /> callback is a <see cref=\"T:Bless.Buffers.SaveAsOperation\" /> object.\n</para>\n\n<example>\n  <code lang=\"C#\">bool doSaveAsProgressCallback(object o, ProgressAction action)\n{\n\t...\n}\n\nvoid doSaveAsFinishedCallback(IAsyncResult ar)\n{\n\tSaveAsOperation so = (SaveAsOperation)ar.AsyncState;\n\n\tif (so.Result == SaveAsOperation.OperationResult.Finished) { // save went ok\n\t\tSystem.Console.WriteLine(\"Save went OK!\");\n\t}\n\telse if (so.Result == SaveAsOperation.OperationResult.Cancelled) { // save cancelled\n\t\tSystem.Console.WriteLine(\"Save was cancelled\");\n\t}\n\telse if (so.Result == SaveAsOperation.OperationResult.CaughtException) {\n\t\tSystem.Console.WriteLine(\"Save caught exception: {0}\", so.ThreadException.Message);\n\t}\n}\n\nvoid doSave()\n{\n\tByteBuffer bb = new ByteBuffer(\"test.txt\");\n\tbb[10] = 0xff;\n\t\n\tbb.BeginSaveAs(\"new_test.txt\", doSaveAsProgressCallback, doSaveAsFinishedCallback);\n}\n\n\n\n  </code>\n</example></remarks></Docs>\n    </Member>\n    <Member MemberName=\"CanRedo\">\n      <MemberSignature Language=\"C#\" Value=\"public bool CanRedo { get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>System.Boolean</ReturnType></ReturnValue>\n      <Docs><summary>Whether this <see cref=\"T:Bless.Buffers.ByteBuffer\" /> has any actions that were undone and can be redone.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"CanUndo\">\n      <MemberSignature Language=\"C#\" Value=\"public bool CanUndo { get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>System.Boolean</ReturnType></ReturnValue>\n      <Docs><summary>Whether this <see cref=\"T:Bless.Buffers.ByteBuffer\" /> has any actions that can be undone.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Changed\">\n      <MemberSignature Language=\"C#\" Value=\"public event Bless.Buffers.ByteBuffer.ChangedHandler Changed;\" />\n      <MemberType>Event</MemberType>\n      <ReturnValue><ReturnType>Bless.Buffers.ByteBuffer+ChangedHandler</ReturnType></ReturnValue>\n      <Docs><summary>Event launched when this <see cref=\"T:Bless.Buffers.ByteBuffer\" /> is modified.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"CloseFile\">\n      <MemberSignature Language=\"C#\" Value=\"public void CloseFile ();\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters />\n      <Docs><summary>Closes the file associated with this <see cref=\"T:Bless.Buffers.ByteBuffer\" />.\n</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Delete\">\n      <MemberSignature Language=\"C#\" Value=\"public void Delete (long pos1, long pos2);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"pos1\" Type=\"System.Int64\" /><Parameter Name=\"pos2\" Type=\"System.Int64\" /></Parameters>\n      <Docs><param name=\"pos1\">The position of the first byte to delete.</param><param name=\"pos2\">The position of the last byte to delete.</param><summary>Deletes the bytes in the specified range.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"EmitChanged\">\n      <MemberSignature Language=\"C#\" Value=\"public void EmitChanged ();\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters />\n      <Docs><summary>Emits the changed event.</summary><remarks>See <see cref=\"E:Bless.Buffers.ByteBuffer.Changed\" />.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"EmitEvents\">\n      <MemberSignature Language=\"C#\" Value=\"public bool EmitEvents { set; get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>System.Boolean</ReturnType></ReturnValue>\n      <Docs><summary>Whether this <see cref=\"T:Bless.Buffers.ByteBuffer\" /> will emit events.</summary><value>To be added.</value><remarks>See <see cref=\"T:Bless.Buffers.ByteBuffer/E\" /> for a list of events that <see cref=\"T:Bless.Buffers.ByteBuffer\" /> emits.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"EmitFileChanged\">\n      <MemberSignature Language=\"C#\" Value=\"public void EmitFileChanged ();\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters />\n      <Docs><summary>Emits the File Changed event.</summary><remarks>See <see cref=\"E:Bless.Buffers.ByteBuffer.FileChanged\" />.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"EmitPermissionsChanged\">\n      <MemberSignature Language=\"C#\" Value=\"public void EmitPermissionsChanged ();\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters />\n      <Docs><summary>Emits the Permission Changed event.</summary><remarks>See <see cref=\"E:Bless.Buffers.ByteBuffer.PermissionsChanged\" />.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"EndActionChaining\">\n      <MemberSignature Language=\"C#\" Value=\"public void EndActionChaining ();\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters />\n      <Docs><summary>Stop treating subsequent actions in this <see cref=\"T:Bless.Buffers.ByteBuffer\" /> as a single one.</summary><remarks>See also <see cref=\"T:Bless.Buffers.ByteBuffer.BeginActionChaining()\" />.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"FileChanged\">\n      <MemberSignature Language=\"C#\" Value=\"public event Bless.Buffers.ByteBuffer.ChangedHandler FileChanged;\" />\n      <MemberType>Event</MemberType>\n      <ReturnValue><ReturnType>Bless.Buffers.ByteBuffer+ChangedHandler</ReturnType></ReturnValue>\n      <Docs><summary>Event launched when the file associated with this <see cref=\"T:Bless.Buffers.ByteBuffer\" /> is modified outside of this <see cref=\"T:Bless.Buffers.ByteBuffer\" />.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Filename\">\n      <MemberSignature Language=\"C#\" Value=\"public string Filename { get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>System.String</ReturnType></ReturnValue>\n      <Docs><summary>The path of the file associated to this <see cref=\"T:Bless.Buffers.ByteBuffer\" />.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"FileOperationsAllowed\">\n      <MemberSignature Language=\"C#\" Value=\"public bool FileOperationsAllowed { set; get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>System.Boolean</ReturnType></ReturnValue>\n      <Docs><summary>Whether file operations are allowed on this <see cref=\"T:Bless.Buffers.ByteBuffer\" />.</summary><value>To be added.</value><remarks>If set to <see langword=\"false\" /> all file operations (save, close etc) are silently ignored.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"FromFile\">\n      <MemberSignature Language=\"C#\" Value=\"public static Bless.Buffers.ByteBuffer FromFile (string filename);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>Bless.Buffers.ByteBuffer</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"filename\" Type=\"System.String\" /></Parameters>\n      <Docs><param name=\"filename\">The path of the file to load into the created <see cref=\"T:Bless.Buffers.ByteBuffer\" />.</param><summary>Create a new  <see cref=\"T:Bless.Buffers.ByteBuffer\" /> and initialize it with the contents of a file.</summary><returns>The created <see cref=\"T:Bless.Buffers.ByteBuffer\" />.</returns><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"HasChanged\">\n      <MemberSignature Language=\"C#\" Value=\"public bool HasChanged { get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>System.Boolean</ReturnType></ReturnValue>\n      <Docs><summary>Whether this <see cref=\"T:Bless.Buffers.ByteBuffer\" /> has changed since the previous save.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"HasFile\">\n      <MemberSignature Language=\"C#\" Value=\"public bool HasFile { get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>System.Boolean</ReturnType></ReturnValue>\n      <Docs><summary>Whether this <see cref=\"T:Bless.Buffers.ByteBuffer\" /> has a file associated with it.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Insert\">\n      <MemberSignature Language=\"C#\" Value=\"public void Insert (long pos, byte[] data);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"pos\" Type=\"System.Int64\" /><Parameter Name=\"data\" Type=\"System.Byte[]\" /></Parameters>\n      <Docs><param name=\"pos\">To be added.</param><param name=\"data\">To be added.</param><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Insert\">\n      <MemberSignature Language=\"C#\" Value=\"public void Insert (long pos, byte[] data, long index, long length);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"pos\" Type=\"System.Int64\" /><Parameter Name=\"data\" Type=\"System.Byte[]\" /><Parameter Name=\"index\" Type=\"System.Int64\" /><Parameter Name=\"length\" Type=\"System.Int64\" /></Parameters>\n      <Docs><param name=\"pos\">To be added.</param><param name=\"data\">To be added.</param><param name=\"index\">To be added.</param><param name=\"length\">To be added.</param><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Item\">\n      <MemberSignature Language=\"C#\" Value=\"public byte this[long index] { set; get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>System.Byte</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"index\" Type=\"System.Int64\" /></Parameters>\n      <Docs><param name=\"index\">The index (position) in the <see cref=\"T:Bless.Buffers.ByteBuffer\" /> of the byte to access.</param><summary>Provides access to the bytes in this <see cref=\"T:Bless.Buffers.ByteBuffer\" />.</summary><value>The byte to write to or read from the specified index. If the <see cref=\"P:Bless.Buffers.ByteBuffer.ReadAllowed\" /> property is set to <see langword=\"false\" /> all attempts to read return the byte 0.</value><remarks>If the index is outside the range of the <see cref=\"T:Bless.Buffers.ByteBuffer\" /> this method throws a <see cref=\"T:System.IndexOutOfRangeException\" />.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"LockObj\">\n      <MemberSignature Language=\"C#\" Value=\"public readonly object LockObj;\" />\n      <MemberType>Field</MemberType>\n      <ReturnValue><ReturnType>System.Object</ReturnType></ReturnValue>\n      <Docs><summary>Object used to ensure synchronized access to this <see cref=\"T:Bless.Buffer.ByteBuffer\" />.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"MaxUndoActions\">\n      <MemberSignature Language=\"C#\" Value=\"public int MaxUndoActions { set; get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>System.Int32</ReturnType></ReturnValue>\n      <Docs><summary>The maximun number of actions that can be undone.</summary><value>The number of actions or -1 for unlimited undo actions.</value><remarks>When the number of undo actions is set to be less than the current number, older undo actions are lost.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"ModifyAllowed\">\n      <MemberSignature Language=\"C#\" Value=\"public bool ModifyAllowed { set; get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>System.Boolean</ReturnType></ReturnValue>\n      <Docs><summary>Whether this <see cref=\"T:Bless.Buffers.ByteBuffer\" /> can be modified.\n</summary><value>To be added.</value><remarks>If set to <see langword=\"false\" />, all buffer actions that can modify the buffer are silently ignored.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"PermissionsChanged\">\n      <MemberSignature Language=\"C#\" Value=\"public event Bless.Buffers.ByteBuffer.ChangedHandler PermissionsChanged;\" />\n      <MemberType>Event</MemberType>\n      <ReturnValue><ReturnType>Bless.Buffers.ByteBuffer+ChangedHandler</ReturnType></ReturnValue>\n      <Docs><summary>Event launched when the permissions of this <see cref=\"T:Bless.Buffers.ByteBuffer\" /> are modified.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Range\">\n      <MemberSignature Language=\"C#\" Value=\"public Bless.Util.Range Range { get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>Bless.Util.Range</ReturnType></ReturnValue>\n      <Docs><summary>The range of this <see cref=\"T:Bless.Buffers.ByteBuffer\" />.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"RangeToByteArray\">\n      <MemberSignature Language=\"C#\" Value=\"public byte[] RangeToByteArray (Bless.Util.Range range);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Byte[]</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"range\" Type=\"Bless.Util.Range\" /></Parameters>\n      <Docs><param name=\"range\">To be added.</param><summary>To be added.</summary><returns>To be added.</returns><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"RangeToSegmentCollection\">\n      <MemberSignature Language=\"C#\" Value=\"public Bless.Buffers.SegmentCollection RangeToSegmentCollection (Bless.Util.Range range);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>Bless.Buffers.SegmentCollection</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"range\" Type=\"Bless.Util.Range\" /></Parameters>\n      <Docs><param name=\"range\">To be added.</param><summary>To be added.</summary><returns>To be added.</returns><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Read\">\n      <MemberSignature Language=\"C#\" Value=\"public int Read (byte[] data, long pos, int len);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Int32</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"data\" Type=\"System.Byte[]\" /><Parameter Name=\"pos\" Type=\"System.Int64\" /><Parameter Name=\"len\" Type=\"System.Int32\" /></Parameters>\n      <Docs><param name=\"data\">To be added.</param><param name=\"pos\">To be added.</param><param name=\"len\">To be added.</param><summary>To be added.</summary><returns>To be added.</returns><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"ReadAllowed\">\n      <MemberSignature Language=\"C#\" Value=\"public bool ReadAllowed { set; get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>System.Boolean</ReturnType></ReturnValue>\n      <Docs><summary>Whether this <see cref=\"T:Bless.Buffers.ByteBuffer\" /> can be safely read.</summary><value>To be added.</value><remarks>If it is set to <see langword=\"false\" />, all attempts to read from this <see cref=\"T:Bless.Buffers.ByteBuffer\" /> return one or more bytes of value 0.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Redo\">\n      <MemberSignature Language=\"C#\" Value=\"public void Redo ();\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters />\n      <Docs><summary>Redo the last undone action.</summary><remarks>This method does nothing if there is no action to redo.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Replace\">\n      <MemberSignature Language=\"C#\" Value=\"public void Replace (long pos1, long pos2, byte[] data);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"pos1\" Type=\"System.Int64\" /><Parameter Name=\"pos2\" Type=\"System.Int64\" /><Parameter Name=\"data\" Type=\"System.Byte[]\" /></Parameters>\n      <Docs><param name=\"pos1\">To be added.</param><param name=\"pos2\">To be added.</param><param name=\"data\">To be added.</param><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Replace\">\n      <MemberSignature Language=\"C#\" Value=\"public void Replace (long pos1, long pos2, byte[] data, long index, long length);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"pos1\" Type=\"System.Int64\" /><Parameter Name=\"pos2\" Type=\"System.Int64\" /><Parameter Name=\"data\" Type=\"System.Byte[]\" /><Parameter Name=\"index\" Type=\"System.Int64\" /><Parameter Name=\"length\" Type=\"System.Int64\" /></Parameters>\n      <Docs><param name=\"pos1\">To be added.</param><param name=\"pos2\">To be added.</param><param name=\"data\">To be added.</param><param name=\"index\">To be added.</param><param name=\"length\">To be added.</param><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Revert\">\n      <MemberSignature Language=\"C#\" Value=\"public void Revert ();\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters />\n      <Docs><summary>Revert this <see cref=\"T:Bless.Buffers.ByteBuffer\" /> to its saved state.</summary><remarks>The method only works if this <see cref=\"T:Bless.Buffers.ByteBuffer\" /> has a file assocciated with it.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Size\">\n      <MemberSignature Language=\"C#\" Value=\"public long Size { get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>System.Int64</ReturnType></ReturnValue>\n      <Docs><summary>The size of this <see cref=\"T:Bless.Buffers.ByteBuffer\" /> in bytes.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"TempDir\">\n      <MemberSignature Language=\"C#\" Value=\"public string TempDir { set; get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>System.String</ReturnType></ReturnValue>\n      <Docs><summary>The directory where temporary files related to this <see cref=\"T:Bless.Buffers.ByteBuffer\" /> are stored.</summary><value>To be added.</value><remarks>When saving under the same filename, the <see cref=\"T:Bless.Buffers.ByteBuffer\" /> is first saved to a temporary file in this directory and then moved over to its final location.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Undo\">\n      <MemberSignature Language=\"C#\" Value=\"public void Undo ();\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters />\n      <Docs><summary>Undo the last done action.</summary><remarks>This method does nothing if there is no action to undo.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"UseGLibIdle\">\n      <MemberSignature Language=\"C#\" Value=\"public bool UseGLibIdle { set; get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>System.Boolean</ReturnType></ReturnValue>\n      <Docs><summary>Whether to use the GLib Idle handler for progress reporting.</summary><value>To be added.</value><remarks><para>\nThe default value is <see langword=\"false\" />.\n</para>\nThis should be set to <see langword=\"true\" /> if progress reporting involves Gtk+ widgets.</remarks></Docs>\n    </Member>\n  </Members>\n  <Docs>\n    <summary>A buffer for holding bytes in a versatile manner.\nIt supports undo-redo and can easily handle large files.\nEditing is also very cheap.</summary>\n    <remarks>To be added.</remarks>\n  </Docs>\n</Type>\n"
  },
  {
    "path": "doc/developer/en/Bless.Buffers/FileBuffer.xml",
    "content": "<Type Name=\"FileBuffer\" FullName=\"Bless.Buffers.FileBuffer\">\n  <TypeSignature Language=\"C#\" Value=\"public class FileBuffer : Bless.Buffers.IBuffer\" />\n  <AssemblyInfo>\n    <AssemblyName>Bless.Buffers</AssemblyName>\n    <AssemblyVersion>0.0.0.0</AssemblyVersion>\n  </AssemblyInfo>\n  <Base>\n    <BaseTypeName>System.Object</BaseTypeName>\n  </Base>\n  <Interfaces>\n    <Interface>\n      <InterfaceName>Bless.Buffers.IBuffer</InterfaceName>\n    </Interface>\n  </Interfaces>\n  <Attributes>\n    <Attribute>\n      <AttributeName>System.Reflection.DefaultMember(\"Item\")</AttributeName>\n    </Attribute>\n  </Attributes>\n  <Members>\n    <Member MemberName=\".ctor\">\n      <MemberSignature Language=\"C#\" Value=\"public FileBuffer (string fn);\" />\n      <MemberType>Constructor</MemberType>\n      <Parameters><Parameter Name=\"fn\" Type=\"System.String\" /></Parameters>\n      <Docs><param name=\"fn\">The path of the file.</param><summary>Creates a <see cref=\"T:Bless.Buffers.FileBuffer\" /> from a file.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\".ctor\">\n      <MemberSignature Language=\"C#\" Value=\"public FileBuffer (string fn, int size);\" />\n      <MemberType>Constructor</MemberType>\n      <Parameters><Parameter Name=\"fn\" Type=\"System.String\" /><Parameter Name=\"size\" Type=\"System.Int32\" /></Parameters>\n      <Docs><param name=\"fn\">The path of the file.</param><param name=\"size\">The size of the moving data window.</param><summary>Creates a <see cref=\"T:Bless.Buffers.FileBuffer\" /> from a file and using the specified window size.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Append\">\n      <MemberSignature Language=\"C#\" Value=\"public void Append (byte data);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"data\" Type=\"System.Byte\" /></Parameters>\n      <Docs><param name=\"data\">To be added.</param><summary>This is a read-only buffer.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Append\">\n      <MemberSignature Language=\"C#\" Value=\"public void Append (byte[] data, long index, long length);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"data\" Type=\"System.Byte[]\" /><Parameter Name=\"index\" Type=\"System.Int64\" /><Parameter Name=\"length\" Type=\"System.Int64\" /></Parameters>\n      <Docs><param name=\"data\">To be added.</param><param name=\"index\">To be added.</param><param name=\"length\">To be added.</param><summary>This is a read-only buffer.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Close\">\n      <MemberSignature Language=\"C#\" Value=\"public void Close ();\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters />\n      <Docs><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Filename\">\n      <MemberSignature Language=\"C#\" Value=\"public string Filename { get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>System.String</ReturnType></ReturnValue>\n      <Docs><summary>The path of the file loaded in this <see cref=\"T:Bless.Buffers.FileBuffer\" />.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Insert\">\n      <MemberSignature Language=\"C#\" Value=\"public void Insert (long pos, byte[] data, long index, long length);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"pos\" Type=\"System.Int64\" /><Parameter Name=\"data\" Type=\"System.Byte[]\" /><Parameter Name=\"index\" Type=\"System.Int64\" /><Parameter Name=\"length\" Type=\"System.Int64\" /></Parameters>\n      <Docs><param name=\"pos\">To be added.</param><param name=\"data\">To be added.</param><param name=\"index\">To be added.</param><param name=\"length\">To be added.</param><summary>This is a read-only buffer.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Item\">\n      <MemberSignature Language=\"C#\" Value=\"public byte this[long index] { set; get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>System.Byte</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"index\" Type=\"System.Int64\" /></Parameters>\n      <Docs><param name=\"index\">To be added.</param><summary>Provides access to the bytes in this <see cref=\"T:Bless.Buffers.FileBuffer\" />.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Load\">\n      <MemberSignature Language=\"C#\" Value=\"public void Load (string filename);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"filename\" Type=\"System.String\" /></Parameters>\n      <Docs><param name=\"filename\">To be added.</param><summary>Loads a file in this <see cref=\"T:Bless.Buffers.FileBuffer\" />.</summary><remarks>If the <see cref=\"T:Bless.Buffers.FileBuffer\" /> already has a file loaded, the old file is closed first.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Read\">\n      <MemberSignature Language=\"C#\" Value=\"public int Read (byte[] ba, long pos, int len);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Int32</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"ba\" Type=\"System.Byte[]\" /><Parameter Name=\"pos\" Type=\"System.Int64\" /><Parameter Name=\"len\" Type=\"System.Int32\" /></Parameters>\n      <Docs><param name=\"ba\">To be added.</param><param name=\"pos\">To be added.</param><param name=\"len\">To be added.</param><summary>To be added.</summary><returns>To be added.</returns><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Size\">\n      <MemberSignature Language=\"C#\" Value=\"public long Size { get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>System.Int64</ReturnType></ReturnValue>\n      <Docs><summary>The size of this <see cref=\"T:Bless.Buffers.FileBuffer\" />.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs>\n    </Member>\n  </Members>\n  <Docs>\n    <summary>A buffer that allows efficient access to a file by using a moving data window.</summary>\n    <remarks><para>\nThis is a read-only buffer, so any attempt to modify it is silently ignored.\n</para>\n<para>\nThe buffer works by keeping only a portion of the file's data in memory, in what is called the data window. An attempt to read\ndata that is currently outside the data window causes the data window to be reloaded. Ofcourse, this procedure is transparent to the caller.\n</para></remarks>\n  </Docs>\n</Type>\n"
  },
  {
    "path": "doc/developer/en/Bless.Buffers/IBuffer.xml",
    "content": "<Type Name=\"IBuffer\" FullName=\"Bless.Buffers.IBuffer\">\n  <TypeSignature Language=\"C#\" Value=\"public interface IBuffer\" />\n  <AssemblyInfo>\n    <AssemblyName>Bless.Buffers</AssemblyName>\n    <AssemblyVersion>0.0.0.0</AssemblyVersion>\n  </AssemblyInfo>\n  <Interfaces />\n  <Attributes>\n    <Attribute>\n      <AttributeName>System.Reflection.DefaultMember(\"Item\")</AttributeName>\n    </Attribute>\n  </Attributes>\n  <Members>\n    <Member MemberName=\"Append\">\n      <MemberSignature Language=\"C#\" Value=\"public void Append (byte data);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"data\" Type=\"System.Byte\" /></Parameters>\n      <Docs><param name=\"data\">To be added.</param><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Append\">\n      <MemberSignature Language=\"C#\" Value=\"public void Append (byte[] data, long index, long length);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"data\" Type=\"System.Byte[]\" /><Parameter Name=\"index\" Type=\"System.Int64\" /><Parameter Name=\"length\" Type=\"System.Int64\" /></Parameters>\n      <Docs><param name=\"data\">To be added.</param><param name=\"index\">To be added.</param><param name=\"length\">To be added.</param><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Insert\">\n      <MemberSignature Language=\"C#\" Value=\"public void Insert (long pos, byte[] data, long index, long length);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"pos\" Type=\"System.Int64\" /><Parameter Name=\"data\" Type=\"System.Byte[]\" /><Parameter Name=\"index\" Type=\"System.Int64\" /><Parameter Name=\"length\" Type=\"System.Int64\" /></Parameters>\n      <Docs><param name=\"pos\">To be added.</param><param name=\"data\">To be added.</param><param name=\"index\">To be added.</param><param name=\"length\">To be added.</param><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Item\">\n      <MemberSignature Language=\"C#\" Value=\"public byte this[long index] { set; get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>System.Byte</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"index\" Type=\"System.Int64\" /></Parameters>\n      <Docs><param name=\"index\">To be added.</param><summary>To be added.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Read\">\n      <MemberSignature Language=\"C#\" Value=\"public int Read (byte[] data, long pos, int len);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Int32</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"data\" Type=\"System.Byte[]\" /><Parameter Name=\"pos\" Type=\"System.Int64\" /><Parameter Name=\"len\" Type=\"System.Int32\" /></Parameters>\n      <Docs><param name=\"data\">To be added.</param><param name=\"pos\">To be added.</param><param name=\"len\">To be added.</param><summary>To be added.</summary><returns>To be added.</returns><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Size\">\n      <MemberSignature Language=\"C#\" Value=\"public long Size { get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>System.Int64</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs>\n    </Member>\n  </Members>\n  <Docs>\n    <summary>An interface describing a buffer.</summary>\n    <remarks>To be added.</remarks>\n  </Docs>\n</Type>\n"
  },
  {
    "path": "doc/developer/en/Bless.Buffers/SaveAsOperation+SaveAsStage.xml",
    "content": "<Type Name=\"SaveAsOperation+SaveAsStage\" FullName=\"Bless.Buffers.SaveAsOperation+SaveAsStage\">\n  <TypeSignature Language=\"C#\" Value=\"public enum SaveAsOperation.SaveAsStage\" />\n  <AssemblyInfo>\n    <AssemblyName>Bless.Buffers</AssemblyName>\n    <AssemblyVersion>0.0.0.0</AssemblyVersion>\n  </AssemblyInfo>\n  <Base>\n    <BaseTypeName>System.Enum</BaseTypeName>\n  </Base>\n  <Members>\n    <Member MemberName=\"BeforeCreate\">\n      <MemberSignature Language=\"C#\" Value=\"BeforeCreate\" />\n      <MemberType>Field</MemberType>\n      <ReturnValue><ReturnType>Bless.Buffers.SaveAsOperation+SaveAsStage</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary></Docs>\n    </Member>\n    <Member MemberName=\"BeforeWrite\">\n      <MemberSignature Language=\"C#\" Value=\"BeforeWrite\" />\n      <MemberType>Field</MemberType>\n      <ReturnValue><ReturnType>Bless.Buffers.SaveAsOperation+SaveAsStage</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary></Docs>\n    </Member>\n  </Members>\n  <Docs>\n    <summary>To be added.</summary>\n    <remarks>To be added.</remarks>\n  </Docs>\n</Type>\n"
  },
  {
    "path": "doc/developer/en/Bless.Buffers/SaveAsOperation.xml",
    "content": "<Type Name=\"SaveAsOperation\" FullName=\"Bless.Buffers.SaveAsOperation\">\n  <TypeSignature Language=\"C#\" Value=\"public class SaveAsOperation : Bless.Util.ThreadedAsyncOperation\" />\n  <AssemblyInfo>\n    <AssemblyName>Bless.Buffers</AssemblyName>\n    <AssemblyVersion>0.0.0.0</AssemblyVersion>\n  </AssemblyInfo>\n  <Base>\n    <BaseTypeName>Bless.Util.ThreadedAsyncOperation</BaseTypeName>\n  </Base>\n  <Interfaces />\n  <Members>\n    <Member MemberName=\".ctor\">\n      <MemberSignature Language=\"C#\" Value=\"public SaveAsOperation (Bless.Buffers.ByteBuffer bb, string fn, Bless.Util.ProgressCallback pc, AsyncCallback ac, bool glibIdle);\" />\n      <MemberType>Constructor</MemberType>\n      <Parameters><Parameter Name=\"bb\" Type=\"Bless.Buffers.ByteBuffer\" /><Parameter Name=\"fn\" Type=\"System.String\" /><Parameter Name=\"pc\" Type=\"Bless.Util.ProgressCallback\" /><Parameter Name=\"ac\" Type=\"System.AsyncCallback\" /><Parameter Name=\"glibIdle\" Type=\"System.Boolean\" /></Parameters>\n      <Docs><param name=\"bb\">To be added.</param><param name=\"fn\">To be added.</param><param name=\"pc\">To be added.</param><param name=\"ac\">To be added.</param><param name=\"glibIdle\">To be added.</param><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Buffer\">\n      <MemberSignature Language=\"C#\" Value=\"public Bless.Buffers.ByteBuffer Buffer { get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>Bless.Buffers.ByteBuffer</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"byteBuffer\">\n      <MemberSignature Language=\"C#\" Value=\"protected Bless.Buffers.ByteBuffer byteBuffer;\" />\n      <MemberType>Field</MemberType>\n      <ReturnValue><ReturnType>Bless.Buffers.ByteBuffer</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"bytesSaved\">\n      <MemberSignature Language=\"C#\" Value=\"protected long bytesSaved;\" />\n      <MemberType>Field</MemberType>\n      <ReturnValue><ReturnType>System.Int64</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"BytesSaved\">\n      <MemberSignature Language=\"C#\" Value=\"public long BytesSaved { get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>System.Int64</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"SavePath\">\n      <MemberSignature Language=\"C#\" Value=\"public string SavePath { set; get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>System.String</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"savePath\">\n      <MemberSignature Language=\"C#\" Value=\"protected string savePath;\" />\n      <MemberType>Field</MemberType>\n      <ReturnValue><ReturnType>System.String</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"StageReached\">\n      <MemberSignature Language=\"C#\" Value=\"public Bless.Buffers.SaveAsOperation.SaveAsStage StageReached { get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>Bless.Buffers.SaveAsOperation+SaveAsStage</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs>\n    </Member>\n  </Members>\n  <Docs>\n    <summary>To be added.</summary>\n    <remarks>To be added.</remarks>\n  </Docs>\n</Type>\n"
  },
  {
    "path": "doc/developer/en/Bless.Buffers/SaveOperation+SaveStage.xml",
    "content": "<Type Name=\"SaveOperation+SaveStage\" FullName=\"Bless.Buffers.SaveOperation+SaveStage\">\n  <TypeSignature Language=\"C#\" Value=\"public enum SaveOperation.SaveStage\" />\n  <AssemblyInfo>\n    <AssemblyName>Bless.Buffers</AssemblyName>\n    <AssemblyVersion>0.0.0.0</AssemblyVersion>\n  </AssemblyInfo>\n  <Base>\n    <BaseTypeName>System.Enum</BaseTypeName>\n  </Base>\n  <Members>\n    <Member MemberName=\"BeforeDelete\">\n      <MemberSignature Language=\"C#\" Value=\"BeforeDelete\" />\n      <MemberType>Field</MemberType>\n      <ReturnValue><ReturnType>Bless.Buffers.SaveOperation+SaveStage</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary></Docs>\n    </Member>\n    <Member MemberName=\"BeforeMove\">\n      <MemberSignature Language=\"C#\" Value=\"BeforeMove\" />\n      <MemberType>Field</MemberType>\n      <ReturnValue><ReturnType>Bless.Buffers.SaveOperation+SaveStage</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary></Docs>\n    </Member>\n    <Member MemberName=\"BeforeSaveAs\">\n      <MemberSignature Language=\"C#\" Value=\"BeforeSaveAs\" />\n      <MemberType>Field</MemberType>\n      <ReturnValue><ReturnType>Bless.Buffers.SaveOperation+SaveStage</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary></Docs>\n    </Member>\n  </Members>\n  <Docs>\n    <summary>To be added.</summary>\n    <remarks>To be added.</remarks>\n  </Docs>\n</Type>\n"
  },
  {
    "path": "doc/developer/en/Bless.Buffers/SaveOperation.xml",
    "content": "<Type Name=\"SaveOperation\" FullName=\"Bless.Buffers.SaveOperation\">\n  <TypeSignature Language=\"C#\" Value=\"public class SaveOperation : Bless.Buffers.SaveAsOperation\" />\n  <AssemblyInfo>\n    <AssemblyName>Bless.Buffers</AssemblyName>\n    <AssemblyVersion>0.0.0.0</AssemblyVersion>\n  </AssemblyInfo>\n  <Base>\n    <BaseTypeName>Bless.Buffers.SaveAsOperation</BaseTypeName>\n  </Base>\n  <Interfaces />\n  <Members>\n    <Member MemberName=\".ctor\">\n      <MemberSignature Language=\"C#\" Value=\"public SaveOperation (Bless.Buffers.ByteBuffer bb, string tempFilename, Bless.Util.ProgressCallback pc, AsyncCallback ac, bool glibIdle);\" />\n      <MemberType>Constructor</MemberType>\n      <Parameters><Parameter Name=\"bb\" Type=\"Bless.Buffers.ByteBuffer\" /><Parameter Name=\"tempFilename\" Type=\"System.String\" /><Parameter Name=\"pc\" Type=\"Bless.Util.ProgressCallback\" /><Parameter Name=\"ac\" Type=\"System.AsyncCallback\" /><Parameter Name=\"glibIdle\" Type=\"System.Boolean\" /></Parameters>\n      <Docs><param name=\"bb\">To be added.</param><param name=\"tempFilename\">To be added.</param><param name=\"pc\">To be added.</param><param name=\"ac\">To be added.</param><param name=\"glibIdle\">To be added.</param><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"StageReached\">\n      <MemberSignature Language=\"C#\" Value=\"public Bless.Buffers.SaveOperation.SaveStage StageReached { get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>Bless.Buffers.SaveOperation+SaveStage</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"TempPath\">\n      <MemberSignature Language=\"C#\" Value=\"public string TempPath { get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>System.String</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs>\n    </Member>\n  </Members>\n  <Docs>\n    <summary>To be added.</summary>\n    <remarks>To be added.</remarks>\n  </Docs>\n</Type>\n"
  },
  {
    "path": "doc/developer/en/Bless.Buffers/Segment.xml",
    "content": "<Type Name=\"Segment\" FullName=\"Bless.Buffers.Segment\">\n  <TypeSignature Language=\"C#\" Value=\"public class Segment\" />\n  <AssemblyInfo>\n    <AssemblyName>Bless.Buffers</AssemblyName>\n    <AssemblyVersion>0.0.0.0</AssemblyVersion>\n  </AssemblyInfo>\n  <Base>\n    <BaseTypeName>System.Object</BaseTypeName>\n  </Base>\n  <Interfaces />\n  <Members>\n    <Member MemberName=\".ctor\">\n      <MemberSignature Language=\"C#\" Value=\"public Segment (Bless.Buffers.IBuffer buffer, long start, long end);\" />\n      <MemberType>Constructor</MemberType>\n      <Parameters><Parameter Name=\"buffer\" Type=\"Bless.Buffers.IBuffer\" /><Parameter Name=\"start\" Type=\"System.Int64\" /><Parameter Name=\"end\" Type=\"System.Int64\" /></Parameters>\n      <Docs><param name=\"buffer\">To be added.</param><param name=\"start\">To be added.</param><param name=\"end\">To be added.</param><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Buffer\">\n      <MemberSignature Language=\"C#\" Value=\"public Bless.Buffers.IBuffer Buffer { set; get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>Bless.Buffers.IBuffer</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Contains\">\n      <MemberSignature Language=\"C#\" Value=\"public bool Contains (long offset, long mapping);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Boolean</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"offset\" Type=\"System.Int64\" /><Parameter Name=\"mapping\" Type=\"System.Int64\" /></Parameters>\n      <Docs><param name=\"offset\">To be added.</param><param name=\"mapping\">To be added.</param><summary>To be added.</summary><returns>To be added.</returns><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"End\">\n      <MemberSignature Language=\"C#\" Value=\"public long End { set; get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>System.Int64</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"MakePrivateCopyOfData\">\n      <MemberSignature Language=\"C#\" Value=\"public void MakePrivateCopyOfData ();\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters />\n      <Docs><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Size\">\n      <MemberSignature Language=\"C#\" Value=\"public long Size { get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>System.Int64</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"SplitAt\">\n      <MemberSignature Language=\"C#\" Value=\"public Bless.Buffers.Segment SplitAt (long pos);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>Bless.Buffers.Segment</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"pos\" Type=\"System.Int64\" /></Parameters>\n      <Docs><param name=\"pos\">To be added.</param><summary>To be added.</summary><returns>To be added.</returns><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Start\">\n      <MemberSignature Language=\"C#\" Value=\"public long Start { set; get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>System.Int64</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs>\n    </Member>\n  </Members>\n  <Docs>\n    <summary>To be added.</summary>\n    <remarks>To be added.</remarks>\n  </Docs>\n</Type>\n"
  },
  {
    "path": "doc/developer/en/Bless.Buffers/SegmentCollection.xml",
    "content": "<Type Name=\"SegmentCollection\" FullName=\"Bless.Buffers.SegmentCollection\">\n  <TypeSignature Language=\"C#\" Value=\"public class SegmentCollection\" />\n  <AssemblyInfo>\n    <AssemblyName>Bless.Buffers</AssemblyName>\n    <AssemblyVersion>0.0.0.0</AssemblyVersion>\n  </AssemblyInfo>\n  <Base>\n    <BaseTypeName>System.Object</BaseTypeName>\n  </Base>\n  <Interfaces />\n  <Members>\n    <Member MemberName=\".ctor\">\n      <MemberSignature Language=\"C#\" Value=\"public SegmentCollection ();\" />\n      <MemberType>Constructor</MemberType>\n      <Parameters />\n      <Docs><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Append\">\n      <MemberSignature Language=\"C#\" Value=\"public void Append (Bless.Buffers.Segment s);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"s\" Type=\"Bless.Buffers.Segment\" /></Parameters>\n      <Docs><param name=\"s\">To be added.</param><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"DeleteRange\">\n      <MemberSignature Language=\"C#\" Value=\"public Bless.Buffers.SegmentCollection DeleteRange (long pos1, long pos2);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>Bless.Buffers.SegmentCollection</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"pos1\" Type=\"System.Int64\" /><Parameter Name=\"pos2\" Type=\"System.Int64\" /></Parameters>\n      <Docs><param name=\"pos1\">To be added.</param><param name=\"pos2\">To be added.</param><summary>To be added.</summary><returns>To be added.</returns><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"FindSegment\">\n      <MemberSignature Language=\"C#\" Value=\"public Bless.Buffers.Segment FindSegment (long offset, out long OutMapping, out Bless.Util.List&lt;Bless.Buffers.Segment&gt;.Node OutNode);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>Bless.Buffers.Segment</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"offset\" Type=\"System.Int64\" /><Parameter Name=\"OutMapping\" Type=\"System.Int64&amp;\" RefType=\"out\" /><Parameter Name=\"OutNode\" Type=\"Bless.Util.List&lt;Bless.Buffers.Segment&gt;+Node&amp;\" RefType=\"out\" /></Parameters>\n      <Docs><param name=\"offset\">To be added.</param><param name=\"OutMapping\">To be added.</param><param name=\"OutNode\">To be added.</param><summary>To be added.</summary><returns>To be added.</returns><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"GetRange\">\n      <MemberSignature Language=\"C#\" Value=\"public Bless.Buffers.SegmentCollection GetRange (long pos1, long pos2);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>Bless.Buffers.SegmentCollection</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"pos1\" Type=\"System.Int64\" /><Parameter Name=\"pos2\" Type=\"System.Int64\" /></Parameters>\n      <Docs><param name=\"pos1\">To be added.</param><param name=\"pos2\">To be added.</param><summary>To be added.</summary><returns>To be added.</returns><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Insert\">\n      <MemberSignature Language=\"C#\" Value=\"public void Insert (Bless.Buffers.SegmentCollection sc, long offset);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"sc\" Type=\"Bless.Buffers.SegmentCollection\" /><Parameter Name=\"offset\" Type=\"System.Int64\" /></Parameters>\n      <Docs><param name=\"sc\">To be added.</param><param name=\"offset\">To be added.</param><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"List\">\n      <MemberSignature Language=\"C#\" Value=\"public Bless.Util.List&lt;Bless.Buffers.Segment&gt; List { get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>Bless.Util.List&lt;Bless.Buffers.Segment&gt;</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs>\n    </Member>\n  </Members>\n  <Docs>\n    <summary>To be added.</summary>\n    <remarks>To be added.</remarks>\n  </Docs>\n</Type>\n"
  },
  {
    "path": "doc/developer/en/Bless.Buffers/SimpleBuffer.xml",
    "content": "<Type Name=\"SimpleBuffer\" FullName=\"Bless.Buffers.SimpleBuffer\">\n  <TypeSignature Language=\"C#\" Value=\"public class SimpleBuffer : Bless.Buffers.IBuffer\" />\n  <AssemblyInfo>\n    <AssemblyName>Bless.Buffers</AssemblyName>\n    <AssemblyVersion>0.0.0.0</AssemblyVersion>\n  </AssemblyInfo>\n  <Base>\n    <BaseTypeName>System.Object</BaseTypeName>\n  </Base>\n  <Interfaces>\n    <Interface>\n      <InterfaceName>Bless.Buffers.IBuffer</InterfaceName>\n    </Interface>\n  </Interfaces>\n  <Attributes>\n    <Attribute>\n      <AttributeName>System.Reflection.DefaultMember(\"Item\")</AttributeName>\n    </Attribute>\n  </Attributes>\n  <Members>\n    <Member MemberName=\".ctor\">\n      <MemberSignature Language=\"C#\" Value=\"public SimpleBuffer ();\" />\n      <MemberType>Constructor</MemberType>\n      <Parameters />\n      <Docs><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Append\">\n      <MemberSignature Language=\"C#\" Value=\"public void Append (byte b);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"b\" Type=\"System.Byte\" /></Parameters>\n      <Docs><param name=\"b\">To be added.</param><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Append\">\n      <MemberSignature Language=\"C#\" Value=\"public void Append (byte[] d, long index, long length);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"d\" Type=\"System.Byte[]\" /><Parameter Name=\"index\" Type=\"System.Int64\" /><Parameter Name=\"length\" Type=\"System.Int64\" /></Parameters>\n      <Docs><param name=\"d\">To be added.</param><param name=\"index\">To be added.</param><param name=\"length\">To be added.</param><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Insert\">\n      <MemberSignature Language=\"C#\" Value=\"public void Insert (long pos, byte[] d, long index, long length);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"pos\" Type=\"System.Int64\" /><Parameter Name=\"d\" Type=\"System.Byte[]\" /><Parameter Name=\"index\" Type=\"System.Int64\" /><Parameter Name=\"length\" Type=\"System.Int64\" /></Parameters>\n      <Docs><param name=\"pos\">To be added.</param><param name=\"d\">To be added.</param><param name=\"index\">To be added.</param><param name=\"length\">To be added.</param><summary>This is an append-only buffer.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Item\">\n      <MemberSignature Language=\"C#\" Value=\"public byte this[long index] { set; get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>System.Byte</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"index\" Type=\"System.Int64\" /></Parameters>\n      <Docs><param name=\"index\">To be added.</param><summary>To be added.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Read\">\n      <MemberSignature Language=\"C#\" Value=\"public int Read (byte[] ba, long pos, int len);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Int32</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"ba\" Type=\"System.Byte[]\" /><Parameter Name=\"pos\" Type=\"System.Int64\" /><Parameter Name=\"len\" Type=\"System.Int32\" /></Parameters>\n      <Docs><param name=\"ba\">To be added.</param><param name=\"pos\">To be added.</param><param name=\"len\">To be added.</param><summary>To be added.</summary><returns>To be added.</returns><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Size\">\n      <MemberSignature Language=\"C#\" Value=\"public long Size { get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>System.Int64</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs>\n    </Member>\n  </Members>\n  <Docs>\n    <summary>A simple and lightweight append-only buffer implementing the <see cref=\"T:Bless.Buffers.IBuffer\" /> interface.</summary>\n    <remarks>To be added.</remarks>\n  </Docs>\n</Type>\n"
  },
  {
    "path": "doc/developer/en/Bless.Buffers.xml",
    "content": "<Namespace Name=\"Bless.Buffers\">\n  <Docs>\n    <summary>To be added.</summary>\n    <remarks>To be added.</remarks>\n  </Docs>\n</Namespace>\n"
  },
  {
    "path": "doc/developer/en/Bless.Util/BaseConverter.xml",
    "content": "<Type Name=\"BaseConverter\" FullName=\"Bless.Util.BaseConverter\">\n  <TypeSignature Language=\"C#\" Value=\"public class BaseConverter\" />\n  <AssemblyInfo>\n    <AssemblyName>Bless.Util</AssemblyName>\n    <AssemblyVersion>0.0.0.0</AssemblyVersion>\n  </AssemblyInfo>\n  <Base>\n    <BaseTypeName>System.Object</BaseTypeName>\n  </Base>\n  <Interfaces />\n  <Members>\n    <Member MemberName=\"ConvertToNum\">\n      <MemberSignature Language=\"C#\" Value=\"public static long ConvertToNum (string s, int b);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Int64</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"s\" Type=\"System.String\" /><Parameter Name=\"b\" Type=\"System.Int32\" /></Parameters>\n      <Docs><param name=\"s\">The string to convert.</param><param name=\"b\">The number base of the number <paramref name=\"s\" /> represents.</param><summary>Converts a string to a number assuming it is represented in the specified number base.</summary><returns>To be added.</returns><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"ConvertToNum\">\n      <MemberSignature Language=\"C#\" Value=\"public static long ConvertToNum (string s, int startIndex, int endIndex, int b);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Int64</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"s\" Type=\"System.String\" /><Parameter Name=\"startIndex\" Type=\"System.Int32\" /><Parameter Name=\"endIndex\" Type=\"System.Int32\" /><Parameter Name=\"b\" Type=\"System.Int32\" /></Parameters>\n      <Docs><param name=\"s\">The string to read the sub-string from.</param><param name=\"startIndex\">The starting index of the sub-string in <paramref name=\"s\" />.</param><param name=\"endIndex\">The ending index of the sub-string in <paramref name=\"s\" />.</param><param name=\"b\">The number base of the number that the sub-string represents.</param><summary>Converts a sub-string of string to a number assuming it is represented in the specified number base.</summary><returns>To be added.</returns><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"ConvertToString\">\n      <MemberSignature Language=\"C#\" Value=\"public static string ConvertToString (long num, int b);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.String</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"num\" Type=\"System.Int64\" /><Parameter Name=\"b\" Type=\"System.Int32\" /></Parameters>\n      <Docs><param name=\"num\">To be added.</param><param name=\"b\">To be added.</param><summary>To be added.</summary><returns>To be added.</returns><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"ConvertToString\">\n      <MemberSignature Language=\"C#\" Value=\"public static string ConvertToString (long num, int b, bool prependPrefix, bool lowercase, int minDigits);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.String</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"num\" Type=\"System.Int64\" /><Parameter Name=\"b\" Type=\"System.Int32\" /><Parameter Name=\"prependPrefix\" Type=\"System.Boolean\" /><Parameter Name=\"lowercase\" Type=\"System.Boolean\" /><Parameter Name=\"minDigits\" Type=\"System.Int32\" /></Parameters>\n      <Docs><param name=\"num\">To be added.</param><param name=\"b\">To be added.</param><param name=\"prependPrefix\">To be added.</param><param name=\"lowercase\">To be added.</param><param name=\"minDigits\">To be added.</param><summary>To be added.</summary><returns>To be added.</returns><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"DefaultMinDigits\">\n      <MemberSignature Language=\"C#\" Value=\"public static int[] DefaultMinDigits;\" />\n      <MemberType>Field</MemberType>\n      <ReturnValue><ReturnType>System.Int32[]</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Parse\">\n      <MemberSignature Language=\"C#\" Value=\"public static long Parse (string s);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Int64</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"s\" Type=\"System.String\" /></Parameters>\n      <Docs><param name=\"s\">To be added.</param><summary>To be added.</summary><returns>To be added.</returns><remarks>To be added.</remarks></Docs>\n    </Member>\n  </Members>\n  <Docs>\n    <summary>Class to convert numbers to strings and vice-versa using any number base (up to 16).</summary>\n    <remarks>To be added.</remarks>\n  </Docs>\n</Type>\n"
  },
  {
    "path": "doc/developer/en/Bless.Util/ByteArray.xml",
    "content": "<Type Name=\"ByteArray\" FullName=\"Bless.Util.ByteArray\">\n  <TypeSignature Language=\"C#\" Value=\"public class ByteArray\" />\n  <AssemblyInfo>\n    <AssemblyName>Bless.Util</AssemblyName>\n    <AssemblyVersion>0.0.0.0</AssemblyVersion>\n  </AssemblyInfo>\n  <Base>\n    <BaseTypeName>System.Object</BaseTypeName>\n  </Base>\n  <Interfaces />\n  <Members>\n    <Member MemberName=\"FromString\">\n      <MemberSignature Language=\"C#\" Value=\"public static byte[] FromString (string s, int baseNum);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Byte[]</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"s\" Type=\"System.String\" /><Parameter Name=\"baseNum\" Type=\"System.Int32\" /></Parameters>\n      <Docs><param name=\"s\">To be added.</param><param name=\"baseNum\">To be added.</param><summary>To be added.</summary><returns>To be added.</returns><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"ToString\">\n      <MemberSignature Language=\"C#\" Value=\"public static string ToString (byte[] ba, int baseNum);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.String</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"ba\" Type=\"System.Byte[]\" /><Parameter Name=\"baseNum\" Type=\"System.Int32\" /></Parameters>\n      <Docs><param name=\"ba\">To be added.</param><param name=\"baseNum\">To be added.</param><summary>To be added.</summary><returns>To be added.</returns><remarks>To be added.</remarks></Docs>\n    </Member>\n  </Members>\n  <Docs>\n    <summary>To be added.</summary>\n    <remarks>To be added.</remarks>\n  </Docs>\n</Type>\n"
  },
  {
    "path": "doc/developer/en/Bless.Util/ConfigureDefines.xml",
    "content": "<Type Name=\"ConfigureDefines\" FullName=\"Bless.Util.ConfigureDefines\">\n  <TypeSignature Language=\"C#\" Value=\"public sealed class ConfigureDefines\" />\n  <AssemblyInfo>\n    <AssemblyName>Bless.Util</AssemblyName>\n    <AssemblyVersion>0.0.0.0</AssemblyVersion>\n  </AssemblyInfo>\n  <Base>\n    <BaseTypeName>System.Object</BaseTypeName>\n  </Base>\n  <Interfaces />\n  <Members>\n    <Member MemberName=\".ctor\">\n      <MemberSignature Language=\"C#\" Value=\"public ConfigureDefines ();\" />\n      <MemberType>Constructor</MemberType>\n      <Parameters />\n      <Docs><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"DATADIR\">\n      <MemberSignature Language=\"C#\" Value=\"public const string DATADIR;\" />\n      <MemberType>Field</MemberType>\n      <ReturnValue><ReturnType>System.String</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"GETTEXT_PACKAGE\">\n      <MemberSignature Language=\"C#\" Value=\"public const string GETTEXT_PACKAGE;\" />\n      <MemberType>Field</MemberType>\n      <ReturnValue><ReturnType>System.String</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"LOCALE_DIR\">\n      <MemberSignature Language=\"C#\" Value=\"public const string LOCALE_DIR;\" />\n      <MemberType>Field</MemberType>\n      <ReturnValue><ReturnType>System.String</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"PACKAGE\">\n      <MemberSignature Language=\"C#\" Value=\"public const string PACKAGE;\" />\n      <MemberType>Field</MemberType>\n      <ReturnValue><ReturnType>System.String</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"VERSION\">\n      <MemberSignature Language=\"C#\" Value=\"public const string VERSION;\" />\n      <MemberType>Field</MemberType>\n      <ReturnValue><ReturnType>System.String</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n  </Members>\n  <Docs>\n    <summary>To be added.</summary>\n    <remarks>To be added.</remarks>\n  </Docs>\n</Type>\n"
  },
  {
    "path": "doc/developer/en/Bless.Util/Deque`1.xml",
    "content": "<Type Name=\"Deque&lt;T&gt;\" FullName=\"Bless.Util.Deque&lt;T&gt;\">\n  <TypeSignature Language=\"C#\" Value=\"public class Deque&lt;T&gt; : System.Collections.Generic.IEnumerable&lt;T&gt;\" />\n  <AssemblyInfo>\n    <AssemblyName>Bless.Util</AssemblyName>\n    <AssemblyVersion>0.0.0.0</AssemblyVersion>\n  </AssemblyInfo>\n  <TypeParameters>\n    <TypeParameter>T</TypeParameter>\n  </TypeParameters>\n  <Base>\n    <BaseTypeName>System.Object</BaseTypeName>\n  </Base>\n  <Interfaces>\n    <Interface>\n      <InterfaceName>System.Collections.Generic.IEnumerable&lt;T&gt;</InterfaceName>\n    </Interface>\n  </Interfaces>\n  <Members>\n    <Member MemberName=\".ctor\">\n      <MemberSignature Language=\"C#\" Value=\"public Deque ();\" />\n      <MemberType>Constructor</MemberType>\n      <Parameters />\n      <Docs><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"AddEnd\">\n      <MemberSignature Language=\"C#\" Value=\"public void AddEnd (T o);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"o\" Type=\"T\" /></Parameters>\n      <Docs><param name=\"o\">To be added.</param><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"AddFront\">\n      <MemberSignature Language=\"C#\" Value=\"public void AddFront (T o);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"o\" Type=\"T\" /></Parameters>\n      <Docs><param name=\"o\">To be added.</param><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Clear\">\n      <MemberSignature Language=\"C#\" Value=\"public void Clear ();\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters />\n      <Docs><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Count\">\n      <MemberSignature Language=\"C#\" Value=\"public int Count { get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>System.Int32</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"GetEnumerator\">\n      <MemberSignature Language=\"C#\" Value=\"public System.Collections.Generic.IEnumerator&lt;T&gt; GetEnumerator ();\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Collections.Generic.IEnumerator&lt;T&gt;</ReturnType></ReturnValue>\n      <Parameters />\n      <Docs><summary>To be added.</summary><returns>To be added.</returns><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"PeekEnd\">\n      <MemberSignature Language=\"C#\" Value=\"public T PeekEnd ();\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>T</ReturnType></ReturnValue>\n      <Parameters />\n      <Docs><summary>To be added.</summary><returns>To be added.</returns><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"PeekFront\">\n      <MemberSignature Language=\"C#\" Value=\"public T PeekFront ();\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>T</ReturnType></ReturnValue>\n      <Parameters />\n      <Docs><summary>To be added.</summary><returns>To be added.</returns><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"RemoveEnd\">\n      <MemberSignature Language=\"C#\" Value=\"public T RemoveEnd ();\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>T</ReturnType></ReturnValue>\n      <Parameters />\n      <Docs><summary>To be added.</summary><returns>To be added.</returns><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"RemoveFront\">\n      <MemberSignature Language=\"C#\" Value=\"public T RemoveFront ();\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>T</ReturnType></ReturnValue>\n      <Parameters />\n      <Docs><summary>To be added.</summary><returns>To be added.</returns><remarks>To be added.</remarks></Docs>\n    </Member>\n  </Members>\n  <Docs>\n    <typeparam name=\"T\">To be added.</typeparam>\n    <summary>To be added.</summary>\n    <remarks>To be added.</remarks>\n  </Docs>\n</Type>\n"
  },
  {
    "path": "doc/developer/en/Bless.Util/FileResourcePath.xml",
    "content": "<Type Name=\"FileResourcePath\" FullName=\"Bless.Util.FileResourcePath\">\n  <TypeSignature Language=\"C#\" Value=\"public class FileResourcePath\" />\n  <AssemblyInfo>\n    <AssemblyName>Bless.Util</AssemblyName>\n    <AssemblyVersion>0.0.0.0</AssemblyVersion>\n  </AssemblyInfo>\n  <Base>\n    <BaseTypeName>System.Object</BaseTypeName>\n  </Base>\n  <Interfaces />\n  <Members>\n    <Member MemberName=\"GetBinPath\">\n      <MemberSignature Language=\"C#\" Value=\"public static string GetBinPath (string[] dirs);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.String</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"dirs\" Type=\"System.String[]\"><Attributes><Attribute><AttributeName>System.ParamArray</AttributeName></Attribute></Attributes></Parameter></Parameters>\n      <Docs><param name=\"dirs\">To be added.</param><summary>To be added.</summary><returns>To be added.</returns><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"GetDataPath\">\n      <MemberSignature Language=\"C#\" Value=\"public static string GetDataPath (string[] dirs);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.String</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"dirs\" Type=\"System.String[]\"><Attributes><Attribute><AttributeName>System.ParamArray</AttributeName></Attribute></Attributes></Parameter></Parameters>\n      <Docs><param name=\"dirs\">To be added.</param><summary>To be added.</summary><returns>To be added.</returns><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"GetUserPath\">\n      <MemberSignature Language=\"C#\" Value=\"public static string GetUserPath (string[] dirs);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.String</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"dirs\" Type=\"System.String[]\"><Attributes><Attribute><AttributeName>System.ParamArray</AttributeName></Attribute></Attributes></Parameter></Parameters>\n      <Docs><param name=\"dirs\">To be added.</param><summary>To be added.</summary><returns>To be added.</returns><remarks>To be added.</remarks></Docs>\n    </Member>\n  </Members>\n  <Docs>\n    <summary>To be added.</summary>\n    <remarks>To be added.</remarks>\n  </Docs>\n</Type>\n"
  },
  {
    "path": "doc/developer/en/Bless.Util/List`1+Node.xml",
    "content": "<Type Name=\"List&lt;T&gt;+Node\" FullName=\"Bless.Util.List&lt;T&gt;+Node\">\n  <TypeSignature Language=\"C#\" Value=\"public class List&lt;T&gt;.Node\" />\n  <AssemblyInfo>\n    <AssemblyName>Bless.Util</AssemblyName>\n    <AssemblyVersion>0.0.0.0</AssemblyVersion>\n  </AssemblyInfo>\n  <TypeParameters>\n    <TypeParameter>T</TypeParameter>\n  </TypeParameters>\n  <Base>\n    <BaseTypeName>System.Object</BaseTypeName>\n  </Base>\n  <Interfaces />\n  <Members>\n    <Member MemberName=\".ctor\">\n      <MemberSignature Language=\"C#\" Value=\"public Node (T d, Bless.Util.List&lt;T&gt;.Node p, Bless.Util.List&lt;T&gt;.Node n);\" />\n      <MemberType>Constructor</MemberType>\n      <Parameters><Parameter Name=\"d\" Type=\"T\" /><Parameter Name=\"p\" Type=\"Bless.Util.List&lt;T&gt;+Node\" /><Parameter Name=\"n\" Type=\"Bless.Util.List&lt;T&gt;+Node\" /></Parameters>\n      <Docs><param name=\"d\">To be added.</param><param name=\"p\">To be added.</param><param name=\"n\">To be added.</param><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"data\">\n      <MemberSignature Language=\"C#\" Value=\"public T data;\" />\n      <MemberType>Field</MemberType>\n      <ReturnValue><ReturnType>T</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"next\">\n      <MemberSignature Language=\"C#\" Value=\"public Bless.Util.List&lt;T&gt;.Node next;\" />\n      <MemberType>Field</MemberType>\n      <ReturnValue><ReturnType>Bless.Util.List&lt;T&gt;+Node</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"prev\">\n      <MemberSignature Language=\"C#\" Value=\"public Bless.Util.List&lt;T&gt;.Node prev;\" />\n      <MemberType>Field</MemberType>\n      <ReturnValue><ReturnType>Bless.Util.List&lt;T&gt;+Node</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n  </Members>\n  <Docs>\n    <summary>To be added.</summary>\n    <remarks>To be added.</remarks>\n  </Docs>\n</Type>\n"
  },
  {
    "path": "doc/developer/en/Bless.Util/List`1.xml",
    "content": "<Type Name=\"List&lt;T&gt;\" FullName=\"Bless.Util.List&lt;T&gt;\">\n  <TypeSignature Language=\"C#\" Value=\"public class List&lt;T&gt; : System.Collections.Generic.IEnumerable&lt;T&gt;\" />\n  <AssemblyInfo>\n    <AssemblyName>Bless.Util</AssemblyName>\n    <AssemblyVersion>0.0.0.0</AssemblyVersion>\n  </AssemblyInfo>\n  <TypeParameters>\n    <TypeParameter>T</TypeParameter>\n  </TypeParameters>\n  <Base>\n    <BaseTypeName>System.Object</BaseTypeName>\n  </Base>\n  <Interfaces>\n    <Interface>\n      <InterfaceName>System.Collections.Generic.IEnumerable&lt;T&gt;</InterfaceName>\n    </Interface>\n  </Interfaces>\n  <Attributes>\n    <Attribute>\n      <AttributeName>System.Reflection.DefaultMember(\"Item\")</AttributeName>\n    </Attribute>\n  </Attributes>\n  <Members>\n    <Member MemberName=\".ctor\">\n      <MemberSignature Language=\"C#\" Value=\"public List ();\" />\n      <MemberType>Constructor</MemberType>\n      <Parameters />\n      <Docs><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Append\">\n      <MemberSignature Language=\"C#\" Value=\"public Bless.Util.List&lt;T&gt;.Node Append (T o);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>Bless.Util.List&lt;T&gt;+Node</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"o\" Type=\"T\" /></Parameters>\n      <Docs><param name=\"o\">To be added.</param><summary>To be added.</summary><returns>To be added.</returns><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Count\">\n      <MemberSignature Language=\"C#\" Value=\"public int Count { get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>System.Int32</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Display\">\n      <MemberSignature Language=\"C#\" Value=\"public void Display ();\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters />\n      <Docs><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"First\">\n      <MemberSignature Language=\"C#\" Value=\"public Bless.Util.List&lt;T&gt;.Node First { get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>Bless.Util.List&lt;T&gt;+Node</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"GetEnumerator\">\n      <MemberSignature Language=\"C#\" Value=\"public System.Collections.Generic.IEnumerator&lt;T&gt; GetEnumerator ();\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Collections.Generic.IEnumerator&lt;T&gt;</ReturnType></ReturnValue>\n      <Parameters />\n      <Docs><summary>To be added.</summary><returns>To be added.</returns><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"InsertAfter\">\n      <MemberSignature Language=\"C#\" Value=\"public Bless.Util.List&lt;T&gt;.Node InsertAfter (Bless.Util.List&lt;T&gt;.Node n, T o);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>Bless.Util.List&lt;T&gt;+Node</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"n\" Type=\"Bless.Util.List&lt;T&gt;+Node\" /><Parameter Name=\"o\" Type=\"T\" /></Parameters>\n      <Docs><param name=\"n\">To be added.</param><param name=\"o\">To be added.</param><summary>To be added.</summary><returns>To be added.</returns><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"InsertBefore\">\n      <MemberSignature Language=\"C#\" Value=\"public Bless.Util.List&lt;T&gt;.Node InsertBefore (Bless.Util.List&lt;T&gt;.Node n, T o);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>Bless.Util.List&lt;T&gt;+Node</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"n\" Type=\"Bless.Util.List&lt;T&gt;+Node\" /><Parameter Name=\"o\" Type=\"T\" /></Parameters>\n      <Docs><param name=\"n\">To be added.</param><param name=\"o\">To be added.</param><summary>To be added.</summary><returns>To be added.</returns><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Item\">\n      <MemberSignature Language=\"C#\" Value=\"public T this[int index] { get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>T</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"index\" Type=\"System.Int32\" /></Parameters>\n      <Docs><param name=\"index\">To be added.</param><summary>To be added.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Last\">\n      <MemberSignature Language=\"C#\" Value=\"public Bless.Util.List&lt;T&gt;.Node Last { get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>Bless.Util.List&lt;T&gt;+Node</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Remove\">\n      <MemberSignature Language=\"C#\" Value=\"public void Remove (Bless.Util.List&lt;T&gt;.Node n);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"n\" Type=\"Bless.Util.List&lt;T&gt;+Node\" /></Parameters>\n      <Docs><param name=\"n\">To be added.</param><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n  </Members>\n  <Docs>\n    <typeparam name=\"T\">To be added.</typeparam>\n    <summary>To be added.</summary>\n    <remarks>To be added.</remarks>\n  </Docs>\n</Type>\n"
  },
  {
    "path": "doc/developer/en/Bless.Util/ProgressAction.xml",
    "content": "<Type Name=\"ProgressAction\" FullName=\"Bless.Util.ProgressAction\">\n  <TypeSignature Language=\"C#\" Value=\"public enum ProgressAction\" />\n  <AssemblyInfo>\n    <AssemblyName>Bless.Util</AssemblyName>\n    <AssemblyVersion>0.0.0.0</AssemblyVersion>\n  </AssemblyInfo>\n  <Base>\n    <BaseTypeName>System.Enum</BaseTypeName>\n  </Base>\n  <Members>\n    <Member MemberName=\"Destroy\">\n      <MemberSignature Language=\"C#\" Value=\"Destroy\" />\n      <MemberType>Field</MemberType>\n      <ReturnValue><ReturnType>Bless.Util.ProgressAction</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary></Docs>\n    </Member>\n    <Member MemberName=\"Details\">\n      <MemberSignature Language=\"C#\" Value=\"Details\" />\n      <MemberType>Field</MemberType>\n      <ReturnValue><ReturnType>Bless.Util.ProgressAction</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary></Docs>\n    </Member>\n    <Member MemberName=\"Hide\">\n      <MemberSignature Language=\"C#\" Value=\"Hide\" />\n      <MemberType>Field</MemberType>\n      <ReturnValue><ReturnType>Bless.Util.ProgressAction</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary></Docs>\n    </Member>\n    <Member MemberName=\"Message\">\n      <MemberSignature Language=\"C#\" Value=\"Message\" />\n      <MemberType>Field</MemberType>\n      <ReturnValue><ReturnType>Bless.Util.ProgressAction</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary></Docs>\n    </Member>\n    <Member MemberName=\"Show\">\n      <MemberSignature Language=\"C#\" Value=\"Show\" />\n      <MemberType>Field</MemberType>\n      <ReturnValue><ReturnType>Bless.Util.ProgressAction</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary></Docs>\n    </Member>\n    <Member MemberName=\"Update\">\n      <MemberSignature Language=\"C#\" Value=\"Update\" />\n      <MemberType>Field</MemberType>\n      <ReturnValue><ReturnType>Bless.Util.ProgressAction</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary></Docs>\n    </Member>\n  </Members>\n  <Docs>\n    <summary>To be added.</summary>\n    <remarks>To be added.</remarks>\n  </Docs>\n</Type>\n"
  },
  {
    "path": "doc/developer/en/Bless.Util/ProgressCallback.xml",
    "content": "<Type Name=\"ProgressCallback\" FullName=\"Bless.Util.ProgressCallback\">\n  <TypeSignature Language=\"C#\" Value=\"public delegate bool ProgressCallback(object o, ProgressAction action);\" />\n  <AssemblyInfo>\n    <AssemblyName>Bless.Util</AssemblyName>\n    <AssemblyVersion>0.0.0.0</AssemblyVersion>\n  </AssemblyInfo>\n  <Base>\n    <BaseTypeName>System.Delegate</BaseTypeName>\n  </Base>\n  <Parameters>\n    <Parameter Name=\"o\" Type=\"System.Object\" />\n    <Parameter Name=\"action\" Type=\"Bless.Util.ProgressAction\" />\n  </Parameters>\n  <ReturnValue>\n    <ReturnType>System.Boolean</ReturnType>\n  </ReturnValue>\n  <Docs>\n    <param name=\"o\">To be added.</param>\n    <param name=\"action\">To be added.</param>\n    <summary>To be added.</summary>\n    <returns>To be added.</returns>\n    <remarks>To be added.</remarks>\n  </Docs>\n</Type>\n"
  },
  {
    "path": "doc/developer/en/Bless.Util/Range.xml",
    "content": "<Type Name=\"Range\" FullName=\"Bless.Util.Range\">\n  <TypeSignature Language=\"C#\" Value=\"public class Range\" />\n  <AssemblyInfo>\n    <AssemblyName>Bless.Util</AssemblyName>\n    <AssemblyVersion>0.0.0.0</AssemblyVersion>\n  </AssemblyInfo>\n  <Base>\n    <BaseTypeName>System.Object</BaseTypeName>\n  </Base>\n  <Interfaces />\n  <Members>\n    <Member MemberName=\".ctor\">\n      <MemberSignature Language=\"C#\" Value=\"public Range ();\" />\n      <MemberType>Constructor</MemberType>\n      <Parameters />\n      <Docs><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\".ctor\">\n      <MemberSignature Language=\"C#\" Value=\"public Range (Bless.Util.Range r);\" />\n      <MemberType>Constructor</MemberType>\n      <Parameters><Parameter Name=\"r\" Type=\"Bless.Util.Range\" /></Parameters>\n      <Docs><param name=\"r\">To be added.</param><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\".ctor\">\n      <MemberSignature Language=\"C#\" Value=\"public Range (long s, long e);\" />\n      <MemberType>Constructor</MemberType>\n      <Parameters><Parameter Name=\"s\" Type=\"System.Int64\" /><Parameter Name=\"e\" Type=\"System.Int64\" /></Parameters>\n      <Docs><param name=\"s\">To be added.</param><param name=\"e\">To be added.</param><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Clear\">\n      <MemberSignature Language=\"C#\" Value=\"public void Clear ();\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters />\n      <Docs><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Contains\">\n      <MemberSignature Language=\"C#\" Value=\"public bool Contains (long n);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Boolean</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"n\" Type=\"System.Int64\" /></Parameters>\n      <Docs><param name=\"n\">To be added.</param><summary>To be added.</summary><returns>To be added.</returns><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Difference\">\n      <MemberSignature Language=\"C#\" Value=\"public void Difference (Bless.Util.Range r, Bless.Util.Range r1);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"r\" Type=\"Bless.Util.Range\" /><Parameter Name=\"r1\" Type=\"Bless.Util.Range\" /></Parameters>\n      <Docs><param name=\"r\">To be added.</param><param name=\"r1\">To be added.</param><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"End\">\n      <MemberSignature Language=\"C#\" Value=\"public long End { set; get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>System.Int64</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Intersect\">\n      <MemberSignature Language=\"C#\" Value=\"public void Intersect (Bless.Util.Range sel);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"sel\" Type=\"Bless.Util.Range\" /></Parameters>\n      <Docs><param name=\"sel\">To be added.</param><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"IsEmpty\">\n      <MemberSignature Language=\"C#\" Value=\"public bool IsEmpty ();\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Boolean</ReturnType></ReturnValue>\n      <Parameters />\n      <Docs><summary>To be added.</summary><returns>To be added.</returns><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Size\">\n      <MemberSignature Language=\"C#\" Value=\"public long Size { get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>System.Int64</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Sort\">\n      <MemberSignature Language=\"C#\" Value=\"public void Sort ();\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters />\n      <Docs><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Start\">\n      <MemberSignature Language=\"C#\" Value=\"public long Start { set; get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>System.Int64</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs>\n    </Member>\n  </Members>\n  <Docs>\n    <summary>To be added.</summary>\n    <remarks>To be added.</remarks>\n  </Docs>\n</Type>\n"
  },
  {
    "path": "doc/developer/en/Bless.Util/RangeCollection.xml",
    "content": "<Type Name=\"RangeCollection\" FullName=\"Bless.Util.RangeCollection\">\n  <TypeSignature Language=\"C#\" Value=\"public class RangeCollection : System.Collections.ArrayList\" />\n  <AssemblyInfo>\n    <AssemblyName>Bless.Util</AssemblyName>\n    <AssemblyVersion>0.0.0.0</AssemblyVersion>\n  </AssemblyInfo>\n  <Base>\n    <BaseTypeName>System.Collections.ArrayList</BaseTypeName>\n  </Base>\n  <Interfaces />\n  <Members>\n    <Member MemberName=\".ctor\">\n      <MemberSignature Language=\"C#\" Value=\"public RangeCollection ();\" />\n      <MemberType>Constructor</MemberType>\n      <Parameters />\n      <Docs><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Clear\">\n      <MemberSignature Language=\"C#\" Value=\"public void Clear ();\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters />\n      <Docs><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"LastAdded\">\n      <MemberSignature Language=\"C#\" Value=\"public Bless.Util.Range LastAdded { get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>Bless.Util.Range</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"UpdateRange\">\n      <MemberSignature Language=\"C#\" Value=\"public void UpdateRange (Bless.Util.Range oldRange, Bless.Util.Range newRange);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"oldRange\" Type=\"Bless.Util.Range\" /><Parameter Name=\"newRange\" Type=\"Bless.Util.Range\" /></Parameters>\n      <Docs><param name=\"oldRange\">To be added.</param><param name=\"newRange\">To be added.</param><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n  </Members>\n  <Docs>\n    <summary>To be added.</summary>\n    <remarks>To be added.</remarks>\n  </Docs>\n</Type>\n"
  },
  {
    "path": "doc/developer/en/Bless.Util/TempFile.xml",
    "content": "<Type Name=\"TempFile\" FullName=\"Bless.Util.TempFile\">\n  <TypeSignature Language=\"C#\" Value=\"public class TempFile\" />\n  <AssemblyInfo>\n    <AssemblyName>Bless.Util</AssemblyName>\n    <AssemblyVersion>0.0.0.0</AssemblyVersion>\n  </AssemblyInfo>\n  <Base>\n    <BaseTypeName>System.Object</BaseTypeName>\n  </Base>\n  <Interfaces />\n  <Members>\n    <Member MemberName=\"CreateName\">\n      <MemberSignature Language=\"C#\" Value=\"public static string CreateName (string dir);\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.String</ReturnType></ReturnValue>\n      <Parameters><Parameter Name=\"dir\" Type=\"System.String\" /></Parameters>\n      <Docs><param name=\"dir\">To be added.</param><summary>To be added.</summary><returns>To be added.</returns><remarks>To be added.</remarks></Docs>\n    </Member>\n  </Members>\n  <Docs>\n    <summary>To be added.</summary>\n    <remarks>To be added.</remarks>\n  </Docs>\n</Type>\n"
  },
  {
    "path": "doc/developer/en/Bless.Util/ThreadedAsyncOperation+OperationResult.xml",
    "content": "<Type Name=\"ThreadedAsyncOperation+OperationResult\" FullName=\"Bless.Util.ThreadedAsyncOperation+OperationResult\">\n  <TypeSignature Language=\"C#\" Value=\"public enum ThreadedAsyncOperation.OperationResult\" />\n  <AssemblyInfo>\n    <AssemblyName>Bless.Util</AssemblyName>\n    <AssemblyVersion>0.0.0.0</AssemblyVersion>\n  </AssemblyInfo>\n  <Base>\n    <BaseTypeName>System.Enum</BaseTypeName>\n  </Base>\n  <Members>\n    <Member MemberName=\"Cancelled\">\n      <MemberSignature Language=\"C#\" Value=\"Cancelled\" />\n      <MemberType>Field</MemberType>\n      <ReturnValue><ReturnType>Bless.Util.ThreadedAsyncOperation+OperationResult</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary></Docs>\n    </Member>\n    <Member MemberName=\"CaughtException\">\n      <MemberSignature Language=\"C#\" Value=\"CaughtException\" />\n      <MemberType>Field</MemberType>\n      <ReturnValue><ReturnType>Bless.Util.ThreadedAsyncOperation+OperationResult</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary></Docs>\n    </Member>\n    <Member MemberName=\"Finished\">\n      <MemberSignature Language=\"C#\" Value=\"Finished\" />\n      <MemberType>Field</MemberType>\n      <ReturnValue><ReturnType>Bless.Util.ThreadedAsyncOperation+OperationResult</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary></Docs>\n    </Member>\n  </Members>\n  <Docs>\n    <summary>To be added.</summary>\n    <remarks>To be added.</remarks>\n  </Docs>\n</Type>\n"
  },
  {
    "path": "doc/developer/en/Bless.Util/ThreadedAsyncOperation.xml",
    "content": "<Type Name=\"ThreadedAsyncOperation\" FullName=\"Bless.Util.ThreadedAsyncOperation\">\n  <TypeSignature Language=\"C#\" Value=\"public abstract class ThreadedAsyncOperation\" />\n  <AssemblyInfo>\n    <AssemblyName>Bless.Util</AssemblyName>\n    <AssemblyVersion>0.0.0.0</AssemblyVersion>\n  </AssemblyInfo>\n  <Base>\n    <BaseTypeName>System.Object</BaseTypeName>\n  </Base>\n  <Interfaces />\n  <Members>\n    <Member MemberName=\".ctor\">\n      <MemberSignature Language=\"C#\" Value=\"public ThreadedAsyncOperation (Bless.Util.ProgressCallback pc, AsyncCallback ac, bool glibIdle);\" />\n      <MemberType>Constructor</MemberType>\n      <Parameters><Parameter Name=\"pc\" Type=\"Bless.Util.ProgressCallback\" /><Parameter Name=\"ac\" Type=\"System.AsyncCallback\" /><Parameter Name=\"glibIdle\" Type=\"System.Boolean\" /></Parameters>\n      <Docs><param name=\"pc\">To be added.</param><param name=\"ac\">To be added.</param><param name=\"glibIdle\">To be added.</param><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"cancelled\">\n      <MemberSignature Language=\"C#\" Value=\"protected bool cancelled;\" />\n      <MemberType>Field</MemberType>\n      <ReturnValue><ReturnType>System.Boolean</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"DoOperation\">\n      <MemberSignature Language=\"C#\" Value=\"protected abstract void DoOperation ();\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters />\n      <Docs><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"EndOperation\">\n      <MemberSignature Language=\"C#\" Value=\"protected abstract void EndOperation ();\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters />\n      <Docs><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"EndProgress\">\n      <MemberSignature Language=\"C#\" Value=\"protected abstract bool EndProgress ();\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Boolean</ReturnType></ReturnValue>\n      <Parameters />\n      <Docs><summary>To be added.</summary><returns>To be added.</returns><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"IdleHandlerEnd\">\n      <MemberSignature Language=\"C#\" Value=\"protected abstract void IdleHandlerEnd ();\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters />\n      <Docs><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"OperationThread\">\n      <MemberSignature Language=\"C#\" Value=\"public void OperationThread ();\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue>\n      <Parameters />\n      <Docs><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"opFinishedCallback\">\n      <MemberSignature Language=\"C#\" Value=\"protected AsyncCallback opFinishedCallback;\" />\n      <MemberType>Field</MemberType>\n      <ReturnValue><ReturnType>System.AsyncCallback</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"progressCallback\">\n      <MemberSignature Language=\"C#\" Value=\"protected Bless.Util.ProgressCallback progressCallback;\" />\n      <MemberType>Field</MemberType>\n      <ReturnValue><ReturnType>Bless.Util.ProgressCallback</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"Result\">\n      <MemberSignature Language=\"C#\" Value=\"public Bless.Util.ThreadedAsyncOperation.OperationResult Result { set; get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>Bless.Util.ThreadedAsyncOperation+OperationResult</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"StartProgress\">\n      <MemberSignature Language=\"C#\" Value=\"protected abstract bool StartProgress ();\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Boolean</ReturnType></ReturnValue>\n      <Parameters />\n      <Docs><summary>To be added.</summary><returns>To be added.</returns><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"ThreadException\">\n      <MemberSignature Language=\"C#\" Value=\"public Exception ThreadException { set; get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>System.Exception</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"UpdateProgress\">\n      <MemberSignature Language=\"C#\" Value=\"protected abstract bool UpdateProgress ();\" />\n      <MemberType>Method</MemberType>\n      <ReturnValue><ReturnType>System.Boolean</ReturnType></ReturnValue>\n      <Parameters />\n      <Docs><summary>To be added.</summary><returns>To be added.</returns><remarks>To be added.</remarks></Docs>\n    </Member>\n  </Members>\n  <Docs>\n    <summary>To be added.</summary>\n    <remarks>To be added.</remarks>\n  </Docs>\n</Type>\n"
  },
  {
    "path": "doc/developer/en/Bless.Util/ThreadedAsyncResult.xml",
    "content": "<Type Name=\"ThreadedAsyncResult\" FullName=\"Bless.Util.ThreadedAsyncResult\">\n  <TypeSignature Language=\"C#\" Value=\"public class ThreadedAsyncResult : IAsyncResult\" />\n  <AssemblyInfo>\n    <AssemblyName>Bless.Util</AssemblyName>\n    <AssemblyVersion>0.0.0.0</AssemblyVersion>\n  </AssemblyInfo>\n  <Base>\n    <BaseTypeName>System.Object</BaseTypeName>\n  </Base>\n  <Interfaces>\n    <Interface>\n      <InterfaceName>System.IAsyncResult</InterfaceName>\n    </Interface>\n  </Interfaces>\n  <Members>\n    <Member MemberName=\".ctor\">\n      <MemberSignature Language=\"C#\" Value=\"public ThreadedAsyncResult (object state, System.Threading.WaitHandle handle, bool complete);\" />\n      <MemberType>Constructor</MemberType>\n      <Parameters><Parameter Name=\"state\" Type=\"System.Object\" /><Parameter Name=\"handle\" Type=\"System.Threading.WaitHandle\" /><Parameter Name=\"complete\" Type=\"System.Boolean\" /></Parameters>\n      <Docs><param name=\"state\">To be added.</param><param name=\"handle\">To be added.</param><param name=\"complete\">To be added.</param><summary>To be added.</summary><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"AsyncState\">\n      <MemberSignature Language=\"C#\" Value=\"public object AsyncState { get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>System.Object</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"AsyncWaitHandle\">\n      <MemberSignature Language=\"C#\" Value=\"public System.Threading.WaitHandle AsyncWaitHandle { get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>System.Threading.WaitHandle</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"CompletedSynchronously\">\n      <MemberSignature Language=\"C#\" Value=\"public bool CompletedSynchronously { get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>System.Boolean</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs>\n    </Member>\n    <Member MemberName=\"IsCompleted\">\n      <MemberSignature Language=\"C#\" Value=\"public bool IsCompleted { get; };\" />\n      <MemberType>Property</MemberType>\n      <ReturnValue><ReturnType>System.Boolean</ReturnType></ReturnValue>\n      <Docs><summary>To be added.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs>\n    </Member>\n  </Members>\n  <Docs>\n    <summary>To be added.</summary>\n    <remarks>To be added.</remarks>\n  </Docs>\n</Type>\n"
  },
  {
    "path": "doc/developer/en/Bless.Util.xml",
    "content": "<Namespace Name=\"Bless.Util\">\n  <Docs>\n    <summary>To be added.</summary>\n    <remarks>To be added.</remarks>\n  </Docs>\n</Namespace>\n"
  },
  {
    "path": "doc/developer/en/index.xml",
    "content": "<Overview>\n  <Assemblies>\n    <Assembly Name=\"Bless.Buffers\" Version=\"0.0.0.0\">\n      <Attributes>\n        <Attribute>\n          <AttributeName>System.Runtime.CompilerServices.RuntimeCompatibility(WrapNonExceptionThrows=true)</AttributeName>\n        </Attribute>\n      </Attributes>\n    </Assembly>\n    <Assembly Name=\"Bless.Util\" Version=\"0.0.0.0\">\n      <Attributes>\n        <Attribute>\n          <AttributeName>System.Runtime.CompilerServices.RuntimeCompatibility(WrapNonExceptionThrows=true)</AttributeName>\n        </Attribute>\n      </Attributes>\n    </Assembly>\n  </Assemblies>\n  <Remarks>To be added.</Remarks>\n  <Copyright>To be added.</Copyright>\n  <Types>\n    <Namespace Name=\"Bless.Buffers\">\n      <Type Name=\"ByteBuffer\" />\n      <Type Name=\"FileBuffer\" />\n      <Type Name=\"IBuffer\" />\n      <Type Name=\"SaveAsOperation\" />\n      <Type Name=\"SaveAsOperation+SaveAsStage\" />\n      <Type Name=\"SaveOperation\" />\n      <Type Name=\"SaveOperation+SaveStage\" />\n      <Type Name=\"Segment\" />\n      <Type Name=\"SegmentCollection\" />\n      <Type Name=\"SimpleBuffer\" />\n      <Type Name=\"ByteBuffer+ChangedHandler\" />\n    </Namespace>\n    <Namespace Name=\"Bless.Util\">\n      <Type Name=\"BaseConverter\" />\n      <Type Name=\"ByteArray\" />\n      <Type Name=\"ConfigureDefines\" />\n      <Type Name=\"Deque`1\" DisplayName=\"Deque&lt;T&gt;\" />\n      <Type Name=\"FileResourcePath\" />\n      <Type Name=\"List`1\" DisplayName=\"List&lt;T&gt;\" />\n      <Type Name=\"List`1+Node\" DisplayName=\"List&lt;T&gt;+Node\" />\n      <Type Name=\"ProgressAction\" />\n      <Type Name=\"Range\" />\n      <Type Name=\"RangeCollection\" />\n      <Type Name=\"TempFile\" />\n      <Type Name=\"ThreadedAsyncOperation\" />\n      <Type Name=\"ThreadedAsyncOperation+OperationResult\" />\n      <Type Name=\"ThreadedAsyncResult\" />\n      <Type Name=\"ProgressCallback\" />\n    </Namespace>\n  </Types>\n  <Title>Bless</Title>\n</Overview>\n"
  },
  {
    "path": "doc/user/C/index.docbook",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE article PUBLIC \"-//OASIS//DTD DocBook XML V4.1.2//EN\" \n\"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd\" [\n\t<!ENTITY legal SYSTEM \"legal.xml\">\n\t<!ENTITY appversion \"0.6.3\">\n\t<!ENTITY manrevision \"1.0\">\n\t<!ENTITY date \"Oct 2020\">\n\t<!ENTITY app \"<application>Bless</application>\">\n\t<!-- Information about the entities\n\t\tThe legal.xml file contains legal information, there is no need to edit the file. \n\t\tUse the appversion entity to specify the version of the application.\n\t\tUse the manrevision entity to specify the revision number of this manual.\n\t\tUse the date entity to specify the release date of this manual.\n\t\tUse the app entity to specify the name of the application. -->\n]>\n\n<!-- \n\t(Do not remove this comment block.)\n\tMaintained by the GNOME Documentation Project\n\thttp://developer.gnome.org/projects/gdp\n\tTemplate version: 2.0 beta\n\tTemplate last modified Feb 06, 2003\n-->\n\n<!-- =============Document Header ============================= -->\n<book id=\"index\" lang=\"en\">\n\t<bookinfo> \n\t\t<title>&app; &appversion; Manual</title>\t\t\t \n\n\t\t<copyright> \n\t\t\t<year>2004</year> \n\t\t\t<year>2020</year>\n\t\t\t<holder>Alexandros Frantzis</holder> \n\t\t</copyright> \n<!-- translators: uncomment this:\n\n\t<copyright>\n\t<year>2002</year>\n\t<holder>ME-THE-TRANSLATOR (Latin translation)</holder>\n\t</copyright>\n\n\t -->\n\t &legal;\n\t <!-- This file\tcontains link to license for the documentation (GNU FDL), and \n\t\t\t\tother legal stuff such as \"NO WARRANTY\" statement. Please do not change \n\tany of this. -->\n\n\t\t<authorgroup> \n\t\t\t<author> \n\t\t\t\t<firstname>Alexandros</firstname> \n\t\t\t\t<surname>Frantzis</surname> \n\t\t\t</author> \n\t\t\t\n<!-- This is appropriate place for other contributors: translators,\n\t\t maintainers,\tetc. Commented out by default.\n\t\t \n\t\t\t<othercredit role=\"translator\">\n\t\t<firstname>Latin</firstname> \n\t\t<surname>Translator 1</surname> \n\t\t<affiliation> \n\t\t\t\t<orgname>Latin Translation Team</orgname> \n\t\t\t\t<address> <email>translator@gnome.org</email> </address> \n\t\t</affiliation>\n\t\t<contrib>Latin translation</contrib>\n\t\t\t</othercredit>\n-->\n\t\t</authorgroup>\n\n\n<!-- According to GNU FDL, revision history is mandatory if you are -->\n<!-- modifying/reusing someone else's document.\tIf not, you can omit it. -->\n<!-- Remember to remove the &manrevision; entity from the revision entries other\n-->\n<!-- than the current revision. -->\n<!-- The revision numbering system for GNOME manuals is as follows: -->\n<!-- * the revision number consists of two components -->\n<!-- * the first component of the revision number reflects the release version of the GNOME desktop. -->\n<!-- * the second component of the revision number is a decimal unit that is incremented with each revision of the manual. -->\n<!-- For example, if the GNOME desktop release is V2.x, the first version of the manual that -->\n<!-- is written in that desktop timeframe is V2.0, the second version of the manual is V2.1, etc. -->\n<!-- When the desktop release version changes to V3.x, the revision number of the manual changes -->\n<!-- to V3.0, and so on. -->\t\n<!--\t\t<revhistory>\n\t\t\t<revision> \n\t\t<revnumber>MY-GNOME-APPLICATION Manual V&manrevision;</revnumber> \n\t\t<date>&date;</date> \n\t\t<revdescription> \n\t\t\t\t<para role=\"author\">Documentation Writer 2\n\t\t\t\t<email>docwriter2@gnome.org</email> \n\t\t\t\t</para>\n\t\t\t\t<para role=\"publisher\">GNOME Documentation Project</para>\n\t\t</revdescription> \n\t\t\t</revision> \n\t\t\t<revision> \n\t\t<revnumber>Full title of previous manual.</revnumber> \n\t\t<date>Release date of previous manual.</date> \n\t\t<revdescription> \n\t\t\t\t<para role=\"author\">Documentation Writer 1 \n\t\t\t\t<email>docwriter1@gnome.org</email> \n\t\t\t\t</para>\n\t\t\t\t<para role=\"publisher\">GNOME Documentation Project</para>\n\t\t</revdescription> \n\t\t\t</revision> \n\t\t</revhistory> \n-->\n\t\t<releaseinfo>This manual describes version &appversion; of &app;.\n\t\t</releaseinfo> \n\t\t\n\t\t<legalnotice> \n\t\t\t<title>Feedback</title> \n\t\t\t<para>To report a bug or make a suggestion regarding the &app; application or\n\t\t\tthis manual, please use the\n\t\t\t<ulink url=\"https://github.com/afrantzis/bless/issues\" type=\"https\">Bless bug page</ulink>.\n\t\t\t</para>\n<!-- Translators may also add here feedback address for translations -->\n\t\t</legalnotice> \n\t</bookinfo> \n\n\t<indexterm zone=\"index\"> \n\t\t<primary>Bless</primary> \n\t</indexterm> \n\t\n<!-- ============= Document Body ============================= -->\n<!-- ============= Introduction ============================== -->\n<!-- Use the Introduction section to give a brief overview of what\n\t\t the application is and what it does. -->\n<chapter id=\"bless-introduction\"> \n\t<title>Introduction</title> \n\t<para>\n\t&app; is a binary (hex) editor, a program that enables you to edit files as\n\tsequences of bytes. It is written in C# and uses the Gtk# bindings for the\n\tGTK+ toolkit.\n\t</para>\n\t<para>\n\t&app; provides the following features:\n\t</para> \n\t<itemizedlist> \n\t\t<listitem>\n\t\t\t<para>Efficient editing of large data files.</para>\n\t\t</listitem>\n\t\t<listitem>\n\t\t\t<para>Multilevel undo - redo operations.</para>\n\t\t</listitem>\n\t\t<listitem>\n\t\t\t<para>Customizable data views.</para>\n\t\t</listitem>\n \t\t<listitem>\n\t\t\t<para>Fast data rendering on screen.</para>\n\t\t</listitem>\n\t\t<listitem>\n\t\t\t<para>Multiple tabs.</para>\n\t\t</listitem>\n\t\t<listitem>\n\t\t\t<para>Fast find and replace operations.</para>\n\t\t</listitem>\n\t\t<listitem>\n\t\t\t<para>A data conversion table.</para>\n\t\t</listitem> \n\t\t<listitem> \n\t\t\t<para>Advanced copy/paste capabilities.</para> \n\t\t</listitem>\n\t\t<listitem> \n\t\t\t<para>Highlighting of selection pattern matches in the file.</para> \n\t\t</listitem>\n\t\t<listitem> \n\t\t\t<para>Exporting to text and html.</para> \n\t\t</listitem>\n\t\t<listitem> \n\t\t\t<para>Extensibility with plugins.</para> \n\t\t</listitem>\n\t</itemizedlist> \n</chapter>\n\n<chapter id=\"bless-install\">\n\t<title>Building and Installing Bless</title> \n\t\t<section id=\"bless-install-requirements\">\n\t\t\t<title>&app; &appversion; requirements</title>\n\t\t\t<para>\n\t\t\t\tThe main target platform for &app; is GNU/Linux. However, all the libraries it\n\t\t\t\tuses are cross-platform, so &app; should be able to run without problems \n\t\t\t\ton all the major platforms (GNU/Linux, *BSD, Solaris, Win32).\n\t\t\t</para>\n\t\t\t<para>\n\t\t\tTo build and run &app; &appversion; you need:\n\t\t\t<itemizedlist>\n\t\t\t\t<listitem>\n\t\t\t\t\t<para>GTK+ &gt;=2.8.x (Included in all modern GNU/Linux distributions, <ulink url=\"http://www.gtk.org\" type=\"http\">http://www.gtk.org</ulink>)</para>\n\t\t\t\t</listitem>\n\t\t\t\t<listitem>\n\t\t\t\t\t<para>mono/.NET runtime and C# compiler &gt;= 1.1.14 (<ulink url=\"http://www.mono-project.com\" type=\"http\">http://www.mono-project.com</ulink>)</para>\n\t\t\t\t</listitem>\n\t\t\t\t<listitem>\n\t\t\t\t\t<para>Gtk#  &gt;=2.8 bindings for GTK+ (<ulink url=\"http://gtk-sharp.sourceforge.net\" type=\"http\">http://gtk-sharp.sourceforge.net</ulink>)</para>\n\t\t\t\t</listitem>\n\t\t\t\t<listitem>\n\t\t\t\t\t<para>pkg-config (Included in all modern GNU/Linux distributions)</para>\n\t\t\t\t</listitem>\n\t\t\t\t<listitem>\n\t\t\t\t\t<para>meson &gt;=0.46</para>\n\t\t\t\t</listitem>\n\t\t\t\t<listitem>\n\t\t\t\t\t<para>nunit and nunit-console, if you want to build and run tests</para>\n\t\t\t\t</listitem>\n\t\t\t\t<listitem>\n\t\t\t\t\t<para>xsltproc and docbook stylesheet, if you want to produce HTML documentation</para>\n\t\t\t\t</listitem>\n\t\t\t</itemizedlist>\n\t\t    </para>\n\t\t    \n\t\t    <note>\n\t\t    \t<para>\n\t\t\t\t\tDevelopment is done using the latest stable versions of the above libraries. \n\t\t\t\t\tAlthough using an older version may be OK, there is no guarantee that there \n\t\t\t\t\twill not be problems.\n\t\t\t\t</para>\n\t\t\t</note>\n\t\t</section>\n\n\t<section id=\"bless-install-guide\"> \n\t\t<title>Installation guide</title>\n\t\t<para>\n\t\t\tIf you downloaded bless as a distribution specific package (eg .rpm, .deb, .tgz) follow your\n\t\t\tdistribution's instructions on how to install packages.\n\t\t</para>\n\t\t<para>\n\t\t\tIf you downloaded Bless from the git repo, or as a source .tar.gz or .tar.bz2\n\t\t\tpackage you will need to build it and install it manually. The building and\n\t\t\tinstallation procedure is described below:\n\t\t</para>\n\t\t<para>\n\t\t\tOverview: git clone https://github.com/afrantzis/bless,\n\t\t\tmeson setup build (-Dopt=val --buildtype=type ...), ninja -C build,\n\t\t\t(ninja -C build install)\n\t    </para>\n\t\t<variablelist>\n\t\t\t<varlistentry>\n\t\t\t\t<term>Step 1: Get the source</term>\n\t\t\t\t<listitem>\n\t\t\t\t\t<para> To get the latest source:</para>\n\t\t\t\t\t<para>\n\t\t\t\t\t\t<command>git clone https://github.com/afrantzis/bless</command>\n\t\t\t\t\t</para>\n\t\t\t\t\t<para>For a compressed tarball use:</para>\n\t\t\t\t\t<para>\n\t\t\t\t\t\t<command>tar -xf bless-a.b.c.tar.gz</command>\n\t\t\t\t\t</para>\n\t\t\t\t</listitem>\n\t\t\t</varlistentry>\n\t\t\t<varlistentry>\n\t\t\t\t<term>Step 2: Configure the build</term>\n\t\t\t\t<listitem>\n\t\t\t\t\t<para>\n\t\t\t\t\tEnter the directory created in the previous step (bless or bless-a.b.c). To\n\t\t\t\t\tconfigure the build and check that your system has all the required libraries\n\t\t\t\t\tuse: \n\t\t\t\t\t</para>\n\t\t\t\t\t<para>\n\t\t\t\t\t\t<command>meson setup build (-Dopt=val --buildtype=type ...)</command>\n\t\t\t\t\t</para>\n\t\t\t\t\t<para>\n\t\t\t\t\t\tUse the <parameter>--prefix=<replaceable>PREFIX</replaceable></parameter>\n\t\t\t\t\t\toption to set the installation directory prefix.  By default the prefix\n\t\t\t\t\t\tis '/usr/local'.\n\t\t\t\t\t</para>\n\t\t\t\t\t<para>\n\t\t\t\t\t\tYou can use the <parameter>--buildtype=release</parameter> option to\n\t\t\t\t\t\tbuild bless in release mode. By default the debug mode is built.\n\t\t\t\t\t</para>\n\t\t\t\t</listitem>\n\t\t\t</varlistentry>\n\t\t\t\n\t\t\t<varlistentry>\n\t\t\t\t<term>Step 3: Build the program</term>\n\t\t\t\t<listitem>\n\t\t\t\t\t<para>\n\t\t\t\t\t\tType <command>ninja -C build</command>. This will create\n\t\t\t\t\t\t<filename>bless.exe</filename> and the necessary libraries in\n\t\t\t\t\t\tthe build/src directory. You can also use\n\t\t\t\t\t\t<command>ninja -C build test</command> to run some tests on various\n\t\t\t\t\t\tbless components. Note that running the tests requires the\n\t\t\t\t\t\t<command>nunit-console</command> binary.\n\t\t\t\t\t</para>\n\t\t\t\t</listitem>\n\t\t\t</varlistentry>\n\t\t\t\n\t\t\t<varlistentry>\n\t\t\t\t<term>Step 4: Install the program (optional)</term>\n\t\t\t\t<listitem>\n\t\t\t\t\t<para>\n\t\t\t\t\t\tBecome root and type <command>ninja -C build install</command>. \n\t\t\t\t\t</para>\n\t\t\t\t</listitem>\n\t\t\t</varlistentry>\n\t\t\t\n\t\t</variablelist>\n\t</section>\t\t\n</chapter> \n<!-- =========== Getting Started ============================== -->\n<!-- Use the Getting Started section to describe the steps required\n\t\t to start the application and to describe the user interface components\n\t\t of the application. If there is other information that it is important\n\t\t for readers to know before they start using the application, you should\n\t\t also include this information here. \n\t\t If the information about how to get started is very short, you can \n\t\t include it in the Introduction and omit this section. -->\n\n<chapter id=\"bless-getting-started\"> \n\t<title>Getting Started</title> \n\n\t<section id=\"bless-start\">\n\t\t<title>To Start &app;</title>\n\t\t<para>You can start <application>&app;</application> in the following ways:\n\t\t</para> \n\t\t<variablelist>\n\t\t\t<varlistentry>\n\t\t\t\t<term><guimenu>Applications</guimenu> menu</term>\n\t\t\t\t<listitem>\n\t\t\t\t\t<para>Choose \n\t\t\t\t\t<menuchoice>\n\t\t\t\t\t\t<guisubmenu>Programming/Development</guisubmenu>\n\t\t\t\t\t\t<guimenuitem>Bless Hex Editor</guimenuitem>\n\t\t\t\t\t</menuchoice>.\n\t\t\t\t\t</para>\n\t\t\t\t</listitem>\n\t\t\t</varlistentry>\n\t\t\t<varlistentry>\n\t\t\t\t<term>Command line</term>\n\t\t\t\t<listitem>\n\t\t\t\t\t<para>To start &app; from a command line, type the following command, \n\t\t\t\t\t\tthen press <keycap>Return</keycap>:\n\t\t\t\t\t</para>\n\t\t\t\t\t<para> \n\t\t\t\t\t\t<command>bless</command> \n\t\t\t\t\t\t<replaceable>filenames</replaceable>\n\t\t\t\t\t</para> \n\t\t\t\t\t<para>where \n\t\t\t\t\t\t<replaceable>filenames</replaceable> are the names of the files you\n\t\t\t\t\t\twant to open. If you don't specify any files, &app; will\n\t\t\t\t\t\ttry to load the previous session. If that fails &app; will open an empty file for you.\n\t\t\t\t\t</para>  \n\t\t\t\t</listitem>\n\t\t\t</varlistentry>\n\t\t</variablelist>\n\t</section>\n\n\t<section id=\"bless-when-start\">\n\t\t<title>When You Start &app;</title>\n\t\t<para>When you start <application>&app;</application>, the following window is displayed.</para>\n\n\t\t<!-- ==== Figure ==== -->\n\t\t<figure id=\"bless-mainwindow\"> \n\t\t\t<title>&app; Start Up Window</title> \n\t\t\t<screenshot> \n\t\t\t\t<mediaobject> \n\t\t\t\t\t<imageobject>\n\t\t\t\t\t\t<imagedata fileref=\"figures/bless_start_window.png\" format=\"PNG\"/> \n\t\t\t\t\t</imageobject>\n\t\t\t\t\t<textobject> \n\t\t\t\t\t\t<phrase>Shows &app; main window. Contains titlebar, menubar, toolbar, display area, and\n\t\t\t\t\t\tscrollbars. Menubar contains File, View, Settings, and Help menus. </phrase> \n\t\t\t\t\t</textobject> \n\t\t\t\t</mediaobject> \n\t\t\t</screenshot> \n\t\t</figure>\n\t\t<!-- ==== End of Figure ==== -->\n\n\t\t<!-- Include any descriptions of the GUI immediately after the screenshot of the main UI, -->\n\t\t<!-- for example, the items on the menubar and on the toolbar. This section is optional. -->\n\n\t\t<para>The &app; window contains the following elements:\n\t\t</para>\n\t\t<variablelist>\n\t\t\t<varlistentry>\n\t\t\t\t<term>Menubar</term>\n\t\t\t\t<listitem>\n\t\t\t\t\t<para>The menus on the menubar contain all of the commands you need to work with files in \n\t\t\t\t\t&app;.</para>\n\t\t\t\t</listitem>\n\t\t\t</varlistentry>\n\t\t\t<varlistentry>\n\t\t\t\t<term>Toolbar</term>\n\t\t\t\t<listitem>\n\t\t\t\t\t<para>Provides shortcuts to the commands that are most frequently used when working with files\n\t\t\t\t\tin &app;.</para>\n\t\t\t\t</listitem>\n\t\t\t</varlistentry>\n\t\t\t<varlistentry>\n\t\t\t\t<term>Data View</term>\n\t\t\t\t<listitem>\n\t\t\t\t\t<para>The data view contains multiple tabs that display the data of the files you are editing.</para>\n\t\t\t\t</listitem>\n\t\t\t</varlistentry>\n\t\t\t<varlistentry>\n\t\t\t\t<term>Conversion Table</term>\n\t\t\t\t<listitem>\n\t\t\t\t\t<para>The conversion table displays the bytes at the current file position converted to various formats.</para>\n\t\t\t\t</listitem>\n\t\t\t</varlistentry>\n\t\t\t<varlistentry>\n\t\t\t\t<term>Statusbar</term>\n\t\t\t\t<listitem>\n\t\t\t\t\t<para>The statusbar displays information about current &app; \n\t\t\t\t\tactivity and information about the current file. </para>\n\t\t\t\t</listitem>\n\t\t\t</varlistentry>\n\t\t</variablelist>\n\t</section>\n</chapter>\n<!-- ================ Usage ================================ -->\n<!-- Use this section to describe how to use the application to perform the tasks for \n\twhich the application is designed. -->\n\n\n<chapter id=\"bless-usage\">\n\t<title>Using &app;</title>\n\t<section id=\"bless-usage-files\">\n\t\t<title>Working with files</title>\n\t\t<para>\n\t\t\t&app; supports multiple tabs in the Data View. Each tab contains data that belong to either an existing or a new file.\n\t\t\tIn case the data is related to an existing file, the file's name is displayed on the tab label. Otherwise the tab is marked\t\n\t\t\twith a name of the form \"Untitled <replaceable>N</replaceable>\", where <replaceable>N</replaceable> is a number.\n\t\t</para>\n\t\t<para>\n\t\t\tWhen a file has been modified since its last save, an asterisk \"*\" is displayed next to its name.\n\t\t</para>\n\t\t<note>\n\t\t\t<para>\n\t\t\t\t&app; can currently handle regular files and block device files (eg /dev/hda).\n\t\t\t</para>\n\t\t</note>\n\t\t\n\t\t<section id=\"bless-usage-files-create\">\n\t\t\t<title>Creating a new file</title>\n\t\t\t<para>\n\t\t\t\tTo create a new file for editing use \n\t\t\t\t<menuchoice>\n\t\t\t\t\t<shortcut>\n\t\t\t\t\t\t<keycombo>\n\t\t\t\t\t\t\t<keycap>Ctrl</keycap>\n\t\t\t\t\t\t\t<keycap>N</keycap>\n\t\t\t\t\t\t</keycombo>\n\t\t\t\t\t</shortcut>\n\t\t\t\t\t<guisubmenu>File</guisubmenu>\n\t\t\t\t\t<guimenuitem>New</guimenuitem>\n\t\t\t\t</menuchoice>.\n\t\t\t</para>\n\t\t\t<para>\n\t\t\t\tThis action creates a new tab with an empty file.\n\t\t\t</para>\n\t\t</section>\n\t\t\n\t\t<section id=\"bless-usage-files-open\">\n\t\t\t<title>Opening an existing file</title>\n\t\t\t<para>\n\t\t\t\tTo open an existing file for editing use \n\t\t\t\t<menuchoice>\n\t\t\t\t\t<shortcut>\n\t\t\t\t\t\t<keycombo>\n\t\t\t\t\t\t\t<keycap>Ctrl</keycap>\n\t\t\t\t\t\t\t<keycap>O</keycap>\n\t\t\t\t\t\t</keycombo>\n\t\t\t\t\t</shortcut>\n\t\t\t\t\t<guisubmenu>File</guisubmenu>\n\t\t\t\t\t<guimenuitem>Open</guimenuitem>\n\t\t\t\t</menuchoice>.\n\t\t\t</para>\n\t\t\t<para>\n\t\t\t\tYou may also open one or more existing files by dragging and dropping them into the &app; window.\n\t\t\t</para>\n\t\t\t<para>\t\n\t\t\t\tThis action normally creates a new tab containing the opened file. An exception to this happens when the tab that \n\t\t\t\twas active before opening the new file contained an empty file. In that case the old tab is <emphasis>replaced</emphasis> \n\t\t\t\twith the new one.\n\t\t\t</para>\n\t\t</section>\n\t\t\n\t\t<section id=\"bless-usage-files-save\">\n\t\t\t<title>Saving a file</title>\n\t\t\t<itemizedlist>\n\t\t\t<listitem>\n\t\t\t<para>\n\t\t\t\tTo save a file make sure the tab that contains it is active and use \n\t\t\t\t<menuchoice>\n\t\t\t\t\t<shortcut>\n\t\t\t\t\t\t<keycombo>\n\t\t\t\t\t\t\t<keycap>Ctrl</keycap>\n\t\t\t\t\t\t\t<keycap>S</keycap>\n\t\t\t\t\t\t</keycombo>\n\t\t\t\t\t</shortcut>\n\t\t\t\t\t<guisubmenu>File</guisubmenu>\n\t\t\t\t\t<guimenuitem>Save</guimenuitem>\n\t\t\t\t</menuchoice>.\n\t\t\t</para>\n\t\t\t</listitem>\n\t\t\t<listitem>\n\t\t\t<para>\n\t\t\t\tTo save a file <emphasis>under a different name or at another location</emphasis>, make sure the tab that contains it is active and use \n\t\t\t\t<menuchoice>\n\t\t\t\t\t<shortcut>\n\t\t\t\t\t\t<keycombo>\n\t\t\t\t\t\t\t<keycap>Shift</keycap>\n\t\t\t\t\t\t\t<keycap>Ctrl</keycap>\n\t\t\t\t\t\t\t<keycap>S</keycap>\n\t\t\t\t\t\t</keycombo>\n\t\t\t\t\t</shortcut>\n\t\t\t\t\t<guisubmenu>File</guisubmenu>\n\t\t\t\t\t<guimenuitem>Save As</guimenuitem>\n\t\t\t\t</menuchoice>.\n\t\t\t</para>\n\t\t\t</listitem>\n\t\t\t</itemizedlist>\n\t\t\t<note>\n\t\t\t<para>\t\n\t\t\t\tIf the data in a tab isn't related to an existing file (for example if it is a new file), the Save action actually performs a Save As action.   \n\t\t\t</para>\n\t\t\t</note>\n\t\t</section>\n\t\t\n\t\t<section id=\"bless-usage-files-close\">\n\t\t\t<title>Closing a file</title>\n\t\t\t<para>\n\t\t\t\tTo close a file, make sure the tab that contains it is active and use \n\t\t\t\t<menuchoice>\n\t\t\t\t\t<shortcut>\n\t\t\t\t\t\t<keycombo>\n\t\t\t\t\t\t\t<keycap>Ctrl</keycap>\n\t\t\t\t\t\t\t<keycap>W</keycap>\n\t\t\t\t\t\t</keycombo>\n\t\t\t\t\t</shortcut>\t\n\t\t\t\t\t<guisubmenu>File</guisubmenu>\n\t\t\t\t\t<guimenuitem>Close</guimenuitem>\n\t\t\t\t</menuchoice>.\n\t\t\t</para>\n\t\t\t<para>\n\t\t\t\tYou can also close a file by clicking on the close icon on its tab label:\n\t\t\t</para>\n\t\t\t\t<!-- ==== Figure ==== -->\n\t\t\t\t<figure id=\"bless_tab_close\"> \n\t\t\t\t\t<title>Closing a tab</title> \n\t\t\t\t\t<screenshot> \n\t\t\t\t\t\t<mediaobject> \n\t\t\t\t\t\t\t<imageobject>\n\t\t\t\t\t\t\t\t<imagedata fileref=\"figures/bless_tab_close.png\" format=\"PNG\"/> \n\t\t\t\t\t\t\t</imageobject>\n\t\t\t\t\t\t\t<textobject> \n\t\t\t\t\t\t\t\t<phrase>Shows how to close a tab using the close icon on its tab label</phrase> \n\t\t\t\t\t\t\t</textobject> \n\t\t\t\t\t\t</mediaobject> \n\t\t\t\t\t</screenshot> \n\t\t\t\t</figure>\n\t\t\t\t<!-- ==== End of Figure ==== -->\n\t\t\t<note><para>\t\n\t\t\t\tIf the file has changed since the previous save you will be prompted to save it.\n\t\t\t</para></note>\n\t\t</section>\n\t\t\n\t\t<section id=\"bless-usage-files-switch-tabs\">\n\t\t\t<title>Changing the active file</title>\n\t\t\t<para>\n\t\t\t\tYou can switch between tabs, therefore making the file the tab contains the active one, using a number of ways:\n\t\t\t\t<itemizedlist>\n\t\t\t\t\t<listitem>\n\t\t\t\t\t\t<para>By clicking on the tab label of the tab you want to switch to.</para>\n\t\t\t\t\t</listitem>\n\t\t\t\t\t<listitem>\n\t\t\t\t\t\t<para>By pressing <keycombo><keycap>Alt</keycap><replaceable>N</replaceable></keycombo>, where <replaceable>N</replaceable> is the number of the tab you want to switch to. This method works for the first nine tabs. For example to switch to the second\n\t\t\t\t\t\ttab you should press Alt+2.</para>\n\t\t\t\t\t</listitem>\n\t\t\t\t\t<listitem>\n\t\t\t\t\t\t<para>\n\t\t\t\t\t\t\tBy pressing <keycombo><keycap>Alt</keycap><keycap>Left arrow</keycap></keycombo> or <keycombo><keycap>Alt</keycap><keycap>Right arrow</keycap></keycombo>, you can switch to the tab immediately to the left or right of the currently active tab.\n\t\t\t\t\t\t</para>\n\t\t\t\t\t</listitem>\n\t\t\t\t</itemizedlist>\n\t\t\t</para>\n\t\t</section>\n\t\n\t</section>\n\t\n\t<section id=\"bless-usage-dataview\">\n\t\t<title>Data View basics</title>\n\t\t<para>\n\t\t\tThe Data View is the part of &app; that displays the data of the files you are editing and enables you to manipulate them. It consists of (possibly) many tabs,\n\t\t\teach corresponding to a file you are editing. Each tab contains areas that display the file's data in various formats. An area can be one of the following types:\n\t\t</para>\n\t\t<itemizedlist>\n\t\t\t<listitem>\n\t\t\t\t<para>Offset Area: Displays the offset of the first byte at the specified row.</para>\n\t\t\t</listitem>\n\t\t\t<listitem>\n\t\t\t\t<para>Separator Area: Displays a vertical separator line.</para>\n\t\t\t</listitem>\n\t\t\t<listitem>\n\t\t\t\t<para>Hexadecimal Area: Displays the data in hexadecimal number base.</para>\n\t\t\t</listitem>\n\t\t\t<listitem>\n\t\t\t\t<para>Decimal Area: Displays the data in decimal number base.</para>\n\t\t\t</listitem>\n\t\t\t<listitem>\n\t\t\t\t<para>Octal Area: Displays the data in octal number base.</para>\n\t\t\t</listitem>\n\t\t\t<listitem>\n\t\t\t\t<para>Binary Area: Displays the data in binary number base.</para>\n\t\t\t</listitem>\n\t\t\t<listitem>\n\t\t\t\t<para>Ascii Area: Displays the data as Ascii text.</para>\n\t\t\t</listitem>\n\t\t</itemizedlist>\n\t\t<para>\n\t\t\tThe types and placement of the areas that each tab contains can be customized with layout files.\n\t\t\tSee <xref linkend=\"bless-customizing-layouts\"/> for more information on how to write and use layout files. \n\t\t</para>\n\t\t\n\t\t<section  id=\"bless-usage-dataview-focus\">\n\t\t\t<title>Selecting the active area</title>\n\t\t\t<para>\n\t\t\t\tAt any time only one of the areas accepts and handles editing events. This area is said to have the focus.\n\t\t\t\tAll areas except Offset and Separator may have the focus.\n\t\t\t</para>\n\t\t\t<!-- ==== Figure ==== -->\n\t\t\t<figure id=\"bless-area-focus\"> \n\t\t\t\t<title>Cursor in focused and not focused areas</title> \n\t\t\t\t<screenshot> \n\t\t\t\t\t<mediaobject> \n\t\t\t\t\t\t<imageobject>\n\t\t\t\t\t\t\t<imagedata fileref=\"figures/bless_area_focus.png\" format=\"PNG\"/> \n\t\t\t\t\t\t</imageobject>\n\t\t\t\t\t\t<textobject> \n\t\t\t\t\t\t\t<phrase>Shows the difference in the cursor when an areas has the focus or not.</phrase> \n\t\t\t\t\t\t</textobject> \n\t\t\t\t\t</mediaobject> \n\t\t\t\t</screenshot> \n\t\t\t</figure>\n\t\t\t<!-- ==== End of Figure ==== -->\n\t\t\t<para>\n\t\t\t\tThe cursor in the focused area consists of a horizontal line under the current byte and a vertical line just before the active digit of the current byte. \n\t\t\t\tIn contrast, the cursor in a non-focused area consists of only the horizontal line beneath the current byte. \n\t\t\t</para>\n\t\t\t<para>\t\n\t\t\t\tChanging the area that has the focus can be done in two ways:\n\t\t\t\t<itemizedlist>\n\t\t\t\t\t<listitem>\n\t\t\t\t\t\t<para>\n\t\t\t\t\t\t\tUsing the <keycap>TAB</keycap> key cycles the focus among the available areas.\n\t\t\t\t\t\t</para>\n\t\t\t\t\t</listitem>\n\t\t\t\t\t<listitem>\n\t\t\t\t\t\t<para>\n\t\t\t\t\t\t\tPressing or releasing the left mouse button in an area, or moving with the left mouse button pressed into an area, gives the focus to that area. If the area\n\t\t\t\t\t\t\tcan't accept the focus (eg it is a Separator area), the focus remains unchanged. \n\t\t\t\t\t\t</para>\n\t\t\t\t\t</listitem>\n\t\t\t\t</itemizedlist>\n\t\t\t</para>\n\t\t</section>\n\t\t<section  id=\"bless-usage-dataview-scroll\">\n\t\t\t<title>Scrolling</title>\n\t\t\t<para>\n\t\t\t\tIf the file you are editing is big enough, only a small range of its data will be visible in the Data View. The size of the visible data is called a <emphasis>page</emphasis>\n\t\t\t\tand changes as the &app; window is resized.\n\t\t\t</para>\n\t\t\t<para>\n\t\t\t\tTo change the visible range of a file's data you should <emphasis>scroll</emphasis> the Data View. You can scroll the Data View in two ways:\n\t\t\t\t<itemizedlist>\n\t\t\t\t\t<listitem>\n\t\t\t\t\t\t<para>\n\t\t\t\t\t\t\tUsing the scrollbar that is located at the right side of the Data View. The scrollbar is visible only if the file is too large to fit in one page.\n\t\t\t\t\t\t</para>\n\t\t\t\t\t</listitem>\n\t\t\t\t\t<listitem>\n\t\t\t\t\t\t<para>\n\t\t\t\t\t\t\tUsing the wheel on your mouse, if it has one. \n\t\t\t\t\t\t</para>\n\t\t\t\t\t</listitem>\n\t\t\t\t</itemizedlist>\n\t\t\t</para>\n\t\t\t<note>\n\t\t\t\t<para>\n\t\t\t\t\tScrolling the Data View does <emphasis>not</emphasis> change the cursor position.\n\t\t\t\t</para>\n\t\t\t</note>\n\t\t</section>\n\t</section>\n\t\n\t\n\t\n\t<section id=\"bless-usage-edit\">\n\t\t<title>Editing a file</title>\n\t\t<section id=\"bless-usage-edit-basic\">\n\t\t\t<title>Basic editing operations</title>\n\t\t\t\n\t\t\t<section id=\"bless-usage-edit-basic-cursor\">\n\t\t\t\t<title>Changing the current cursor position</title>\n\t\t\t\t<para>\n\t\t\t\t\tYou can move the cursor in two ways:\n\t\t\t\t</para>\n\t\t\t\t<variablelist>\n\t\t\t\t\t<varlistentry>\n\t\t\t\t\t\t<term>Using the keyboard</term>\n\t\t\t\t\t\t<listitem>\n\t\t\t\t\t\t\t<itemizedlist>\n\t\t\t\t\t\t\t\t<listitem>Pressing the <keycap>Up Arrow</keycap> key moves the cursor to the byte just above the current one.</listitem>\n\t\t\t\t\t\t\t\t<listitem>Pressing the <keycap>Down Arrow</keycap> key moves the cursor to the byte just below the current one.</listitem>\n\t\t\t\t\t\t\t\t<listitem>Pressing the <keycap>Left Arrow</keycap> key moves the cursor to the previous digit of the current byte. If the cursor was at the first digit\n\t\t\t\t\t\t\t\tof a byte, it is moved to the last digit of the previous byte.</listitem>\n\t\t\t\t\t\t\t\t<listitem>Pressing the <keycap>Right Arrow</keycap> key moves the cursor to the next digit of the current byte. If the cursor was at the last digit\n\t\t\t\t\t\t\t\tof a byte, it is moved to the first digit of next byte.</listitem>\n\t\t\t\t\t\t\t\t<listitem>Pressing the <keycap>Page Up</keycap> key moves the cursor to the byte which is one page before the current position.</listitem>\n\t\t\t\t\t\t\t\t<listitem>Pressing the <keycap>Page Down</keycap> key moves the cursor to the byte which is one page after the current position.</listitem>\n\t\t\t\t\t\t\t\t<listitem>Pressing the <keycap>Home</keycap> key moves the cursor to the first byte in the file.</listitem>\n\t\t\t\t\t\t\t\t<listitem>Pressing the <keycap>End</keycap> key moves the cursor one byte after the last byte in the file.</listitem>\n\t\t\t\t\t\t\t</itemizedlist>\n\t\t\t\t\t\t</listitem>\n\t\t\t\t\t</varlistentry>\n\t\t\t\t\t<varlistentry>\n\t\t\t\t\t\t<term>Using the mouse</term>\n\t\t\t\t\t\t<listitem>Clicking on a digit of a byte moves the cursor to that byte and digit.</listitem>\n\t\t\t\t\t</varlistentry>\n\t\t\t\t</variablelist>\n\t\t\t\t<note>\n\t\t\t\t\t<para>\n\t\t\t\t\t\tIf the new cursor position is outside the currently visible page of data, the view scrolls automatically so that the new cursor position is made visible.\t\n\t\t\t\t\t</para>\n\t\t\t\t</note>\n\t\t\t</section>\n\t\t\t\n\t\t\t<section id=\"bless-usage-edit-basic-goto\">\n\t\t\t\t<title>Moving the cursor to a specific position</title>\n\t\t\t\t<para>\n\t\t\t\t\tTo access the Go to Offset Bar use:\n\t\t\t\t\t<menuchoice>\n\t\t\t\t\t\t<shortcut>\n\t\t\t\t\t\t\t<keycombo>\n\t\t\t\t\t\t\t\t<keycap>Ctrl</keycap>\n\t\t\t\t\t\t\t\t<keycap>G</keycap>\n\t\t\t\t\t\t\t</keycombo>\n\t\t\t\t\t\t</shortcut>\t\n\t\t\t\t\t\t<guisubmenu>Search</guisubmenu>\n\t\t\t\t\t\t<guimenuitem>Go to Offset</guimenuitem>\n\t\t\t\t\t</menuchoice>. \n\t\t\t\t</para>\n\t\t\t\t<figure>\n\t\t\t\t\t<title>Go to Offset Bar</title>\n\t\t\t\t\t<screenshot>\n\t\t\t\t\t\t<mediaobject>\n\t\t\t\t\t\t\t<imageobject>\n\t\t\t\t\t\t\t\t<imagedata fileref=\"figures/bless_goto.png\" format=\"PNG\"/>\n\t\t\t\t\t\t\t</imageobject>\n\t\t\t\t\t\t\t<textobject>\n\t\t\t\t\t\t\t\t<phrase>Go to Offset Bar</phrase>\n\t\t\t\t\t\t\t</textobject>\n\t\t\t\t\t\t</mediaobject>\n\t\t\t\t\t</screenshot>\n\t\t\t\t</figure>\n\t\t\t\t<para>\n\t\t\t\t\tTo move the cursor to a specific position in the file:\n\t\t\t\t\t<orderedlist>\n\t\t\t\t\t\t<listitem>\n\t\t\t\t\t\t\t<para>\n\t\t\t\t\t\t\t\tType the offset in the <guilabel>Offset</guilabel> text entry (in the desired number format).\n\t\t\t\t\t\t\t\tif the typed offset starts with '0x' it is considered hexadecimal, if it starts with '0' it is \n\t\t\t\t\t\t\t\tconsidered octal, otherwise it is considered decimal.\n\t\t\t\t\t\t\t</para>\n\t\t\t\t\t\t</listitem>\n\t\t\t\t\t\t<listitem>\n\t\t\t\t\t\t\t<para>Press the <guibutton>Go to Offset</guibutton> button</para>\n\t\t\t\t\t\t</listitem>\n\t\t\t\t\t</orderedlist>\n\t\t\t\t</para>\n\t\t\t</section>\n\t\t\t\n\t\t\t<section id=\"bless-usage-edit-basic-select\">\n\t\t\t\t<title>Selecting a range of data</title>\n\t\t\t\t<para>\n\t\t\t\t\tThere are three ways to select a range of data from the file you are editing:\n\t\t\t\t<variablelist>\n\t\t\t\t\t<varlistentry>\n\t\t\t\t\t\t<term>Using the keyboard</term>\n\t\t\t\t\t\t<listitem>\n\t\t\t\t\t\t\t<itemizedlist>\n\t\t\t\t\t\t\t\t<listitem>Position the cursor at one end of the range you want to select.</listitem>\n\t\t\t\t\t\t\t\t<listitem>\n\t\t\t\t\t\t\t\t\tHold down the <keycap>Shift</keycap> key and move the cursor\n\t\t\t\t\t\t\t\t\tto the other end of the range using the keyboard. As you move the cursor, the currently selected data range will be highlighted.\n\t\t\t\t\t\t\t\t</listitem> \n\t\t\t\t\t\t\t\t<listitem>Release the <keycap>Shift</keycap> key.</listitem>\n\t\t\t\t\t\t\t</itemizedlist>\n\t\t\t\t\t\t</listitem>\n\t\t\t\t\t</varlistentry>\n\t\t\t\t\t<varlistentry>\n\t\t\t\t\t\t<term>Using the mouse</term>\n\t\t\t\t\t\t<listitem>\n\t\t\t\t\t\t\t<itemizedlist>\n\t\t\t\t\t\t\t\t<listitem>Position the cursor at one end of the range you want to select.</listitem>\n\t\t\t\t\t\t\t\t<listitem>\n\t\t\t\t\t\t\t\t\tHold down the Left mouse button and move the cursor to the other end of the range using the mouse. \n\t\t\t\t\t\t\t\t\tAs you move the cursor, the currently selected data range will be highlighted.\n\t\t\t\t\t\t\t\t</listitem>\n\t\t\t\t\t\t\t\t<listitem>Release the Left mouse button.</listitem>\n\t\t\t\t\t\t\t\t<listitem>\n\t\t\t\t\t\t\t\t\t...alternatively, while pressing the <keycap>Shift</keycap> key, position the mouse pointer over \n\t\t\t\t\t\t\t\t\tthe other end of the selection and click using the Left mouse button.\n\t\t\t\t\t\t\t\t</listitem>\n\t\t\t\t\t\t\t</itemizedlist>\n\t\t\t\t\t\t</listitem>\n\t\t\t\t\t</varlistentry>\n\t\t\t\t\t<varlistentry>\n\t\t\t\t\t\t<term>Using the Select Range Bar</term>\n\t\t\t\t\t\t<listitem>\n\t\t\t\t\t\t\t<para>\n\t\t\t\t\t\t\t\tTo access the Select Range Bar use:\n\t\t\t\t\t\t\t\t<menuchoice>\n\t\t\t\t\t\t\t\t\t<shortcut>\n\t\t\t\t\t\t\t\t\t\t<keycombo>\n\t\t\t\t\t\t\t\t\t\t\t<keycap>Ctrl</keycap>\n\t\t\t\t\t\t\t\t\t\t\t<keycap>Shift</keycap>\n\t\t\t\t\t\t\t\t\t\t\t<keycap>R</keycap>\n\t\t\t\t\t\t\t\t\t\t</keycombo>\n\t\t\t\t\t\t\t\t\t</shortcut>\t\n\t\t\t\t\t\t\t\t\t<guisubmenu>Edit</guisubmenu>\n\t\t\t\t\t\t\t\t\t<guimenuitem>Select Range</guimenuitem>\n\t\t\t\t\t\t\t\t</menuchoice>. \n\t\t\t\t\t\t\t</para>\n\t\t\t\t\t\t\t<figure>\n\t\t\t\t\t\t\t\t<title>Select Range Bar</title>\n\t\t\t\t\t\t\t\t<screenshot>\n\t\t\t\t\t\t\t\t\t<mediaobject>\n\t\t\t\t\t\t\t\t\t\t<imageobject>\n\t\t\t\t\t\t\t\t\t\t\t<imagedata fileref=\"figures/bless_select_range.png\" format=\"PNG\"/>\n\t\t\t\t\t\t\t\t\t\t</imageobject>\n\t\t\t\t\t\t\t\t\t\t<textobject>\n\t\t\t\t\t\t\t\t\t\t\t<phrase>Select Range Bar</phrase>\n\t\t\t\t\t\t\t\t\t\t</textobject>\n\t\t\t\t\t\t\t\t\t</mediaobject>\n\t\t\t\t\t\t\t\t</screenshot>\n\t\t\t\t\t\t\t</figure>\n\t\t\t\t\t\t\t<para>\n\t\t\t\t\t\t\t\tTo select a range:\n\t\t\t\t\t\t\t\t<orderedlist>\n\t\t\t\t\t\t\t\t\t<listitem>\n\t\t\t\t\t\t\t\t\t\t<para>\n\t\t\t\t\t\t\t\t\t\t\tType the starting offset in the <guilabel>from</guilabel> text entry (in the desired number format).\n\t\t\t\t\t\t\t\t\t\t\tif the typed offset starts with '0x' it is considered hexadecimal, if it starts with '0' it is \n\t\t\t\t\t\t\t\t\t\t\tconsidered octal, otherwise it is considered decimal.\n\t\t\t\t\t\t\t\t\t\t</para>\n\t\t\t\t\t\t\t\t\t</listitem>\n\t\t\t\t\t\t\t\t\t<listitem>\n\t\t\t\t\t\t\t\t\t\t<para>Type the ending offset in the <guilabel>to</guilabel> text entry (in the desired number format).\n\t\t\t\t\t\t\t\t\t\t\tif the typed offset starts with '0x' it is considered hexadecimal, if it starts with '0' it is \n\t\t\t\t\t\t\t\t\t\t\tconsidered octal, otherwise it is considered decimal.</para>\n\t\t\t\t\t\t\t\t\t\t<para>\n\t\t\t\t\t\t\t\t\t\t\tInstead of specifying an absolute ending offset you can specify the length of the selection. To do\n\t\t\t\t\t\t\t\t\t\t\tthis type the length in the <guilabel>to</guilabel> text entry, prepending it with either '+' or '-'.\n\t\t\t\t\t\t\t\t\t\t\tThe '+' or '-' specify the direction of the selection: '+' means select towards the end of the file and\n\t\t\t\t\t\t\t\t\t\t\t'-' means select towards the beginning. The selected range always contains the starting offset. \n\t\t\t\t\t\t\t\t\t\t</para>\t\t\n\t\t\t\t\t\t\t\t\t</listitem>\n\t\t\t\t\t\t\t\t</orderedlist>\n\t\t\t\t\t\t\t</para>\n\t\t\t\t\t\t</listitem>\n\t\t\t\t\t</varlistentry>\n\t\t\t\t</variablelist>\n\t\t\t\t</para>\n\t\t\t\t<para>\n\t\t\t\t\tSelecting a range of data has another useful effect: all the patterns matching the selected\n\t\t\t\t\tdata in the file are highlighted, thus providing a quick way to find or emphasize patterns.\n\t\t\t\t\tThe color of the highlighting can be changed using Layout files (see <xref linkend=\"bless-customizing-layouts\"/>).\n\t\t\t\t\tThis feature can be turned off in the Preferences Dialog (see <xref linkend=\"bless-customizing-preferences-general\"/>).\n\t\t\t\t</para>\n\t\t\t\t<note>\n\t\t\t\t\t<para>\n\t\t\t\t\t\tThe patterns matching the selected data are highlighted only if the selected data size is at most 1024 bytes.\n\t\t\t\t\t</para>\n\t\t\t\t</note>\n\t\t\t</section>\n\t\t\t\n\t\t\t<section id=\"bless-usage-edit-basic-overwrite-mode\">\n\t\t\t\t<title>Toggling Overwrite/Insert edit mode</title>\n\t\t\t\t<para>\n\t\t\t\t\tBy pressing the <keycap>Insert</keycap> key on the keyboard or by clicking on the edit mode statusbar, you can change the edit mode &app; is currently in. The edit mode\n\t\t\t\t\tdetermines what happens when you add new data to the file. There are two available modes:\n\t\t\t\t\t<variablelist>\n\t\t\t\t\t\t<varlistentry>\n\t\t\t\t\t\t\t<term>Insert Mode</term>\n\t\t\t\t\t\t\t<listitem>The new data is inserted at the current cursor position. &app; automatically makes space for the new data.</listitem>\n\t\t\t\t\t\t</varlistentry>\n\t\t\t\t\t\t<varlistentry>\n\t\t\t\t\t\t\t<term>Overwrite Mode</term>\n\t\t\t\t\t\t\t<listitem>The new data overwrites the old data, starting from the current cursor position.</listitem>\n\t\t\t\t\t\t</varlistentry> \n\t\t\t\t\t</variablelist>\n\t\t\t\t</para>\n\t\t\t\t<!-- ==== Figure ==== -->\n\t\t\t\t<figure id=\"bless-edit-mode\"> \n\t\t\t\t\t<title>Edit mode statusbar display</title> \n\t\t\t\t\t<screenshot> \n\t\t\t\t\t\t<mediaobject> \n\t\t\t\t\t\t\t<imageobject>\n\t\t\t\t\t\t\t\t<imagedata fileref=\"figures/bless_edit_mode.png\" format=\"PNG\"/> \n\t\t\t\t\t\t\t</imageobject>\n\t\t\t\t\t\t\t<textobject> \n\t\t\t\t\t\t\t\t<phrase>Shows the edit mode display in the statusbar</phrase> \n\t\t\t\t\t\t\t</textobject> \n\t\t\t\t\t\t</mediaobject> \n\t\t\t\t\t</screenshot> \n\t\t\t\t</figure>\n\t\t\t<!-- ==== End of Figure ==== -->\n\t\t\t\t<para>\n\t\t\t\t\tThe current edit mode is displayed at the far right in the statusbar.\n\t\t\t\t</para>\n\t\t\t</section>\n\t\t\t\n\t\t\t<section id=\"bless-usage-edit-basic-number-base\">\n\t\t\t\t<title>Changing the statusbar number base</title>\n\t\t\t\t<para>\n\t\t\t\t\tYou can change the number base of the information displayed in the statusbar (current offset, current selection).\n\t\t\t\t\tClicking on the Offset or Selection information in the statusbar cycles among Hexadecimal, Decimal and Octal number bases.\n\t\t\t\t\tYou can distinguish the current number base by checking the prefix of displayed numbers. A \"0x\" prefix denotes Hexadecimal,\n\t\t\t\t\ta \"0\" prefix denotes Octal and no prefix denotes Decimal.  \n\t\t\t\t</para>\n\t\t\t\t<!-- ==== Figure ==== -->\n\t\t\t\t<figure id=\"bless-number-base\"> \n\t\t\t\t\t<title>Statusbar number base</title> \n\t\t\t\t\t<screenshot> \n\t\t\t\t\t\t<mediaobject> \n\t\t\t\t\t\t\t<imageobject>\n\t\t\t\t\t\t\t\t<imagedata fileref=\"figures/bless_number_base.png\" format=\"PNG\"/> \n\t\t\t\t\t\t\t</imageobject>\n\t\t\t\t\t\t\t<textobject> \n\t\t\t\t\t\t\t\t<phrase>Shows statusbar information in several number bases</phrase> \n\t\t\t\t\t\t\t</textobject> \n\t\t\t\t\t\t</mediaobject> \n\t\t\t\t\t</screenshot> \n\t\t\t\t</figure>\n\t\t\t<!-- ==== End of Figure ==== -->\n\t\t\t</section>\n\t\t\t\n\t\t\t<section id=\"bless-usage-edit-basic-modify\">\n\t\t\t\t<title>Modifying the data</title>\n\t\t\t\t<para>\n\t\t\t\t\tYou can directly modify the data in a file by using the keyboard:\n\t\t\t\t</para>\n\t\t\t\t<variablelist>\n\t\t\t\t\t<varlistentry>\n\t\t\t\t\t\t<term>Inserting a new byte at a specific position</term>\n\t\t\t\t\t\t<listitem>\n\t\t\t\t\t\t\t<itemizedlist>\n\t\t\t\t\t\t\t\t<listitem>Make sure you are in Insert Mode.</listitem>\n\t\t\t\t\t\t\t\t<listitem>Move the cursor to the <emphasis>first digit</emphasis> of desired position.</listitem> \n\t\t\t\t\t\t\t\t<listitem>\n\t\t\t\t\t\t\t\t\tPress the keys which correspond to the digits of the desired byte.\n\t\t\t\t\t\t\t\t\tEach keypress automatically moves the cursor one position to the right.\n\t\t\t\t\t\t\t\t</listitem>\n\t\t\t\t\t\t\t</itemizedlist>\n\t\t\t\t\t\t</listitem>\n\t\t\t\t\t</varlistentry>\n\t\t\t\t\t<varlistentry>\n\t\t\t\t\t\t<term>Modifying an existing byte</term>\n\t\t\t\t\t\t<listitem>\n\t\t\t\t\t\t\t<itemizedlist>\n\t\t\t\t\t\t\t\t<listitem>Make sure you are in Overwrite Mode (only required if you want to modify the first digit of a byte).</listitem>\n\t\t\t\t\t\t\t\t<listitem>Move the cursor to desired byte/digit position.</listitem> \n\t\t\t\t\t\t\t\t<listitem>\n\t\t\t\t\t\t\t\t\tPress the keys which correspond to the digits of the desired byte.\n\t\t\t\t\t\t\t\t\tEach keypress automatically moves the cursor one position to the right.\n\t\t\t\t\t\t\t\t</listitem>\n\t\t\t\t\t\t\t</itemizedlist>\n\t\t\t\t\t\t</listitem>\n\t\t\t\t\t</varlistentry>\n\t\t\t\t\t<varlistentry>\n\t\t\t\t\t\t<term>Appending data to the end of the file</term>\n\t\t\t\t\t\t<listitem>\n\t\t\t\t\t\t\t<itemizedlist>\n\t\t\t\t\t\t\t\t<listitem>Move the cursor to the position just after the last byte in the file.</listitem> \n\t\t\t\t\t\t\t\t<listitem>\n\t\t\t\t\t\t\t\t\tPress the keys which correspond to the digits of the desired byte.\n\t\t\t\t\t\t\t\t\tEach keypress automatically moves the cursor one position to the right.\n\t\t\t\t\t\t\t\t</listitem>\n\t\t\t\t\t\t\t</itemizedlist>\n\t\t\t\t\t\t</listitem>\n\t\t\t\t\t</varlistentry>\n\t\t\t\t</variablelist>\n\t\t\t\t\n\t\t\t\t<note>\n\t\t\t\t\t<para>\n\t\t\t\t\t\tEach area accepts only certain digits (eg the hexadecimal area accepts only 0-9 and A-F). If a key (representing a digit) is pressed in an area that doesn't\n\t\t\t\t\t\taccept it, the keypress is ignored.\n\t\t\t\t\t</para>\n\t\t\t\t</note>\n\t\t\t</section>\n\t\t\t\n\t\t\t\n\t\t</section>\n\t\t\n\t\t<section id=\"bless-usage-edit-clipboard\">\n\t\t\t<title>Clipboard operations</title>\n\t\t\t<para>Bless features an advanced system to handle clipboard operations.</para>\n\t\t\t\n\t\t\t<section id=\"bless-usage-edit-clipboard-cut\">\n\t\t\t\t<title>Copy and Cut operations</title>\n\t\t\t\t<para>To copy the selected data to the clipboard use:\n\t\t\t\t\t<menuchoice>\n\t\t\t\t\t\t<shortcut>\n\t\t\t\t\t\t\t<keycombo>\n\t\t\t\t\t\t\t\t<keycap>Ctrl</keycap>\n\t\t\t\t\t\t\t\t<keycap>C</keycap>\n\t\t\t\t\t\t\t</keycombo>\n\t\t\t\t\t\t</shortcut>\t\n\t\t\t\t\t\t<guisubmenu>Edit</guisubmenu>\n\t\t\t\t\t\t<guimenuitem>Copy</guimenuitem>\n\t\t\t\t\t</menuchoice>.\n\t\t\t\t</para>\n\t\t\t\t\n\t\t\t\t<para>To cut the selected data from the file and copy it to the clipboard use:\n\t\t\t\t\t<menuchoice>\n\t\t\t\t\t\t<shortcut>\n\t\t\t\t\t\t\t<keycombo>\n\t\t\t\t\t\t\t\t<keycap>Ctrl</keycap>\n\t\t\t\t\t\t\t\t<keycap>X</keycap>\n\t\t\t\t\t\t\t</keycombo>\n\t\t\t\t\t\t</shortcut>\t\n\t\t\t\t\t\t<guisubmenu>Edit</guisubmenu>\n\t\t\t\t\t\t<guimenuitem>Cut</guimenuitem>\n\t\t\t\t\t</menuchoice>.\n\t\t\t\t</para>\n\t\t\t\t<para>\n\t\t\t\t\tWhen copying or cutting data, that data becomes available to &app; and other applications as well.\n\t\t\t\t\t&app; can offer its data to other applications in two main formats:\n\t\t\t\t\t<variablelist>\n\t\t\t\t\t\t<varlistentry>\n\t\t\t\t\t\t\t<term>Raw bytes</term>\n\t\t\t\t\t\t\t<listitem>\n\t\t\t\t\t\t\t\t<para>\n\t\t\t\t\t\t\t\t&app; can offer the selected data as raw bytes to applications that can handle it, for example other hex editors.\n\t\t\t\t\t\t\t\tThis is the format &app; uses when interacting with itself (for example when you copy from a tab and paste into another). \n\t\t\t\t\t\t\t\t</para>\n\t\t\t\t\t\t\t</listitem>\n\t\t\t\t\t\t</varlistentry>\n\t\t\t\t\t\t<varlistentry>\n\t\t\t\t\t\t\t<term>UTF-8 string</term>\n\t\t\t\t\t\t\t<listitem>\n\t\t\t\t\t\t\t\t<para>\n\t\t\t\t\t\t\t\t\t&app; can offer a string representation of the selected data in various number bases or UTF-8 text.\n\t\t\t\t\t\t\t\t\tThe number base is determined by the type of the area that has the focus at the end of the selection action for the cut/copied data.\n\t\t\t\t\t\t\t\t\tFor example if that area is hexadecimal, the offered string will contain the hexadecimal string representation \n\t\t\t\t\t\t\t\t\tof the selected data. If the ending area is the text area, the offered string will contain the UTF-8 text represented by\n\t\t\t\t\t\t\t\t\tthe selected data (if possible). \n\t\t\t\t\t\t\t\t</para>\n\t\t\t\t\t\t\t</listitem>\n\t\t\t\t\t\t</varlistentry>\n\t\t\t\t\t</variablelist>\n\t\t\t\t</para>\n\t\t\t\t<para>\n\t\t\t\t\t \n\t\t\t\t</para>\n\t\t\t\t\n\t\t\t</section>\n\t\t\t\n\t\t\t<section id=\"bless-usage-edit-clipboard-paste\">\n\t\t\t\t<title>Paste operation</title>\n\t\t\t\t<para>To paste data from the clipboard to the current cursor position use:\n\t\t\t\t\t<menuchoice>\n\t\t\t\t\t\t<shortcut>\n\t\t\t\t\t\t\t<keycombo>\n\t\t\t\t\t\t\t\t<keycap>Ctrl</keycap>\n\t\t\t\t\t\t\t\t<keycap>V</keycap>\n\t\t\t\t\t\t\t</keycombo>\n\t\t\t\t\t\t</shortcut>\t\n\t\t\t\t\t\t<guisubmenu>Edit</guisubmenu>\n\t\t\t\t\t\t<guimenuitem>Paste</guimenuitem>\n\t\t\t\t\t</menuchoice>.\n\t\t\t\t</para>\n\t\t\t\n\t\t\t\t<para>\n\t\t\t\t\tThe value of the Overwrite/Insert mode, affects the way paste operations function. If the mode is Insert, the pasted data is inserted at\n\t\t\t\t\tthe current cursor position. If the mode is Overwrite, the pasted data overwrites the data from the cursor position and on, as needed.    \n\t\t\t\t</para>\n\t\t\t\t\n\t\t\t\t<para>\n\t\t\t\t\tPasted data can originate from &app; itself or some other application. \n\t\t\t\t\t&app; can accept data in two formats:\n\t\t\t\t\t<variablelist>\n\t\t\t\t\t\t<varlistentry>\n\t\t\t\t\t\t\t<term>Raw bytes</term>\n\t\t\t\t\t\t\t<listitem>\n\t\t\t\t\t\t\t\t<para>\n\t\t\t\t\t\t\t\t\tThis is the format &app; uses when interacting with itself (for example when you copy from a tab and paste into another).\n\t\t\t\t\t\t\t\t\tExternal applications that offer raw bytes are usually other hex editors. \n\t\t\t\t\t\t\t\t</para>\n\t\t\t\t\t\t\t</listitem>\n\t\t\t\t\t\t</varlistentry>\n\t\t\t\t\t\t<varlistentry>\n\t\t\t\t\t\t\t<term>UTF-8 string</term>\n\t\t\t\t\t\t\t<listitem>\n\t\t\t\t\t\t\t\t<para>\n\t\t\t\t\t\t\t\t\t&app; can accept data as a UTF-8 string (for example, from a text editor). It tries to parse the data and convert it to raw bytes \n\t\t\t\t\t\t\t\t\taccording to the type of the area that currently has the focus. For example if the focus is in an octal area, &app; will try to parse \n\t\t\t\t\t\t\t\t\tthe string as a sequence of bytes represented in octal format. If the parse fails, the data will be inserted as UTF-8 text (as if they \n\t\t\t\t\t\t\t\t\thad been pasted into a text area).\n\t\t\t\t\t\t\t\t</para>\n\t\t\t\t\t\t\t</listitem>\n\t\t\t\t\t\t</varlistentry>\n\t\t\t\t\t</variablelist>\n\t\t\t\t</para>\n\t\t\t</section>\n\n\t\t\t<section id=\"bless-usage-edit-clipboard-copy-offsets\">\n\t\t\t\t<title>Copy offset(s) operations</title>\n\t\t\t\t<para>To copy the offset(s) of the current cursor position or the currently selected range use:\n\t\t\t\t\t<menuchoice>\n\t\t\t\t\t\t<shortcut>\n\t\t\t\t\t\t\t<keycombo>\n\t\t\t\t\t\t\t\t<keycap>Ctrl</keycap>\n\t\t\t\t\t\t\t\t<keycap>Shift</keycap>\n\t\t\t\t\t\t\t\t<keycap>C</keycap>\n\t\t\t\t\t\t\t</keycombo>\n\t\t\t\t\t\t</shortcut>\n\t\t\t\t\t\t<guisubmenu>Edit</guisubmenu>\n\t\t\t\t\t\t<guimenuitem>Copy Offset(s)</guimenuitem>\n\t\t\t\t\t</menuchoice>.\n\t\t\t\t\tThis operation is also available in the pop-menu when right-clicking\n\t\t\t\t\tin the Data View.\n\t\t\t\t</para>\n\n\t\t\t\t<para>\n\t\t\t\t\tIf there is an active selection this operation copies the start and\n\t\t\t\t\tend offsets of the selection to the clipboard, separated by a comma.\n\t\t\t\t\tOtherwise, just the offset of the cursor position is copied to the\n\t\t\t\t\tclipboard.\n\t\t\t\t</para>\n\n\t\t\t\t<para>\n\t\t\t\t\tThe number base used for the offsets is determined by a plugin\n\t\t\t\t\tpreference which can be set through the preferences dialog.\n\t\t\t\t\tSee <xref linkend=\"bless-customizing-layouts\"/>.\n\t\t\t\t</para>\n\t\t\t</section>\n\t\t</section>\n\t\t\n\t\t<section id=\"bless-usage-edit-undo\">\n\t\t\t<title>Undo/Redo operations</title>\n\t\t\t<para>To undo previous actions use:\n\t\t\t\t\t<menuchoice>\n\t\t\t\t\t\t<shortcut>\n\t\t\t\t\t\t\t<keycombo>\n\t\t\t\t\t\t\t\t<keycap>Ctrl</keycap>\n\t\t\t\t\t\t\t\t<keycap>Z</keycap>\n\t\t\t\t\t\t\t</keycombo>\n\t\t\t\t\t\t</shortcut>\t\n\t\t\t\t\t\t<guisubmenu>Edit</guisubmenu>\n\t\t\t\t\t\t<guimenuitem>Undo</guimenuitem>\n\t\t\t\t\t</menuchoice>.\n\t\t\t\t</para>\n\t\t\t\t\n\t\t\t\t<para>To redo previously undone actions use:\n\t\t\t\t\t<menuchoice>\n\t\t\t\t\t\t<shortcut>\n\t\t\t\t\t\t\t<keycombo>\n\t\t\t\t\t\t\t\t<keycap>Shift</keycap>\n\t\t\t\t\t\t\t\t<keycap>Ctrl</keycap>\n\t\t\t\t\t\t\t\t<keycap>Z</keycap>\n\t\t\t\t\t\t\t</keycombo>\n\t\t\t\t\t\t</shortcut>\t\n\t\t\t\t\t\t<guisubmenu>Edit</guisubmenu>\n\t\t\t\t\t\t<guimenuitem>Redo</guimenuitem>\n\t\t\t\t\t</menuchoice>.\n\t\t\t\t</para>\n\t\t</section>\n\t\t\n\t</section>\n\t\n\t<section id=\"bless-usage-search\">\n\t\t<title>Searching and Replacing in files</title>\n\t\t<section id=\"bless-usage-search-find\">\n\t\t\t<title>Searching in files</title>\n\t\t\t<para>To access the Search Bar use\n\t\t\t<menuchoice>\n\t\t\t\t<shortcut>\n\t\t\t\t\t<keycombo>\n\t\t\t\t\t\t<keycap>Ctrl</keycap>\n\t\t\t\t\t\t<keycap>F</keycap>\n\t\t\t\t\t</keycombo>\n\t\t\t\t</shortcut>\t\n\t\t\t\t<guisubmenu>Search</guisubmenu>\n\t\t\t\t<guimenuitem>Find</guimenuitem>\n\t\t\t</menuchoice>.\n\t\t\t</para>\n\t\t\t<figure>\n\t\t\t\t<title>Search Bar</title>\n\t\t\t\t<screenshot>\n\t\t\t\t\t<mediaobject>\n\t\t\t\t\t\t<imageobject>\n\t\t\t\t\t\t\t<imagedata fileref=\"figures/bless_search_find.png\" format=\"PNG\"/>\n\t\t\t\t\t\t</imageobject>\n\t\t\t\t\t\t<textobject>\n\t\t\t\t\t\t\t<phrase>Search Bar</phrase>\n\t\t\t\t\t\t</textobject>\n\t\t\t\t\t</mediaobject>\n\t\t\t\t</screenshot>\n\t\t\t</figure>\n\t\t\t<para>\n\t\t\t\tTo search for a sequence of bytes:\n\t\t\t\t<orderedlist>\n\t\t\t\t\t<listitem>\n\t\t\t\t\t\t<para>Type the sequence in the <guilabel>Search for</guilabel> text entry (in the desired format).</para>\n\t\t\t\t\t</listitem>\n\t\t\t\t\t<listitem>\n\t\t\t\t\t\t<para>Select the format of the typed sequence from the <guilabel>Interpret as</guilabel> option menu.</para>\n\t\t\t\t\t</listitem>\n\t\t\t\t\t<listitem>\n\t\t\t\t\t\t<para>\n\t\t\t\t\t\t\tPress the <guibutton>Find Next</guibutton> or <guibutton>Find Previous</guibutton> button. If a match is found \n\t\t\t\t\t\t\tit will be highlighted in the Data View, otherwise an alert informing you that no match was found will be shown.\n\t\t\t\t\t\t</para>\n\t\t\t\t\t</listitem>\n\t\t\t\t</orderedlist>\n\t\t\t</para>\n\t\t\t<para>\n\t\t\t\tTo hide the Search Bar press the <keycap>Escape</keycap> key while the bar has the focus or click on the close button located\n\t\t\t\tat the right side of the bar.\n\t\t\t</para>\n\t\t\t<tip>\n\t\t\t\t<para>\n\t\t\t\t\tYou can use the \n\t\t\t\t\t<menuchoice>\n\t\t\t\t\t\t<shortcut>\n\t\t\t\t\t\t\t<keycombo>\n\t\t\t\t\t\t\t\t<keycap>F3</keycap>\n\t\t\t\t\t\t\t</keycombo>\n\t\t\t\t\t\t</shortcut>\t\n\t\t\t\t\t\t<guisubmenu>Search</guisubmenu>\n\t\t\t\t\t\t<guimenuitem>Find Next</guimenuitem>\n\t\t\t\t\t</menuchoice> and\n\t\t\t\t\t<menuchoice>\n\t\t\t\t\t\t<shortcut>\n\t\t\t\t\t\t\t<keycombo>\n\t\t\t\t\t\t\t\t<keycap>Shift</keycap>\n\t\t\t\t\t\t\t\t<keycap>F3</keycap>\n\t\t\t\t\t\t\t</keycombo>\n\t\t\t\t\t\t</shortcut>\t\n\t\t\t\t\t\t<guisubmenu>Search</guisubmenu>\n\t\t\t\t\t\t<guimenuitem>Find Previous</guimenuitem>\n\t\t\t\t\t</menuchoice> \n\t\t\t\t\tcommands to search without re-opening the Search Bar.\n\t\t\t\t</para>\n\t\t\t</tip>\n\t\t</section>\n\t\t<section id=\"bless-usage-search-replace\">\n\t\t\t<title>Replacing in files</title>\n\t\t\t<para>To access the Replace Bar use\n\t\t\t<menuchoice>\n\t\t\t\t<shortcut>\n\t\t\t\t\t<keycombo>\n\t\t\t\t\t\t<keycap>Ctrl</keycap>\n\t\t\t\t\t\t<keycap>R</keycap>\n\t\t\t\t\t</keycombo>\n\t\t\t\t</shortcut>\t\n\t\t\t\t<guisubmenu>Search</guisubmenu>\n\t\t\t\t<guimenuitem>Replace</guimenuitem>\n\t\t\t</menuchoice>.\n\t\t\t</para>\n\t\t\t<figure>\n\t\t\t\t<title>Replace Bar</title>\n\t\t\t\t<screenshot>\n\t\t\t\t\t<mediaobject>\n\t\t\t\t\t\t<imageobject>\n\t\t\t\t\t\t\t<imagedata fileref=\"figures/bless_search_replace.png\" format=\"PNG\"/>\n\t\t\t\t\t\t</imageobject>\n\t\t\t\t\t\t<textobject>\n\t\t\t\t\t\t\t<phrase>Replace Bar</phrase>\n\t\t\t\t\t\t</textobject>\n\t\t\t\t\t</mediaobject>\n\t\t\t\t</screenshot>\n\t\t\t</figure>\n\t\t\t<para>\n\t\t\t\tTo replace a sequence of bytes with another sequence of bytes:\n\t\t\t\t<orderedlist>\n\t\t\t\t\t<listitem>\n\t\t\t\t\t\t<para>Type the search sequence in the <guilabel>Search for</guilabel> text entry (in the desired format).</para>\n\t\t\t\t\t</listitem>\n\t\t\t\t\t<listitem>\n\t\t\t\t\t\t<para>Select the format of the search sequence from the <emphasis>first</emphasis> <guilabel>Interpret as</guilabel> option menu.</para>\n\t\t\t\t\t</listitem>\n\t\t\t\t\t<listitem>\n\t\t\t\t\t\t<para>Type the replace sequence in the <guilabel>Replace with</guilabel> text entry (in the desired format).</para>\n\t\t\t\t\t</listitem>\n\t\t\t\t\t<listitem>\n\t\t\t\t\t\t<para>Select the format of the replace sequence from the <emphasis>second</emphasis> <guilabel>Interpret as</guilabel> option menu.</para>\n\t\t\t\t\t</listitem>\n\t\t\t\t\t<listitem>\n\t\t\t\t\t\t<para>\n\t\t\t\t\t\t\tPress the <guibutton>Replace</guibutton> button to replace the current match, the <guibutton>Replace All</guibutton> to replace all matches\n\t\t\t\t\t\t\tin the file or the <guibutton>Find</guibutton> button to skip the current match and go to the next match. If a match is found \n\t\t\t\t\t\t\tit will be highlighted in the Data View, otherwise an alert informing you that no match was found will be shown.\n\t\t\t\t\t\t</para>\n\t\t\t\t\t</listitem>\n\t\t\t\t</orderedlist>\n\t\t\t</para>\n\t\t\t<para>\n\t\t\t\tTo hide the Replace Bar press the <keycap>Escape</keycap> key while the bar has the focus or click on the close button located\n\t\t\t\tat the right side of the bar.\n\t\t\t</para>\n\t\t\t<tip>\n\t\t\t\t<para>\n\t\t\t\t\tTo delete the matched search sequences, leave the <guilabel>Replace with</guilabel> text entry <emphasis>completely blank</emphasis>.\n\t\t\t\t</para>\n\t\t\t</tip>\n\t\t</section>\n\t</section>\n\t\n\t<section id=\"bless-usage-export\">\n\t\t<title>Exporting Data</title>\n\t\t<para>\n\t\t\t&app; features an advanced and customizable export system. It can currently export data to text or \n\t\t\thtml files.\n\t\t</para>\n\t\t<section id=\"bless-usage-export-pattern\">\n\t\t<title>Export Patterns</title>\n\t\t\t<para>\n\t\t\t\tThe exporting is based on an export pattern. The pattern consists of string literals and special command strings. \n\t\t\t\tThe literals are printed in the output file as they are whereas the command strings tell the exporter to \n\t\t\t\tdo something. Commands strings are enclosed in '%'s and specify the command and its parameters. The command \n\t\t\t\tis specified by an uppercase letter and the parameters by lowercase letters. Each letter (whether it corresponds\n\t\t\t\tto a command or a parameter) may be followed by an argument enclosed in double quotes '\"'.\n\t\t\t</para>\n\t\t\t<informaltable>\n\t\t\t\t<tgroup cols=\"3\">\n\t\t\t\t<thead>\n\t\t\t\t\t<row>\n\t\t\t\t\t\t<entry>Command</entry>\n\t\t\t\t\t\t<entry>Description</entry>\n\t\t\t\t\t\t<entry>Parameters [default]</entry>\n\t\t\t\t\t</row>\n\t\t\t\t</thead>\n\t\t\t\t<tbody>\n\t\t\t\t\t<row>\n\t\t\t\t\t\t<entry>Export (E)</entry>\n\t\t\t\t\t\t<entry>Writes actual data.</entry>\n\t\t\t\t\t\t<entry>\n\t\t\t\t\t\t\t<simplelist>\n\t\t\t\t\t\t\t\t<member>\n\t\t\t\t\t\t\t\t\t<para>E: the number of bytes to export [\"1\"]</para>\n\t\t\t\t\t\t\t\t</member>\n\t\t\t\t\t\t\t\t<member>\n\t\t\t\t\t\t\t\t\t<para>p: the prefix to write before each byte [\"\"]</para>\n\t\t\t\t\t\t\t\t</member>\n\t\t\t\t\t\t\t\t<member>\n\t\t\t\t\t\t\t\t\t<para>s: the suffix to write after each byte [\"\"]</para>\n\t\t\t\t\t\t\t\t</member>\n\t\t\t\t\t\t\t\t<member>\n\t\t\t\t\t\t\t\t\t<para>x: the separator to use between bytes [\"\"]</para>\n\t\t\t\t\t\t\t\t</member>\n\t\t\t\t\t\t\t\t<member>\n\t\t\t\t\t\t\t\t\t<para>e: the string to use for not printed bytes (due to alignment) [\" \"]</para>\n\t\t\t\t\t\t\t\t</member>\n\t\t\t\t\t\t\t\t<member>\n\t\t\t\t\t\t\t\t\t<para>t: the type to export the byte(s) to (see below) [\"H\"]</para>\n\t\t\t\t\t\t\t\t</member>\n\t\t\t\t\t\t\t</simplelist>\n\t\t\t\t\t\t</entry>\n\t\t\t\t\t</row>\n\t\t\t\t\t<row>\n\t\t\t\t\t\t<entry>Ignore (I)</entry>\n\t\t\t\t\t\t<entry>Ignores data.</entry>\n\t\t\t\t\t\t<entry>\n\t\t\t\t\t\t\t<simplelist>\n\t\t\t\t\t\t\t\t<member>\n\t\t\t\t\t\t\t\t\t<para>I: the number of bytes to ignore [\"1\"]</para>\n\t\t\t\t\t\t\t\t</member>\n\t\t\t\t\t\t\t</simplelist>\n\t\t\t\t\t\t</entry>\n\t\t\t\t\t</row>\t\t\t\t\n\t\t\t\t\t<row>\n\t\t\t\t\t\t<entry>Offset (O)</entry>\n\t\t\t\t\t\t<entry>Writes the current offset.</entry>\n\t\t\t\t\t\t<entry>\n\t\t\t\t\t\t\t<simplelist>\n\t\t\t\t\t\t\t\t<member>\n\t\t\t\t\t\t\t\t\t<para>O: the number of digits to use for writing the offset [\"8\"]</para>\n\t\t\t\t\t\t\t\t</member>\n\t\t\t\t\t\t\t\t<member>\n\t\t\t\t\t\t\t\t\t<para>t: the type to write the offset in (see below) [\"H\"]</para>\n\t\t\t\t\t\t\t\t</member>\n\t\t\t\t\t\t\t</simplelist>\n\t\t\t\t\t\t</entry>\n\t\t\t\t\t</row>\n\t\t\t\t</tbody>\n\t\t\t\t</tgroup>\n\t\t\t</informaltable>\n\t\t\t<informaltable>\n\t\t\t\t<tgroup cols=\"2\">\n\t\t\t\t<thead>\n\t\t\t\t\t<row>\n\t\t\t\t\t\t<entry>Export Type</entry>\n\t\t\t\t\t\t<entry>Description</entry>\n\t\t\t\t\t</row>\n\t\t\t\t</thead>\n\t\t\t\t<tbody>\n\t\t\t\t\t<row>\n\t\t\t\t\t\t<entry>H</entry>\n\t\t\t\t\t\t<entry>Hexadecimal with uppercase characters</entry>\n\t\t\t\t\t</row>\n\t\t\t\t\t<row>\n\t\t\t\t\t\t<entry>h</entry>\n\t\t\t\t\t\t<entry>Hexadecimal with lowercase characters</entry>\n\t\t\t\t\t</row>\n\t\t\t\t\t<row>\n\t\t\t\t\t\t<entry>D</entry>\n\t\t\t\t\t\t<entry>Decimal</entry>\n\t\t\t\t\t</row>\n\t\t\t\t\t<row>\n\t\t\t\t\t\t<entry>O</entry>\n\t\t\t\t\t\t<entry>Octal</entry>\n\t\t\t\t\t</row>\n\t\t\t\t\t<row>\n\t\t\t\t\t\t<entry>B</entry>\n\t\t\t\t\t\t<entry>Binary</entry>\n\t\t\t\t\t</row>\n\t\t\t\t\t<row>\n\t\t\t\t\t\t<entry>A</entry>\n\t\t\t\t\t\t<entry>Ascii</entry>\n\t\t\t\t\t</row>\n\t\t\t\t</tbody>\n\t\t\t\t</tgroup>\n\t\t\t</informaltable>\n\t\t\t<para>\n\t\t\t\tCommand strings can be grouped together with square brackets '[',']'. After such a group\n\t\t\t\tof commands is executed the pointer which keeps track of the next byte to export is reset\n\t\t\t\tto the position it had just before the group was executed.\n\t\t\t</para>\n\t\t\t<para>\n\t\t\t\tSome sample patterns and their output will make things much clearer:\n\t\t\t\t<variablelist>\n\t\t\t\t\t<varlistentry>\n\t\t\t\t\t\t<term>%O\"4\"%: %E\"4\"p\"0x\"x\" \"% - %E\"4\"p\"0x\"x\" \"%\\n</term>\n\t\t\t\t\t\t<listitem>\n\t\t\t\t\t\t\t<para>\n\t\t\t\t\t\t\t\t<screen>0000: 0x00 0x01 0x02 0x03 - 0x04 0x05 0x06 0x07\n0008: 0x08 0x09 0x0a 0x0b - 0x0c 0x0d 0x0e 0x0f\n0010: 0x10 0x11 0x12 0x13 - 0x14 0x15 0x16 0x17\n0018: 0x18 0x19 0x10 0x1a - 0x1b 0x1c 0x1d 0x1e\n0020: 0x1f                -                    </screen> \n\t\t\t\t\t\t\t</para>\n\t\t\t\t\t\t</listitem>\n\t\t\t\t\t</varlistentry>\n\t\t\t\t\t<varlistentry>\n\t\t\t\t\t\t<term>[%E\"2\"% %I\"2\"% %E\"2\"% %I\"2\"%] %I\"2\"% %E\"2\"% %I\"2\"% %E\"2\"%\\n</term>\n\t\t\t\t\t\t<listitem>\n\t\t\t\t\t\t\t<para>\n\t\t\t\t\t\t\t<screen>0001  0405   0203  0607\n0809  0c0d   0a0b  0e0f\n1011  1415   1213  1617\n1819  1b1c   101a  1d1e\n1f\n</screen> \n\t\t\t\t\t\t\t</para>\n\t\t\t\t\t\t</listitem>\n\t\t\t\t\t</varlistentry>\n\t\t\t\t\t</variablelist>\n\t\t\t</para>\n\t\t</section>\n\t\t<section id=\"bless-usage-export-dialog\">\n\t\t<title>Export Dialog</title>\n\t\t\t<figure>\n\t\t\t\t<title>Export Dialog</title>\n\t\t\t\t<screenshot><mediaobject>\n\t\t\t\t\t<imageobject>\n\t\t\t\t\t\t<imagedata fileref=\"figures/bless_export_dialog.png\" format=\"PNG\"/>\n\t\t\t\t\t</imageobject>\n\t\t\t\t\t<textobject>\n\t\t\t\t\t\t<phrase>Export Dialog</phrase>\n\t\t\t\t\t</textobject>\n\t\t\t\t</mediaobject></screenshot>\n\t\t\t</figure>\n\t\t\t<variablelist>\n\t\t\t<title>Export Dialog</title>\n\t\t\t\t<varlistentry>\n\t\t\t\t\t<term>Export to file</term>\n\t\t\t\t\t<listitem>\n\t\t\t\t\t\t<para>\n\t\t\t\t\t\t\tThe name of the file to export the data to.\n\t\t\t\t\t\t</para>\n\t\t\t\t\t</listitem>\n\t\t\t\t</varlistentry>\n\t\t\t\t<varlistentry>\n\t\t\t\t\t<term>Export type</term>\n\t\t\t\t\t<listitem>\n\t\t\t\t\t\t<para>\n\t\t\t\t\t\t\tThe type of file to export to. New types can be added with plugins.\n\t\t\t\t\t\t</para>\n\t\t\t\t\t</listitem>\n\t\t\t\t</varlistentry>\n\t\t\t\t<varlistentry>\n\t\t\t\t\t<term>Export pattern</term>\n\t\t\t\t\t<listitem>\n\t\t\t\t\t\t<para>\n\t\t\t\t\t\t\tThe pattern to use when exporting the file (see <xref linkend=\"bless-usage-export-pattern\"/>). Use the save and delete buttons\n\t\t\t\t\t\t\tnext to the pattern entry to manage the saved patterns.\n\t\t\t\t\t\t</para>\n\t\t\t\t\t</listitem>\n\t\t\t\t</varlistentry>\n\t\t\t\t<varlistentry>\n\t\t\t\t\t<term>Range</term>\n\t\t\t\t\t<listitem>\n\t\t\t\t\t\t<para>\n\t\t\t\t\t\t\tThe range of data to export.\n\t\t\t\t\t\t</para>\n\t\t\t\t\t</listitem>\n\t\t\t\t</varlistentry>\n\t\t\t</variablelist>\n\t\t</section>\n\t</section>\n\t\n\t<section id=\"bless-usage-bitwiseops\">\n\t<title>Performing bitwise operations</title>\n\t\t<para>To access the Bitwise Operations Bar use\n\t\t\t<menuchoice>\n\t\t\t\t<shortcut>\n\t\t\t\t\t<keycombo>\n\t\t\t\t\t\t<keycap>Ctrl</keycap>\n\t\t\t\t\t\t<keycap>B</keycap>\n\t\t\t\t\t</keycombo>\n\t\t\t\t</shortcut>\t\n\t\t\t\t<guisubmenu>Tools</guisubmenu>\n\t\t\t\t<guimenuitem>Bitwise Operations</guimenuitem>\n\t\t\t</menuchoice>.\n\t\t</para>\n\t\t<figure>\n\t\t\t<title>Bitwise Operations Bar</title>\n\t\t\t<screenshot>\n\t\t\t\t<mediaobject>\n\t\t\t\t\t<imageobject>\n\t\t\t\t\t\t<imagedata fileref=\"figures/bless_bitwise_ops.png\" format=\"PNG\"/>\n\t\t\t\t\t</imageobject>\n\t\t\t\t\t<textobject>\n\t\t\t\t\t\t<phrase>Bitwise Operations Bar</phrase>\n\t\t\t\t\t</textobject>\n\t\t\t\t</mediaobject>\n\t\t\t</screenshot>\n\t\t</figure>\n\t\t<para>\n\t\t\tTo apply a bitwise operation on a range of data:\n\t\t\t<orderedlist>\n\t\t\t\t<listitem>\n\t\t\t\t\t<para>Select the range to apply the operation on (see <xref linkend=\"bless-usage-edit-basic-select\"/>). If no range\n\t\t\t\t\tis selected the operation will be performed on the current offset.\n\t\t\t\t\tThe selected range is displayed at the far left of the bar. Clicking\n\t\t\t\t\ton the displayed range cycles the number base used to display it (Hexadecimal, Octal, Decimal).</para>\n\t\t\t\t</listitem>\n\t\t\t\t<listitem>\n\t\t\t\t\t<para>Select the desired operation from the operations list. Available operations are AND, OR, XOR and NOT.</para>\n\t\t\t\t</listitem>\n\t\t\t\t<listitem>\n\t\t\t\t\t<para>Type the data to use for the operation in the data text entry (if applicable).</para>\n\t\t\t\t</listitem>\n\t\t\t\t<listitem>\n\t\t\t\t\t<para>Select the type of the data from the data type list.</para>\n\t\t\t\t</listitem>\n\t\t\t\t<listitem>\n\t\t\t\t\t<para>Press the <guibutton>Execute</guibutton> button to perform the operation.</para>\n\t\t\t\t</listitem>\n\t\t\t</orderedlist>\n\t\t</para>\n\t</section>\n</chapter>\n\n<chapter id=\"bless-customizing\">\n\t<title>Customizing &app;</title>\n\t\n\t<section id=\"bless-customizing-config\">\n\t<title>Configuration Files</title>\n\t<para>\n\t\t&app; keeps its configuration files under <filename class='directory'>$XDG_CONFIG_HOME/bless</filename> (usually <filename class='directory'>$HOME/.config/bless</filename> on UNIX based systems and\n\t\t<filename class='directory'>C:\\Documents and Settings\\User Name\\Application Data\\bless</filename> on MS Windows systems)\n\t\tin accordance to the XDG specification. This directory contains the following files and directories\n\t</para>\n\t\n\t<variablelist>\n\t<title></title>\n\t\t<varlistentry>\n\t\t\t<term>export_patterns</term>\n\t\t\t<listitem>\n\t\t\t\t<para>\n\t\t\t\t\tKeeps the list of saved export patterns.\n\t\t\t\t</para>\n\t\t\t</listitem>\n\t\t</varlistentry>\n\t\t<varlistentry>\n\t\t\t<term>history.xml</term>\n\t\t\t<listitem>\n\t\t\t\t<para>\n\t\t\t\t\tKeeps the list of recently opened files.\n\t\t\t\t</para>\n\t\t\t</listitem>\n\t\t</varlistentry>\n\t\t<varlistentry>\n\t\t\t<term>last.session</term>\n\t\t\t<listitem>\n\t\t\t\t<para>\n\t\t\t\t\tKeeps the state of &app; the last time it was closed. This includes the open files,\n\t\t\t\t\tthe file offset and cursor offset in each file, the active file, the window dimensions etc.\n\t\t\t\t</para>\n\t\t\t</listitem>\n\t\t</varlistentry>\n\t\t<varlistentry>\n\t\t\t<term>preferences.xml</term>\n\t\t\t<listitem>\n\t\t\t\t<para>\n\t\t\t\t\tKeeps the user preferences.\n\t\t\t\t</para>\n\t\t\t</listitem>\n\t\t</varlistentry>\n\t\t<varlistentry>\n\t\t\t<term>layouts/</term>\n\t\t\t<listitem>\n\t\t\t\t<para>\n\t\t\t\t\tThis directory holds the layout description files for each user. \n\t\t\t\t\tSee <xref linkend=\"bless-customizing-layouts\"/>.\n\t\t\t\t</para>\n\t\t\t</listitem>\n\t\t</varlistentry>\n\t</variablelist>\n\t\n\t</section>\n\t\n\t<section id=\"bless-customizing-preferences\">\n\t<title>Preferences</title>\n\t<para>\n\t\tYou can edit the user preferences in the Preferences dialog. It can be\n\t\taccessed by using \n\t\t<menuchoice>\n\t\t\t<guisubmenu>Edit</guisubmenu>\n\t\t\t<guimenuitem>Preferences...</guimenuitem>\n\t\t</menuchoice>.\n\t</para>\n\t\t<section id=\"bless-customizing-preferences-general\">\n\t\t<title>General Preferences</title>\n\t\t<figure>\n\t\t\t<title>General Preferences</title>\n\t\t\t<screenshot><mediaobject>\n\t\t\t\t<imageobject>\n\t\t\t\t\t<imagedata fileref=\"figures/bless_preferences_general.png\" format=\"PNG\"/>\n\t\t\t\t</imageobject>\n\t\t\t\t<textobject>\n\t\t\t\t\t<phrase>General Preferences</phrase>\n\t\t\t\t</textobject>\n\t\t\t</mediaobject></screenshot>\n\t\t</figure>\n\t\t<variablelist>\n\t\t<title>Default Layout</title>\n\t\t\t<varlistentry>\n\t\t\t\t<term>Layout File</term>\n\t\t\t\t<listitem>\n\t\t\t\t\t<para>\n\t\t\t\t\t\tThe layout file to use when opening a new tab. If it is left empty a default\n\t\t\t\t\t\twill be used.\n\t\t\t\t\t</para>\n\t\t\t\t</listitem>\n\t\t\t</varlistentry>\n\t\t\t<varlistentry>\n\t\t\t\t<term>Use layout of currently active tab if any</term>\n\t\t\t\t<listitem>\n\t\t\t\t\t<para>\n\t\t\t\t\t\tIf it is checked, &app; will try to use the layout of the currently active tab for new tabs.\n\t\t\t\t\t\tIf there are no open tabs, &app; will use the file from the \"Layout File\" preference.\n\t\t\t\t\t</para>\n\t\t\t\t</listitem>\n\t\t\t</varlistentry>\n\t\t</variablelist>\n\t\t<variablelist>\n\t\t<title>Misc</title>\n\t\t\t<varlistentry>\n\t\t\t\t<term>Default edit mode</term>\n\t\t\t\t<listitem>\n\t\t\t\t\t<para>\n\t\t\t\t\t\tThe edit mode new tabs will be placed in (Insert or Overwrite).\n\t\t\t\t\t</para>\n\t\t\t\t</listitem>\n\t\t\t</varlistentry>\n\t\t\t<varlistentry>\n\t\t\t\t<term>Temporary Directory</term>\n\t\t\t\t<listitem>\n\t\t\t\t\t<para>\n\t\t\t\t\t\tThe directory to save temporary files into (leave blank for default eg /tmp).\n\t\t\t\t\t\tWhen a file is saved, it is saved into this directory and then moved\n\t\t\t\t\t\tto its final position.\n\t\t\t\t\t</para>\n\t\t\t\t</listitem>\n\t\t\t</varlistentry>\n\t\t</variablelist>\n\t\t\n\t\t</section>\n\t\t\n\t\t<section id=\"bless-customizing-preferences-undo\">\n\t\t<title>Undo Preferences</title>\n\t\t<figure>\n\t\t\t<title>Undo Preferences</title>\n\t\t\t<screenshot><mediaobject>\n\t\t\t\t<imageobject>\n\t\t\t\t\t<imagedata fileref=\"figures/bless_preferences_undo.png\" format=\"PNG\"/>\n\t\t\t\t</imageobject>\n\t\t\t\t<textobject>\n\t\t\t\t\t<phrase>Undo Preferences</phrase>\n\t\t\t\t</textobject>\n\t\t\t</mediaobject></screenshot>\n\t\t</figure>\n\t\t<variablelist>\n\t\t<title>Undo Limit</title>\n\t\t\t<varlistentry>\n\t\t\t\t<term>Limit to X actions</term>\n\t\t\t\t<listitem>\n\t\t\t\t\t<para>\n\t\t\t\t\t\tLimit the number of actions that can be undone to X actions.\n\t\t\t\t\t</para>\n\t\t\t\t</listitem>\n\t\t\t</varlistentry>\n\t\t\t<varlistentry>\n\t\t\t\t<term>Unlimited Undo</term>\n\t\t\t\t<listitem>\n\t\t\t\t\t<para>\n\t\t\t\t\t\tDon't limit the number of actions that can be undone.\n\t\t\t\t\t</para>\n\t\t\t\t</listitem>\n\t\t\t</varlistentry>\n\t\t</variablelist>\n\t\t<variablelist>\n\t\t<title>Keep Undo History After Save</title>\n\t\t\t<varlistentry>\n\t\t\t\t<term>Always</term>\n\t\t\t\t<listitem>\n\t\t\t\t\t<para>\n\t\t\t\t\t\tAlways keep undo history after a file is saved.\n\t\t\t\t\t</para>\n\t\t\t\t\t<warning>\n\t\t\t\t\t\tWhen dealing with large amounts of undo data this option may\n\t\t\t\t\t\tfill up all memory and cause a severe degradation of system performance.\n\t\t\t\t\t</warning>\n\t\t\t\t</listitem>\n\t\t\t</varlistentry>\n\t\t\t<varlistentry>\n\t\t\t\t<term>What fits in main memory</term>\n\t\t\t\t<listitem>\n\t\t\t\t\t<para>\n\t\t\t\t\t\tOnly keep the part of the history that fits in main memory (RAM).\n\t\t\t\t\t</para>\n\t\t\t\t</listitem>\n\t\t\t</varlistentry>\n\t\t\t<varlistentry>\n\t\t\t\t<term>Never</term>\n\t\t\t\t<listitem>\n\t\t\t\t\t<para>\n\t\t\t\t\t\tNever keep undo history after a file is saved.\n\t\t\t\t\t</para>\n\t\t\t\t</listitem>\n\t\t\t</varlistentry>\n\t\t</variablelist>\n\t\t\n\t\t</section>\n\t\t\n\t\t<section id=\"bless-customizing-preferences-session\">\n\t\t<title>Session Preferences</title>\n\t\t<figure>\n\t\t\t<title>Session Preferences</title>\n\t\t\t<screenshot><mediaobject>\n\t\t\t\t<imageobject>\n\t\t\t\t\t<imagedata fileref=\"figures/bless_preferences_session.png\" format=\"PNG\"/>\n\t\t\t\t</imageobject>\n\t\t\t\t<textobject>\n\t\t\t\t\t<phrase>Session Preferences</phrase>\n\t\t\t\t</textobject>\n\t\t\t</mediaobject></screenshot>\n\t\t</figure>\n\t\t<variablelist>\n\t\t<title></title>\n\t\t\t<varlistentry>\n\t\t\t\t<term>Load previous session on startup</term>\n\t\t\t\t<listitem>\n\t\t\t\t\t<para>\n\t\t\t\t\t\tWhether the previous session (the state of Bless at the time of the last quit)\n\t\t\t\t\t\tshould be loaded on startup. The state includes all open files, the focused tab,\n\t\t\t\t\t\tthe focused area in each file, the cursor position in each file and the window geometry. \n\t\t\t\t\t</para>\n\t\t\t\t</listitem>\n\t\t\t</varlistentry>\n\t\t\t<varlistentry>\n\t\t\t\t<term>Ask before loading session</term>\n\t\t\t\t<listitem>\n\t\t\t\t\t<para>\n\t\t\t\t\t\tAsk before loading session on startup.\n\t\t\t\t\t</para>\n\t\t\t\t</listitem>\n\t\t\t</varlistentry>\n\t\t\t<varlistentry>\n\t\t\t\t<term>Remember cursor position</term>\n\t\t\t\t<listitem>\n\t\t\t\t\t<para>\n\t\t\t\t\t\tWhether &app; should remember and restore the position of the cursor in\n\t\t\t\t\t\teach of the loaded files when loading the previous session.\n\t\t\t\t\t</para>\n\t\t\t\t</listitem>\n\t\t\t</varlistentry>\n\t\t\t<varlistentry>\n\t\t\t\t<term>Remember window geometry</term>\n\t\t\t\t<listitem>\n\t\t\t\t\t<para>\n\t\t\t\t\t\tWhether &app; should remember and restore the window size when loading the previous session.\n\t\t\t\t\t</para>\n\t\t\t\t</listitem>\n\t\t\t</varlistentry>\n\t\t</variablelist>\n\t\t</section>\n\t</section>\n\t\n\t<section id=\"bless-customizing-layouts\">\n\t<title>Layout Files</title>\n\t\n\t<para>\n\t\tThe way &app; presents the data is highly customizable. The configuration is done \n\t\tthrough layout description files. Currently there is no way to graphically edit the\n\t\tlayouts but one is planned for a later version.\n\t</para>\n\t\n\t<section id=\"bless-customizing-layouts-selecting\">\n\t\t<title>Selecting a layout</title>\n\t\t<para>\n\t\t\t&app; searches for layout description files in the <filename class='directory'>$XDG_CONFIG_HOME/bless/layouts</filename> directory\n\t\t\t(usually $HOME/.config/bless/layouts). You can preview and select the available layouts with the layout \n\t\t\tselection dialog, which can be accessed by using\n\t\t\t<menuchoice>\n\t\t\t<guisubmenu>View</guisubmenu>\n\t\t\t<guimenuitem>Layouts</guimenuitem>\n\t\t\t</menuchoice>.\n\t\t</para>\n\t</section>\n\t\n\t<section id=\"bless-customizing-layouts-creating\">\n\t\t<title>Creating Layout Files</title>\n\t\t<para>\n\t\t\tLayout description files are XML files ending with the .layout suffix. They consist of \n\t\t\tthe &lt;layout&gt; tag which contains a series of &lt;area&gt; tags that describe each \n\t\t\tarea in the layout. The &lt;area&gt; tag takes one attribute, <emphasis>type</emphasis>, which defines \n\t\t\tthe type of the area. The valid values for <emphasis>type</emphasis> are:\n\t\t</para>\n\t\t<informaltable>\n\t\t\t<tgroup cols=\"2\">\n\t\t\t<thead>\n\t\t\t\t<row>\n\t\t\t\t\t<entry>Type</entry>\n\t\t\t\t\t<entry>Description</entry>\n\t\t\t\t</row>\n\t\t\t</thead>\n\t\t\t<tbody>\n\t\t\t\t<row>\n\t\t\t\t\t<entry>hexadecimal</entry>\n\t\t\t\t\t<entry>Displays the data in hexadecimal format.</entry>\n\t\t\t\t</row>\n\t\t\t\t<row>\n\t\t\t\t\t<entry>decimal</entry>\n\t\t\t\t\t<entry>Displays the data in decimal format.</entry>\n\t\t\t\t</row>\n\t\t\t\t<row>\n\t\t\t\t\t<entry>octal</entry>\n\t\t\t\t\t<entry>Displays the data in octal format.</entry>\n\t\t\t\t</row>\n\t\t\t\t<row>\n\t\t\t\t\t<entry>binary</entry>\n\t\t\t\t\t<entry>Displays the data in binary format.</entry>\n\t\t\t\t</row>\n\t\t\t\t<row>\n\t\t\t\t\t<entry>ascii</entry>\n\t\t\t\t\t<entry>Displays the data in ascii format.</entry>\n\t\t\t\t</row>\n\t\t\t\t<row>\n\t\t\t\t\t<entry>offset</entry>\n\t\t\t\t\t<entry>Displays the data offset.</entry>\n\t\t\t\t</row>\n\t\t\t\t<row>\n\t\t\t\t\t<entry>separator</entry>\n\t\t\t\t\t<entry>A vertical line that visually separates areas.</entry>\n\t\t\t\t</row>\n\t\t\t</tbody>\n\t\t\t</tgroup>\n\t\t</informaltable>\n\t\t<para>For example, the following simple layout file:</para>\n\t\t<programlisting>&lt;layout&gt;\n\t&lt;area type=\"offset\"&gt;&lt;/area&gt;\n\t&lt;area type=\"hexadecimal\"&gt;&lt;/area&gt;\n\t&lt;area type=\"offset\"&gt;&lt;/area&gt;\n\t&lt;area type=\"separator\"&gt;&lt;/area&gt;\n\t&lt;area type=\"ascii\"&gt;&lt;/area&gt;\n&lt;/layout&gt;</programlisting>\n\t<para>produces the standard offset-hex-ascii view with default colors:</para>\n\t<figure>\n\t\t<title>Standard offset-hex-ascii view</title>\n\t\t<screenshot><mediaobject>\n\t\t\t<imageobject>\n\t\t\t\t<imagedata fileref=\"figures/bless_layout_oha.png\" format=\"PNG\"/>\n\t\t\t</imageobject>\n\t\t\t<textobject>\n\t\t\t\t<phrase>Standard offset-hex-ascii view</phrase>\n\t\t\t</textobject>\n\t\t</mediaobject></screenshot>\n\t</figure>\n\t<para>\n\t\tEach area may include additional options about how to display the data. Some options \n\t\tare available to all areas whereas others are area-specific. The options that aren't\n\t\texplicitly defined assume their default values. Also if an option is specified for an \n\t\tarea that doesn't support it, the option is just ignored.\n\t</para>\n\t\t<informaltable>\n\t\t<tgroup cols=\"4\">\n\t\t\t<thead>\n\t\t\t\t<row>\n\t\t\t\t\t<entry>Option</entry>\n\t\t\t\t\t<entry>Values</entry>\n\t\t\t\t\t<entry>Description</entry>\n\t\t\t\t\t<entry>Areas</entry>\n\t\t\t\t</row>\n\t\t\t</thead>\n\t\t\t<tbody>\n\t\t\t\t<row>\n\t\t\t\t\t<entry>display</entry>\n\t\t\t\t\t<entry>see below</entry>\n\t\t\t\t\t<entry>The fonts and colors that should be used for the display.</entry>\n\t\t\t\t\t<entry>all</entry>\n\t\t\t\t</row>\n\t\t\t\t<row>\n\t\t\t\t\t<entry>case</entry>\n\t\t\t\t\t<entry>upper|lower</entry>\n\t\t\t\t\t<entry>Whether to display hexadecimal values using lowercase or uppercase.</entry>\n\t\t\t\t\t<entry>offset, hexadecimal</entry>\n\t\t\t\t</row>\n\t\t\t\t<row>\n\t\t\t\t\t<entry>grouping</entry>\n\t\t\t\t\t<entry>#int</entry>\n\t\t\t\t\t<entry>The number of bytes that should be grouped together in each column.</entry>\n\t\t\t\t\t<entry>hexadecimal, decimal, octal, binary</entry>\n\t\t\t\t</row>\n\t\t\t\t<row>\n\t\t\t\t\t<entry>bpr</entry>\n\t\t\t\t\t<entry>#int</entry>\n\t\t\t\t\t<entry>The number of bytes on each row in the area (see below for more information)</entry>\n\t\t\t\t\t<entry>hexadecimal, decimal, octal, binary, ascii</entry>\n\t\t\t\t</row>\n\t\t\t\t<row>\n\t\t\t\t\t<entry>bytes</entry>\n\t\t\t\t\t<entry>#int</entry>\n\t\t\t\t\t<entry>The number of bytes which will be used to display offsets (default 4)</entry>\n\t\t\t\t\t<entry>offset</entry>\n\t\t\t\t</row>\n\t\t\t</tbody>\n\t\t\t</tgroup>\n\t\t</informaltable>\t\t\t\n\t\t<section id=\"bless-customizing-layouts-creating-bpr\">\n\t\t\t<title>The bpr option</title>\n\t\t\t<para>\n\t\t\t\tThe &lt;bpr&gt; (bytes per row) option sets the (maximum) number of bytes that each row in an area can have. If it is not\n\t\t\t\tspecified, the number of bytes on each row changes dynamically in order to fill the whole available width. If it is specified \n\t\t\t\tin at least one area in the layout all the areas in the layout conform to the specified restriction. In case of a conflict, for example \n\t\t\t\twhen two areas specify different bprs, the smallest value is used. Finally, if there is a conflict between bpr and grouping values, \n\t\t\t\tthe highest value that conforms to the grouping and is below the bpr is used (eg if bpr=5 and grouping=2 the bytes per row will\n\t\t\t\tbe 4).\n\t\t\t</para>\n\t\t</section>\n\t\t\n\t\t<section id=\"bless-customizing-layouts-creating-display\">\n\t\t\t<title>The display option</title>\n\t\t\t<para>\n\t\t\t\tThe &lt;display&gt; option is the most complicated of the lot and deserves additional explanation.\n\t\t\t</para>\n\t\t\t<para>\n\t\t\t\tBless distinguishes between even and odd rows, and even and odd columns. You can choose\n\t\t\t\thow to color each of the above items thus creating a visual result tailored to your needs. This\n \t\t\t\tis achieved by using the &lt;display&gt; tag. Note that the first row and column are numbered as 0\n\t\t\t\tand are therefore considered even.\n\t\t\t</para>\n\t\t\t<para>\n\t\t\t\tA &lt;display&gt; tag may contain a &lt;font&gt; tag which sets the font family and size to use for \n\t\t\t\tdisplaying data in the area (eg \"Courier 10\"). The font should be a monospaced font, otherwise the\n\t\t\t\tdata in the area won't be displayed correctly. It is also advised to use same sized fonts in all the \n\t\t\t\tareas so that the data is correctly aligned.\n\t\t\t</para>\n\t\t\t<para>\n\t\t\t\tA &lt;display&gt; tag may also contain a &lt;evenrow&gt; and a &lt;oddrow&gt; tag which describe how \n\t\t\t\tthe even and odd rows will look like. Each of the &lt;evenrow&gt; and &lt;oddrow&gt; tags may     \n\t\t\t\tcontain a &lt;evencolumn&gt;, an &lt;oddcolumn&gt;, a &lt;selectedcolumn&gt; and a \n\t\t\t\t&lt;patternmatchcolumn&gt; tag. The first two describe the appearance of the respective columns\n\t\t\t\tunder normal conditions (no highlighting). The &lt;selectedcolumn&gt; tag \n\t\t\t\tdescribes the appearance of selected bytes and the &lt;patternmatchcolumn&gt; tag the appearance\n\t\t\t\tof the highlighted bytes that match the selected bytes (see <xref linkend=\"bless-usage-edit-basic-select\"/>).\n\t\t\t\tThe description for all the above is accomplished by using the &lt;foreground&gt; and \n\t\t\t\t&lt;background&gt; tags which specify the foreground and background colors to use.\n\t\t\t</para>\n\t\t\t<para>\n\t\t\t\tThe colors can be specified either by name (eg dark blue) or by an RGB triad (eg #ff004e).\n\t\t\t</para>\n\t\t\t<figure>\n\t\t\t\t<title>Display tag hierarchy</title>\n\t\t\t\t<screenshot><mediaobject>\n\t\t\t\t\t<imageobject>\n\t\t\t\t\t\t<imagedata fileref=\"figures/bless_display_tag.png\" format=\"PNG\"/>\n\t\t\t\t\t</imageobject>\n\t\t\t\t\t<textobject>\n\t\t\t\t\t\t<phrase>Display tag hierarchy</phrase>\n\t\t\t\t\t</textobject>\n\t\t\t\t</mediaobject></screenshot>\n\t\t\t</figure>\n\t\t\t<para>\n\t\t\t\tAn example:\n\t\t\t</para>\n<programlisting>\n&lt;layout&gt;\n    &lt;area type=\"offset\"&gt;\n        &lt;display&gt;\n            &lt;evenrow&gt;\n                &lt;evencolumn&gt;\n                    &lt;foreground&gt;dark red&lt;/foreground&gt;\n                &lt;/evencolumn&gt;\n            &lt;/evenrow&gt;\n            &lt;oddrow&gt;\n                &lt;evencolumn&gt;\n                    &lt;foreground&gt;dark red&lt;/foreground&gt;\n                &lt;/evencolumn&gt;\n            &lt;/oddrow&gt;\n        &lt;/display&gt;                        \n    &lt;/area&gt;\n    \n    &lt;area type=\"separator\"&gt;\n        &lt;display&gt;\n            &lt;evenrow&gt;\n                &lt;evencolumn&gt;\n                    &lt;foreground&gt;dark green&lt;/foreground&gt;\n                    &lt;background&gt;white&lt;/background&gt;\n                &lt;/evencolumn&gt;\n            &lt;/evenrow&gt;\n        &lt;/display&gt;                        \n    &lt;/area&gt;\n    \n    &lt;area type=\"hexadecimal\"&gt;\n        &lt;grouping&gt;2&lt;/grouping&gt;\n        &lt;case&gt;upper&lt;/case&gt;\n        &lt;display&gt;\n            &lt;evenrow&gt;\n                &lt;selectedcolumn&gt;\n                    &lt;foreground&gt;white&lt;/foreground&gt;\n                    &lt;background&gt;#8faec8&lt;/background&gt;\n                &lt;/selectedcolumn&gt;\n            &lt;/evenrow&gt;    \n            &lt;oddrow&gt;\n                &lt;evencolumn&gt;\n                    &lt;background&gt;#eeeeee&lt;/background&gt;\n                &lt;/evencolumn&gt;\n                &lt;oddcolumn&gt;\n                    &lt;background&gt;#eeeeee&lt;/background&gt;\n                &lt;/oddcolumn&gt;\n                &lt;selectedcolumn&gt;\n                    &lt;foreground&gt;white&lt;/foreground&gt;\n                    &lt;background&gt;#7b96ac&lt;/background&gt;\n                &lt;/selectedcolumn&gt;\n            &lt;/oddrow&gt;    \n        &lt;/display&gt;    \n    &lt;/area&gt;\n\n    &lt;area type=\"separator\"&gt;\n        &lt;display&gt;\n            &lt;evenrow&gt;\n                &lt;evencolumn&gt;\n                    &lt;foreground&gt;dark green&lt;/foreground&gt;\n                    &lt;background&gt;white&lt;/background&gt;\n                &lt;/evencolumn&gt;\n            &lt;/evenrow&gt;\n        &lt;/display&gt;                        \n    &lt;/area&gt;\n    \n    &lt;area type=\"decimal\"&gt;\n    &lt;/area&gt;\n\n    &lt;area type=\"separator\"&gt;\n        &lt;display&gt;\n            &lt;evenrow&gt;\n                &lt;evencolumn&gt;\n                    &lt;foreground&gt;dark green&lt;/foreground&gt;\n                    &lt;background&gt;white&lt;/background&gt;\n                &lt;/evencolumn&gt;\n            &lt;/evenrow&gt;\n        &lt;/display&gt;                        \n    &lt;/area&gt;\n\n    &lt;area type=\"binary\"&gt;\n    &lt;/area&gt;\n&lt;/layout&gt;\n</programlisting>\n\t\t\t<para>The result is:</para>\n\t\t\t<figure>\n\t\t\t\t\t<title>Example layout</title>\n\t\t\t\t\t<screenshot><mediaobject>\n\t\t\t\t\t\t<imageobject>\n\t\t\t\t\t\t\t<imagedata fileref=\"figures/bless_layout_example1.png\" format=\"PNG\"/>\n\t\t\t\t\t\t</imageobject>\n\t\t\t\t\t\t<textobject>\n\t\t\t\t\t\t\t<phrase>Example layout screenshot</phrase>\n\t\t\t\t\t\t</textobject>\n\t\t\t\t\t</mediaobject></screenshot>\n\t\t\t</figure>\n\t\t\n\t\t\n\t\t<note><para>\n\t\t\tNot all font options are used in all areas. The hexadecimal, decimal, octal and binary areas use\n\t\t\tall options. The ascii, offset and separator areas do not use the &lt;oddcolumn&gt; tag.\n\t\t</para></note>\n\t\t<note><para>\n\t\t\tThe */evencolumn/background colors are considered the primary background colors for \n\t\t\ttheir respective row. They are used to paint all parts of the row that are not otherwise painted \n\t\t\t(eg space between columns). The evenrow/evencolumn/background color is also considered the main\n\t\t\tbackground color of the area and is used to paint the unused parts of the area.\t\n\t\t</para></note>\n\n\t\t</section>\n\t</section>\n\t</section>\n\t<section id=\"bless-customizing-plugins\">\n\t<title>Extending with plugins</title>\n\t\t<para>As of version 0.5.0 &app; can be extended by using plugins. Internally &app; uses plugins\n\t\tfor almost all of its GUI. Currently the parts that can be extended by plugins are:\n\t\t</para>\n\t\t<simplelist>\n\t\t\t<member>The GUI</member>\n\t\t\t<member>The areas displayed inside the Data Views</member>\n\t\t\t<member>Export builders</member>\n\t\t</simplelist>\n\t\t<para>\n\t\t\tSee the developer documentation for more information on how to write plugins (TODO).\n\t\t</para>\n\t</section>\t\n</chapter>\n<!-- ============= Bugs ================================== -->\n<!-- This section is optional and is commented out by default. \n\t\t You can use it to describe known bugs and limitations of the \n\t\tprogram if there are any - please be frank and list all\n\t\t problems you know of. \n\t\n\t<chapter id=\"mayapp-bugs\">\n\t<title>Known Bugs and Limitations</title>\n\t<para> </para>\n </chapter>\n-->\n<chapter id=\"bless-faq\">\n\t<title>Frequently Asked Questions</title>\n\n\t<qandaset defaultlabel='number'>\n\t\n\t  <qandadiv><title>Philosophical Questions</title>\n\t\n\t    <qandaentry><question><simpara>Why did you start Bless? Aren't there enough hex editors?</simpara></question>\n\t        <answer><simpara>There aren't enough free (as in speech) graphical hex editors. The two main\n\tones are khexedit and ghex. Khexedit hasn't been updated in years and ghex is moving \n\tvery slowly.</simpara></answer>\n\t        </qandaentry>\n\t\t\n\t\t<qandaentry><question><simpara>So, why didn't you contribute to one of the existing projects?</simpara></question>\n\t        <answer><simpara>I wanted to try out the mono/Gtk# combination for graphical applications and none such \n\tproject existed.</simpara></answer>\n\t        </qandaentry>\n\t\t\n\t\t<qandaentry><question><simpara>What kind of name is Bless?</simpara></question>\n\t        <answer><simpara>It is a wordplay on the word hex. Hex also means curse and a bless(ing) is the opposite of a curse.</simpara></answer>\n\t        </qandaentry>\n\n\t</qandadiv>\n\t\n\t<qandadiv><title>Technical Questions</title>\n\t\n\t    <qandaentry><question><simpara>How can I get the latest source of Bless?</simpara></question>\n\t        <answer><para>Bless now uses <ulink url=\"https://git-scm.com\" type=\"https\">Git</ulink> as its version control system.\n\tAfter you install Git on your system use the following command to get the latest version\n\tof Bless into the bless directory (this might take some time):\n\t</para>\n\t<para>\n\t<command>git clone https://github.com/afrantzis/bless</command>\n\t</para>\n\t<para>\n\tIf you already downloaded a previous version (using the above command, not source tarballs) and want to update to the latest version \n\tuse:\n\t</para>\n\t<para>\n\t<command>git pull</command>\n\t</para>\n\t<para>\n\tfrom within the directory that contains the previous version. \n\t</para></answer>\n\t        </qandaentry>\n\t\t\n\t\t<qandaentry><question><simpara>I don't like the way Bless displays data. Can I change it?</simpara></question>\n\t        <answer><simpara>Yes! Bless is highly customizable. See <xref linkend=\"bless-customizing-layouts\"/>\n\t        </simpara></answer>\n\t        </qandaentry>\n\t\t\n\t\t<qandaentry><question><simpara>I am trying to save a large file (under the same name) but while saving Bless complains that there is\n\tno space left! I was sure I had enough space! What's going on?</simpara></question>\n\t        <answer><simpara>To be able to save a file under the same name (File-&gt;Save command) you need\n\tto have (temporarily) enough disk space to hold both the original and the\n\tnew file. This happens because the new file is created in a temporary file\n\tdirectory (eg /tmp see <xref linkend=\"bless-customizing-preferences-general\"/>) and then moved to its proper position. For example if you have a\n\t20MB file and edit it so that it becomes 21MB and the new file is supposed to\n\tbe saved in the same storage device as /tmp, you need to have 20+21=41MB free\n\tspace in that storage device to be able to save it. After a successful save,\n\tthe original file is deleted, in this case freeing 20MB.Although this can be a problem (when there is not enough disk space), it\n\tcan also be seen as a safety measure in case something goes wrong when saving.</simpara>\n\t<simpara>\n\t\tA notable exception to the above is when the size of the file to be saved has not been changed. In that case the file is saved in-place.\n\t</simpara>\n\t</answer>\n\t        </qandaentry>\n\n\t<qandaentry><question><simpara>The data in the data areas isn't displayed correctly! What is wrong?</simpara></question>\n\t        <answer><para>On some systems the data in the data areas are garbled. This is an\n\t issue with the font subsystem. What happens is that the font subsystem reports to Bless a different font width than the one that is actually used on screen.\n\t This bug should be fixed in current versions of Pango.</para>\n\t<para>\n\t Anyway, the bug is now irrevelevant: since version 0.5.0 &app; uses a different way to measure the font width.\n\t Also, the temporary workaround with the FontWidthFix preference introduced in 0.4.1 is now disabled.\n\t If you are still experiencing such problems with versions >= 0.5.0 please file a bug report.\n\t</para>\t\t\t \n\t </answer>\n\t        </qandaentry>\n\t        <qandaentry><question><simpara>Where does Bless keep its configuration files?</simpara></question>\n\t        <answer><simpara>See <xref linkend=\"bless-customizing-config\"/></simpara></answer>\n\t        </qandaentry>\n\t</qandadiv>\n\t</qandaset>\n </chapter>\n\n<!-- ============= About ================================== -->\n<!-- This section contains info about the program (not docs), such as\n\t\t\tauthor's name(s), web page, license, feedback address. This\n\t\t\tsection is optional: primary place for this info is \"About..\" box of\n\t\t\tthe program. However, if you do wish to include this info in the\n\t\t\tmanual, this is the place to put it. Alternatively, you can put this information in the title page.-->\n\t<chapter id=\"bless-about\"> \n\t\t<title>About &app;</title> \n\t\t<para> &app; was written by Alexandros Frantzis\n\t\t\t(<email>alf82 at freemail dot gr</email>). To find more information about\n\t\t\t&app;, please visit the \n\t\t\t<ulink url=\"https://github.com/afrantzis/bless\" type=\"https\">Bless Web page</ulink>.\n\t\t</para>\n\n\t\t<para> This program is distributed under the terms of the GNU\n\t\t\tGeneral Public license as published by the Free Software\n\t\t\tFoundation; either version 2 of the License, or (at your option)\n\t\t\tany later version. A copy of this license can be found at this\n\t\t\t<ulink url=\"ghelp:gpl\" type=\"help\">link</ulink>, or in the file\n\t\t\tCOPYING included with the source code of this program. </para>\n\n\t</chapter> \n</book>\n"
  },
  {
    "path": "doc/user/C/legal.xml",
    "content": "  <legalnotice id=\"legalnotice\">\n\t<para>\n\t  Permission is granted to copy, distribute and/or modify this\n\t  document under the terms of the GNU Free Documentation\n\t  License (GFDL), Version 1.1 or any later version published\n\t  by the Free Software Foundation with no Invariant Sections,\n\t  no Front-Cover Texts, and no Back-Cover Texts.  You can find\n\t  a copy of the GFDL at this <ulink type=\"help\"\n\t  url=\"ghelp:fdl\">link</ulink> or in the file COPYING-DOCS\n\t  distributed with this manual.\n         </para>\n         <para> This manual is part of a collection of GNOME manuals\n          distributed under the GFDL.  If you want to distribute this\n          manual separately from the collection, you can do so by\n          adding a copy of the license to the manual, as described in\n          section 6 of the license.\n\t</para>\n\n\t<para>\n\t  Many of the names used by companies to distinguish their\n\t  products and services are claimed as trademarks. Where those\n\t  names appear in any GNOME documentation, and the members of\n\t  the GNOME Documentation Project are made aware of those\n\t  trademarks, then the names are in capital letters or initial\n\t  capital letters.\n\t</para>\n\n\t<para>\n\t  DOCUMENT AND MODIFIED VERSIONS OF THE DOCUMENT ARE PROVIDED\n\t  UNDER  THE TERMS OF THE GNU FREE DOCUMENTATION LICENSE\n\t  WITH THE FURTHER UNDERSTANDING THAT:\n\n\t  <orderedlist>\n\t\t<listitem>\n\t\t  <para>DOCUMENT IS PROVIDED ON AN \"AS IS\" BASIS,\n                    WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR\n                    IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES\n                    THAT THE DOCUMENT OR MODIFIED VERSION OF THE\n                    DOCUMENT IS FREE OF DEFECTS MERCHANTABLE, FIT FOR\n                    A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE\n                    RISK AS TO THE QUALITY, ACCURACY, AND PERFORMANCE\n                    OF THE DOCUMENT OR MODIFIED VERSION OF THE\n                    DOCUMENT IS WITH YOU. SHOULD ANY DOCUMENT OR\n                    MODIFIED VERSION PROVE DEFECTIVE IN ANY RESPECT,\n                    YOU (NOT THE INITIAL WRITER, AUTHOR OR ANY\n                    CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY\n                    SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER\n                    OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS\n                    LICENSE. NO USE OF ANY DOCUMENT OR MODIFIED\n                    VERSION OF THE DOCUMENT IS AUTHORIZED HEREUNDER\n                    EXCEPT UNDER THIS DISCLAIMER; AND\n\t\t  </para>\n\t\t</listitem>\n\t\t<listitem>\n\t\t  <para>UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL\n                       THEORY, WHETHER IN TORT (INCLUDING NEGLIGENCE),\n                       CONTRACT, OR OTHERWISE, SHALL THE AUTHOR,\n                       INITIAL WRITER, ANY CONTRIBUTOR, OR ANY\n                       DISTRIBUTOR OF THE DOCUMENT OR MODIFIED VERSION\n                       OF THE DOCUMENT, OR ANY SUPPLIER OF ANY OF SUCH\n                       PARTIES, BE LIABLE TO ANY PERSON FOR ANY\n                       DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR\n                       CONSEQUENTIAL DAMAGES OF ANY CHARACTER\n                       INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS\n                       OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR\n                       MALFUNCTION, OR ANY AND ALL OTHER DAMAGES OR\n                       LOSSES ARISING OUT OF OR RELATING TO USE OF THE\n                       DOCUMENT AND MODIFIED VERSIONS OF THE DOCUMENT,\n                       EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF\n                       THE POSSIBILITY OF SUCH DAMAGES.\n\t\t  </para>\n\t\t</listitem>\n\t  </orderedlist>\n\t</para>\n  </legalnotice>\n\n"
  },
  {
    "path": "doc/user/meson.build",
    "content": "gnome = import('gnome')\n\nhelp_sources = [\n    'index.docbook',\n    'legal.xml',\n]\n\nhelp_html = [\n    'ch01.html',\n    'ch02.html',\n    'ch02s02.html',\n    'ch03.html',\n    'ch03s02.html',\n    'ch04.html',\n    'ch04s02.html',\n    'ch04s03.html',\n    'ch04s04.html',\n    'ch04s05.html',\n    'ch04s06.html',\n    'ch05.html',\n    'ch05s02.html',\n    'ch05s03.html',\n    'ch05s04.html',\n    'ch06.html',\n    'ch07.html',\n    'index.html',\n]\n\nhelp_media = [\n    'figures/bless_area_focus.png',\n    'figures/bless_bitwise_ops.png',\n    'figures/bless_display_tag.png',\n    'figures/bless_edit_mode.png',\n    'figures/bless_export_dialog.png',\n    'figures/bless_goto.png',\n    'figures/bless_layout_example1.png',\n    'figures/bless_layout_oha.png',\n    'figures/bless_number_base.png',\n    'figures/bless_preferences_general.png',\n    'figures/bless_preferences_session.png',\n    'figures/bless_preferences_undo.png',\n    'figures/bless_search_find.png',\n    'figures/bless_search_replace.png',\n    'figures/bless_select_range.png',\n    'figures/bless_start_window.png',\n    'figures/bless_tab_close.png',\n]\n\nif get_option('html_user_doc')\n    html_xsl = 'http://docbook.sourceforge.net/release/xsl/current/html/chunk.xsl'\n    xsltproc = find_program('xsltproc', required: false)\n\n    if xsltproc.found()\n        cmd = run_command([xsltproc, '--nonet', html_xsl])\n        if cmd.returncode() != 0\n            error('No XSLT stylesheet found, cannot generating html documentation. You can disable with -Dhtml_user_doc=false')\n        endif\n    else\n        error('No XSLT processor found, cannot generating html documentation. You can disable with -Dhtml_user_doc=false')\n    endif\n\n    custom_target(\n        'help-html',\n        command: [xsltproc, '--nonet', '-o', '@OUTDIR@/', html_xsl, '@INPUT@'],\n        input: files('C/index.docbook'),\n        output: help_html,\n        build_by_default: true,\n        install: true,\n        install_dir: join_paths(get_option('datadir'), 'help', 'C', meson.project_name()),\n    )\nendif\n\ngnome.yelp(            \n    meson.project_name(),       \n    sources: help_sources,\n    media: help_media,\n    symlink_media: true,\n)    \n"
  },
  {
    "path": "meson.build",
    "content": "project(\n    'bless',\n    'cs',\n    version: '0.6.3',\n    meson_version: '>= 0.46',\n    default_options: ['libdir=lib'],\n)\n\nadd_project_arguments('-d:ENABLE_UNIX_SPECIFIC', language: 'cs')\n\ngtk_sharp_2_dep = dependency('gtk-sharp-2.0')\nglib_sharp_2_dep = dependency('glib-sharp-2.0')\n\nsubdir('src')\nsubdir('data')\nif get_option('tests')\n    subdir('tests')\nendif\nif get_option('user_doc')\n    subdir('doc/user')\nendif\n"
  },
  {
    "path": "meson_options.txt",
    "content": "option('user_doc',\n       type: 'boolean', value: true,\n       description: 'Build and install docbook user documentation')\n\noption('html_user_doc',\n       type: 'boolean', value: true,\n       description: 'Build and install HTML user documentation (requires xsltproc and stylesheets)')\n\noption('tests',\n       type: 'boolean', value: true,\n       description: 'Build tests (requires nunit)')\n\noption('run_tests',\n       type: 'boolean', value: true,\n       description: 'Whether to run tests (requires nunit-console)')\n\n"
  },
  {
    "path": "po/LINGUAS",
    "content": ""
  },
  {
    "path": "po/Makevars",
    "content": "# Makefile variables for PO directory in any package using GNU gettext.\n\n# Usually the message domain is the same as the package name.\nDOMAIN = $(PACKAGE)\n\n# These two variables depend on the location of this directory.\nsubdir = po\ntop_builddir = ..\n\n# These options get passed to xgettext.\nXGETTEXT_OPTIONS = --keyword=_ --keyword=N_\n\n# This is the copyright holder that gets inserted into the header of the\n# $(DOMAIN).pot file.  Set this to the copyright holder of the surrounding\n# package.  (Note that the msgstr strings, extracted from the package's\n# sources, belong to the copyright holder of the package.)  Translators are\n# expected to transfer the copyright for their translations to this person\n# or entity, or to disclaim their copyright.  The empty string stands for\n# the public domain; in this case the translators are expected to disclaim\n# their copyright.\nCOPYRIGHT_HOLDER = Alexandros Frantzis\n\n# This is the email address or URL to which the translators shall report\n# bugs in the untranslated strings:\n# - Strings which are not entire sentences, see the maintainer guidelines\n#   in the GNU gettext documentation, section 'Preparing Strings'.\n# - Strings which use unclear terms or require additional context to be\n#   understood.\n# - Strings which make invalid assumptions about notation of date, time or\n#   money.\n# - Pluralisation problems.\n# - Incorrect English spelling.\n# - Incorrect formatting.\n# It can be your email address, or a mailing list address where translators\n# can write to without being subscribed, or the URL of a web page through\n# which the translators can contact you.\nMSGID_BUGS_ADDRESS =\n\n# This is the list of locale categories, beyond LC_MESSAGES, for which the\n# message catalogs shall be used.  It is usually empty.\nEXTRA_LOCALE_CATEGORIES =\n"
  },
  {
    "path": "po/POTFILES.in",
    "content": "# List of source files which contain translatable strings.\ndata/ui/BitwiseOperationsPlugin.ui\ndata/ui/ConversionTablePlugin.ui\ndata/ui/ExportDialog.ui\ndata/ui/FindReplacePlugin.ui\ndata/ui/GotoOffsetPlugin.ui\ndata/ui/LayoutSelectionDialog.ui\ndata/ui/MainWindow.ui\ndata/ui/PreferencesDialog.ui\ndata/ui/ProgressDialog.ui\ndata/ui/ProgressDisplayPlugin.ui\ndata/ui/SelectRangePlugin.ui\nsrc/buffers/SaveAsOperation.cs\nsrc/buffers/SaveOperation.cs\nsrc/gui/FileChangedBar.cs\nsrc/gui/FileService.cs\nsrc/gui/MainWindow.cs\nsrc/gui/dialogs/AboutDialog.cs\nsrc/gui/dialogs/ExportDialog.cs\nsrc/gui/dialogs/FileOverwriteAlert.cs\nsrc/gui/dialogs/LayoutSelectionDialog.cs\nsrc/gui/dialogs/PreferencesDialog.cs\nsrc/gui/dialogs/RevertConfirmationAlert.cs\nsrc/gui/dialogs/SaveConfirmationAlert.cs\nsrc/gui/dialogs/SaveConfirmationMultiAlert.cs\nsrc/gui/plugins/ConversionTablePlugin.cs\nsrc/gui/plugins/CopyOffsetPlugin.cs\nsrc/gui/plugins/FileExportPlugin.cs\nsrc/gui/plugins/FileOperationsPlugin.cs\nsrc/gui/plugins/FindReplacePlugin.cs\nsrc/gui/plugins/GotoOffsetPlugin.cs\nsrc/gui/plugins/HelpOperationsPlugin.cs\nsrc/gui/plugins/InfobarPlugin.cs\nsrc/gui/plugins/SelectLayoutPlugin.cs\nsrc/gui/plugins/SelectRangePlugin.cs\nsrc/util/BaseConverter.cs\n"
  },
  {
    "path": "src/bless-bin.in",
    "content": "#!/bin/sh\n\nmono \"@blessassemblydir@/bless.exe\" \"$@\"\n"
  },
  {
    "path": "src/buffers/ByteBuffer.cs",
    "content": "// created on 6/6/2004 at 10:46 AM\n/*\n *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing System.Collections;\nusing System;\nusing System.IO;\nusing System.Threading;\nusing Bless.Util;\nusing Bless.Tools;\nusing Mono.Unix;\n\nnamespace Bless.Buffers {\n\n///<summary>\n/// A buffer for holding bytes in a versatile manner.\n/// It supports undo-redo and can easily handle large files.\n/// Editing is also very cheap.\n///</summary>\npublic class ByteBuffer : BaseBuffer {\n\n\t///<summary>The file buffer associated with the ByteBuffer</summary>\n\tinternal FileBuffer\tfileBuf;\n\t\n\t///<summary>The collection of segments that comprise the ByteBuffer</summary>\n\tinternal SegmentCollection segCol;\n\t\n\t///<summary>Double ended queues to hold undo/redo actions</summary>\n\tDeque<ByteBufferAction> undoDeque;\n\tDeque<ByteBufferAction> redoDeque;\n\t\n\t///<summary>The last action before a Save was made</summary>\n\tByteBufferAction SaveCheckpoint;\n\t\n\t///<summary>Watches the file for external changes (outside Bless)</summary>\n\tFileSystemWatcher fsw;\n\t\n\tint maxUndoActions;\n\tbool changedBeyondUndo;\n\tstring tempDir;\n\t\n\t// automatic file naming\n\tstring autoFilename;\n\tstatic int autoNum = 1;\n\t\n\tinternal long size;\n\t\n\t// chaining related\n\tbool actionChaining;\n\tbool actionChainingFirst;\n\tMultiAction multiAction;\n\t\n\t\n\t///<summary>\n\t///  Object to use for synchronized access to the ByteBuffer\n\t///</summary>\n\treadonly public object LockObj = new object();\n\t\n\t// buffer permissions\n\tbool readAllowed;\n\tbool modifyAllowed;\n\tbool fileOperationsAllowed;\n\tbool emitEvents;\n\t\n\tpublic delegate void ChangedHandler(ByteBuffer bb);\n\t\n\t///<summary>Emitted when buffer changes</summary>\n\tpublic event ChangedHandler Changed;\n\t///<summary>Emitted when file changes (outside DataView)</summary>\n\tpublic event ChangedHandler FileChanged;\n\t///<summary>Emitted when buffer permissions change</summary>\n\tpublic event ChangedHandler PermissionsChanged;\n\t\n\tpublic void EmitChanged()\n\t{\n\t\tif (emitEvents && Changed != null) {\n\t\t\tChanged(this);\n\t\t}\n\t}\n\n\tpublic void EmitFileChanged()\n\t{\n\t\tif (emitEvents && FileChanged != null) {\n\t\t\tFileChanged(this);\n\t\t}\n\t}\n\t\n\tpublic void EmitPermissionsChanged()\n\t{\n\t\tif (emitEvents && PermissionsChanged != null) {\n\t\t\tPermissionsChanged(this);\n\t\t}\n\t}\n\t\n\t// related to asynchronous save model\n\tAsyncCallback userSaveAsyncCallback;\n\tAutoResetEvent saveFinishedEvent;\n\tbool useGLibIdle;\n\t\n\tpublic ByteBuffer() \n\t{\n\t\tsegCol = new SegmentCollection();\n\t\tundoDeque = new Deque<ByteBufferAction>();\n\t\tredoDeque = new Deque<ByteBufferAction>();\n\t\tsize = 0;\n\t\tSaveCheckpoint = null;\n\t\t\n\t\t// name the buffer automatically\n\t\tautoFilename = Catalog.GetString(\"Untitled\") + \" \" + ByteBuffer.autoNum;\n\t\tByteBuffer.autoNum++;\n\t\t\n\t\t// set default permissions \n\t\treadAllowed = true;\n\t\tfileOperationsAllowed = true;\n\t\tmodifyAllowed = true;\n\t\t\n\t\tsaveFinishedEvent = new AutoResetEvent(false);\n\t\tuseGLibIdle = false;\n\t\temitEvents = true;\n\t\t\n\t\tmaxUndoActions = -1; // unlimited undo\n\t\ttempDir = Path.GetTempPath();\n\t}\n\t\n\t///<summary>Create a ByteBuffer loaded with a file</summary>\n\tstatic public ByteBuffer FromFile(string filename)\n\t{\n\t\tByteBuffer bb = new ByteBuffer();\n\t\t\n\t\tbb.LoadWithFile(filename);\n\t\t\n\t\t// fix automatic file naming\n\t\tByteBuffer.autoNum--;\n\t\t\n\t\treturn bb;\n\t}\n\t\n\t///<summary>Create a ByteBuffer with a dummy-name</summary>\n\tpublic ByteBuffer(string filename): this() \n\t{\n\t\tthis.autoFilename = filename;\n\t\t\n\t\t// fix automatic file naming\n\t\tByteBuffer.autoNum--;\n\t}\n\t\n\t///<summary>Regard all following actions as a single one</summary>\n\tpublic void BeginActionChaining()\n\t{\n\t\tactionChaining = true;\n\t\tactionChainingFirst = true;\n\t\tmultiAction = new MultiAction();\n\t\temitEvents = false;\n\t}\n\t\n\t///<summary>Stop regarding actions as a single one</summary>\n\tpublic void EndActionChaining()\n\t{\n\t\tactionChaining = false;\n\t\tactionChainingFirst = false;\n\t\temitEvents = true;\n\t\t\n\t\tEmitChanged();\n\t}\n\t\n\t///<summary>Handle actions as a single one</summary>\n\tbool HandleChaining(ByteBufferAction action)\n\t{\n\t\tif (!actionChaining)\n\t\t\treturn false;\n\t\t\n\t\t// add the multiAction to the undo deque\t\n\t\tif (actionChainingFirst) {\n\t\t\tAddUndoAction(multiAction);\n\t\t\tactionChainingFirst = false;\n\t\t}\n\t\t\n\t\tmultiAction.Add(action);\n\t\t\n\t\treturn true;\n\t}\n\t\n\t///<summary>\n\t/// Add an action to the undo deque, taking into\n\t/// account maximum undo action restrictions \n\t///</summary>\n\tvoid AddUndoAction(ByteBufferAction action)\n\t{\n\t\tif (maxUndoActions!=-1)\n\t\t\twhile (undoDeque.Count >= maxUndoActions) {\n\t\t\t\tundoDeque.RemoveEnd();\n\t\t\t\tchangedBeyondUndo = true;\n\t\t\t}\n\t\t\t\n\t\tundoDeque.AddFront(action);\n\t}\n\t\n\tvoid RedoDequeDispose()\n\t{\n\t\tredoDeque.Clear();\n\t}\n\t\n\t///<summary>Append bytes at the end of the buffer</summary>\n\tpublic override void Append(byte[] data, long index, long length) \n\t{\t\n\t\tlock (LockObj) {\n\t\t\tif (!modifyAllowed) return;\n\t\t\tif (!IsResizable) return;\n\t\t\n\t\t\tAppendAction aa = new AppendAction(data, index, length, this);\t\n\t\t\taa.Do();\n\t\t\t\n\t\t\t// if action isn't handled as chained (ActionChaining==false)\n\t\t\t// handle it manually\n\t\t\tif (!HandleChaining(aa)) {\n\t\t\t\tAddUndoAction(aa);\n\t\t\t\tRedoDequeDispose();\n\t\t\t}\n\t\t\t\n\t\t\tEmitChanged();\n\t\t}\n\t}\n\n\t///<summary>Insert bytes into the buffer</summary>\n\tpublic override void Insert(long pos, byte[] data, long index, long length) \n\t{\n\t\tlock (LockObj) {\n\t\t\tif (!modifyAllowed) return;\n\t\t\tif (!IsResizable) return;\n\t\t\t\n\t\t\tif (pos == size) {\n\t\t\t\tAppend(data, index, length);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t\n\t\t\tInsertAction ia = new InsertAction(pos, data, index, length, this);\n\t\t\tia.Do();\n\t\t\t\n\t\t\t// if action isn't handled as chained (ActionChaining == false)\n\t\t\t// handle it manually\n\t\t\tif (!HandleChaining(ia)) {\t\t\n\t\t\t\tAddUndoAction(ia);\n\t\t\t\tRedoDequeDispose();\n\t\t\t}\n\t\t\t\n\t\t\tEmitChanged();\n\t\t}\n\t}\t\t\n\n\t///<summary>Delete bytes from the buffer</summary>\n\tpublic void Delete(long pos1, long pos2) \n\t{\n\t\tlock (LockObj) {\n\t\t\tif (!modifyAllowed) return;\n\t\t\tif (!IsResizable) return;\n\t\t\n\t\t\tDeleteAction da = new DeleteAction(pos1, pos2, this);\n\t\t\tda.Do();\n\t\t\t\n\t\t\t// if action isn't handled as chained (ActionChaining == false)\n\t\t\t// handle it manually\n\t\t\tif (!HandleChaining(da)) {\t\n\t\t\t\tAddUndoAction(da);\n\t\t\t\tRedoDequeDispose();\n\t\t\t}\n\t\t\t\n\t\t\tEmitChanged();\n\t\t}\n\t}\n\t\n\t///<summary>Replace bytes in the buffer</summary>\n\tpublic void Replace(long pos1, long pos2, byte[] data, long index, long length) \n\t{\n\t\tlock (LockObj) {\n\t\t\tif (!modifyAllowed) return;\n\t\t\t\n\t\t\t// if the file isn't resizable allow replaces \n\t\t\t// only if they don't change the file length\n\t\t\tbool equalLength = (pos2 - pos1 + 1 == length);\n\t\t\tif (!IsResizable && !equalLength) return;\n\t\t\t\n\t\t\tReplaceAction ra = new ReplaceAction(pos1, pos2, data, index, length, this);\n\t\t\tra.Do();\n\t\t\t\n\t\t\t// if action isn't handled as chained (ActionChaining == false)\n\t\t\t// handle it manually\n\t\t\tif (!HandleChaining(ra)) {\n\t\t\t\tAddUndoAction(ra);\n\t\t\t\tRedoDequeDispose();\n\t\t\t}\n\t\t\t\n\t\t\tEmitChanged();\n\t\t}\n\t}\n\t\n\tpublic void Replace(long pos1, long pos2, byte[] data) \n\t{\n\t\tReplace(pos1, pos2, data, 0, data.Length);\n\t}\n\t\n\t///<summary>Undo the last action</summary>\n\tpublic void Undo() \n\t{\n\t\tlock (LockObj) {\t\n\t\t\tif (!modifyAllowed) return;\n\t\t\n\t\t\t// if there is an action to undo\n\t\t\tif (undoDeque.Count > 0) {\n\t\t\t\tByteBufferAction action = undoDeque.RemoveFront();\n\t\t\t\taction.Undo();\n\t\t\t\tredoDeque.AddFront(action);\n\t\t\t\t\n\t\t\t\tEmitChanged();\n\t\t\t}\n\t\t\t\n\t\t}\n\t}\t\n\t\n\t///<summary>Redo the last undone action</summary>\n\tpublic void Redo() \n\t{\n\t\tlock (LockObj) {\t\n\t\t\tif (!modifyAllowed) return;\n\t\t\t\n\t\t\t// if there is an action to redo\n\t\t\tif (redoDeque.Count > 0) {\n\t\t\t\tByteBufferAction action = redoDeque.RemoveFront();\n\t\t\t\taction.Do();\n\t\t\t\tAddUndoAction(action);\n\t\t\t\t\n\t\t\t\tEmitChanged();\n\t\t\t}\n\t\t\t\n\t\t}\n\t}\n\t\n\t///<summary>\n\t/// Save the buffer as a file, using an asynchronous model\n\t///</summary>\n\tpublic IAsyncResult BeginSaveAs(string filename, ProgressCallback progressCallback, AsyncCallback ac)\n\t{\n\t\tlock (LockObj) {\n\t\t\tif (!fileOperationsAllowed) return null;\n\t\t\t\n\t\t\tsaveFinishedEvent.Reset();\n\t\t\tuserSaveAsyncCallback = ac;\n\t\t\t\n\t\t\tSaveAsOperation so = new SaveAsOperation(this, filename, progressCallback, SaveAsAsyncCallback, useGLibIdle);\n\t\t\t\n\t\t\t// don't allow messing up with the buffer\n\t\t\t// while we are saving\n\t\t\t// ...ReadAllowed is set in SaveOperation\n\t\t\t// this.ReadAllowed = false;\n\t\t\tthis.ModifyAllowed = false;\n\t\t\tthis.FileOperationsAllowed = false;\n\t\t\tthis.EmitEvents = false;\n\t\t\tif (fsw != null)\n\t\t\t\tfsw.EnableRaisingEvents = false;\n\t\t\t\n\t\t\t// start save thread\n\t\t\tThread saveThread = new Thread(so.OperationThread);\n\t\t\tsaveThread.IsBackground = true;\n\t\t\tsaveThread.Start();\n\t\t\t\n\t\t\treturn new ThreadedAsyncResult(so, saveFinishedEvent, false);\n\t\t}\n\t\t\n\t}\n\t\n\t///<summary>\n\t/// Called when an asynchronous Save As operation finishes\n\t///</summary>\n\tvoid SaveAsAsyncCallback(IAsyncResult ar)\n\t{\n\t\tlock (LockObj) {\n\t\t\tSaveAsOperation so = (SaveAsOperation)ar.AsyncState;\n\t\t\t\n\t\t\t// re-allow buffer usage\n\t\t\tthis.FileOperationsAllowed = true;\n\t\t\t\n\t\t\t\n\t\t\t// make sure Save As went smoothly before doing anything\n\t\t\tif (so.Result==SaveAsOperation.OperationResult.Finished) {\n\t\t\t\t// make sure data in undo redo are stored safely\n\t\t\t\t// because we are going to close the file\n\t\t\t\tMakePrivateCopyOfUndoRedo();\n\t\t\t\tCloseFile();\n\t\t\t\tLoadWithFile(so.SavePath);\n\t\t\t\t\n\t\t\t\tif (undoDeque.Count > 0)\n\t\t\t\t\tSaveCheckpoint = undoDeque.PeekFront();\n\t\t\t\telse\n\t\t\t\t\tSaveCheckpoint = null;\n\t\t\t\t\t\n\t\t\t\tchangedBeyondUndo = false;\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// if cancelled or caught an exception\n\t\t\t\t// delete the file only if we have altered it\n\t\t\t\tif (so.StageReached != SaveAsOperation.SaveAsStage.BeforeCreate) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tSystem.IO.File.Delete(so.SavePath);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (Exception e) {\n\t\t\t\t\t\tSystem.Console.WriteLine(e.Message);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\t// re-allow buffer usage\n\t\t\tthis.ReadAllowed = true;\n\t\t\tthis.ModifyAllowed = true;\n\t\t\t\n\t\t\tthis.EmitEvents = true;\n\t\t\t\n\t\t\tif (fsw != null)\n\t\t\t\tfsw.EnableRaisingEvents = true;\n\t\t\t\n\t\t\t// notify the world about the changes\t\t\t\n\t\t\tEmitPermissionsChanged();\n\t\t\tEmitChanged();\n\t\t\t\t\n\t\t\t// if user provided a callback, call it now\n\t\t\tif (userSaveAsyncCallback != null)\n\t\t\t\tuserSaveAsyncCallback(ar);\n\t\t\t\n\t\t\t// notify that Save As has finished\n\t\t\tsaveFinishedEvent.Set();\n\t\t}\n\t}\n\t\n\t///<summary>\n\t/// Save the buffer under the same filename, using an asynchronous model\n\t///</summary>\n\tpublic IAsyncResult BeginSave(ProgressCallback progressCallback, AsyncCallback ac) \n\t{\n\t\tlock (LockObj) {\t\t\n\t\t\tif (!fileOperationsAllowed) return null;\n\t\t\t\n\t\t\tsaveFinishedEvent.Reset();\n\t\t\tuserSaveAsyncCallback = ac;\n\t\t\t\n\t\t\tThread saveThread = null;\n\t\t\tThreadedAsyncResult tar = null;\n\n\t\t\t// decide whether to save in place or normally\n\t\t\tif (!fileBuf.IsResizable || this.Size == fileBuf.Size) {\n\t\t\t\tSaveInPlaceOperation sipo = new SaveInPlaceOperation(this, progressCallback, SaveInPlaceAsyncCallback, useGLibIdle);\n\t\t\t\tsaveThread = new Thread(sipo.OperationThread);\n\t\t\t\ttar = new ThreadedAsyncResult(sipo, saveFinishedEvent, false);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tSaveOperation so = new SaveOperation(this, TempFile.CreateName(tempDir), progressCallback, SaveAsyncCallback, useGLibIdle);\n\t\t\t\tsaveThread = new Thread(so.OperationThread);\n\t\t\t\ttar = new ThreadedAsyncResult(so, saveFinishedEvent, false);\n\t\t\t}\n\t\t\t\n\t\t\t// don't allow messing up with the buffer\n\t\t\t// while we are saving\n\t\t\t// ...ReadAllowed is set in SaveOperation\n\t\t\t//this.ReadAllowed=false;\n\t\t\tthis.ModifyAllowed = false;\n\t\t\tthis.FileOperationsAllowed = false;\n\t\t\t\n\t\t\tthis.EmitEvents = false;\n\t\t\tfsw.EnableRaisingEvents = false;\n\t\t\t\n\t\t\t// start save thread\t\t\t\n\t\t\tsaveThread.IsBackground = true;\n\t\t\tsaveThread.Start();\n\t\t\t\n\t\t\treturn tar;\n\t\t}\n\t}\n\t\n\t///<summary>\n\t/// Called when an asynchronous save operation finishes\n\t///</summary>\n\tvoid SaveAsyncCallback(IAsyncResult ar)\n\t{\n\t\tlock (LockObj) {\n\t\t\tSaveOperation so = (SaveOperation)ar.AsyncState;\n\t\t\t\n\t\t\tif (so.Result == SaveOperation.OperationResult.Finished) { // save went ok\n\t\t\t\t// No need to call CloseFile() MakePrivateCopyOfUndoRedo()\n\t\t\t\t// because it has already been called in SaveOperation\n\n\t\t\t\tLoadWithFile(so.SavePath);\n\t\t\t\t\n\t\t\t\tif (undoDeque.Count > 0)\n\t\t\t\t\tSaveCheckpoint = undoDeque.PeekFront();\n\t\t\t\telse\n\t\t\t\t\tSaveCheckpoint = null;\n\t\t\t\t\n\t\t\t\tchangedBeyondUndo = false;\n\t\t\t}\n\t\t\telse if (so.Result == SaveOperation.OperationResult.Cancelled) { // save cancelled\n\t\t\t\tif (so.StageReached == SaveOperation.SaveStage.BeforeSaveAs) {\n\t\t\t\t\tSystem.IO.File.Delete(so.TempPath);\n\t\t\t\t}\n\t\t\t\telse if (so.StageReached == SaveOperation.SaveStage.BeforeDelete) {\n\t\t\t\t\tSystem.IO.File.Delete(so.TempPath);\n\t\t\t\t\tfileBuf.Load(so.SavePath);\n\t\t\t\t}\n\t\t\t\telse if (so.StageReached == SaveOperation.SaveStage.BeforeMove) {\n\t\t\t\t\t// cancel has no effect during move.\n\t\t\t\t\t// mark operation as successful\n\t\t\t\t\tso.Result = SaveOperation.OperationResult.Finished;\n\t\t\t\t\tLoadWithFile(so.SavePath);\n\t\t\t\t\n\t\t\t\t\tif (undoDeque.Count > 0)\n\t\t\t\t\t\tSaveCheckpoint = undoDeque.PeekFront();\n\t\t\t\t\telse\n\t\t\t\t\t\tSaveCheckpoint = null;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (so.Result == SaveOperation.OperationResult.CaughtException) {\n\t\t\t\tif (so.StageReached == SaveOperation.SaveStage.BeforeSaveAs) {\n\t\t\t\t\tSystem.IO.File.Delete(so.TempPath);\n\t\t\t\t}\n\t\t\t\telse if (so.StageReached == SaveOperation.SaveStage.BeforeDelete) {\n\t\t\t\t\tSystem.IO.File.Delete(so.TempPath);\n\t\t\t\t\tfileBuf.Load(so.SavePath);\n\t\t\t\t\t// make sure FSW is valid (it is probably not\n\t\t\t\t\t// because bb.CloseFile has been called in SaveOperation)\n\t\t\t\t\tSetupFSW();\n\t\t\t\t}\n\t\t\t\telse if (so.StageReached == SaveOperation.SaveStage.BeforeMove) {\n\t\t\t\t\t// TO-DO: better handling?\n\t\t\t\t\tfileBuf.Load(so.SavePath);\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\t// re-allow buffer usage\n\t\t\tthis.ReadAllowed = true;\n\t\t\tthis.ModifyAllowed = true;\n\t\t\tthis.FileOperationsAllowed = true;\n\t\t\t\n\t\t\tthis.EmitEvents = true;\n\t\t\tfsw.EnableRaisingEvents = true;\n\t\t\t\n\t\t\t// notify the world about the changes\t\t\t\n\t\t\tEmitPermissionsChanged();\n\t\t\tEmitChanged();\t\t\t\n\t\t\t\n\t\t\t// if user provided a callback, call it now\n\t\t\tif (userSaveAsyncCallback != null)\n\t\t\t\tuserSaveAsyncCallback(ar);\n\t\t\t\n\t\t\t// notify that Save has finished\t\n\t\t\tsaveFinishedEvent.Set();\n\t\t}\n\t}\n\t\n\t///<summary>\n\t/// Called when an asynchronous in-place save operation finishes\n\t///</summary>\n\tvoid SaveInPlaceAsyncCallback(IAsyncResult ar)\n\t{\n\t\tlock (LockObj) {\n\t\t\tSaveInPlaceOperation sipo = (SaveInPlaceOperation)ar.AsyncState;\n\t\t\t\n\t\t\tif (sipo.Result == ThreadedAsyncOperation.OperationResult.Finished) { // save went ok\n\t\t\t\tLoadWithFile(sipo.SavePath);\n\t\t\t\t\n\t\t\t\tif (undoDeque.Count > 0)\n\t\t\t\t\tSaveCheckpoint = undoDeque.PeekFront();\n\t\t\t\telse\n\t\t\t\t\tSaveCheckpoint = null;\n\t\t\t\t\n\t\t\t\tchangedBeyondUndo = false;\n\t\t\t}\n\t\t\telse if (sipo.Result == ThreadedAsyncOperation.OperationResult.Cancelled) { // save cancelled\n\t\t\t\t\n\t\t\t}\n\t\t\telse if (sipo.Result == ThreadedAsyncOperation.OperationResult.CaughtException) {\n\t\t\t\t\n\t\t\t}\n\t\t\t\n\t\t\t// re-allow buffer usage\n\t\t\tthis.ReadAllowed = true;\n\t\t\tthis.ModifyAllowed = true;\n\t\t\tthis.FileOperationsAllowed = true;\n\t\t\t\n\t\t\tthis.EmitEvents = true;\n\t\t\tfsw.EnableRaisingEvents = true;\n\t\t\t\n\t\t\t// notify the world about the changes\t\t\t\n\t\t\tEmitPermissionsChanged();\n\t\t\tEmitChanged();\t\t\t\n\t\t\t\n\t\t\t// if user provided a callback, call it now\n\t\t\tif (userSaveAsyncCallback != null)\n\t\t\t\tuserSaveAsyncCallback(ar);\n\t\t\t\n\t\t\t// notify that Save has finished\t\n\t\t\tsaveFinishedEvent.Set();\n\t\t}\n\t}\n\t\n\t///<summary> \n\t/// Revert ByteBuffer to the last saved state\n\t///</summary> \n\tpublic void Revert()\n\t{\n\t\tlock (LockObj) {\n\t\t\tif (!modifyAllowed) return;\n\t\t\t\n\t\t\tif (this.HasFile) {\n\t\t\t\t// reload file\n\t\t\t\tstring filename = fileBuf.Filename;\n\t\t\t\tif (!File.Exists(filename))\n\t\t\t\t\tthrow new FileNotFoundException(filename);\n\t\t\t\n\t\t\t\tfileBuf.Close();\n\t\t\t\t\n\t\t\t\tundoDeque.Clear();\n\t\t\t\tredoDeque.Clear();\n\t\t\t\t\n\t\t\t\tLoadWithFile(filename);\n\n\t\t\t\t\n\t\t\t\tSaveCheckpoint = null;\n\t\t\t\tchangedBeyondUndo = false;\n\t\t\t\t\n\t\t\t\t// emit bytebuffer changed event\n\t\t\t\tEmitChanged();\t\t\n\t\t\t}\n\t\t}\n\t}\n\t\n\t///<summary>\n\t/// Returns in a byte array the data contained in \n\t/// the specified range in the buffer.  \n\t///</summary>\n\tpublic byte[] RangeToByteArray(IRange range)\n\t{\n\t\tif (range.Size==0)\n\t\t\treturn null;\n\t\t\n\t\tbyte[] rangeData=new byte[range.Size];\n\t\t\n\t\tlong i=0;\n\t\t\n\t\twhile (i < range.Size) {\n\t\t\trangeData[i]=this[range.Start+i];\n\t\t\ti++;\n\t\t}\n\t\t\n\t\treturn rangeData;\n\t}\n\t\n\t///<summary>\n\t/// Returns as a SegmentCollection the data contained in \n\t/// the specified range in the buffer.  \n\t///</summary>\n\tpublic SegmentCollection RangeToSegmentCollection(Util.Range range)\n\t{\n\t\tif (range.Size == 0)\n\t\t\treturn null;\n\t\t\n\t\treturn segCol.GetRange(range.Start, range.End);\n\t}\n\t\n\t///<summary> \n\t/// Sets the file buffer and resets the segment collection\n\t///</summary> \n\tprivate void LoadWithFile(string filename)\n\t{\n\t\tif (fileBuf == null)\n\t\t\tfileBuf = new FileBuffer(filename, 0xffff); // 64KB buffer\n\t\telse {\n\t\t\tfileBuf.Load(filename);\n\t\t}\n\t\t\n\t\tSegment s = new Segment(fileBuf, 0, fileBuf.Size-1);\n\t\tsegCol = new SegmentCollection();\n\t\tsegCol.Append(s);\n\t\tsize = fileBuf.Size;\n\t\t\n\t\tSetupFSW();\n\t\t\n\t\t \n\t}\n\t\n\tinternal void MakePrivateCopyOfUndoRedo()\n\t{\n\t\t// Data in the actions may reference a file buffer that \n\t\t// can become invalid (eg after saving a file)\n\t\t// Copy the data to private in-memory buffers to avoid data corruption\n\t\t// and crashes...\n\t\t//\n\n\t\tif (Preferences.Instance[\"Undo.KeepAfterSave\"] == \"Never\") {\n\t\t\tundoDeque.Clear();\n\t\t\tredoDeque.Clear();\n\t\t\treturn;\n\t\t}\n\n\t\tif (Preferences.Instance[\"Undo.KeepAfterSave\"] == \"Always\") {\n\t\t\tforeach(ByteBufferAction action in undoDeque)\n\t\t\t\taction.MakePrivateCopyOfData();\n\n\t\t\tforeach(ByteBufferAction action in redoDeque)\n\t\t\t\taction.MakePrivateCopyOfData();\n\n\t\t\treturn;\n\t\t}\n\n\t\t// if Preferences.Instance[\"Undo.KeepAfterSave\"] == \"Memory\"\n\t\t// drop the undo and redo actions that don't fit into memory (and all actions\n\t\t// after them in the Deques).\n\t\tDeque<ByteBufferAction> newUndoDeque = new Deque<ByteBufferAction>();\n\t\tDeque<ByteBufferAction> newRedoDeque = new Deque<ByteBufferAction>();\n\n\t\tforeach(ByteBufferAction action in undoDeque) {\n\t\t\tlong freeMem = long.MaxValue;\n\t\t\ttry {\t\n\t\t\t\tfreeMem = Portable.GetAvailableMemory();\n\t\t\t}\n\t\t\tcatch(NotImplementedException) {}\n\n\t\t\tif (freeMem < action.GetPrivateCopySize())\n\t\t\t\tbreak;\n\n\t\t\taction.MakePrivateCopyOfData();\n\t\t\tnewUndoDeque.AddEnd(action);\n\t\t}\n\t\t\n\t\t\n\t\tforeach(ByteBufferAction action in redoDeque) {\n\t\t\tlong freeMem = long.MaxValue;\n\t\t\ttry {\t\n\t\t\t\tfreeMem = Portable.GetAvailableMemory();\n\t\t\t}\n\t\t\tcatch(NotImplementedException) {}\n\n\t\t\tif (freeMem < action.GetPrivateCopySize())\n\t\t\t\tbreak;\n\n\t\t\taction.MakePrivateCopyOfData();\n\t\t\tnewRedoDeque.AddEnd(action);\n\t\t}\n\n\t\tundoDeque.Clear();\n\t\tredoDeque.Clear();\n\n\t\tundoDeque = newUndoDeque;\n\t\tredoDeque = newRedoDeque;\n\t}\n\t\n\tprivate void SetupFSW()\n\t{\t\n\t\t// monitor the file for changes\n\t\tif (fsw != null) {\n\t\t\tfsw.Dispose();\n\t\t\tfsw = null;\n\t\t}\n\t\t\t\n\t\tfsw = new FileSystemWatcher();\n\t\tfsw.Path = Path.GetDirectoryName(fileBuf.Filename);\n\t\tfsw.Filter = Path.GetFileName(fileBuf.Filename);\n\t\t// Currently we only properly support file content changes\n\t\tfsw.NotifyFilter = NotifyFilters.LastWrite;\n\t\tfsw.Changed += new FileSystemEventHandler(OnFileChanged);\n\t\t\n\t\tfsw.EnableRaisingEvents = true;\n\t}\n\t\n\tprivate void OnFileChanged(object source, FileSystemEventArgs e)\n\t{\n\t\tEmitFileChanged();\n\t}\n\n\tpublic override byte this[long index] {\n\t\tset { } \n\t\tget {\n\t\t\tlock (LockObj) {\n\t\t\t\tif (!readAllowed) { return 0;}\n\t\t\t\t\n\t\t\t\tlong map; \n\t\t\t\tUtil.List<Segment>.Node node;\n\t\t\t\tSegment seg = segCol.FindSegment(index, out map, out node);\n\t\t\t\t//Console.WriteLine(\"Searching index {0} at {1}:{2}\", index, map, seg);\n\t\t\t\tif (seg == null)\n\t\t\t\t\tthrow new IndexOutOfRangeException(string.Format(\"ByteBuffer[{0}]\",index));\n\t\t\t\telse {\n\t\t\t\t\ttry {\n\t\t\t\t\t\treturn seg.Buffer[seg.Start+index-map];\t\n\t\t\t\t\t}\n\t\t\t\t\tcatch(IndexOutOfRangeException) {\n\t\t\t\t\t\tConsole.WriteLine(\"Problem at index {0} at {1}:{2}\", index, map, seg);\n\t\t\t\t\t\tthrow;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t\n\t///<summary>\n\t/// Close the file associated with the ByteBuffer \n\t///</summary>\n\tpublic void CloseFile()\n\t{\n\t\tlock (LockObj) {\n\t\t\t// close the file buffer and dispose the file watcher\n\t\t\tif (fileBuf != null && fileOperationsAllowed) {\n\t\t\t\tfileBuf.Close();\n\t\t\t\tfsw.Dispose();\n\t\t\t\tfsw = null;\n\t\t\t\tsegCol = null;\n\t\t\t\t// buffer is in an unreadable state...\n\t\t\t\tthis.ReadAllowed = false;\n\t\t\t}\n\t\t}\n\t}\n\t\n\tpublic override long Size {\n\t\tget { return size;}\n\t}\n\n\tpublic bool HasFile {\n\t\tget { return fileBuf != null; }\n\t\t\t\n\t}\n\t\n\tpublic string Filename {\n\t\tget {\n\t\t\tif (fileBuf != null)\n\t\t\t\treturn fileBuf.Filename;\n\t\t\telse\n\t\t\t\treturn this.autoFilename; \n\t\t\t}\t\n\t}\n\n\tpublic bool HasChanged {\n\t\tget {\n\t\t\tif (undoDeque.Count > 0)\n\t\t\t\treturn (changedBeyondUndo || SaveCheckpoint != undoDeque.PeekFront());\n\t\t\telse\n\t\t\t\treturn (changedBeyondUndo || SaveCheckpoint != null);\n\t\t}\n\t\n\t}\n\t\n\tpublic bool CanUndo {\n\t\tget { return (undoDeque.Count > 0); }\n\t}\n\t\n\tpublic bool CanRedo {\n\t\tget { return (redoDeque.Count > 0); }\n\t}\n\t\n\tpublic bool ActionChaining {\n\t\tget { return actionChaining; }\n\t}\n\t\n\t// Whether the ByteBuffer will emit events\n\t// (eg Changed event)\n\tpublic bool EmitEvents {\n\t\tget { return emitEvents; }\n\t\tset { emitEvents = value; }\n\t}\n\t\n\t// whether buffer can be safely read\n\t// by user eg to display data in a DataView.\n\t// if false reading from the buffer just returns zeroes\n\tpublic bool ReadAllowed { \n\t\tget { return readAllowed; }\n\t\tset { \n\t\t\treadAllowed = value;\n\t\t\tEmitPermissionsChanged();\n\t\t}\n\t}\n\t\n\t// Whether buffer can be modified.\n\t// If it is false, all buffer actions\n\t// that can modify the buffer are \n\t// rendered ineffective.\n\tpublic bool ModifyAllowed {\n\t\tget { return modifyAllowed;}\n\t\tset { \n\t\t\tmodifyAllowed = value; \n\t\t\tEmitPermissionsChanged();\n\t\t}\n\t}\n\t\n\t// Whether buffer can be saved, closed etc\n\t// If it is false, all save and close operations\n\t// are ignored.\n\tpublic bool FileOperationsAllowed {\n\t\tget { return fileOperationsAllowed;}\n\t\tset { \n\t\t\tfileOperationsAllowed = value; \n\t\t\tEmitPermissionsChanged();\n\t\t}\n\t}\n\t\n\t// Whether buffer can be resized (read-only property)\n\tpublic bool IsResizable {\n\t\tget {\n\t\t\tif (fileBuf != null)\n\t\t\t\treturn fileBuf.IsResizable;\n\t\t\telse\n\t\t\t\treturn true;\n\t\t}\n\t}\n\t// Use the GLib Idle handler for progress reporting.\n\t// Mandatory if progress reporting involves Gtk+ widgets.\n\tpublic bool UseGLibIdle {\n\t\tget { return useGLibIdle; }\n\t\tset { useGLibIdle = value; }\n\t}\n\t\n\t// The maximum number of actions the Buffer\n\t// will be able to undo\n\tpublic int MaxUndoActions {\n\t\tget { return maxUndoActions; }\n\t\tset { \n\t\t\tmaxUndoActions = value;\n\t\t\tif (maxUndoActions != -1) {\n\t\t\t\t// if we are going to remove undo actions,\n\t\t\t\t// mark that we won't be able to get back to \n\t\t\t\t// the original buffer state\n\t\t\t\tif (undoDeque.Count > maxUndoActions)\n\t\t\t\t\tchangedBeyondUndo = true;\n\t\t\t\t\n\t\t\t\t// clear all undo actions beyond the limit\n\t\t\t\twhile (undoDeque.Count > maxUndoActions) {\n\t\t\t\t\tundoDeque.RemoveEnd();\n\t\t\t\t}\n\t\t\t\t\n\t\t\t}\n\t\t}\n\t}\n\t\n\t///<summary>\n\t/// The directory where temporary files are stored \n\t///</summary>\n\tpublic string TempDir {\n\t\tget { return tempDir; }\n\t\tset {  tempDir = (value == \"\") ? Path.GetTempPath() : value; }\n\t}\n\t\n\t///<summary>\n\t/// The range of the buffer as a Util.Range \n\t///</summary>\n\tpublic Util.Range Range {\n\t\tget { \n\t\t\tUtil.Range range = new Util.Range();\n\t\t\tif (size > 0) {\n\t\t\t\trange.Start = 0;\n\t\t\t\trange.End = size - 1;\n\t\t\t}\n\t\t\t\n\t\t\treturn range;\n\t\t}\n\t}\n\t\n\tinternal void Display(string s)\n\t{\n\t\tConsole.Write(s);\n\t\tsegCol.List.Display();\n\t}\n\n}\n\n} // end namespace \n"
  },
  {
    "path": "src/buffers/ByteBufferAction.cs",
    "content": "// created on 2/13/2005 at 7:02 PM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System;\nusing System.Collections.Generic;\n\nnamespace Bless.Buffers {\n\n///<summary>Abstract class for ByteBuffer actions</summary>\nabstract class ByteBufferAction {\n\tabstract public void Do();\n\tabstract public void Undo();\n\tvirtual public void MakePrivateCopyOfData() { }\n\tvirtual public long GetPrivateCopySize() { return 0; }\n}\n\n///<summary>Action for appending at the end of a ByteBuffer</summary>\nclass AppendAction: ByteBufferAction {\n\n\tSegment seg;\n\tByteBuffer byteBuf;\n\t\n\tpublic AppendAction(byte[] d, long index, long length, ByteBuffer bb) \n\t{\n\t\tbyteBuf = bb;\n\t\t\n\t\t// if there is no data to append\n\t\t// don't create a segment\n\t\tif (d.Length == 0)\n\t\t\tseg = null;\n\t\telse {\n\t\t\tSimpleBuffer cb = new SimpleBuffer();\n\t\t\tseg = new Segment(cb, cb.Size, cb.Size + length - 1);\n\t\t\t\n\t\t\tcb.Append(d, index, length);\n\t\t}\n\t}\n\t\n\tpublic override void Do() \n\t{\n\t\tif (seg == null)\n\t\t\treturn;\n\t\t// use copy of segment seg to protect it from alterations \n\t\tbyteBuf.segCol.Append(new Segment(seg.Buffer, seg.Start, seg.End));\n\t\tbyteBuf.size += seg.Size;\n\t}\n\t\n\tpublic override void Undo() {\n\t\tif (seg == null)\n\t\t\treturn;\n\t\tbyteBuf.size -= seg.Size;\n\t\tbyteBuf.segCol.DeleteRange(byteBuf.size, byteBuf.size + seg.Size - 1);\n\t}\n}\n\n///<summary>Action for inserting in a ByteBuffer</summary>\nclass InsertAction: ByteBufferAction {\n\n\tSegment seg;\n\tlong pos;\n\tByteBuffer byteBuf;\n\t\n\tpublic InsertAction(long p, byte[] d, long index, long length, ByteBuffer bb) {\n\t\tbyteBuf = bb;\n\t\tpos = p;\n\t\t\n\t\t// if there is no data to insert\n\t\t// don't create a segment\n\t\tif (length == 0)\n\t\t\tseg = null;\n\t\telse {\n\t\t\tSimpleBuffer cb = new SimpleBuffer();\n\t\t\tseg = new Segment(cb, cb.Size, cb.Size + length - 1);\n\t\t\tcb.Append(d, index, length);\n\t\t}\n\t}\n\t\n\tpublic override void Do() \n\t{\n\t\tif (seg == null)\n\t\t\treturn;\n\t\tSegmentCollection tmp = new SegmentCollection();\n\t\t// use copy of segment seg to protect it from alterations\n\t\ttmp.Append(new Segment(seg.Buffer, seg.Start, seg.End));\n\t\tbyteBuf.segCol.Insert(tmp, pos);\n\t\tbyteBuf.size += seg.Size;\n\t}\n\t\n\tpublic override void Undo() \n\t{\n\t\tif (seg == null)\n\t\t\treturn;\n\t\tbyteBuf.segCol.DeleteRange(pos, pos + seg.Size - 1);\n\t\tbyteBuf.size -= seg.Size;\n\t}\n\n}\n\n///<summary>Action for deleting from a ByteBuffer</summary>\nclass DeleteAction: ByteBufferAction {\n\n\tSegmentCollection del;\n\tlong pos1, pos2;\n\tByteBuffer byteBuf;\n\t\n\tpublic DeleteAction(long p1, long p2, ByteBuffer bb) \n\t{\n\t\tbyteBuf = bb;\n\t\tpos1 = p1;\n\t\tpos2 = p2;\n\t}\n\t\n\tpublic override void Do() \n\t{\n\t\tdel = byteBuf.segCol.DeleteRange(pos1, pos2);\n\t\tbyteBuf.size -= pos2 - pos1 + 1;\n\t}\n\t\n\tpublic override void Undo() \n\t{\n\t\tbyteBuf.segCol.Insert(del, pos1);\n\t\tbyteBuf.size += pos2 - pos1 + 1;\n\t}\n\t\n\tpublic override void MakePrivateCopyOfData()\n\t{\n\t\tforeach(Segment seg in del.List) {\n\t\t\tif (seg.Buffer.GetType() == typeof(FileBuffer)) {\n\t\t\t\tseg.MakePrivateCopyOfData();\n\t\t\t}\n\t\t}\n\t}\n\t\n\tpublic override long GetPrivateCopySize() \n\t{ \n\t\tlong size = 0;\n\n\t\tforeach(Segment seg in del.List) {\n\t\t\tif (seg.Buffer.GetType() == typeof(FileBuffer)) {\n\t\t\t\tsize += seg.Size;\n\t\t\t}\n\t\t}\n\n\t\treturn size;\n\t}\n}\n\n///<summary>Convenience action for replacing data in ByteBuffer</summary>\nclass ReplaceAction: ByteBufferAction {\n\n\tDeleteAction del;\n\tInsertAction ins;\n\t\n\tpublic ReplaceAction(long p1, long p2, byte[] d, long index, long length, ByteBuffer bb) \n\t{\n\t\tdel = new DeleteAction(p1, p2, bb);\n\t\tins = new InsertAction(p1, d, index, length, bb);\n\t}\n\t\n\tpublic override void Do() \n\t{\n\t\tdel.Do();\n\t\tins.Do();\n\t}\n\t\n\tpublic override void Undo() \n\t{\n\t\tins.Undo();\n\t\tdel.Undo();\n\t}\n\n\tpublic override void MakePrivateCopyOfData()\n\t{\n\t\tdel.MakePrivateCopyOfData();\n\t}\n\n\tpublic override long GetPrivateCopySize() \n\t{ \n\t\treturn del.GetPrivateCopySize();\n\t}\n}\n\n///<summary>Container fo many related ByteBufferActions</summary>\nclass MultiAction: ByteBufferAction {\n\n\tList<ByteBufferAction> list;\n\t\n\tpublic MultiAction()\n\t{ \n\t\tlist = new List<ByteBufferAction>();\n\t}\n\t\n\tpublic void Add(ByteBufferAction action)\n\t{\n\t\tlist.Add(action);\n\t}\n\t\n\tpublic override void Do()\n\t{\n\t\t// do the actions in normal order\n\t\tfor(int i = 0; i < list.Count; i++)\n\t\t\tlist[i].Do();\n\t}\n\t\n\tpublic override void Undo()\n\t{\n\t\t// undo the actions in reverse order\n\t\tfor(int i = list.Count - 1; i >= 0; i--)\n\t\t\tlist[i].Undo();\n\t}\n\t\n\tpublic override void MakePrivateCopyOfData()\n\t{\n\t\tforeach(ByteBufferAction a in list) {\n\t\t\ta.MakePrivateCopyOfData();\n\t\t}\n\t}\n\n\tpublic override long GetPrivateCopySize() \n\t{\n\t\tlong size = 0;\n\n\t\tforeach(ByteBufferAction a in list) {\n\t\t\tsize +=\ta.GetPrivateCopySize();\n\t\t}\n\n\t\treturn size;\n\t}\n}\n\n\n} // end namespace\n"
  },
  {
    "path": "src/buffers/FileBuffer.cs",
    "content": "// created on 6/5/2004 at 5:04 PM\n/*\n *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System.IO;\nusing System;\nusing Mono.Unix;\nusing System.Runtime.InteropServices;\n\nnamespace Bless.Buffers {\n\n///<summary>\n/// A buffer that allows access to a file by using a moving window\n///</summary>\npublic class FileBuffer: BaseBuffer\n{\n\t[DllImport (\"libc\", SetLastError=true)]\n\tstatic extern int ioctl (int fd, uint request, ref long size);\n\tconst uint BLKGETSIZE64 = 0x80041272;\n\t\n\t///<summary>The offset in the file of the start of the buffer window</summary>\n\tlong winOffset;\n\t\n\t///<summary>The number of bytes in the window that contain valid file data</summary>\n\tint winOccupied;\n\t\n\t///<summary>The data window</summary>\n\tbyte[] window;\n\t\n\t///<summary>Whether the file object is resizable</summary>\n\tbool isResizable;\n\t\n\tBinaryReader reader;\n\t\n\tlong FileLength;\n\tconst int default_size=4096; \n\t\n\t\n\tpublic FileBuffer(string fn): this(fn,default_size) { }\n\tpublic FileBuffer(string fn, int size) \n\t{\n\t\twindow = new byte[size];\n\t\tLoad(fn);\n\t}\n\t\n\t///<summary>\n\t/// Whether offset pos is contained in the current window \n\t///</summary>\n\tprivate bool InWindow(long pos) \n\t{\n\t\treturn (pos >= winOffset && pos < winOffset + winOccupied);\n\t}\n\t\n\t///<summary>\n\t/// Read data from the buffer \n\t///</summary>\n\tpublic override long Read(byte[] ba, long index, long pos, long len) \n\t{\n\t\t// bounds checking\n\t\tif (pos >= FileLength || pos<0)\n\t\t\treturn 0;\n\t\tif (pos + len > FileLength)\n\t\t\tlen = FileLength-pos+1; \n\n\t\treader.BaseStream.Seek(pos, SeekOrigin.Begin);\n\t\t// FIXME: The casts are dangerous but .NET doesn't have\n\t\t// an Int64 version of Read()!\n\t\treader.Read(ba, (int)index, (int)len);\n\t\t\n\t\t// seek back to previous position\n\t\t//reader.BaseStream.Seek(winOffset, SeekOrigin.Begin);\n\t\treturn len;\n\t}\n\t\n\tpublic override byte this[long index] {\n\t\tset { /* read only buffer */ }\n\t\tget {\n\t\t\t// if the offset we are trying to read is not in the\n\t\t\t// current window, load the window with data from the file\n\t\t\t// so that the offset is in the middle of the window\n\t\t\tif (!InWindow(index)) {\n\t\t\t\tif (index >= FileLength) {\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t\t}\t\n\t\t\t\twinOffset = index - window.Length / 2;\n\t\t\t\tif (winOffset < 0)\n\t\t\t\t\twinOffset = 0;\n\t\t\t\t\t\n\t\t\t\treader.BaseStream.Seek(winOffset, SeekOrigin.Begin);\n\t\t\t\twinOccupied = reader.Read(window, 0, window.Length);\n\t\t\t}\n\t\t\t\n\t\t\treturn window[index-winOffset];\n\t\t\t\n\t\t}\n\t}\n\t\n\n\tpublic override long Size {\n\t\tget { return FileLength; }\n\t}\n\t\n\t///<summary>\n\t/// Load the buffer with a file\n\t///</summary>\n\tpublic void Load(string filename) \n\t{\n\t\tif (reader != null)\n\t\t\treader.Close();\n\t\t\n#if ENABLE_UNIX_SPECIFIC\n\t\tUnixFileInfo fsInfo = new UnixFileInfo(filename);\n\t\tif (!fsInfo.Exists)\n\t\t\tthrow new FileNotFoundException(fsInfo.FullName);\n\t\t\n\t\t// get the size of the file or device\n\t\tif (fsInfo.IsRegularFile) {\n\t\t\tFileLength = fsInfo.Length;\n\t\t\tisResizable = true;\n\t\t}\n\t\telse if (fsInfo.IsBlockDevice) {\n\t\t\tUnixStream unixStream = fsInfo.OpenRead();\n\t\t\tioctl(unixStream.Handle, BLKGETSIZE64, ref FileLength);\n\t\t\tunixStream.Close();\n\t\t\tisResizable = false;\n\t\t}\n\t\telse\n\t\t\tthrow new NotSupportedException(\"File object isn't a regular or block device.\");\n#endif\n\n\t\tStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read,\n\t\t                               FileShare.ReadWrite);\n\t\t\n\t\tif (stream.CanSeek == false)\n\t\t\tthrow new NotSupportedException(\"File object doesn't support seeking.\");\n\t\t\n#if !ENABLE_UNIX_SPECIFIC\n\t\tFileLength = stream.Seek(0, SeekOrigin.End);\n\t\tstream.Seek(0, SeekOrigin.Begin);\n\t\tisResizable = false;\n#endif\n\t\treader = new BinaryReader(stream);\n\t\t\n\t\twinOccupied = reader.Read(window, 0, window.Length);\n\t\twinOffset = 0;\n\t}\n\n\tpublic string Filename {\n\t\tget {\n\t\t\tif (reader != null)\n\t\t\t\treturn (reader.BaseStream as FileStream).Name;\n\t\t\telse\n\t\t\t\treturn null;\n\t\t}\n\t}\n\t\n\tpublic bool IsResizable {\n\t\tget { return isResizable; }\n\t}\n\t\n\tpublic void Close()\n\t{\n\t\treader.Close();\n\t\treader = null;\n\t}\n\t\n}\n\n} // end namespace\n"
  },
  {
    "path": "src/buffers/IBuffer.cs",
    "content": "// created on 6/4/2004 at 3:37 PM\n/*\n *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing System;\n\nnamespace Bless.Buffers {\n\n\npublic interface IBuffer {\n\n\tvoid Insert(long pos, byte[] data, long index, long length);\n\tlong Read(byte[] data, long index, long pos, long len);\n\tvoid Append(byte[] data, long index, long length);\n\t\n\tvoid InsertBuffer(long pos, IBuffer buf, long index, long length);\n\tvoid AppendBuffer(IBuffer buf, long index, long length);\n\n\tbyte this[long index] {\n\t\tset;\n\t\tget;\n\t}\n\t\n\tlong Size {\n\t\tget;\n\t}\n}\n\n\npublic class BaseBuffer : IBuffer\n{\n\tpublic virtual void Insert(long pos, byte[] data, long index, long length)\n\t{\n\t\tthrow new NotImplementedException();\n\t}\n\n\tpublic virtual long Read(byte[] data, long index, long pos, long len)\n\t{\n\t\tthrow new NotImplementedException();\n\t}\n\n\tpublic virtual void Append(byte[] data, long index, long length)\n\t{\n\t\tthrow new NotImplementedException();\n\t}\n\n\tpublic virtual void InsertBuffer(long pos, IBuffer buf, long index, long length)\n\t{\n\t\tthrow new NotImplementedException();\n\t}\n\n\tpublic virtual void AppendBuffer(IBuffer buf, long index, long length)\n\t{\n\t\tthrow new NotImplementedException();\n\t}\n\n\tpublic virtual byte this[long index] {\n\t\tset { throw new NotImplementedException(); }\n\t\tget { throw new NotImplementedException(); }\n\t}\n\t\n\tpublic virtual long Size {\n\t\tget { throw new NotImplementedException(); }\n\t}\n}\n\n}\n"
  },
  {
    "path": "src/buffers/ISaveState.cs",
    "content": "// created on 2/24/2008 at 5:02 PM\n/*\n *   Copyright (c) 2008, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing Bless.Util;\n\nnamespace Bless.Buffers {\n\n///<summary>Holds information about the state of an asynchronous save operation</summary>\npublic interface ISaveState \n{\n\t\n\tThreadedAsyncOperation.OperationResult Result {\n\t\tget;\n\t}\n\n\tstring SavePath {\n\t\tget;\n\t}\n\t\n\tByteBuffer Buffer { \n\t\tget; \n\t}\n\t\n\tSystem.Exception ThreadException {\n\t\tget;\n\t}\n}\n\n} // end namespace"
  },
  {
    "path": "src/buffers/SaveAsOperation.cs",
    "content": "// created on 3/28/2005 at 3:19 PM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing System;\nusing System.IO;\nusing System.Threading;\nusing Bless.Util;\nusing Mono.Unix;\n\nnamespace Bless.Buffers {\n\n///<summary>\n/// Saves the contents of a ByteBuffer using an asynchronous threaded model\n///</summary>\npublic class SaveAsOperation : ThreadedAsyncOperation, ISaveState\n{\n\tprotected ByteBuffer byteBuffer;\n\tprotected long bytesSaved;\n\t\n\tprotected string savePath;\n\tFileStream fs;\n\t\n\tSaveAsStage stageReached;\n\t\n\tpublic ByteBuffer Buffer {\n\t\tget {return byteBuffer;}\n\t}\n\t\n\tpublic string SavePath {\n\t\tget { return savePath; }\n\t\tset { savePath=value; }\n\t}\n\t\n\tpublic long BytesSaved {\n\t\tget {return bytesSaved;}\n\t}\n\t\n\tpublic enum SaveAsStage { BeforeCreate, BeforeWrite }\n\t\n\tpublic SaveAsStage StageReached {\n\t\tget { return stageReached; }\n\t}\n\t\n\tpublic SaveAsOperation(ByteBuffer bb, string fn, ProgressCallback pc,\n\t\t\t\t\t\t\tAsyncCallback ac, bool glibIdle): base(pc, ac, glibIdle)\n\t{\n\t\tbyteBuffer=bb;\n\t\tsavePath=fn;\n\t\tfs=null;\n\t\tbytesSaved=0;\n\t}\n\t\n\tprotected bool CheckFreeSpace(string path, long extraSpace)\n\t{\n\t\ttry {\n\t\t\tlong freeSpace = Portable.GetAvailableDiskSpace(path);\n\t\t\t//System.Console.WriteLine(\"CFS {0}: {1}+{2} {3}\", path, freeSpace, extraSpace, byteBuffer.Size);\n\n\t\t\treturn (freeSpace + extraSpace >= byteBuffer.Size);\n\t\t}\n\t\tcatch (NotImplementedException) {\n\t\t\treturn true;\t\n\t\t}\n\n\t}\n\n\tprotected override bool StartProgress()\n\t{\n\t\tprogressCallback(string.Format(Catalog.GetString(\"Saving '{0}'\"), SavePath), ProgressAction.Message);\n\t\treturn progressCallback(((double)bytesSaved)/byteBuffer.Size, ProgressAction.Show);\n\t}\n\t\n\tprotected override bool UpdateProgress()\n\t{\n\t\treturn progressCallback(((double)bytesSaved)/byteBuffer.Size, ProgressAction.Update);\n\t}\n\t\n\tprotected override bool EndProgress()\n\t{\n\t\treturn progressCallback(((double)bytesSaved)/byteBuffer.Size, ProgressAction.Destroy);\n\t}\n\t\n\tprotected override void DoOperation()\n\t{\n\t\tstageReached = SaveAsStage.BeforeCreate;\n\n\t\tif (!CheckFreeSpace(Path.GetDirectoryName(savePath), 0)) {\n\t\t\tstring msg = string.Format(Catalog.GetString(\"There is not enough free space on the device to save file '{0}'.\"), savePath);\n\t\t\tthrow new IOException(msg);\n\t\t}\n\n\t\t// try to open in append mode first, so that a sharing violation\n\t\t// doesn't end up with the file truncated (as opposed\n\t\t// to using FileMode.Create)\n\t\tfs = new FileStream(savePath, FileMode.Append, FileAccess.Write);\n\t\tfs.Close();\n\t\t\n\t\t// do the actual create\n\t\tfs = new FileStream(savePath, FileMode.Create, FileAccess.Write);\n\t\t\n\t\tstageReached = SaveAsStage.BeforeWrite;\n\t\t\n\t\tconst int blockSize = 0xffff;\n\t\t\n\t\tbyte[] baTemp = new byte[blockSize];\n\t\t\n\t\t// for every node\n\t\tUtil.List<Segment>.Node node = byteBuffer.segCol.List.First;\n\t\t\n\t\twhile (node != null && !cancelled)\n\t\t{\n\t\t\t// Save the data in the node \n\t\t\t// in blocks of blockSize each\n\t\t\tSegment s = node.data;\n\t\t\tlong len = s.Size;\n\t\t\tlong nBlocks = len/blockSize;\n\t\t\tint last = (int)(len % blockSize); // bytes in last block\n\t\t\tlong i;\n\t\t\n\t\t\t// for every full block\n\t\t\tfor (i = 0; i < nBlocks; i++) {\n\t\t\t\ts.Buffer.Read(baTemp, 0, s.Start + i * blockSize, blockSize);\n\t\t\t\tfs.Write(baTemp, 0, blockSize);\n\t\t\t\tbytesSaved = (i + 1) * blockSize;\n\t\t\t\t\n\t\t\t\tif (cancelled)\n\t\t\t\t\tbreak;\t\n\t\t\t}\n\t\t\n\t\t\t// if last non-full block is not empty\n\t\t\tif (last != 0 && !cancelled) {\n\t\t\t\ts.Buffer.Read(baTemp, 0, s.Start + i * blockSize, last);\n\t\t\t\tfs.Write(baTemp, 0, last);\n\t\t\t}\n\t\t\t\t\t\n\t\t\tnode = node.next;\n\t\t}\t\n\t\t\n\t\tfs.Close();\n\t\tfs = null;\t\n\t}\n\t\n\tprotected override void EndOperation()\n\t{\n\t\tif (fs != null) {\n\t\t\tfs.Close();\n\t\t\tfs = null;\n\t\t}\n\t}\n}\n\n} // end namespace\n"
  },
  {
    "path": "src/buffers/SaveInPlaceOperation.cs",
    "content": "// created on 2/24/2008 at 4:04 PM\n/*\n *   Copyright (c) 2008, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing System;\nusing System.IO;\nusing System.Threading;\nusing Bless.Util;\nusing Mono.Unix;\n\nnamespace Bless.Buffers {\n\n///<summary>\n/// Saves the contents of a ByteBuffer using an asynchronous threaded model.\n/// This class saves the file in place and can only be used if the file size\n/// has not been changed. It works by just saving the changed parts.\n///</summary>\npublic class SaveInPlaceOperation : ThreadedAsyncOperation, ISaveState\n{\n\tprotected ByteBuffer byteBuffer;\n\tprotected long bytesSaved;\n\t\n\tprotected string savePath;\n\tFileStream fs;\n\t\n\tSaveInPlaceStage stageReached;\n\t\n\tpublic ByteBuffer Buffer {\n\t\tget {return byteBuffer;}\n\t}\n\t\n\tpublic string SavePath {\n\t\tget { return savePath; }\n\t\tset { savePath = value; }\n\t}\n\t\n\tpublic long BytesSaved {\n\t\tget {return bytesSaved;}\n\t}\n\t\n\tpublic enum SaveInPlaceStage { BeforeClose, BeforeWrite }\n\t\n\tpublic SaveInPlaceStage StageReached {\n\t\tget { return stageReached; }\n\t}\n\t\n\tpublic SaveInPlaceOperation(ByteBuffer bb, ProgressCallback pc,\n\t\t\t\t\t\t\tAsyncCallback ac, bool glibIdle): base(pc, ac, glibIdle)\n\t{\n\t\tbyteBuffer = bb;\n\t\tsavePath = byteBuffer.Filename;\n\t\tfs = null;\n\t\tbytesSaved = 0;\n\t}\n\t\n\tprotected override bool StartProgress()\n\t{\n\t\tprogressCallback(string.Format(Catalog.GetString(\"Saving '{0}'\"), SavePath), ProgressAction.Message);\n\t\treturn progressCallback(((double)bytesSaved) / byteBuffer.Size, ProgressAction.Show);\n\t}\n\t\n\tprotected override bool UpdateProgress()\n\t{\n\t\treturn progressCallback(((double)bytesSaved) / byteBuffer.Size, ProgressAction.Update);\n\t}\n\t\n\tprotected override bool EndProgress()\n\t{\n\t\treturn progressCallback(((double)bytesSaved) / byteBuffer.Size, ProgressAction.Destroy);\n\t}\n\t\n\tprotected override void DoOperation()\n\t{\n\t\tstageReached = SaveInPlaceStage.BeforeClose;\n\n\t\t// Open the file for editing.\n\t\t// Do this in the beginning to figure out if we have all the\n\t\t// required permissions before invalidating the byteBuffer.\n\t\tfs = new FileStream(savePath, FileMode.Open, FileAccess.Write, FileShare.ReadWrite);\n\t\t\n\t\t// hold a reference to the bytebuffer's segment collection\n\t\t// because it is lost when the file is closed\n\t\tSegmentCollection segCol = byteBuffer.segCol;\n\t\t\n\t\t// close file\n\t\tif (!cancelled) {\n\t\t\t// close the file, make sure that File Operations\n\t\t\t// are temporarily allowed\n\t\t\tlock(byteBuffer.LockObj) {\n\t\t\t\t// CloseFile invalidates the file buffer,\n\t\t\t\t// so make sure undo/redo data stays valid\n\t\t\t\tbyteBuffer.MakePrivateCopyOfUndoRedo();\n\t\t\t\tbyteBuffer.FileOperationsAllowed = true;\n\t\t\t\tbyteBuffer.CloseFile();\n\t\t\t\tbyteBuffer.FileOperationsAllowed = false;\n\t\t\t}\n\t\t}\n\t\t\n\t\tstageReached = SaveInPlaceStage.BeforeWrite;\n\t\t\n\t\tconst int blockSize = 0xffff;\n\t\t\n\t\tbyte[] baTemp = new byte[blockSize];\n\t\t\n\t\t//\n\t\t// Just save the changed parts...\n\t\t//\n\t\t\n\t\tUtil.List<Segment>.Node node = segCol.List.First;\n\t\t\n\t\t// hold the mapping of the start of the current segment\n\t\t// (at which offset in the file it is mapped)\n\t\tlong mapping = 0;\n\t\t\n\t\twhile (node != null && !cancelled)\n\t\t{\n\t\t\t// Save the data in the node \n\t\t\t// in blocks of blockSize each\n\t\t\tSegment s = node.data;\n\t\t\t\n\t\t\t// if the segment belongs to the original buffer, skip it\n\t\t\tif (s.Buffer.GetType() == typeof(FileBuffer)) {\n\t\t\t\tmapping += s.Size;\n\t\t\t\tnode = node.next;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t\t\n\t\t\tlong len = s.Size;\n\t\t\tlong nBlocks = len/blockSize;\n\t\t\tint last = (int)(len % blockSize); // bytes in last block\n\t\t\tlong i;\n\t\t\t\n\t\t\t// move the file cursor to the current mapping\n\t\t\tfs.Seek(mapping, SeekOrigin.Begin);\n\t\t\t\n\t\t\tbytesSaved = mapping;\n\t\t\t\n\t\t\t// for every full block\n\t\t\tfor (i = 0; i < nBlocks; i++) {\n\t\t\t\ts.Buffer.Read(baTemp, 0, s.Start + i * blockSize, blockSize);\t\n\t\t\t\tfs.Write(baTemp, 0, blockSize);\n\t\t\t\tbytesSaved = (i + 1) * blockSize;\n\t\t\t\t\n\t\t\t\tif (cancelled)\n\t\t\t\t\tbreak;\t\n\t\t\t}\n\t\t\n\t\t\t// if last non-full block is not empty\n\t\t\tif (last != 0 && !cancelled) {\n\t\t\t\ts.Buffer.Read(baTemp, 0, s.Start + i * blockSize, last);\n\t\t\t\tfs.Write(baTemp, 0, last);\n\t\t\t}\n\t\t\t\n\t\t\tmapping += s.Size;\n\t\t\tnode = node.next;\n\t\t}\t\n\t\t\n\t\tfs.Close();\n\t\tfs = null;\t\n\t}\n\t\n\tprotected override void EndOperation()\n\t{\n\t\tif (fs != null) {\n\t\t\tfs.Close();\n\t\t\tfs = null;\n\t\t}\n\t}\n}\n\n} // end namespace\n"
  },
  {
    "path": "src/buffers/SaveOperation.cs",
    "content": "// created on 4/5/2005 at 1:04 PM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing System;\nusing System.IO;\nusing System.Threading;\nusing Bless.Util;\n\nusing Mono.Unix;\n\nnamespace Bless.Buffers {\n\n///<summary>\n/// Saves the contents of a ByteBuffer using an asynchronous threaded model\n///</summary>\npublic class SaveOperation :  ThreadedAsyncOperation, ISaveState\n{\n\n\tprotected ByteBuffer byteBuffer;\n\tprotected long bytesSaved;\n\t\n\tprotected string savePath;\n\t\n\tstring tempPath;\n\tSaveStage stageReached;\n\n\tpublic ByteBuffer Buffer {\n\t\tget {return byteBuffer;}\n\t}\n\t\n\tpublic string SavePath {\n\t\tget { return savePath; }\n\t\tset { savePath = value; }\n\t}\n\t\n\tpublic long BytesSaved {\n\t\tget {return bytesSaved;}\n\t}\n\t\n\tpublic string TempPath {\n\t\tget { return tempPath;}\n\t}\n\t\n\tpublic enum SaveStage { BeforeSaveAs, BeforeDelete, BeforeMove }\n\t\n\tpublic SaveStage StageReached {\n\t\tget { return stageReached; }\n\t}\n\t\n\tpublic SaveOperation(ByteBuffer bb, string tempFilename, ProgressCallback pc,\n\t\t\t\t\t\t\tAsyncCallback ac, bool glibIdle)\n\t\t\t\t\t\t\t: base(pc, ac, glibIdle)\n\t{\n\t\tbyteBuffer = bb;\n\t\tsavePath = byteBuffer.Filename;\n\t\ttempPath = tempFilename;\n\t\tbytesSaved = 0;\n\t\tactivateProgress = false;\n\t}\n\t\n\tprotected bool CheckFreeSpace(string path, long extraSpace)\n\t{\n\t\ttry {\n\t\t\tlong freeSpace = Portable.GetAvailableDiskSpace(path);\n\t\t\t//System.Console.WriteLine(\"CFS {0}: {1}+{2} {3}\", path, freeSpace, extraSpace, byteBuffer.Size);\n\n\t\t\treturn (freeSpace + extraSpace >= byteBuffer.Size);\n\t\t}\n\t\tcatch (NotImplementedException) {\n\t\t\treturn true;\t\n\t\t}\n\n\t}\n\n\tprotected override bool StartProgress()\n\t{\n\t\tprogressCallback(string.Format(Catalog.GetString(\"Moving '{0}' to '{1}'\"), tempPath, savePath), ProgressAction.Message);\n\t\treturn progressCallback(((double)bytesSaved)/byteBuffer.Size, ProgressAction.Show);\n\t}\n\t\n\tprotected override bool UpdateProgress()\n\t{\n\t\treturn progressCallback(((double)bytesSaved)/byteBuffer.Size, ProgressAction.Update);\n\t}\n\t\n\tprotected override bool EndProgress()\n\t{\n\t\treturn progressCallback(((double)bytesSaved)/byteBuffer.Size, ProgressAction.Destroy);\n\t}\n\t\n\tprotected override void DoOperation()\n\t{\n\t\tSaveAsOperation sao = new SaveAsOperation(byteBuffer, tempPath, this.progressCallback, null, false);\n\t\tstageReached = SaveStage.BeforeSaveAs;\n\n\t\t// Check for free space for final file\n\t\t// free space for temporary file is checked in sao.DoOperation()\n\t\tif (!CheckFreeSpace(Path.GetDirectoryName(byteBuffer.Filename), byteBuffer.fileBuf.Size)) {\n\t\t\tstring msg = string.Format(Catalog.GetString(\"There is not enough free space on the device to save file '{0}'.\"), byteBuffer.Filename);\n\t\t\tthrow new IOException(msg);\n\t\t}\n\n\t\t// Save ByteBuffer as a temp file\n\t\tsao.OperationThread();\n\n\t\tif (sao.Result == ThreadedAsyncOperation.OperationResult.CaughtException)\n\t\t\tthrow sao.ThreadException;\n\t\telse if (sao.Result == ThreadedAsyncOperation.OperationResult.Cancelled)\t\n\t\t\tcancelled = true;\n\n\t\t// if user hasn't cancelled, move temp file to \n\t\t// its final location\t\n\t\tif (!cancelled) {\n\t\t\tthis.ActivateProgressReport(true);\n\t\t\tstageReached = SaveStage.BeforeDelete;\n\t\t\t\n\t\t\t// Delete here to fail early (before invalidating the byteBuffer)\n\t\t\t// if there are any issues.\n\t\t\tif (System.IO.File.Exists(savePath))\n\t\t\t\tSystem.IO.File.Delete(savePath);\n\n\t\t\t// close the file, make sure that File Operations\n\t\t\t// are temporarily allowed\n\t\t\tlock(byteBuffer.LockObj) {\n\t\t\t\t// CloseFile invalidates the file buffer,\n\t\t\t\t// so make sure undo/redo data stays valid\n\t\t\t\tbyteBuffer.MakePrivateCopyOfUndoRedo();\n\t\t\t\tbyteBuffer.FileOperationsAllowed = true;\n\t\t\t\tbyteBuffer.CloseFile();\n\t\t\t\tbyteBuffer.FileOperationsAllowed = false;\n\t\t\t}\n\t\t\t\n\t\t\tstageReached = SaveStage.BeforeMove;\n\t\t\tSystem.IO.File.Move(tempPath, savePath);\n\t\t}\t\n\t}\n\t\n\tprotected override void EndOperation()\n\t{\n\t}\n}\n\n} // end namespace\n"
  },
  {
    "path": "src/buffers/Segment.cs",
    "content": "// created on 6/4/2004 at 3:37 PM\n/*\n *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nnamespace Bless.Buffers {\n\n///<summary>Represents a portion of a buffer</summary>\npublic class Segment {\n\n\tIBuffer buffer;\n\n\tlong start;\n\tlong end;\n\n\t/// <summary>Create a segment of a buffer</summary>\n\tpublic Segment(IBuffer buffer, long start, long end)\n\t{\n\t\tthis.buffer = buffer;\n\t\tthis.start = start;\n\t\tthis.end = end;\n\t}\n\n\t///<summary>Does this segment contain an offset</summary>\n\tpublic bool Contains(long offset, long mapping) \n\t{\n\t\tif (offset >= mapping && offset <= mapping + end - start)\n\t\t\treturn true;\n\t\telse\n\t\t\treturn false;\n\t}\n\n\t///<summary>Split a segment into two</summary>\n\tpublic Segment SplitAt(long pos) \n\t{\n\t\tif (pos > end - start || pos == 0)\n\t\t\treturn null;\n \n\t\tSegment s = new Segment(buffer, start + pos, end);\t\n\t\tthis.end = start + pos - 1;\n\t\t\n\t\treturn s;\n\t}\n\t\n\tpublic void MakePrivateCopyOfData()\n\t{\n\t\tSimpleBuffer sb = new SimpleBuffer();\n\t\tsb.AppendBuffer(buffer, start, Size);\n\n\t\tbuffer = sb;\n\t\tstart = 0;\n\t\tend = sb.Size - 1;\n\t}\n\t\n\tpublic override string ToString() \n\t{\n\t\treturn string.Format(\"({0}->{1})\", start, end);\n\t}\n\t\n\tpublic long Size {\n\t\tget { return end - start + 1; }\t\n\t}\n\n\tpublic IBuffer Buffer {\n\t\tget { return buffer;}\n\t\tset { buffer = value;}\n\t}\n\t\n\t\n\tpublic long Start {\n\t\tget { return start;}\n\t\tset { start = value; }\n\t}\n\t\n\tpublic long End {\n\t\tget { return end;}\n\t\tset { end = value; }\n\t}\n\t\n}\n\n} // end namespace\n"
  },
  {
    "path": "src/buffers/SegmentCollection.cs",
    "content": "/*\n *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System;\n\nnamespace Bless.Buffers {\n\n///<summary>A collection of buffer segments</summary>\npublic class SegmentCollection {\n\n\tUtil.List<Segment> list;\n\t\n\t// cache\n\tUtil.List<Segment>.Node cachedNode;\n\tlong cachedMapping;\n\t\n\tpublic Util.List<Segment> List {\n\t\tget { return list; }\n\t}\n\t\n\tpublic SegmentCollection() {\n\t\tlist = new Util.List<Segment>();\n\t}\n\t\n\t\n\tprivate void InvalidateCache() \n\t{\n\t\tcachedNode = null;\n\t\tcachedMapping = 0;\n\t}\n\t\n\tprivate void SetCache(Util.List<Segment>.Node n, long map) \n\t{\n\t\tcachedNode = n;\n\t\tcachedMapping = map;\n\t}\n\t\n\t///<summary>Append a segment to the collection</summary>\n\tpublic void Append(Segment s) \n\t{\n\t\tUtil.List<Segment>.Node n = list.Last;\n\t\tif (n != null && n.data != null) {\n\t\t\tSegment ls = n.data;\n\t\t\tif ((s.Buffer == ls.Buffer) && (s.Start == ls.End + 1)) {\n\t\t\t\tls.End = s.End;\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tlist.Append(s);\n\t}\n\n\t///<summary>Inserts a segment after a node \n\t///and merges them if possible</summary>\n\tprivate Util.List<Segment>.Node InsertAfter(Util.List<Segment>.Node n, Segment s) \n\t{\n\t\tif (n != null && n.data != null) {\n\t\t\tSegment ls = n.data;\n\t\t\tif ((s.Buffer == ls.Buffer) && (s.Start == ls.End + 1)) {\n\t\t\t\tls.End = s.End;\n\t\t\t\treturn n;\n\t\t\t}\n\t\t}\n\t\treturn list.InsertAfter(n, s);\n\t}\n\t\n\t///<summary>Inserts a segment before a node \n\t///and merges them if possible</summary>\n\tprivate Util.List<Segment>.Node InsertBefore(Util.List<Segment>.Node n, Segment s) \n\t{\n\t\tif (n != null && n.data != null) {\n\t\t\tSegment ls = n.data;\n\t\t\tif ((s.Buffer == ls.Buffer) && (s.End + 1 == ls.Start)) {\n\t\t\t\tls.Start = s.Start;\n\t\t\t\treturn n;\n\t\t\t}\n\t\t}\n\t\treturn list.InsertBefore(n, s);\n\t}\n\t\n\t///\n\t///<summary>Find the segment that the given offset is mapped into</summary>\n\t///\n\tpublic Segment FindSegment(long offset, out long OutMapping, out Util.List<Segment>.Node OutNode) \n\t{\n\t\tOutMapping = 0;\n\t\tOutNode = null;\n\t\t\n\t\t// if this is the first search\n\t\t// set up things\n\t\tif (cachedNode == null) {\n\t\t\tif (list.First == null)\n\t\t\t\treturn null;\n\t\t\tSetCache(list.First, 0);\n\t\t}\t\n\t\t\n\t\tSegment s = cachedNode.data;\n\t\tlong curMapping = cachedMapping;\t\n\t\tUtil.List<Segment>.Node curNode = cachedNode;\n\t\t\n\t\t// is the cached node the one we want?\n\t\tif (s.Contains(offset, curMapping) == true) {\n\t\t\tOutMapping = curMapping;\n\t\t\tOutNode = curNode;\n\t\t\treturn s;\n\t\t}\n\t\t\n\t\t// search towards the beginning\n\t\tif (offset < curMapping ) {\n\t\t\twhile (curNode.prev != null) {\n\t\t\t\tcurNode = curNode.prev;\n\t\t\t\ts = curNode.data;\n\t\t\t\tcurMapping -= s.Size ;\n\t\t\t\tif (s.Contains(offset, curMapping) == true) {\n\t\t\t\t\tSetCache(curNode, curMapping); \n\t\t\t\t\tOutMapping = curMapping;\n\t\t\t\t\tOutNode = curNode;\n\t\t\t\t\treturn s;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse { // search towards the end\n\t\t\twhile (curNode.next != null) {\n\t\t\t\tcurMapping += s.Size;\n\t\t\t\tcurNode = curNode.next;\n\t\t\t\ts = curNode.data;\n\t\t\t\tif (s.Contains(offset, curMapping) == true) {\n\t\t\t\t\tSetCache(curNode, curMapping);\n\t\t\t\t\tOutMapping = curMapping;\n\t\t\t\t\tOutNode = curNode;\n\t\t\t\t\treturn s;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t\n\t\t// offset not found but return last accessed node info\n\t\tOutMapping = curMapping;\n\t\tOutNode = curNode;\n\t\treturn null;\n\t}\n\t\n\t///\n\t///<summary>Insert (or Append) a segment collection at a given offset</summary>\n\t/// \n\tpublic void Insert(SegmentCollection sc, long offset) \n\t{\n\t\tlong mapping;\n\t\tUtil.List<Segment>.Node node;\n\t\t\n\t\tSegment s = FindSegment(offset, out mapping, out node);\n\t\t\n\t\t// offset not found, check if we have to append\n\t\tif (s == null) {\n\t\t\tif ((node == null && offset == 0 ) || (node != null && offset == mapping + node.data.Size)) {\n\t\t\t\tUtil.List<Segment> lst = sc.List;\n\t\t\t\tint N = lst.Count;\n\t\t\t\tUtil.List<Segment>.Node n = lst.First;\n\t\t\t\tfor (int i = 0; i < N; i++) {\n\t\t\t\t\tAppend(n.data);\n\t\t\t\t\tn = n.next;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\t\n\t\tif (mapping == offset) { // start of segment?\n\t\t\t// insert data from the current node backwards\n\t\t\tUtil.List<Segment> lst = sc.List;\n\t\t\tint N = lst.Count;\n\t\t\tUtil.List<Segment>.Node n = lst.Last;\n\t\t\tfor (int i = 0; i < N; i++) { \n\t\t\t\tnode = InsertBefore(node, n.data);\n\t\t\t\tn = n.prev;\n\t\t\t}\n\t\t\t// update cache\n\t\t\tSetCache(node, mapping);\n\t\t}\n\t\telse { //middle of segment\t\n\t\t\tSegment s1 = s.SplitAt(offset - mapping);\n\t\t\tlist.InsertAfter(node, s1);\n\t\t\t\n\t\t\tUtil.List<Segment> lst = sc.List;\n\t\t\tint N = lst.Count;\n\t\t\tUtil.List<Segment>.Node n = lst.First;\n\t\t\tfor (int i = 0; i < N; i++) {\n\t\t\t\tnode = InsertAfter(node, n.data);\n\t\t\t\tn = n.next;\n\t\t\t}\n\t\t\t\n\t\t}\t\n\t}\n\t\n\t///<summary>Delete a range from the collection</summary>\n\tpublic SegmentCollection DeleteRange(long pos1, long pos2) \n\t{\n\t\tlong mapping1, mapping2;\n\t\tUtil.List<Segment>.Node node1;\n\t\tUtil.List<Segment>.Node node2;\n\t\t\n\t\t// Find the segments of the end points.\n\t\t// Search for the ending point first so that we won't\n\t\t// have to invalidate the cache later\n\t\tSegment s2 = FindSegment(pos2, out mapping2, out node2);\n\t\tSegment s1 = FindSegment(pos1, out mapping1, out node1);\n\t\t\n\t\tif (s1 == null || s2 == null)\n\t\t\treturn null;\n\t\t\n\t\t// ending segment == starting segment \n\t\t// needs special handling\n#region Special Handling if node1==node2\t\t\n\t\tif (ReferenceEquals(node1, node2)) {\n\t\t\tbool remove_flag = false;\n\t\t\t\n\t\t\t// try to split segment at pos1\n\t\t\tSegment s_f = s1.SplitAt(pos1-mapping1);\n\t\t\t// if we can't, this means that pos1 is \n\t\t\t// at the beginning of the segment \n\t\t\tif (s_f == null) {\n\t\t\t\ts_f = s1;\n\t\t\t\tremove_flag = true;\n\t\t\t}\n\t\t\t\n\t\t\t// try to split s_f at pos2+1\n\t\t\t// s_l is the ending part of s1 that we \n\t\t\t// should keep\n\t\t\tSegment s_l = s_f.SplitAt(pos2 - pos1 + 1);\n\t\t\t\n\t\t\t// if we can't split, this means that pos2 is \n\t\t\t// at the end of the segment,\n\t\t\t// otherwise add s_l after node1 (which contains s1) \n\t\t\tif (s_l != null)\n\t\t\t\tlist.InsertAfter(node1, s_l);\n\t\t\t\n\t\t\t// if we should remove s1\n\t\t\tif (remove_flag) {\n\t\t\t\t// try to set the cache\n\t\t\t\tif (node1.next != null)\n\t\t\t\t\tSetCache(node1.next, mapping1);\n\t\t\t\telse if (node1.prev != null) {\n\t\t\t\t\tSegment s = node1.prev.data;\n\t\t\t\t\tSetCache(node1.prev, mapping1 - s.Size);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tInvalidateCache();\n\t\t\t\t\t\n\t\t\t\tlist.Remove(node1);\n\t\t\t}\n\t\t\t//else leave the cache set as is (node1, mapping1)\n\t\t\t\n\t\t\tSegmentCollection s_c = new SegmentCollection();\n\t\t\ts_c.Append(s_f);\n\t\t\t\n\t\t\treturn s_c;\n\t\t}\n#endregion\t\t\n\t\t// try to split the ending segment\t\n\t\tSegment sl = s2.SplitAt(pos2 - mapping2 + 1);\n\t\t\n\t\t// if we can't, this means that pos2 is the \n\t\t// at the end of the ending segment\n\t\tif (sl == null)\n\t\t\tsl = s2;\t// set the whole segment for removal\n\t\telse\n\t\t\tlist.InsertAfter(node2, sl); \n\t\t\t\n\t\t\t\n\t\tUtil.List<Segment>.Node n = node1.next;\n\t\t\n\t\t// try to split the starting segment\n\t\tSegment sf = s1.SplitAt(pos1 - mapping1);\n\t\t\n\t\t// if we can't, this means that pos1 is \n\t\t// at the beginning of the starting segment \n\t\tif (sf == null) {\n\t\t\tsf = s1;\n\t\t\t// try to set the cache\n\t\t\tif (node1.prev != null) {\n\t\t\t\tSegment s = node1.prev.data;\n\t\t\t\tSetCache(node1.prev, mapping1 - s.Size);\n\t\t\t}\n\t\t\telse \n\t\t\t\tInvalidateCache();\n\t\t\t\n\t\t\tlist.Remove(node1); // remove the whole segment\n\t\t}\n\t\t\n\t\tSegmentCollection sc = new SegmentCollection();\n\t\t\n\t\t// append the first segment \n\t\tsc.Append(sf);\n\t\t\n\t\t// append to new and remove from old \n\t\t// all segments up to node2\n\t\twhile(ReferenceEquals(n, node2) == false) {\n\t\t\tsc.Append(n.data);\n\t\t\tUtil.List<Segment>.Node p = n;\n\t\t\tn = n.next;\n\t\t\t// Remove() must be placed after n.next\n\t\t\t// because it sets n.next=null\n\t\t\tlist.Remove(p);\t\n\t\t}\n\t\t// append and remove node2\n\t\tlist.Remove(n);\n\t\tsc.Append(n.data);\n\t\t\n\t\treturn sc;\n\t\t\n\t}\n\t\n\tpublic SegmentCollection GetRange(long pos1, long pos2)\n\t{\n\t\tlong mapping1, mapping2;\n\t\tUtil.List<Segment>.Node node1;\n\t\tUtil.List<Segment>.Node node2;\n\t\t\n\t\t// Find the segments of the end points.\n\t\t// Search for the ending point first so that we won't\n\t\t// have to invalidate the cache later\n\t\tSegment s2 = FindSegment(pos2, out mapping2, out node2);\n\t\tSegment s1 = FindSegment(pos1, out mapping1, out node1);\n\t\t\n\t\tif (s1 == null || s2 == null)\n\t\t\treturn null;\n\t\t\t\n\t\tif (ReferenceEquals(node1, node2)) {\n\t\t\tSegmentCollection scTemp = new SegmentCollection();\n\t\t\tSegment seg = new Segment(s1.Buffer, pos1 - mapping1 + s1.Start, pos2 - mapping1 + s1.Start);\n\t\t\tscTemp.Append(seg);\n\t\t\treturn scTemp;\n\t\t}\n\t\t\n\t\t// try to split the ending segment\t\n\t\tSegment sl = new Segment(s2.Buffer, s2.Start, pos2 - mapping2 + s2.Start );\n\t\t\n\t\t// try to split the starting segment\n\t\tSegment sf = new Segment(s1.Buffer, pos1 - mapping1 + s1.Start, s1.End);\n\t\t\n\t\t\t\t\n\t\tSegmentCollection sc = new SegmentCollection();\n\t\t\n\t\t// append the first segment \n\t\tsc.Append(sf);\n\t\t\n\t\tUtil.List<Segment>.Node n = node1.next;\n\t\t\n\t\t// append to new and remove from old\n\t\t// all segments up to node2\n\t\twhile(ReferenceEquals(n, node2) == false) {\n\t\t\tsc.Append(new Segment(n.data.Buffer, n.data.Start, n.data.End));\n\t\t\tn = n.next;\t\n\t\t}\n\t\t\n\t\tsc.Append(sl);\n\t\t\n\t\treturn sc;\n\t}\n}\n\n} // end namespace\n"
  },
  {
    "path": "src/buffers/SimpleBuffer.cs",
    "content": "// created on 6/29/2005 at 7:05 PM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System;\n\nnamespace Bless.Buffers\n{\n\n///<summary>\n/// A simple and lightweight buffer implementing the Buffer interface \n///</summary>\npublic class SimpleBuffer : BaseBuffer\n{\n\tbyte[] data;\n\t\n\tpublic SimpleBuffer() \n\t{\n\t\tdata=new byte[0];\n\t}\n\t\n\tpublic override long Read(byte[] ba, long index, long pos, long len) \n\t{\n\t\tArray.Copy(data, pos, ba, index, len);\n\t\treturn len;\n\t}\n\t\n\tpublic override void Append(byte[] d, long index, long length) \n\t{\n\t\tif (length == 0)\n\t\t\treturn;\n\t\t\n\t\tif (data.Length > 0) {\n\t\t\tbyte[] tmp = new byte[data.LongLength + length];\n\t\t\tdata.CopyTo(tmp, 0);\n\t\t\tArray.Copy(d, index, tmp, data.LongLength, length);\n\t\t\tdata = tmp;\n\t\t}\n\t\telse {\n\t\t\tdata = new byte[length];\n\t\t\tArray.Copy(d, index, data, 0, length);\n\t\t}\n\t}\n\t\n\t\n\tpublic override void AppendBuffer(IBuffer buf, long index, long length) \n\t{\n\t\tif (length == 0)\n\t\t\treturn;\n\t\t\n\t\tif (data.Length > 0) {\n\t\t\tbyte[] tmp = new byte[data.LongLength + length];\n\t\t\tdata.CopyTo(tmp, 0);\n\t\t\tbuf.Read(tmp, data.LongLength, index, length);\n\t\t\tdata = tmp;\n\t\t}\n\t\telse {\n\t\t\tdata = new byte[length];\n\t\t\tbuf.Read(data, 0, index, length);\n\t\t}\n\t}\n\n\tpublic override byte this[long index] {\n\t\tset {\n\t\t\tif (index >= data.LongLength)\n\t\t\t\treturn;\n\t\t\tdata[index]=value;\t\n\t\t }\n\t\t \n\t\tget {\n\t\t\tif (index >= data.LongLength)\n\t\t\t\treturn 0;\n\t\t\treturn data[index];\n\t\t}\n\t}\n\n\tpublic override long Size {\n\t\tget { return data.LongLength; }\n\t}\n\t\n}\n\n} // end namespace\n \n"
  },
  {
    "path": "src/gui/DataBook.cs",
    "content": "// created on 12/14/2004 at 4:23 PM\n/*\n *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing Gtk;\nusing Gdk;\nusing System;\nusing System.IO;\nusing Bless.Buffers;\n\nnamespace Bless.Gui {\n\n///<summary>A delegate to call when a databook is closed</summary>\npublic delegate void CloseViewDelegate(DataView dv);\n\n///<summary>A notebook containing DataViews</summary>\npublic class DataBook : Gtk.Notebook\n{\n\n\tpublic DataBook()\n\t{\n\t\tthis.Scrollable = true;\n\t\tthis.CanFocus = true;\n\t\tthis.EnablePopup = false;\n\t}\n\n\t///<summary>Insert a DataView into the databook.</summary>\n\tpublic void InsertView(DataView dv, CloseViewDelegate deleg, string text, int pos)\n\t{\n\t\tbase.InsertPage(dv.Display, new DataBookTabLabel(dv, deleg, text), pos);\n\t\tthis.ShowAll();\n\n\t\tdv.Buffer.Changed += new ByteBuffer.ChangedHandler(OnBufferContentsChanged);\n\t\tdv.BufferChanged += new DataView.DataViewEventHandler(OnBufferChanged);\n\n\t\tif (PageAdded != null)\n\t\t\tPageAdded(dv);\n\n\t\t// this must be placed after the page added signal,\n\t\t// so that the page change is caught by others (eg EditOperationsPlugin)\n\t\tthis.CurrentPage = pos;\n\n\t\tthis.FocusChild = dv.Display;\n\t}\n\n\t///<summary>Append a DataView to the databook.</summary>\n\tpublic void AppendView(DataView dv, CloseViewDelegate deleg, string text)\n\t{\n\t\tthis.InsertView(dv, deleg, text, this.NPages);\n\t}\n\n\t///<summary>Remove a DataView from databook.</summary>\n\tpublic void RemoveView(DataView dv)\n\t{\n\t\tdv.Buffer.Changed -= new ByteBuffer.ChangedHandler(OnBufferContentsChanged);\n\t\tdv.BufferChanged -= new DataView.DataViewEventHandler(OnBufferChanged);\n\n\t\t((DataBookTabLabel)this.GetTabLabel(dv.Display)).Cleanup();\n\n\t\tthis.RemovePage(this.PageNum(dv.Display));\n\n\t\tif (PageRemoved != null)\n\t\t\tPageRemoved(dv);\n\t}\n\n\t///<summary>Replace a DataView from databook with a new one.</summary>\n\tpublic void ReplaceView(DataView oldDv, DataView newDv, CloseViewDelegate deleg, string text)\n\t{\n\t\t// find pos of old dataview\n\t\tint pos = this.PageNum(oldDv.Display);\n\n\t\tRemoveView(oldDv);\n\n\t\tInsertView(newDv, deleg, text, pos);\n\t}\n\n\t///<summary>\n\t/// Whether a databook page can be replaced by a new one.\n\t///</summary>\n\tpublic bool CanReplacePage(int nPage)\n\t{\n\t\t// if there isn't such a page, it can't be replaced\n\t\tif (nPage >= this.NPages || nPage < 0)\n\t\t\treturn false;\n\n\t\tDataView dv = ((DataViewDisplay)this.GetNthPage(nPage)).View;\n\n\t\tByteBuffer bb = dv.Buffer;\n\n\t\tif (bb.HasChanged == false && bb.Size == 0 && !bb.HasFile)\n\t\t\treturn true;\n\t\telse\n\t\t\treturn false;\n\t}\n\n\t///<summary>\n\t/// Sets the sensitivity status of the close button of a tab containing 'w'.\n\t///</summary>\n\tpublic void SetCloseSensitivity(Widget w, bool sensitive)\n\t{\n\t\tDataBookTabLabel dbt = (DataBookTabLabel)this.GetTabLabel(w);\n\n\t\tdbt.Button.Sensitive = sensitive;\n\t}\n\n\t///<summary>\n\t/// Sets the text on tab label of the tab containg 'w'.\n\t///</summary>\n\tpublic new void SetTabLabelText(Widget w, string text)\n\t{\n\t\tDataBookTabLabel dbt = (DataBookTabLabel)this.GetTabLabel(w);\n\n\t\tdbt.Text = text;\n\t}\n\n\t///<summary>\n\t/// Updates the title of the tab with the specified DataView\n\t///</summary>\n\tvoid UpdateTabLabel(DataView dv)\n\t{\n\t\tByteBuffer bb = dv.Buffer;\n\n\t\tif (bb.HasChanged)\n\t\t\tSetTabLabelText(dv.Display, System.IO.Path.GetFileName(bb.Filename) + \"*\");\n\t\telse\n\t\t\tSetTabLabelText(dv.Display, System.IO.Path.GetFileName(bb.Filename));\n\t}\n\n\tprotected override bool OnKeyPressEvent(Gdk.EventKey e)\n\t{\n\t\tint page = -1;\n\n\t\t// if alt is pressed\n\t\tif ((e.State & ModifierType.Mod1Mask) == ModifierType.Mod1Mask) {\n\t\t\t// select a page\n\t\t\tswitch (e.Key) {\n\t\t\t\tcase Gdk.Key.Key_1:\n\t\t\t\t\tpage = 0; break;\n\t\t\t\tcase Gdk.Key.Key_2:\n\t\t\t\t\tpage = 1; break;\n\t\t\t\tcase Gdk.Key.Key_3:\n\t\t\t\t\tpage = 2; break;\n\t\t\t\tcase Gdk.Key.Key_4:\n\t\t\t\t\tpage = 3; break;\n\t\t\t\tcase Gdk.Key.Key_5:\n\t\t\t\t\tpage = 4; break;\n\t\t\t\tcase Gdk.Key.Key_6:\n\t\t\t\t\tpage = 5; break;\n\t\t\t\tcase Gdk.Key.Key_7:\n\t\t\t\t\tpage = 6; break;\n\t\t\t\tcase Gdk.Key.Key_8:\n\t\t\t\t\tpage = 7; break;\n\t\t\t\tcase Gdk.Key.Key_9:\n\t\t\t\t\tpage = 8; break;\n\t\t\t\tcase Gdk.Key.Left:\n\t\t\t\t\tpage = this.CurrentPage - 1; break;\n\t\t\t\tcase Gdk.Key.Right:\n\t\t\t\t\tpage = this.CurrentPage + 1; break;\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t// change the current page if the new one is valid\n\t\tif (page >= 0 && page < this.NPages)\n\t\t\tthis.Page = page;\n\n\t\treturn true;\n\t}\n\n\tprotected override bool OnKeyReleaseEvent(Gdk.EventKey k)\n\t{\n\t\treturn true;\n\t}\n\n\tvoid OnBufferChanged(DataView dv)\n\t{\n\t\tUpdateTabLabel(dv);\n\t}\n\n\t///<summary>Handle ByteBuffer changes</summary>\n\tvoid OnBufferContentsChanged(ByteBuffer bb)\n\t{\n\t\tGtk.Application.Invoke(delegate {\n\t\t\tDataView dv = null;\n\n\t\t\t// find DataView that owns bb\n\t\t\tforeach (DataViewDisplay dvtemp in this.Children) {\n\t\t\t\tif (dvtemp.View.Buffer == bb) {\n\t\t\t\t\tdv = dvtemp.View;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tUpdateTabLabel(dv);\n\t\t});\n\t}\n\n\n\tpublic new event DataView.DataViewEventHandler PageAdded;\n\tpublic new event DataView.DataViewEventHandler PageRemoved;\n}\n\n///<summary>A widget to display on each tab label</summary>\nclass DataBookTabLabel : Gtk.HBox\n{\n\tGtk.Label label;\n\tGtk.Button closeButton;\n\tDataView dataView;\n\tCloseViewDelegate doCloseFile;\n\n\tpublic string Text {\n\t\tget { return label.Text; }\n\t\tset { label.Text = value; }\n\t}\n\n\tpublic Gtk.Button Button {\n\t\tget { return closeButton; }\n\t}\n\n\tpublic DataBookTabLabel(DataView dv, CloseViewDelegate deleg, string str)\n\t{\n\t\tdataView = dv;\n\t\tdoCloseFile = deleg;\n\n\t\tdataView.NotificationChanged += OnNotificationChanged;\n\n\t\tlabel = new Gtk.Label(str);\n\t\tlabel.UseMarkup = true;\n\t\tlabel.UseUnderline = false;\n\n\t\tGtk.Image img = new Gtk.Image(Gtk.Stock.Close, Gtk.IconSize.Menu);\n\t\timg.SetSizeRequest(8, 8);\n\n\t\t// This doesn't compile in 1.0.2 and older,\n\t\t// keep it for later eg gtk# 2.0\n\t\tcloseButton = new Gtk.Button(img);\n\n\t\tcloseButton.Relief = Gtk.ReliefStyle.None;\n\t\tcloseButton.Clicked += OnCloseClicked;\n\t\tcloseButton.CanFocus = false;\n\n\t\tthis.Spacing = 2;\n\t\tthis.PackStart(label, false, false, 0);\n\t\tthis.PackStart(closeButton, false, false, 0);\n\n\t\tthis.ShowAll();\n\t}\n\n\tprivate void OnNotificationChanged(DataView dv)\n\t{\n\t\tif (dv.Notification == true) {\n\t\t\tlabel.Markup = \"<span foreground=\\\"blue\\\" underline=\\\"single\\\">\" + label.Text + \"</span>\";\n\t\t}\n\t\telse {\n\t\t\tlabel.Markup = label.Text;\n\t\t}\n\t}\n\n\tprivate void OnCloseClicked(object o, EventArgs args)\n\t{\n\t\tdoCloseFile(dataView);\n\t}\n\n\tpublic void Cleanup()\n\t{\n\t\tdataView.NotificationChanged -= OnNotificationChanged;\n\t\tdataView = null;\n\t}\n}\n\n}\n"
  },
  {
    "path": "src/gui/DataBookFinder.cs",
    "content": "// created on 1/17/2005 at 5:00 PM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing System;\nusing System.Text;\nusing System.Threading;\nusing Bless.Util;\nusing Bless.Buffers;\nusing Bless.Tools.Find;\n\nnamespace Bless.Gui {\n\npublic class DataBookFinder : IFinder\n{\n\tDataBook dataBook;\n\tIFindStrategy strategy;\n\tBless.Util.Range lastFound;\n\tBless.Util.Range threadResult; // the result of the search thread\n\tThread findThread;\n\n\tpublic event FirstFindHandler FirstFind;\n\n\tProgressCallback progressCallback; // callback for progress reporting\n\tAsyncCallback userFindAsyncCallback;\n\tAutoResetEvent findFinishedEvent; //\n\n\t// shared between main and ReplaceAll threads\n\tBless.Util.Range firstMatch;\n\tint numReplaced;\n\n\tbool firstTime;\n\n\t// The find progress handler runs an iteration of the application\n\t// event loop to make the gui more responsive. During such an iteration\n\t// an event may arrive and trigger again a DataBookFinder method (in the same\n\t// thread) but DataBookFinder methods are not re-entrant. The inUse variable\n\t// is used to check if the DataBookFinder is already in use and disallow such\n\t// a re-entrance.\n\tbool inUse;\n\n\tpublic DataBookFinder(DataBook db, ProgressCallback pc)\n\t{\n\t\t// connect with databook\n\t\tdataBook = db;\n\t\tlastFound = new Bless.Util.Range();\n\t\tfirstTime = true;\n\t\tinUse = false;\n\t\tprogressCallback = pc;\n\n\t\t// initialize events\n\t\tfindFinishedEvent = new AutoResetEvent(false);\n\n\t}\n\n\tpublic IFindStrategy Strategy\n\t{\n\t\tget { return strategy;}\n\t\tset { strategy = value; }\n\t}\n\n\tpublic Bless.Util.Range LastFound\n\t{\n\t\tget { return lastFound;}\n\t\tset { lastFound = value; }\n\t}\n\n\t///<summary>Sets up the messages displayed when reporting the search progress</summary>\n\tvoid SetUpFindProgressReport()\n\t{\n\t\tprogressCallback(\"Searching\", ProgressAction.Message);\n\n\t\tStringBuilder details = new StringBuilder();\n\t\tdetails.AppendFormat(\"File: {0}\", strategy.Buffer.Filename);\n\n\t\tprogressCallback(details.ToString(), ProgressAction.Details);\n\t}\n\n\t///<summary>Sets up the messages displayed when reporting the replace all progress</summary>\n\tvoid SetUpReplaceAllProgressReport()\n\t{\n\t\tprogressCallback(\"Replacing All\", ProgressAction.Message);\n\n\t\tStringBuilder details = new StringBuilder();\n\t\tdetails.AppendFormat(\"File: {0}\", strategy.Buffer.Filename);\n\n\t\tprogressCallback(details.ToString(), ProgressAction.Details);\n\t}\n\n\t///<summary>\n\t/// Handles operations that will surely produce on result (eg when\n\t/// no DataView exists).\n\t///</summary>\n\tIAsyncResult HandleProblematicOp(GenericFindOperation op, AsyncCallback ac)\n\t{\n\t\top.Result = GenericFindOperation.OperationResult.Finished;\n\n\t\tfindFinishedEvent.Reset();\n\n\t\tIAsyncResult iar = new ThreadedAsyncResult(op, findFinishedEvent, true);\n\t\tif (ac != null)\n\t\t\tac(iar);\n\n\t\tfindFinishedEvent.Set();\n\t\treturn iar;\n\t}\n\n\t///<summary>\n\t/// Find the next occurence of the byte pattern. Works asynchronously.\n\t///</summary>\n\tpublic IAsyncResult FindNext(AsyncCallback ac)\n\t{\n\t\tif (dataBook.NPages == 0 || inUse) {\n\t\t\tFindNextOperation op = new FindNextOperation(strategy, null, FindAsyncCallback);\n\t\t\treturn HandleProblematicOp(op, ac);\n\t\t}\n\n\t\tinUse = true;\n\n\t\tuserFindAsyncCallback = ac;\n\t\tfindFinishedEvent.Reset();\n\n\t\t// if this is the first time we are checking\n\t\t// for a valid pattern, emit the event\n\t\tif (firstTime == true && strategy.Pattern.Length > 0) {\n\t\t\tfirstTime = false;\n\t\t\tif (FirstFind != null)\n\t\t\t\tFirstFind();\n\t\t} // is pattern acceptable?\n\t\telse if (strategy.Pattern.Length == 0)\n\t\t\treturn null;\n\n\t\tDataView dv = ((DataViewDisplay)dataBook.CurrentPageWidget).View;\n\n\t\tstrategy.Buffer = dv.Buffer;\n\n\t\t// decide where to start searching from\n\t\tif (!dv.Selection.IsEmpty())\n\t\t\tstrategy.Position = dv.Selection.Start + 1;\n\t\telse\n\t\t\tstrategy.Position = dv.CursorOffset;\n\n\t\tSetUpFindProgressReport();\n\n\n\t\tFindNextOperation fno = new FindNextOperation(strategy, progressCallback, FindAsyncCallback);\n\n\t\t// lock the buffer, so user can't modify it while\n\t\t// searching\n\t\tstrategy.Buffer.ModifyAllowed = false;\n\t\tstrategy.Buffer.FileOperationsAllowed = false;\n\n\t\t// start find thread\n\t\tThread findThread = new Thread(fno.OperationThread);\n\t\tfindThread.IsBackground = true;\n\t\tfindThread.Start();\n\n\t\treturn new ThreadedAsyncResult(fno, findFinishedEvent, false);\n\t}\n\n\t///<summary>\n\t/// Find the previous occurence of the byte pattern. Works asynchronously.\n\t///</summary>\n\tpublic IAsyncResult FindPrevious(AsyncCallback ac)\n\t{\n\t\tif (dataBook.NPages == 0 || inUse) {\n\t\t\tFindPreviousOperation op = new FindPreviousOperation(strategy, null, FindAsyncCallback);\n\t\t\treturn HandleProblematicOp(op, ac);\n\t\t}\n\n\t\tinUse = true;\n\n\t\tuserFindAsyncCallback = ac;\n\t\tfindFinishedEvent.Reset();\n\n\t\t// if this is the first time we are checking\n\t\t// for a valid pattern, emit the event\n\t\tif (firstTime == true && strategy.Pattern.Length > 0) {\n\t\t\tfirstTime = false;\n\t\t\tif (FirstFind != null)\n\t\t\t\tFirstFind();\n\t\t} // is pattern acceptable?\n\t\telse if (strategy.Pattern.Length == 0)\n\t\t\treturn null;\n\n\t\tDataView dv = ((DataViewDisplay)dataBook.CurrentPageWidget).View;\n\n\t\tstrategy.Buffer = dv.Buffer;\n\n\t\t// decide where to start searching from\n\t\tif (!dv.Selection.IsEmpty())\n\t\t\tstrategy.Position = dv.Selection.End;\n\t\telse\n\t\t\tstrategy.Position = dv.CursorOffset;\n\n\t\tSetUpFindProgressReport();\n\n\t\tFindPreviousOperation fpo = new FindPreviousOperation(strategy, progressCallback, FindAsyncCallback);\n\n\t\t// lock the buffer, so user can't modify it while\n\t\t// searching\n\t\tstrategy.Buffer.ModifyAllowed = false;\n\t\tstrategy.Buffer.FileOperationsAllowed = false;\n\n\t\t// start find thread\n\t\tThread findThread = new Thread(fpo.OperationThread);\n\t\tfindThread.IsBackground = true;\n\t\tfindThread.Start();\n\n\t\treturn new ThreadedAsyncResult(fpo, findFinishedEvent, false);\n\t}\n\n\t///<summary>\n\t/// Called when an asynchronous Find Next/Previous operation finishes.\n\t///</summary>\n\tvoid FindAsyncCallback(IAsyncResult ar)\n\t{\n\t\tGenericFindOperation state = (GenericFindOperation)ar.AsyncState;\n\t\tThreadedAsyncOperation.OperationResult result = state.Result;\n\t\tUtil.Range match = state.Match;\n\n\t\tDataView dv = null;\n\n\t\t// find DataView that owns bb\n\t\tforeach (DataViewDisplay dvtemp in dataBook.Children) {\n\t\t\tif (dvtemp.View.Buffer == strategy.Buffer) {\n\t\t\t\tdv = dvtemp.View;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t// decide what to do based on the result of the find operation\n\t\tswitch (result) {\n\t\t\tcase ThreadedAsyncOperation.OperationResult.Finished:\n\t\t\t\tif (match != null) {\n\t\t\t\t\tlastFound = match;\n\t\t\t\t\tdv.SetSelection(match.Start, match.End);//System.Console.WriteLine(\"Found at {0}-{1}\", r.Start, r.End);\n\t\t\t\t\tdv.MoveCursor(match.End + 1, 0);\n\t\t\t\t\tdv.Display.MakeOffsetVisible(match.Start, DataViewDisplay.ShowType.Closest);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tlastFound.Clear();\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase ThreadedAsyncOperation.OperationResult.Cancelled:\n\t\t\t\tdv.MoveCursor(strategy.Position, 0);\n\t\t\t\tdv.Display.MakeOffsetVisible(strategy.Position, DataViewDisplay.ShowType.Closest);\n\t\t\t\tbreak;\n\t\t\tcase ThreadedAsyncOperation.OperationResult.CaughtException:\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\n\t\tinUse = false;\n\n\t\t// if user provided a callback, call it now\n\t\tif (userFindAsyncCallback != null)\n\t\t\tuserFindAsyncCallback(ar);\n\n\t\t// notify that the find operation has finished\n\t\tfindFinishedEvent.Set();\n\t}\n\n\t///<summary>Check if the specified range of bytes in a ByteBuffer equals a byte pattern</summary>\n\tbool RangeEqualsPattern(ByteBuffer bb, Bless.Util.Range sel, byte[] pattern)\n\t{\n\t\tint i = 0;\n\t\tint len = pattern.Length;\n\n\t\tif (sel.IsEmpty())\n\t\t\treturn false;\n\n\t\twhile (i < len && pattern[i] == bb[sel.Start+i])\n\t\t\ti++;\n\n\t\tif (i != len)\n\t\t\treturn false;\n\t\telse\n\t\t\treturn true;\n\n\t}\n\n\t///<summary>\n\t/// Replace the last match with a pattern.\n\t/// Returns whether the replace operation was succesful.\n\t///</summary>\n\tpublic bool Replace(byte[] ba)\n\t{\n\t\tif (dataBook.NPages == 0)\n\t\t\treturn false;\n\n\t\t// DataBookFinder is already in use\n\t\tif (inUse)\n\t\t\treturn true;\n\n\t\tinUse = true;\n\n\t\tDataView dv = ((DataViewDisplay)dataBook.CurrentPageWidget).View;\n\t\tif (RangeEqualsPattern(dv.Buffer, dv.Selection, strategy.Pattern)) {\n\t\t\tdv.Buffer.Replace(dv.Selection.Start, dv.Selection.End, ba);\n\n\t\t\tdv.CursorUndoDeque.AddFront(new CursorState(dv.Selection.Start, 0, dv.Selection.Start + ba.Length, 0));\n\t\t\tdv.CursorRedoDeque.Clear();\n\n\t\t\tdv.MoveCursor(dv.Selection.Start + ba.Length, 0);\n\t\t\tdv.SetSelection(-1, -1);\n\n\t\t\tlastFound.Clear();\n\n\t\t\tinUse = false;\n\t\t\treturn true;\n\t\t}\n\n\t\tinUse = false;\n\n\t\treturn false;\n\t}\n\n\t///<summary>\n\t/// Replace all matches with a pattern. Works asynchronously.\n\t///</summary>\n\tpublic IAsyncResult ReplaceAll(byte[] ba, AsyncCallback ac)\n\t{\n\t\tif (dataBook.NPages == 0 || inUse) {\n\t\t\tReplaceAllOperation op = new ReplaceAllOperation(strategy, null, ReplaceAllAsyncCallback, ba);\n\t\t\treturn HandleProblematicOp(op, ac);\n\t\t}\n\n\t\t// DataBookFinder is already in use\n\t\tif (inUse)\n\t\t\treturn null;\n\n\t\tinUse = true;\n\n\t\tuserFindAsyncCallback = ac;\n\n\t\tDataView dv = ((DataViewDisplay)dataBook.CurrentPageWidget).View;\n\n\t\t// initialize strategy\n\t\tstrategy.Buffer = dv.Buffer;\n\t\tstrategy.Position = 0;\n\n\t\tSetUpReplaceAllProgressReport();\n\n\t\tReplaceAllOperation rao = new ReplaceAllOperation(strategy, progressCallback, ReplaceAllAsyncCallback, ba);\n\n\t\tfindFinishedEvent.Reset();\n\n\t\t// don't allow messing up with the buffer\n\n\t\t// start replace all thread\n\t\tThread findThread = new Thread(rao.OperationThread);\n\t\tfindThread.IsBackground = true;\n\t\tfindThread.Start();\n\n\t\treturn new ThreadedAsyncResult(rao, findFinishedEvent, false);\n\t}\n\n\t///<summary>\n\t/// Called when an asynchronous Replace All operation finishes.\n\t///</summary>\n\tvoid ReplaceAllAsyncCallback(IAsyncResult ar)\n\t{\n\t\tReplaceAllOperation state = (ReplaceAllOperation)ar.AsyncState;\n\t\tThreadedAsyncOperation.OperationResult result = state.Result;\n\t\tUtil.Range firstMatch = state.FirstMatch;\n\n\t\tDataView dv = null;\n\n\t\t// find DataView that owns bb\n\t\tforeach (DataViewDisplay dvtemp in dataBook.Children) {\n\t\t\tif (dvtemp.View.Buffer == strategy.Buffer) {\n\t\t\t\tdv = dvtemp.View;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t// decide what to do based on the result of the Replace All operation\n\t\tif (result == ThreadedAsyncOperation.OperationResult.Cancelled) {\n\t\t\tdv.Buffer.Undo();\n\t\t}\n\t\t// if we have replaced at least one occurence,\n\t\telse if (result == ThreadedAsyncOperation.OperationResult.Finished && firstMatch != null) {\n\t\t\tlastFound = state.Match;\n\t\t\t// save the cursor state for undo/redo\n\t\t\tdv.CursorUndoDeque.AddFront(new CursorState(firstMatch.Start, 0, lastFound.Start + state.ReplacePattern.Length, 0));\n\n\t\t\t// move cursor after final replacement\n\t\t\tdv.SetSelection(-1, -1);\n\t\t\tdv.MoveCursor(lastFound.Start + state.ReplacePattern.Length, 0);\n\t\t\tdv.Display.MakeOffsetVisible(lastFound.Start + state.ReplacePattern.Length, DataViewDisplay.ShowType.Closest);\n\t\t}\n\n\t\tinUse = false;\n\n\t\t// if user provided a callback, call it now\n\t\tif (userFindAsyncCallback != null)\n\t\t\tuserFindAsyncCallback(ar);\n\n\t\t// notify that the replace all operation has finished\n\t\tfindFinishedEvent.Set();\n\t}\n}\n\n} // end namespace\n"
  },
  {
    "path": "src/gui/DataView.cs",
    "content": "// created on 6/14/2004 at 10:35 PM\n/*\n *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System.Collections;\nusing System;\nusing Gtk;\nusing Bless.Buffers;\nusing Bless.Gui.Areas;\nusing Bless.Gui.Drawers;\nusing Bless.Util;\nusing Bless.Tools;\n\nnamespace Bless.Gui {\n\n///<summary>An interface to a widget that displays data from a buffer</summary>\npublic class DataView {\n\tLayout layout;\n\tByteBuffer byteBuffer;\n\tGtk.VScrollbar vscroll;\n\tbool widgetRealized;\n\tstring prefID;\n\n\tDataViewControl dvControl;\n\tDataViewDisplay dvDisplay;\n\n\t// clipboard related\n\tbyte[] clipdata;\n\tGtk.Clipboard clipboard;\n\n\tstatic TargetEntry[] clipboardTargets = new TargetEntry[]{\n\t\t\t\t\t\t\t\t\t\t\t\tnew TargetEntry(\"application/octet-stream\", 0, 0),\n\t\t\t\t\t\t\t\t\t\t\t\tnew TargetEntry(\"UTF8_STRING\", 0, 0)\n\t\t\t\t\t\t\t\t\t\t\t};\n\n\tbool overwrite;\n\tbool notification;\n\n\t//undo-redo related\n\tDeque<CursorState> cursorUndoDeque;\n\tDeque<CursorState> cursorRedoDeque;\n\n\tpublic Deque<CursorState> CursorUndoDeque {\n\t\tget { return cursorUndoDeque; }\n\t}\n\n\tpublic Deque<CursorState> CursorRedoDeque {\n\t\tget { return cursorRedoDeque; }\n\t}\n\n\tpublic DataViewControl Control {\n\t\tget { return dvControl; }\n\t}\n\n\tpublic DataViewDisplay Display {\n\t\tget { return dvDisplay; }\n\t}\n\n\tpublic ByteBuffer Buffer {\n\t\tget { return byteBuffer; }\n\t\tset {\n\t\t\tif (value != null)\n\t\t\t\tSetupByteBuffer(value);\n\t\t\telse\n\t\t\t\tCleanupByteBuffer();\n\t\t}\n\t}\n\n\tpublic bool Overwrite {\n\t\tset {\n\t\t\toverwrite = value;\n\t\t\tif (OverwriteChanged != null)\n\t\t\t\tOverwriteChanged(this);\n\t\t}\n\n\t\tget { return overwrite; }\n\t}\n\n\tpublic Area FocusedArea {\n\t\tget { return dvDisplay.Layout.AreaGroup.FocusedArea; }\n\t}\n\n\t///<summary>\n\t/// Whether the DataView should notify the user\n\t/// that something important is going on\n\t///</summary>\n\tpublic bool Notification  {\n\t\tget { return notification; }\n\t\tset {\n\t\t\tnotification = value;\n\t\t\tif (NotificationChanged != null)\n\t\t\t\tNotificationChanged(this);\n\t\t}\n\t}\n\n\tprivate void OnByteBufferChanged(ByteBuffer bb)\n\t{\n\t\tGtk.Application.Invoke(delegate {\n\t\t\tif (byteBuffer.ReadAllowed)\n\t\t\t\tdvDisplay.Layout.AreaGroup.RedrawNow();\n\t\t});\n\t}\n\n\tprivate void OnByteBufferFileChanged(ByteBuffer bb)\n\t{\n\t\tGtk.Application.Invoke(delegate {\n\t\t\tdvDisplay.ShowFileChangedBar();\n\t\t\tNotification = true;\n\t\t\tbyteBuffer.FileOperationsAllowed = false;\n\t\t});\n\t}\n\n\n\tvoid OnPreferencesChanged(Preferences prefs)\n\t{\n\t\tif (byteBuffer == null)\n\t\t\treturn;\n\n\t\tstring undoLimited = prefs[\"Undo.Limited\"];\n\t\tstring undoActions = prefs[\"Undo.Actions\"];\n\n\t\tif (undoLimited == \"True\") {\n\t\t\tbyteBuffer.MaxUndoActions = Int32.Parse(undoActions);\n\t\t\twhile (cursorUndoDeque.Count > byteBuffer.MaxUndoActions)\n\t\t\t\tcursorUndoDeque.RemoveEnd();\n\t\t}\n\t\telse\n\t\t\tbyteBuffer.MaxUndoActions = -1;\n\n\t\t// temp dir\n\t\tbyteBuffer.TempDir = prefs[\"ByteBuffer.TempDir\"];\n\t}\n\n\tvoid AddUndoCursorState(CursorState state)\n\t{\n\t\tif (byteBuffer.MaxUndoActions != -1)\n\t\t\twhile (cursorUndoDeque.Count >= byteBuffer.MaxUndoActions)\n\t\t\t\tcursorUndoDeque.RemoveEnd();\n\n\t\tcursorUndoDeque.AddFront(state);\n\t}\n\n\tprivate void DeleteSelectionInternal()\n\t{\n\t\tAreaGroup areaGroup = dvDisplay.Layout.AreaGroup;\n\t\t\n\t\t//\n\t\t// set cursor and selection before deleting so that the view remains in a consistent state\n\t\t// (eg the selection isn't beyond the EOF)\n\t\t//\n\t\tUtil.Range prevSelection = this.Selection;\n\t\tAddUndoCursorState(new CursorState(areaGroup.CursorOffset, 0, areaGroup.Selection.Start, 0));\n\t\tcursorRedoDeque.Clear();\n\n\t\tthis.MoveCursor(areaGroup.Selection.Start, 0);\n\t\tthis.SetSelection(-1, -1);\n\t\t\n\t\tbyteBuffer.Delete(prevSelection.Start, prevSelection.End);\t\t\n\t}\n\n\t//<summary>Called when an application wants to get our clipboard data</summary>\n\tprivate void OnClipboardGet(Clipboard cb, SelectionData sd, uint n)\n\t{\n\t\t// if application accepts text\n\t\tif (sd.Target.Name == \"UTF8_STRING\") {\n\t\t\tswitch (this.FocusedArea.Type) {\n\t\t\t\tcase \"hexadecimal\":\n\t\t\t\t\tsd.Text = ByteArray.ToString(clipdata, 16);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"decimal\":\n\t\t\t\t\tsd.Text = ByteArray.ToString(clipdata, 10);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"octal\":\n\t\t\t\t\tsd.Text = ByteArray.ToString(clipdata, 8);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"binary\":\n\t\t\t\t\tsd.Text = ByteArray.ToString(clipdata, 2);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"ascii\":\n\t\t\t\t\tsd.Set(sd.Target, 8, clipdata);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t} // if application accepts raw bytes\n\t\telse if (sd.Target.Name == \"application/octet-stream\") {\n\t\t\tsd.Set(sd.Target, 8, clipdata);\n\t\t}\n\t}\n\n\tprivate void OnClipboardClear(Clipboard cb)\n\t{\n\n\t}\n\n\t///<summary>Returns any clipboard data we can accept</summary>\n\tprivate byte[] GetPasteData()\n\t{\n\t\tbyte[] data = null;\n\n\t\tSelectionData sd = clipboard.WaitForContents(Gdk.Atom.Intern(\"application/octet-stream\", false));\n\n\t\t// if there are no octet-stream data, try UTF8_STRING\n\t\t// and try to convert it to bytes\n\t\tif (sd == null) {\n\t\t\tsd = clipboard.WaitForContents(Gdk.Atom.Intern(\"UTF8_STRING\", false));\n\t\t\tif (sd != null) {\n\t\t\t\ttry {\n\t\t\t\t\t// parse string according to currently focused area\n\t\t\t\t\tswitch (this.FocusedArea.Type) {\n\t\t\t\t\t\tcase \"hexadecimal\":\n\t\t\t\t\t\t\tdata = ByteArray.FromString(sd.Text, 16);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"decimal\":\n\t\t\t\t\t\t\tdata = ByteArray.FromString(sd.Text, 10);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"octal\":\n\t\t\t\t\t\t\tdata = ByteArray.FromString(sd.Text, 8);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"binary\":\n\t\t\t\t\t\t\tdata = ByteArray.FromString(sd.Text, 2);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"ascii\":\n\t\t\t\t\t\t\tdata = sd.Data;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcatch (FormatException) {\n\t\t\t\t\t// if string cannot be parsed, consider it as plain text\n\t\t\t\t\tdata = sd.Data;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse // found octet-stream data\n\t\t\tdata = sd.Data;\n\n\t\treturn data;\n\t}\n\n\t///<summary>Create a DataView</summary>\n\tpublic DataView()\n\t{\n\t\tdvControl = new DataViewControl(this);\n\t\tdvDisplay = new DataViewDisplay(this);\n\n\t\tdvDisplay.Control = dvControl;\n\t\tdvControl.Display = dvDisplay;\n\n\t\t// initialize clipdata buffer\n\t\t// and clipboard\n\t\tclipdata = new byte[0];\n\t\tclipboard = Gtk.Clipboard.Get(Gdk.Atom.Intern(\"CLIPBOARD\", true));\n\n\t\t// initialize undo/redo cursor offset stacks\n\t\tcursorUndoDeque = new Deque<CursorState>();\n\t\tcursorRedoDeque = new Deque<CursorState>();\n\n\t\tprefID = \"dv\" + this.GetHashCode().ToString();\n\t\tPreferencesChangedHandler handler = new PreferencesChangedHandler(OnPreferencesChanged);\n\t\tPreferences.Proxy.Subscribe(\"Undo.Limited\", prefID, handler);\n\t\tPreferences.Proxy.Subscribe(\"Undo.Actions\", prefID, handler);\n\t\tPreferences.Proxy.Subscribe(\"Highlight.PatternMatch\", prefID, handler);\n\t\tPreferences.Proxy.Subscribe(\"ByteBuffer.TempDir\", prefID, handler);\n\t}\n\n\tpublic void Copy()\n\t{\n\t\tAreaGroup areaGroup = dvDisplay.Layout.AreaGroup;\n\t\t\n\t\tif (areaGroup.Areas.Count <= 0)\n\t\t\treturn;\n\n\t\tif (!byteBuffer.ReadAllowed)\n\t\t\treturn;\n\n\t\tbyte[] ba = byteBuffer.RangeToByteArray(areaGroup.Selection);\n\n\t\t// if no selection, do nothing (keep old clipboard data)\n\t\tif (ba == null)\n\t\t\treturn;\n\n\t\tclipdata = ba;\n\n\t\t// set clipboard\n\t\tclipboard.SetWithData(clipboardTargets, new ClipboardGetFunc(OnClipboardGet),\n\t\t\t\t\t\t\t  new ClipboardClearFunc(OnClipboardClear));\n\n\t\tdvDisplay.MakeOffsetVisible(areaGroup.CursorOffset, DataViewDisplay.ShowType.Closest);\n\t}\n\n\tpublic void Cut()\n\t{\n\t\tAreaGroup areaGroup = dvDisplay.Layout.AreaGroup;\n\t\t\n\t\tif (areaGroup.Areas.Count <= 0)\n\t\t\treturn;\n\t\t\n\t\t// if we can't modify the buffer...\n\t\tif (!byteBuffer.ModifyAllowed)\n\t\t\treturn;\n\t\t\n\t\t// if the buffer isn't resizable...\n\t\tif (!byteBuffer.IsResizable) {\n\t\t\treturn;\n\t\t}\n\n\t\tbyte[] ba = byteBuffer.RangeToByteArray(areaGroup.Selection);\n\n\t\t// if no selection, do nothing (keep old clipboard data)\n\t\tif (ba == null)\n\t\t\treturn;\n\n\t\tclipdata = ba;\n\n\t\t// set clipboard\n\t\tclipboard.SetWithData(clipboardTargets, new ClipboardGetFunc(OnClipboardGet),\n\t\t\t\t\t\t\t  new ClipboardClearFunc(OnClipboardClear));\n\n\t\tthis.DeleteSelectionInternal();\n\t\t\t\t\n\t\t// Make sure dataView.Redraw() is called before dvDisplay.MakeOffsetVisible()\n\t\t// so that the Scrollbar has the correct range\n\t\t// when calling dataView.Goto().\n\t\t// dataView.Redraw();\n\t\tdvDisplay.MakeOffsetVisible(areaGroup.CursorOffset, DataViewDisplay.ShowType.Closest);\n\t}\n\n\tpublic void Paste()\n\t{\n\t\tAreaGroup areaGroup = dvDisplay.Layout.AreaGroup;\n\t\t\n\t\tif (areaGroup.Areas.Count <= 0)\n\t\t\treturn;\n\n\t\t// if we can't modify the buffer...\n\t\tif (!byteBuffer.ModifyAllowed)\n\t\t\treturn;\n\t\t\t\n\t\t// if the buffer isn't resizable, ignore non-overwriting paste\n\t\tif (!byteBuffer.IsResizable && !overwrite) {\n\t\t\treturn;\n\t\t}\n\n\t\t// get data from clipboard\n\t\tbyte[] pasteData = GetPasteData();\n\n\t\t// if there wasn't any suitable data, return\n\t\tif (pasteData == null || pasteData.Length == 0)\n\t\t\treturn;\n\n\t\t// if no range is selected insert/overtwrite the data and move\n\t\t// cursor to the end of inserted data\n\t\tif (areaGroup.Selection.IsEmpty()){\n\t\t\t// if user wants to overwrite and there is something to overwrite...\n\t\t\t// There is something to overwrite if we are not pasting at the end\n\t\t\t// of the file.\n\t\t\tif (overwrite == true && areaGroup.CursorOffset < byteBuffer.Size) {\n\t\t\t\tlong endPos = areaGroup.CursorOffset + pasteData.Length - 1;\n\t\t\t\tif (endPos >= byteBuffer.Size)\n\t\t\t\t\tendPos = byteBuffer.Size - 1;\n\t\t\t\tbyteBuffer.Replace(areaGroup.CursorOffset, endPos, pasteData);\n\t\t\t}\n\t\t\telse // if user doesn't want to overwrite or there is nothing to overwrite\n\t\t\t\tbyteBuffer.Insert(areaGroup.CursorOffset, pasteData, 0, pasteData.LongLength);\n\n\t\t\tAddUndoCursorState(new CursorState(areaGroup.CursorOffset, 0, areaGroup.CursorOffset + pasteData.Length, 0));\n\t\t\tcursorRedoDeque.Clear();\n\n\t\t\tthis.MoveCursor(areaGroup.CursorOffset + pasteData.Length, 0);\n\t\t}\n\t\telse {\n\t\t\t// if a range is selected, replace the range with\n\t\t\t// the data and move the cursor to the end of\n\t\t\t// the new data\n\t\t\tbyteBuffer.Replace(areaGroup.Selection.Start, areaGroup.Selection.End, pasteData);\n\t\t\tAddUndoCursorState(new CursorState(areaGroup.Selection.Start, 0, areaGroup.Selection.Start + pasteData.Length, 0));\n\t\t\tcursorRedoDeque.Clear();\n\n\t\t\tthis.MoveCursor(areaGroup.Selection.Start + pasteData.Length, 0);\n\t\t\tthis.SetSelection(-1, -1);\n\t\t}\n\n\t\t// Make sure dataView.Redraw() is called before dvDisplay.MakeOffsetVisible()\n\t\t// so that the Scrollbar has the correct range\n\t\t// when calling dvDisplay.MakeOffsetVisible().\n\t\t// dataView.Redraw();\n\t\tdvDisplay.MakeOffsetVisible(areaGroup.CursorOffset, DataViewDisplay.ShowType.Closest);\n\t}\n\n\tpublic void Delete()\n\t{\n\t\tAreaGroup areaGroup = dvDisplay.Layout.AreaGroup;\n\t\t\n\t\tif (areaGroup.Areas.Count <= 0)\n\t\t\treturn;\n\n\t\t// if we can't modify the buffer...\n\t\tif (!byteBuffer.ModifyAllowed)\n\t\t\treturn;\n\n\t\t// if nothing is selected, delete the byte at the current offset\n\t\tif (areaGroup.Selection.IsEmpty() == true) {\n\t\t\tif (areaGroup.CursorOffset < byteBuffer.Size) {\n\t\t\t\tbyteBuffer.Delete(areaGroup.CursorOffset, areaGroup.CursorOffset);\n\t\t\t\tAddUndoCursorState(new CursorState(areaGroup.CursorOffset, areaGroup.CursorDigit, areaGroup.CursorOffset, areaGroup.CursorDigit));\n\t\t\t\tcursorRedoDeque.Clear();\n\t\t\t}\n\t\t}\n\t\telse { // delete the selection\n\t\t\tDeleteSelectionInternal();\n\t\t}\n\n\t\tdvDisplay.MakeOffsetVisible(areaGroup.CursorOffset, DataViewDisplay.ShowType.Closest);\n\t}\n\n\tpublic void DeleteBackspace()\n\t{\n\t\tAreaGroup areaGroup = dvDisplay.Layout.AreaGroup;\n\t\t\n\t\tif (areaGroup.Areas.Count <= 0)\n\t\t\treturn;\n\n\t\tif (!byteBuffer.ModifyAllowed)\n\t\t\treturn;\n\n\t\t// if nothing is selected, delete the byte at the previous offset\n\t\tif (areaGroup.Selection.IsEmpty() == true) {\n\t\t\tlong cOffset = areaGroup.CursorOffset;\n\n\t\t\tif (cOffset > 0) {\n\t\t\t\tthis.MoveCursor(cOffset - 1, areaGroup.CursorDigit);\n\t\t\t\tbyteBuffer.Delete(cOffset - 1, cOffset - 1);\n\t\t\t\tAddUndoCursorState(new CursorState(cOffset, areaGroup.CursorDigit, cOffset - 1, areaGroup.CursorDigit));\n\t\t\t\tcursorRedoDeque.Clear();\n\t\t\t}\n\t\t}\n\t\telse { // delete the selection\n\t\t\tDeleteSelectionInternal();\n\t\t}\n\n\t\tdvDisplay.MakeOffsetVisible(areaGroup.CursorOffset, DataViewDisplay.ShowType.Closest);\n\t}\n\n\tpublic void Undo()\n\t{\n\t\t// if we can't modify the buffer...\n\t\tif (!byteBuffer.ModifyAllowed)\n\t\t\treturn;\n\n\t\t// undo buffer changes\n\t\tbyteBuffer.Undo();\n\n\t\t// restore cursor position\n\t\tif (cursorUndoDeque.Count > 0) {\n\t\t\tCursorState ch = (CursorState)cursorUndoDeque.RemoveFront();\n\t\t\tcursorRedoDeque.AddFront(ch);\n\n\t\t\t// clear the selection\n\t\t\tthis.SetSelection(-1, -1);\n\n\t\t\tdvDisplay.MakeOffsetVisible(ch.UndoOffset, DataViewDisplay.ShowType.Closest);\n\t\t\tthis.MoveCursor(ch.UndoOffset, ch.UndoDigit);\n\t\t}\n\t}\n\n\tpublic void Redo()\n\t{\n\t\t// if we can't modify the buffer...\n\t\tif (!byteBuffer.ModifyAllowed)\n\t\t\treturn;\n\n\t\t// redo buffer changes\n\t\tbyteBuffer.Redo();\n\n\t\t// restore cursor position\n\t\tif (cursorRedoDeque.Count > 0) {\n\t\t\tCursorState ch = (CursorState)cursorRedoDeque.RemoveFront();\n\t\t\tAddUndoCursorState(ch);\n\n\t\t\t// clear the selection\n\t\t\tthis.SetSelection(-1, -1);\n\n\t\t\tdvDisplay.MakeOffsetVisible(ch.RedoOffset, DataViewDisplay.ShowType.Closest);\n\t\t\tthis.MoveCursor(ch.RedoOffset, ch.RedoDigit);\n\t\t}\n\t}\n\n\tpublic void Revert()\n\t{\n\t\t// if we can't modify the buffer...\n\t\tif (!byteBuffer.ModifyAllowed)\n\t\t\treturn;\n\n\t\tbyteBuffer.Revert();\n\n\t\tcursorRedoDeque.Clear();\n\t\tcursorUndoDeque.Clear();\n\n\t\tSetSelection(-1, -1);\n\t\tMoveCursor(0, 0);\n\t}\n\n\tprivate void SetupByteBuffer(ByteBuffer bb)\n\t{\n\t\tbyteBuffer = bb;\n\t\tbyteBuffer.Changed += OnByteBufferChanged;\n\t\tbyteBuffer.FileChanged += OnByteBufferFileChanged;\n\n\t\t\n\t\tAreaGroup areaGroup = dvDisplay.Layout.AreaGroup;\n\t\t\n\t\tareaGroup.Buffer = byteBuffer;\n\t\tareaGroup.SetCursor(0, 0);\n\t\tareaGroup.Selection = new Util.Range();\n\t\t\n\t\tdvDisplay.Redraw();\n\t\tdvDisplay.VScroll.Adjustment.Value = 0;\n\n\t\tOnPreferencesChanged(Preferences.Instance);\n\t\tif (BufferChanged != null)\n\t\t\tBufferChanged(this);\n\t}\n\n\tprivate void CleanupByteBuffer()\n\t{\n\t\tif (byteBuffer != null) {\n\t\t\tbyteBuffer.Changed -= OnByteBufferChanged;\n\t\t\tbyteBuffer.FileChanged -= OnByteBufferFileChanged;\n\t\t}\n\t\t\n\t\tAreaGroup areaGroup = dvDisplay.Layout.AreaGroup;\n\t\t\n\t\tareaGroup.Buffer = null;\n\t\tareaGroup.SetCursor(0, 0);\n\t\tareaGroup.Selection.Clear();\n\n\t\tbyteBuffer = null;\n\t}\n\n\tpublic void Cleanup()\n\t{\n\t\tthis.Buffer = null;\n\n\t\t// all these to help the GC...\n\t\tdvDisplay.Cleanup();\n\t\tdvDisplay = null;\n\t\tdvControl.Cleanup();\n\t\tdvControl = null;\n\n\t\tPreferences.Proxy.Unsubscribe(\"Undo.Limited\", prefID);\n\t\tPreferences.Proxy.Unsubscribe(\"Undo.Actions\", prefID);\n\t\tPreferences.Proxy.Unsubscribe(\"Highlight.PatternMatch\", prefID);\n\t\tPreferences.Proxy.Unsubscribe(\"ByteBuffer.TempDir\", prefID);\n\t}\n\t\n\t/// <summary>\n\t/// Sets the current selection. It makes sure that the selection is sorted.\n\t/// </summary>\n\tpublic void SetSelection(long start, long end)\n\t{\n\t\tAreaGroup areaGroup = dvDisplay.Layout.AreaGroup;\n\t\t\n\t\t// check whether the selection has really\n\t\t// changed...\n\t\tif (areaGroup.Areas.Count <= 0)\n\t\t\treturn;\n\n\t\tBless.Util.IRange sel = areaGroup.Selection;\n\n\t\t// if there is no change, don't do anything\n\t\tif (sel.Start == start && sel.End == end)\n\t\t\treturn;\n\n\t\tBless.Util.Range newSel = new Bless.Util.Range(start, end);\n\t\tnewSel.Sort();\n\t\t\n\t\tareaGroup.Selection = newSel;\n\t\t\n\t\tif (SelectionChanged != null)\n\t\t\tSelectionChanged(this);\n\t}\n\n\tpublic Bless.Util.Range Selection\n\t{\n\t\tget {\n\t\t\tAreaGroup areaGroup = dvDisplay.Layout.AreaGroup;\n\t\t\t\n\t\t\tif (areaGroup.Areas.Count <= 0)\n\t\t\t\treturn new Bless.Util.Range();\n\n\n\t\t\tBless.Util.Range r = areaGroup.Selection;\n\t\t\treturn new Bless.Util.Range(r);\n\t\t}\n\t\tset {\n\t\t\tthis.SetSelection(value.Start, value.End);\n\t\t}\n\t}\n\n\n\tpublic void MoveCursor(long offset, int digit)\n\t{\n\t\tAreaGroup areaGroup = dvDisplay.Layout.AreaGroup;\n\t\t\n\t\tareaGroup.SetCursor(offset, digit);\n\n\t\tif (CursorChanged != null)\n\t\t\tCursorChanged(this);\n\t}\n\n\n\tpublic long CursorOffset\n\t{\n\t\tget {\n\t\t\tAreaGroup areaGroup = dvDisplay.Layout.AreaGroup;\n\t\t\t\n\t\t\treturn areaGroup.CursorOffset;\n\t\t}\n\t}\n\n\tpublic int CursorDigit\n\t{\n\t\tget {\n\t\t\tAreaGroup areaGroup = dvDisplay.Layout.AreaGroup;\n\t\t\t\n\t\t\treturn areaGroup.CursorDigit;\n\t\t}\n\t}\n\n\tpublic long Offset\n\t{\n\t\tget {\n\t\t\tAreaGroup areaGroup = dvDisplay.Layout.AreaGroup;\n\t\t\t\n\t\t\treturn areaGroup.Offset;\n\t\t}\n\n\t\tset {\n\t\t\tAreaGroup areaGroup = dvDisplay.Layout.AreaGroup;\n\t\t\t\n\t\t\tareaGroup.Offset = value;\n\t\t}\n\t}\n\n\tpublic delegate void DataViewEventHandler(DataView dv);\n\n\t///<summary>\n\t/// Fire the FocusChangedEvent\n\t///</summary>\n\tpublic void FireFocusChangedEvent()\n\t{\n\t\tif (FocusChanged != null)\n\t\t\tFocusChanged(this);\n\t}\n\n\t// events\n\tpublic event DataViewEventHandler BufferChanged;\n\tpublic event DataViewEventHandler SelectionChanged;\n\tpublic event DataViewEventHandler CursorChanged;\n\tpublic event DataViewEventHandler OverwriteChanged;\n\tpublic event DataViewEventHandler NotificationChanged;\n\tpublic event DataViewEventHandler FocusChanged;\n\n}// end DataView\n\n\n// class to store cursor position for undo/redo\npublic class CursorState {\n\tpublic long UndoOffset;\n\tpublic int UndoDigit;\n\tpublic long RedoOffset;\n\tpublic int RedoDigit;\n\tpublic CursorState(long uo, int ud, long ro, int rd)\n\t{ UndoOffset = uo; RedoOffset = ro; UndoDigit = ud; RedoDigit = rd;}\n}\n\n\n}//namespace\n"
  },
  {
    "path": "src/gui/DataViewControl.cs",
    "content": "// created on 12/13/2004 at 1:15 PM\n/*\n *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing Gtk;\nusing Bless.Buffers;\nusing Bless.Gui.Areas;\nusing Bless.Util;\n\nnamespace Bless.Gui {\n\n///<summary>Handles all dataview ui aspects except display</summary>\npublic class DataViewControl\n{\n\tprivate struct Position\n\t{\n\t\tpublic long First;\n\t\tpublic long Second;\n\t\tpublic int Digit;\n\t}\n\n\tDataView dataView;\n\tDataViewDisplay dvDisplay;\n\n\t// mouse selection related\n\tPosition selStartPos;\n\tPosition selEndPos;\n\n\t// Filter keypresses\n\tGtk.IMContext imContext;\n\n\tpublic DataViewDisplay Display {\n\t\tget { return dvDisplay;}\n\t\tset { dvDisplay = value;}\n\t}\n\n\tpublic DataView View {\n\t\tget { return dataView;}\n\t}\n\n\tpublic DataViewControl(DataView dv)\n\t{\n\t\tdataView = dv;\n\n\t\tselStartPos = new Position();\n\t\tselEndPos = new Position();\n\n\t\timContext = new IMContextSimple();\n\t}\n\n\t///<summary>Get the area that contains (X,Y)</summary>\n\tprivate Area GetAreaByXY(int x, int y)\n\t{\n\t\tArea clickArea = null;\n\n\t\tforeach(Area a in dvDisplay.Layout.AreaGroup.Areas) {\n\t\t\tif ((x >= a.X) && (x <= a.X + a.Width)) {\n\t\t\t\tclickArea = a;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn clickArea;\n\t}\n\n\tprivate void UpdateSelection(bool abyss)\n\t{\n\t\t//System.Console.WriteLine(\"* (1) Start: {0},{1},{2} End: {3},{4},{5}\", selStartPos.First, selStartPos.Second, selStartPos.Digit, selEndPos.First, selEndPos.Second, selEndPos.Digit);\n\t\tBless.Util.Range r;\n\t\tif (selStartPos.Second <= selEndPos.First)\n\t\t\tr = new Bless.Util.Range(ValidateOffset(selStartPos.Second), ValidateOffset(selEndPos.First));\n\t\telse\n\t\t\tr = new Bless.Util.Range(ValidateOffset(selEndPos.Second), ValidateOffset(selStartPos.First));\n\n\t\t//System.Console.WriteLine(\"Selection is ({0}, {1}) Expected ({2}, {3})\", dataView.Selection.Start, dataView.Selection.End, r.Start, r.End);\n\t\t// if nothing is selected and cursor position has changed externally\n\t\tif (dataView.Selection.IsEmpty() && dataView.CursorOffset != selStartPos.Second) {\n\t\t\tlong offset = dataView.CursorOffset;\n\t\t\tselStartPos.First = offset - (abyss ? 1 : 0);\n\t\t\tselStartPos.Second = offset;\n\t\t\tselStartPos.Digit = dataView.CursorDigit;\n\t\t\tselEndPos = selStartPos;\n\t\t\t//System.Console.WriteLine(\"* (2) Start: {0},{1},{2} End: {3},{4},{5}\", selStartPos.First, selStartPos.Second, selStartPos.Digit, selEndPos.First, selEndPos.Second, selEndPos.Digit);\n\t\t}\n\t\telse if (!dataView.Selection.IsEmpty() && !r.Equals(dataView.Selection)) {\n\t\t\tselStartPos.Second = dataView.Selection.Start;\n\t\t\tselStartPos.First = selStartPos.Second - 1;\n\t\t\tselEndPos.First = dataView.Selection.End;\n\t\t\tselEndPos.Second = selEndPos.First + 1;\n\t\t}\n\t\t//System.Console.WriteLine(\"* Selection is ({0}, {1}) Expected ({2}, {3}) Fixed ({4}, {5})\", dataView.Selection.Start, dataView.Selection.End, r.Start, r.End, selStartPos.Second, selEndPos.First);\n\n\t}\n\n\tprivate bool UpdateFocus(Area area)\n\t{\n\t\tif (area.CanFocus && !area.HasCursorFocus) {\n\t\t\tdvDisplay.Layout.AreaGroup.FocusedArea = area;\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tprivate void CalculatePosition(Area area, int x, int y, ref Position pos)\n\t{\n\t\tArea.GetOffsetFlags flags;\n\t\tint digit;\n\n\t\tlong off2;\n\t\tlong off1 = area.GetOffsetByDisplayInfo(x, y, out digit, out flags);\n\n\t\tif ((flags & Area.GetOffsetFlags.Eof) == Area.GetOffsetFlags.Eof) {\n\t\t\toff1 = dataView.Buffer.Size;\n\t\t\toff2 = off1;\n\t\t}\n\t\telse if ((flags & Area.GetOffsetFlags.Abyss) == Area.GetOffsetFlags.Abyss) {\n\t\t\toff2 = off1 + 1;\n\t\t}\n\t\telse\n\t\t\toff2 = off1;\n\n\t\tpos.First = off1;\n\t\tpos.Second = off2;\n\t\tpos.Digit = digit;\n\t}\n\n\tprivate long ValidateOffset(long offset)\n\t{\n\t\tif (offset < 0)\n\t\t\treturn 0;\n\n\t\tif (offset >= dataView.Buffer.Size)\n\t\t\treturn dataView.Buffer.Size - 1;\n\n\t\treturn offset;\n\t}\n\n\t///<summary>\n\t/// Sets the selection and the cursor position according to the values of selStartPos, selEndPos\n\t///</summary>\n\tprivate void EvaluateSelection(DataViewDisplay.ShowType showType)\n\t{\n\t\t//System.Console.WriteLine(\"Evaluate (1) Start: {0},{1},{2} End: {3},{4},{5}\", selStartPos.First, selStartPos.Second, selStartPos.Digit, selEndPos.First, selEndPos.Second, selEndPos.Digit);\n\t\tlong cursorOffset;\n\n\t\t// no selection\n\t\tif (selStartPos.First == selEndPos.First && selStartPos.Second == selEndPos.Second) {\n\t\t\tcursorOffset = selStartPos.Second;\n\t\t\t// make sure cursor (or end of selection) is visible\n\t\t\tdvDisplay.MakeOffsetVisible(cursorOffset, showType);\n\n\t\t\tdataView.SetSelection(-1, -1);\n\t\t\tdataView.MoveCursor(selStartPos.Second, selEndPos.Digit);\n\t\t}\n\t\t// selection with start pos <= end pos\n\t\telse if (selStartPos.Second <= selEndPos.First) {\n\t\t\t// set end position between bytes\n\t\t\t// this is done so that selections performed with \n\t\t\t// the mouse can be continued with the keyboard\n\t\t\t// (keyboard selections always set positions between bytes)\n\t\t\tselEndPos.Second = selEndPos.First + 1;\n\n\t\t\t// if selEndPos.Second is at or beyond the EOF\n\t\t\tlong off = ValidateOffset(selEndPos.Second);\n\t\t\tif (selEndPos.First >= off)\n\t\t\t\toff++;\n\t\t\tcursorOffset = off;\n\t\t\tdvDisplay.MakeOffsetVisible(cursorOffset, showType);\n\n\t\t\t// set the selection only if the start position (which is the start of the selection)\n\t\t\t// is within the file's limits\n\t\t\tif (selStartPos.Second < dataView.Buffer.Size)\n\t\t\t\tdataView.SetSelection(ValidateOffset(selStartPos.Second), ValidateOffset(selEndPos.First));\n\t\t\telse\n\t\t\t\tdataView.SetSelection(-1, -1);\n\n\t\t\tdataView.MoveCursor(off, 0);\n\t\t}\n\t\t// selection with start pos > end pos\n\t\telse {\n\t\t\t// set start position between bytes\n\t\t\t// this is done so that selections performed with \n\t\t\t// the mouse can be continued with the keyboard\n\t\t\t// (keyboard selections always set positions between bytes)\n\t\t\t// TODO: This is currently disabled because it breaks mouse\n\t\t\t// selection\n\t\t\t//\n\t\t\t//selStartPos.Second = selStartPos.First + 1;\n\n\t\t\tlong off = selEndPos.Second;\n\t\t\tcursorOffset = off;\n\t\t\tdvDisplay.MakeOffsetVisible(cursorOffset, showType);\n\n\t\t\t// set the selection only if the end position (which is the start of the selection)\n\t\t\t// is within the file's limits\n\t\t\tif (selEndPos.Second < dataView.Buffer.Size)\n\t\t\t\tdataView.SetSelection(ValidateOffset(selEndPos.Second), ValidateOffset(selStartPos.First));\n\t\t\telse\n\t\t\t\tdataView.SetSelection(-1, -1);\n\n\t\t\tdataView.MoveCursor(off, 0);\n\t\t}\n\n\n\t\t//System.Console.WriteLine(\"Evaluate (2) Start: {0},{1},{2} End: {3},{4},{5}\", selStartPos.First, selStartPos.Second, selStartPos.Digit, selEndPos.First, selEndPos.Second, selEndPos.Digit);\n\t}\n\n\t///<summary>Handle mouse button presses</summary>\n\tinternal void OnButtonPress (object o, ButtonPressEventArgs args)\n\t{\n\t\tdvDisplay.GrabKeyboardFocus();\n\n\t\tGdk.EventButton e = args.Event;\n\t\tArea clickArea = GetAreaByXY((int)e.X, (int)e.Y);\n\n\t\tif (clickArea == null)\n\t\t\treturn;\n\n\t\t// get the position in the file\n\t\tPosition pos = new Position();\n\n\t\tCalculatePosition(clickArea, (int)(e.X - clickArea.X), (int)(e.Y - clickArea.Y), ref pos);\n\n\t\t// right mouse button\n\t\tif (e.Button == 3) {\n\t\t\t// show the popup\n\t\t\tclickArea.ShowPopup(Services.UI.Manager);\n\t\t\t// if there is no selection change the cursor position\n\t\t\tif (dataView.Selection.IsEmpty()) {\n\t\t\t\tselStartPos = pos;\n\t\t\t\tselEndPos = pos;\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\t// update selection and cursor if they have changed externally\n\t\t\tUpdateSelection(pos.First != pos.Second);\n\n\t\t\t// if shift is pressed the position is the end position of the selection\n\t\t\tif ((e.State & Gdk.ModifierType.ShiftMask) != 0) {\n\t\t\t\tselEndPos = pos;\n\t\t\t}\n\t\t\telse { // ... start a new selection\n\t\t\t\tselStartPos = pos;\n\t\t\t\tselEndPos = pos;\n\t\t\t}\n\t\t}\n\t\t\n\t\t// give the focus to the appropriate area\n\t\t// do this before setting the new cursor/selection\n\t\tUpdateFocus(clickArea);\n\t\t\n\t\tEvaluateSelection(DataViewDisplay.ShowType.Closest);\n\t}\n\n\t///<summary>Handle mouse motion</summary>\n\tinternal void OnMotionNotify(object o, MotionNotifyEventArgs args)\n\t{\n\t\tGdk.EventMotion e = args.Event;\n\t\tGtk.DrawingArea da = (Gtk.DrawingArea)o;\n\t\tint x, y;\n\t\tGdk.ModifierType state;\n\n\t\tif (e.IsHint)\n\t\t\tda.GdkWindow.GetPointer(out x, out y, out state);\n\t\telse {\n\t\t\tx = (int)e.X;\n\t\t\ty = (int)e.Y;\n\t\t\tstate = e.State;\n\t\t}\n\n\t\t// if left mouse button is not down\n\t\tif ((state & Gdk.ModifierType.Button1Mask) == 0)\n\t\t\treturn;\n\n\t\t// find in which area the pointer is\n\t\tArea clickArea = GetAreaByXY(x, y);\n\n\t\tif (clickArea == null)\n\t\t\treturn;\n\n\t\t// get the position in the file\n\t\tPosition pos = new Position();\n\t\tCalculatePosition(clickArea, (int)(x - clickArea.X), (int)(y - clickArea.Y), ref pos);\n\n\t\t// update selection and cursor if they have changed externally\n\t\tUpdateSelection(pos.First != pos.Second);\n\n\t\t// Evaluate selection before moving the cursor\n\t\t// for better visual result\n\t\tselEndPos = pos;\n\n\t\t// give the focus to the appropriate area\n\t\t// do this before setting the new cursor/selection\n\t\tUpdateFocus(clickArea);\n\t\t\n\t\tEvaluateSelection(DataViewDisplay.ShowType.Closest);\n\t}\n\n\t///<summary>Handle mouse button release</summary>\n\tinternal void OnButtonRelease (object o, ButtonReleaseEventArgs args)\n\t{\n\t\tGdk.EventButton e = args.Event;\n\t\tArea clickArea = GetAreaByXY((int)e.X, (int)e.Y);\n\n\t\tif (clickArea == null)\n\t\t\treturn;\n\n\t\tint x = (int)e.X;\n\t\tint y;\n\t\t// if the pointer has moved out of the area height borders\n\t\t// make sure there is consistency in the selection\n\t\t// when depressing the mouse button\n\t\tif (e.Y > clickArea.Height + clickArea.Y)\n\t\t\ty = clickArea.Height + clickArea.Y - clickArea.Drawer.Height;\n\t\telse if (e.Y < clickArea.Y)\n\t\t\ty = clickArea.Y;\n\t\telse\n\t\t\ty = (int)e.Y;\n\n\t\t// get the position in the file\n\t\tPosition pos = new Position();\n\t\tCalculatePosition(clickArea, (int)(x - clickArea.X), (int)(y - clickArea.Y), ref pos);\n\n\t\t// update selection and cursor if they have changed externally\n\t\tUpdateSelection(pos.First != pos.Second);\n\n\t\t// Evaluate selection before moving the cursor\n\t\t// for better visual result\n\t\tselEndPos = pos;\n\t\t//System.Console.WriteLine(\"Start: {0},{1},{2} End: {3},{4},{5}\", selStartPos.First, selStartPos.Second, selStartPos.Digit, selEndPos.First, selEndPos.Second, selEndPos.Digit);\n\t\t\n\t\t// give the focus to the appropriate area\n\t\t// do this before setting the new cursor/selection\n\t\tUpdateFocus(clickArea);\n\t\t\n\t\tEvaluateSelection(DataViewDisplay.ShowType.Closest);\n\t}\n\t\n\t// variables that are shared by OnKeyPress and OnKey* handler methods\n\tArea okp_focusArea;\n\tint okp_bpr;\n\tint okp_dpb;\n\tDataViewDisplay.ShowType okp_showType;\n\n\t///<summary>Handle key presses</summary>\n\tinternal void OnKeyPress (object o, KeyPressEventArgs args)\n\t{\n\t\tGdk.EventKey e = args.Event;\n\n\t\tokp_focusArea = null;\n\t\tbool shiftPressed = false;\n\n\t\t// find focused area\n\t\tokp_focusArea = dvDisplay.Layout.AreaGroup.FocusedArea;\n\n\t\t// if no area has the focus, give it to the first one applicable\n\t\tif (okp_focusArea == null) {\n\t\t\tdvDisplay.Layout.AreaGroup.CycleFocus();\n\t\t\tokp_focusArea = dvDisplay.Layout.AreaGroup.FocusedArea;\n\t\t}\n\n\n\t\t// if still no area got the focus give up\n\t\tif (okp_focusArea == null)\n\t\t\treturn;\n\t\t\n\t\tokp_bpr = okp_focusArea.BytesPerRow;\n\t\tokp_dpb = okp_focusArea.DigitsPerByte;\n\t\tokp_showType = DataViewDisplay.ShowType.Closest;\n\n\t\tif ((e.State & Gdk.ModifierType.ShiftMask) == Gdk.ModifierType.ShiftMask)\n\t\t\tshiftPressed = true;\n\n\t\tUpdateSelection(true);\n\n\t\tPosition cur = new Position();\n\t\tif (shiftPressed || !dvDisplay.Layout.AreaGroup.Selection.IsEmpty()) {\n\t\t\tcur = selEndPos;\n\t\t\tcur.Digit = 0;\n\t\t}\n\t\telse {\n\t\t\tcur = selStartPos;\n\t\t}\n\n\t\tPosition next = new Position();\n\t\t// set next to cur in case it is not set by a keypress handler\n\t\tnext = cur;\n\n\t\t// handle keys\n\t\tbool specialKey = false;\n\n\t\tswitch (e.Key) {\n\t\t\tcase Gdk.Key.Up:\n\t\t\t\tOnKeyUp(ref cur, ref next);\n\t\t\t\tbreak;\n\t\t\tcase Gdk.Key.Down:\n\t\t\t\tOnKeyDown(ref cur, ref next);\n\t\t\t\tbreak;\n\t\t\tcase Gdk.Key.Left:\n\t\t\t\tOnKeyLeft(ref cur, ref next);\n\t\t\t\tbreak;\n\t\t\tcase Gdk.Key.Right:\n\t\t\t\tif (shiftPressed)\n\t\t\t\t\tcur.Digit = okp_dpb - 1;\n\t\t\t\tOnKeyRight(ref cur, ref next);\n\t\t\t\tbreak;\n\t\t\tcase Gdk.Key.Page_Up:\n\t\t\t\tOnKeyPageUp(ref cur, ref next);\n\t\t\t\tbreak;\n\t\t\tcase Gdk.Key.Page_Down:\n\t\t\t\tOnKeyPageDown(ref cur, ref next);\n\t\t\t\tbreak;\n\t\t\tcase Gdk.Key.Home:\n\t\t\t\tOnKeyHome(ref cur, ref next);\n\t\t\t\tbreak;\n\t\t\tcase Gdk.Key.End:\n\t\t\t\tOnKeyEnd(ref cur, ref next);\n\t\t\t\tbreak;\n\t\t\tcase Gdk.Key.Insert:\n\t\t\t\tOnKeyInsert();\n\t\t\t\tbreak;\n\t\t\tcase Gdk.Key.Tab:\n\t\t\t\tOnKeyTab();\n\t\t\t\t// cycling through the areas may change the current cursor digit\n\t\t\t\t// (note however that we don't want to call EvaluateSelection()->SetCursor()\n\t\t\t\t//  because that will reset the digit of all areas. So we just update\n\t\t\t\t//  selStartPos.Digit here and set specialKey = true to avoid calling SetCursor()...)\n\t\t\t\tselStartPos.Digit = dvDisplay.Layout.AreaGroup.CursorDigit;\n\t\t\t\tspecialKey = true;\n\t\t\t\tbreak;\n\t\t\tcase Gdk.Key.BackSpace:\n\t\t\t\tOnKeyBackspace();\n\t\t\t\treturn; // OnKeyBackspace() handles drawing\n\t\t\tdefault:\n\t\t\t\tOnKeyDefault(e, ref cur, ref next, out specialKey);\n\t\t\t\tbreak;\n\t\t} // end switch()\n\t\t//System.Console.WriteLine(\"Current: {0},{1},{2} Next: {3},{4},{5}\", cur.First, cur.Second, cur.Digit, next.First, next.Second, next.Digit);\n\n\t\t// if just a special key was pressed (eg shift, ctrl, tab or a digit the area doesn't understand don't do anything)\n\t\tif (specialKey)\n\t\t\treturn;\n\n\t\tif (shiftPressed) {\n\t\t\tnext.Digit = 0;\n\t\t\tif (selStartPos.First == selStartPos.Second)\n\t\t\t\tselStartPos.First--;\n\t\t\tselEndPos = next;\n\t\t}\n\t\telse {\n\t\t\tselEndPos = next;\n\t\t\tselStartPos = next;\n\t\t}\n\t\t//System.Console.WriteLine(\"Start: {0},{1},{2} End: {3},{4},{5}\", selStartPos.First, selStartPos.Second, selStartPos.Digit, selEndPos.First, selEndPos.Second, selEndPos.Digit);\n\t\tEvaluateSelection(okp_showType);\n\t}\n\n\t///<summary>Handle key releases</summary>\n\tinternal void OnKeyRelease (object o, KeyReleaseEventArgs args)\n\t{\n\t\t// do nothing\n\t}\n\n\tinternal void OnMouseWheel(object o, ScrollEventArgs args)\n\t{\n\t\tGdk.EventScroll e = args.Event;\n\n\t\tif (e.Direction == Gdk.ScrollDirection.Down) {\n\t\t\tdouble newValue = dvDisplay.VScroll.Value + dvDisplay.VScroll.Adjustment.StepIncrement;\n\t\t\tif (newValue <= dvDisplay.VScroll.Adjustment.Upper - dvDisplay.VScroll.Adjustment.PageSize)\n\t\t\t\tdvDisplay.VScroll.Value = newValue;\n\t\t\telse\n\t\t\t\tdvDisplay.VScroll.Value = dvDisplay.VScroll.Adjustment.Upper - dvDisplay.VScroll.Adjustment.PageSize;\n\t\t}\n\t\telse if (e.Direction == Gdk.ScrollDirection.Up) {\n\t\t\tdouble newValue = dvDisplay.VScroll.Value - dvDisplay.VScroll.Adjustment.StepIncrement;\n\t\t\tif (newValue >= dvDisplay.VScroll.Adjustment.Lower)\n\t\t\t\tdvDisplay.VScroll.Value = newValue;\n\t\t\telse\n\t\t\t\tdvDisplay.VScroll.Value = dvDisplay.VScroll.Adjustment.Lower;\n\t\t}\n\t}\n\n\t///<summary>\n\t/// Handle DataView focus gain\n\t///</summary>\n\tinternal void OnFocusInEvent (object o, FocusInEventArgs args)\n\t{\n\t\tforeach(Area a in dvDisplay.Layout.AreaGroup.Areas)\n\t\ta.IsActive = true;\n\n\t\tdataView.FireFocusChangedEvent();\n\t}\n\n\t///<summary>\n\t/// Handle DataView focus loss\n\t///</summary>\n\tinternal void OnFocusOutEvent (object o, FocusOutEventArgs args)\n\t{\n\t\tforeach(Area a in dvDisplay.Layout.AreaGroup.Areas)\n\t\ta.IsActive = false;\n\n\t\tdataView.FireFocusChangedEvent();\n\t}\n\n\t//\n\t// Key Handlers, called by OnKeyPress\n\t//\n\n\tvoid OnKeyUp(ref Position cur, ref Position next)\n\t{\n\t\tlong offset = cur.Second;\n\n\t\toffset -= okp_bpr;\n\n\t\tif (offset < 0) {\n\t\t\tnext.First = cur.Second;\n\t\t\tnext.Second = cur.Second;\n\t\t}\n\t\telse {\n\t\t\tnext.First = offset - 1;\n\t\t\tnext.Second = offset;\n\t\t}\n\n\t\tnext.Digit = cur.Digit;\n\t}\n\n\tvoid OnKeyDown(ref Position cur, ref Position next)\n\t{\n\t\tlong offset = cur.Second;\n\t\toffset += okp_bpr;\n\n\t\tif (offset > dataView.Buffer.Size) {\n\t\t\tnext.First = dataView.Buffer.Size;\n\t\t\tnext.Second = dataView.Buffer.Size;\n\t\t}\n\t\telse {\n\t\t\tnext.First = offset - 1;\n\t\t\tnext.Second = offset;\n\t\t}\n\n\t\tnext.Digit = cur.Digit;\n\t}\n\n\tvoid OnKeyLeft(ref Position cur, ref Position next)\n\t{\n\t\tlong offset = cur.Second;\n\t\tint digit = cur.Digit;\n\n\t\tdigit--;\n\n\t\tif (digit < 0) {\n\t\t\toffset--;\n\t\t\tdigit = okp_dpb - 1;\n\t\t}\n\n\t\tif (offset < 0) {\n\t\t\toffset = 0;\n\t\t\tdigit = 0;\n\t\t}\n\n\t\tnext.First = offset - 1;\n\t\tnext.Second = offset;\n\t\tnext.Digit = digit;\n\n\t}\n\n\tvoid OnKeyRight(ref Position cur, ref Position next)\n\t{\n\t\tlong offset = cur.Second;\n\t\tint digit = cur.Digit;\n\n\t\tdigit++;\n\n\t\tif (digit >= okp_dpb) {\n\t\t\toffset++;\n\t\t\tdigit = 0;\n\t\t}\n\n\t\tif (offset > dataView.Buffer.Size) {\n\t\t\toffset = dataView.Buffer.Size;\n\t\t\tdigit = okp_dpb - 1;\n\t\t}\n\n\t\tnext.First = offset - 1;\n\t\tnext.Second = offset;\n\t\tnext.Digit = digit;\n\n\t}\n\n\n\tvoid OnKeyPageUp(ref Position cur, ref Position next)\n\t{\n\t\tlong offset = cur.Second;\n\t\tint digit = cur.Digit;\n\n\t\toffset -= okp_bpr * (int)dvDisplay.VScroll.Adjustment.PageIncrement;\n\n\t\tif (offset < 0) {\n\t\t\toffset = 0;\n\t\t\t//digit = 0;\n\t\t}\n\n\t\tokp_showType = DataViewDisplay.ShowType.Cursor;\n\n\t\tnext.First = offset;\n\t\tnext.Second = offset;\n\t\tnext.Digit = digit;\n\n\t}\n\n\tvoid OnKeyPageDown(ref Position cur, ref Position next)\n\t{\n\t\tlong offset = cur.Second;\n\t\tint digit = cur.Digit;\n\n\t\toffset += okp_bpr * (int)dvDisplay.VScroll.Adjustment.PageIncrement;\n\n\t\tif (offset > dataView.Buffer.Size) {\n\t\t\toffset = dataView.Buffer.Size;\n\t\t\t//digit = 0;\n\t\t}\n\n\t\tokp_showType = DataViewDisplay.ShowType.Cursor;\n\n\t\tnext.First = offset;\n\t\tnext.Second = offset;\n\t\tnext.Digit = digit;\n\n\t}\n\n\tvoid OnKeyHome(ref Position cur, ref Position next)\n\t{\n\t\tnext.First = 0;\n\t\tnext.Second = 0;\n\t\tnext.Digit = 0;\n\n\t\tokp_showType = DataViewDisplay.ShowType.Start;\n\t}\n\n\tvoid OnKeyEnd(ref Position cur, ref Position next)\n\t{\n\t\tnext.First = dataView.Buffer.Size;\n\t\tnext.Second = dataView.Buffer.Size;\n\t\tnext.Digit = 0;\n\n\t\tokp_showType = DataViewDisplay.ShowType.End;\n\t}\n\n\n\tvoid OnKeyInsert()\n\t{\n\t\tdataView.Overwrite = !dataView.Overwrite;\n\t}\n\n\tvoid OnKeyTab()\n\t{\n\t\tdvDisplay.Layout.AreaGroup.CycleFocus();\n\t}\n\n\tvoid OnKeyBackspace()\n\t{\n\t\t// move one position backwards and delete\n\t\tdataView.DeleteBackspace();\n\t}\n\n\tvoid OnKeyDefault(Gdk.EventKey e, ref Position cur, ref Position next, out bool specialKey)\n\t{\n\t\tif (!dataView.Buffer.ModifyAllowed) {\n\t\t\tspecialKey = true;\n\t\t\treturn;\n\t\t}\n\t\t\n\t\t// if the buffer isn't resizable, ignore non-overwriting keypresses\n\t\tif (!dataView.Buffer.IsResizable && !dataView.Overwrite) {\n\t\t\tspecialKey = true;\n\t\t\treturn;\n\t\t}\n\t\t\n\t\tif (dataView.Selection.IsEmpty()) {\n\t\t\tif (imContext.FilterKeypress(e) && okp_focusArea.HandleKey(e.Key, dataView.Overwrite) == true) {\n\t\t\t\tOnKeyRight(ref cur, ref next);\n\t\t\t\tdataView.CursorUndoDeque.AddFront(new CursorState(cur.Second, cur.Digit, next.Second, next.Digit));\n\n\t\t\t\tdataView.CursorRedoDeque.Clear();\n\n\t\t\t\tselStartPos = selEndPos = next;\n\t\t\t\tspecialKey = false;\n\t\t\t}\n\t\t\telse\n\t\t\t\tspecialKey = true;\n\t\t}\n\t\telse {\n\t\t\tdataView.Buffer.BeginActionChaining();\n\n\t\t\t// Insert the new data and delete the old\n\t\t\tif (imContext.FilterKeypress(e) && okp_focusArea.HandleKey(e.Key, false) == true) {\n\t\t\t\tUtil.Range curSel = dataView.Selection;\n\t\t\t\tlong curOffset = dataView.CursorOffset;\n\t\t\t\t\n\t\t\t\t// move cursor to the right\n\t\t\t\tOnKeyRight(ref cur, ref next);\n\n\t\t\t\tnext.First = next.Second = curSel.Start;\n\t\t\t\tselEndPos = selStartPos = next;\n\n\t\t\t\t// the new data could have been inserted either just after the end\n\t\t\t\t// or at the beginning of the selection. Handle each case \n\t\t\t\t// and delete the old data.\n\t\t\t\tif (curOffset > curSel.End) { // new data just after end\n\t\t\t\t\tdataView.Delete();\n\t\t\t\t}\n\t\t\t\telse { // curOffset == curSel.Start, new data at the beginning\n\t\t\t\t\t// shift selection one position to the right\n\t\t\t\t\tdataView.SetSelection(curSel.Start + 1, curSel.End + 1);\n\t\t\t\t\tdataView.Delete();\n\t\t\t\t}\n\n\t\t\t\tspecialKey = false;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tspecialKey = true;\n\t\t\t}\n\n\t\t\tdataView.Buffer.EndActionChaining();\n\n\t\t}\n\t\t// any other key pass it to focused area\n\t\t// if area handled it move one position right\n\n\t}\n\n\tpublic void Cleanup()\n\t{\n\t\tokp_focusArea = null;\n\t\tdataView = null;\n\t\tdvDisplay = null;\n\t}\n\n} // end DataViewControl\n\n} //end namespace\n"
  },
  {
    "path": "src/gui/DataViewDisplay.cs",
    "content": "// created on 1/11/2005 at 9:43 PM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing System;\nusing Gtk;\nusing Bless.Buffers;\nusing Bless.Gui.Areas;\nusing Bless.Gui.Drawers;\nusing Bless.Util;\n\nnamespace Bless.Gui {\n\n///<summary>A widget that displays data from a buffer</summary>\npublic class DataViewDisplay : Gtk.VBox {\n\tLayout layout;\n\tGtk.HBox hbox;\n\tGtk.DrawingArea drawingArea;\n\t//static Gtk.DrawingArea drawingArea=new Gtk.DrawingArea();\n\tGtk.VScrollbar vscroll;\n\tGtk.HBox fileChangedBar;\n\tbool widgetRealized;\n\n\tDataViewControl dvControl;\n\tDataView dataView;\n\n\tpublic enum ShowType { Closest, Start, End, Cursor }\n\n\tpublic DataView View {\n\t\tget { return dataView;}\n\t}\n\n\tpublic DataViewControl Control {\n\t\tset {\n\t\t\tDisconnectFromControl();\n\t\t\t// connect new control\n\t\t\tdvControl = value;\n\t\t\tConnectToControl();\n\t\t}\n\n\t\tget { return dvControl; }\n\t}\n\n\tpublic Layout Layout {\n\t\tget { return layout; }\n\n\t\tset {\n\t\t\t// temporarily save previous layout\n\t\t\tLayout prevLayout = layout;\n\n\t\t\t// dispose Area pixmaps\n\t\t\tlayout.DisposePixmaps();\n\n\t\t\t// set new layout\n\t\t\tlayout = value;\n\n\t\t\t// set buffer\n\t\t\tlayout.AreaGroup.Buffer = dataView.Buffer;\n\t\t\t\n\t\t\tif (widgetRealized) {\n\t\t\t\tlayout.Realize(drawingArea);\n\t\t\t\tGdk.Rectangle alloc = drawingArea.Allocation;\n\t\t\t\tResize(alloc.Width, alloc.Height);\n\n\t\t\t\tlong prevOffset = 0;\n\n\t\t\t\t// Setup new areas according to the old ones\n\t\t\t\tif (prevLayout != null && prevLayout.AreaGroup.Areas.Count > 0) {\n\t\t\t\t\tlayout.AreaGroup.SetCursor(prevLayout.AreaGroup.CursorOffset, 0);\n\t\t\t\t\tlayout.AreaGroup.Selection = prevLayout.AreaGroup.Selection;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tlayout.AreaGroup.SetCursor(0, 0);\n\t\t\t\t}\n\n\t\t\t\t// make sure cursor is visible\n\t\t\t\tMakeOffsetVisible(prevOffset, ShowType.Closest);\n\t\t\t}\n\t\t}\n\n\t}\n\n\tinternal Gtk.VScrollbar VScroll {\n\t\tget { return vscroll; }\n\t}\n\n\tpublic new bool HasFocus {\n\t\tget { return drawingArea.HasFocus; }\n\t\tset { drawingArea.HasFocus = value; }\n\t}\n\n\t///<summary>Create a DataViewDisplay</summary>\n\tpublic DataViewDisplay(DataView dv)\n\t{\n\t\tdataView = dv;\n\n\t\t// load the default layout from the data directory\n\t\tlayout = new Layout(FileResourcePath.GetDataPath(\"bless-default.layout\"));\n\n\t\t// initialize scrollbar\n\t\tGtk.Adjustment\n\t\tadj = new Gtk.Adjustment(0.0, 0.0, 1.0, 1.0, 10.0, 0.0);\n\t\tvscroll = new Gtk.VScrollbar(adj);\n\n\t\tadj.ValueChanged += OnScrolled;\n\n\t\t// initialize drawing area\n\t\tdrawingArea = new Gtk.DrawingArea();\n\t\tdrawingArea.Realized += OnRealized;\n\t\tdrawingArea.ExposeEvent += OnExposed;\n\t\tdrawingArea.ConfigureEvent += OnConfigured;\n\t\tdrawingArea.ModifyBg(StateType.Normal, new Gdk.Color(0xff, 0xff, 0xff));\n\n\t\t// add events that we want to handle\n\t\tdrawingArea.AddEvents((int)Gdk.EventMask.ButtonPressMask);\n\t\tdrawingArea.AddEvents((int)Gdk.EventMask.ButtonReleaseMask);\n\t\tdrawingArea.AddEvents((int)Gdk.EventMask.PointerMotionMask);\n\t\tdrawingArea.AddEvents((int)Gdk.EventMask.PointerMotionHintMask);\n\t\tdrawingArea.AddEvents((int)Gdk.EventMask.KeyPressMask);\n\t\tdrawingArea.AddEvents((int)Gdk.EventMask.KeyReleaseMask);\n\n\t\tdrawingArea.CanFocus = true; // needed to catch key events\n\n\t\thbox = new Gtk.HBox();\n\n\t\thbox.PackStart(drawingArea , true, true, 0);\n\t\thbox.PackStart(vscroll , false, false, 0);\n\n\t\tthis.PackStart(hbox);\n\t}\n\n\t///<summary>Force a complete redraw of the view</summary>\n\tpublic void Redraw()\n\t{\n\t\tif (!widgetRealized)\n\t\t\treturn;\n\n\t\tGdk.Rectangle alloc = drawingArea.Allocation;\n\t\tResize(alloc.Width, alloc.Height);\n\t\tlayout.AreaGroup.Invalidate();\n\t\tdrawingArea.QueueDraw();\n\t}\n\n\t///<summary>\n\t/// Find the number of bytes per row in order\n\t/// to best utilize the available space and\n\t/// keep all areas synchronized.\n\t///</summary>\n\tprivate int FindBestBpr(int width)\n\t{\n\t\tint n = 1; // current bpr\n\t\tint bestBpr = -1; // best bpr so far\n\t\tint swBest = 0; // width of best bpr so far\n\n\t\t// try all values for n, from 0 upwards,\n\t\t// until the width for a given n exceeds\n\t\t// the available or the fixed bpr of an\n\t\t// area is exceeded\n\t\twhile (true) {\n\t\t\tint sw = 0; // total width with current bpr\n\t\t\tbool breaksGrouping = false;\n\t\t\tbool breaksFixed = false;\n\n\t\t\tforeach(Area a in layout.AreaGroup.Areas) {\n\t\t\t\tint w = a.CalcWidth(n, false);\n\n\t\t\t\t// if this number of bpr is not acceptable\n\t\t\t\tif (w == -1) {\n\t\t\t\t\tif (a.FixedBytesPerRow != -1 && n > a.FixedBytesPerRow )\n\t\t\t\t\t\tbreaksFixed = true;\n\t\t\t\t\telse\n\t\t\t\t\t\tbreaksGrouping = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tsw += w;\n\t\t\t}\n\n\t\t\t// If current bpr breaks a fixed size area\n\t\t\t// stop searching and use the last bpr value\n\t\t\t// that did't break it.\n\t\t\t// If there isn't such an area, keep searching\n\t\t\tif (breaksFixed && bestBpr != -1)\n\t\t\t\tbreak;\n\n\t\t\t// if current bpr breaks grouping, skip it\n\t\t\tif (!breaksGrouping) {\n\t\t\t\tbool shouldBreak = false;\n\n\t\t\t\t// stop searching if available width is exceeded\n\t\t\t\t// or last best width value equals current one\n\t\t\t\tif (sw > width || sw == swBest)\n\t\t\t\t\tshouldBreak = true;\n\n\t\t\t\t// if we should break, but haven't found a suitable\n\t\t\t\t// width yet, mark the current width as best so far\n\t\t\t\t// even if it violates available width constraints.\n\t\t\t\tif ((shouldBreak && bestBpr == -1) || (!shouldBreak)) {\n\t\t\t\t\t// keep best bpr so far\n\t\t\t\t\tbestBpr = n;\n\t\t\t\t\tswBest = sw;\n\t\t\t\t}\n\n\t\t\t\tif (shouldBreak)\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tn++;\n\t\t}\n\n\t\treturn bestBpr;\n\t}\n\n\t///<summary>Benchmark the rendering</summary>\n\tpublic void Benchmark()\n\t{\n\n\t\tSystem.DateTime t1;\n\t\tSystem.DateTime t2;\n\n\t\tint sum = 0;\n\n\t\tGdk.Window win = drawingArea.GdkWindow;\n\t\tGdk.Rectangle alloc = drawingArea.Allocation;\n\t\tGdk.Rectangle rect1 = new Gdk.Rectangle(0, 0, alloc.Width, alloc.Height);\n\n\t\tfor (int i = 0; i < 100; i++) {\n\t\t\tt1 = System.DateTime.Now;\n\n\t\t\twin.BeginPaintRect(rect1);\n\n\t\t\tlayout.AreaGroup.Render(true);\n\n\t\t\twin.EndPaint();\n\n\t\t\tt2 = System.DateTime.Now;\n\n\t\t\tsum += (t2 - t1).Milliseconds;\n\t\t}\n\n\n\t\tGdk.Rectangle rect = drawingArea.Allocation;\n\t\tConsole.WriteLine(\"100 render screen ({0},{1}): {2} ms\", rect.Width, rect.Height, sum / 100);\n\n\t}\n\n\tprivate void SetupScrollbarRange()\n\t{\n\t\tif (layout.AreaGroup.Areas.Count <= 0)\n\t\t\treturn;\n\n\t\tlong bpr = ((Area)layout.AreaGroup.Areas[0]).BytesPerRow;\n\t\tlong nrows = ((dataView.Buffer.Size + 1) / bpr); // +1 because of append cursor position\n\n\t\tif (nrows < vscroll.Adjustment.PageSize) {\n\t\t\tvscroll.Value = 0;\n\t\t\t// set adjustment manually instead of using SetRange\n\t\t\t// because gtk+ complains if low==high in SetRange()\n\t\t\tvscroll.Adjustment.Lower = 0;\n\t\t\tvscroll.Adjustment.Upper = nrows;\n\t\t\tvscroll.Hide();\n\t\t}\n\t\telse if ((dataView.Buffer.Size + 1) % bpr == 0) {\n\t\t\tvscroll.SetRange(0, nrows);\n\t\t\tvscroll.Show();\n\t\t}\n\t\telse {\n\t\t\tvscroll.SetRange(0, nrows + 1);\n\t\t\tvscroll.Show();\n\t\t}\n\n\t}\n\n\t///<summary>Handles window resizing</summary>\n\tprivate void Resize(int winWidth, int winHeight)\n\t{\n\t\t// find bytes per row...\n\t\tint bpr = FindBestBpr(winWidth);\n\n\t\t// Ensure our offset is always aligned with bpr\n\t\tif (bpr > 0)\n\t\t\tlayout.AreaGroup.Offset = (layout.AreaGroup.Offset / bpr) * bpr;\n\n\t\t// configure areas\n\t\tint s = 0;\n\t\tint fontHeight = winHeight;\n\t\tforeach(Area a in layout.AreaGroup.Areas) {\n\t\t\ta.Height = winHeight;\n\t\t\ta.Width = a.CalcWidth(bpr, true);\n\t\t\ta.X = s;\n\t\t\ta.BytesPerRow = bpr;\n\t\t\ts += a.Width;\n\t\t\tif (a.Drawer.Height < fontHeight) {\n\t\t\t\tfontHeight = a.Drawer.Height;\n\t\t\t}\n\t\t}\n\n\t\t// configure scrollbar\n\t\tvscroll.Adjustment.PageSize = (winHeight / fontHeight);\n\t\tvscroll.SetIncrements(3, vscroll.Adjustment.PageSize - 1);\n\n\t\t// decide whether the scrollbar is visible\n\t\t// and its range\n\t\tif (bpr == 0) {\n\t\t\t// this can cause eternal loop!\n\t\t\t// because hiding the scrollbar changes the\n\t\t\t// area and causes a reconfigure which may\n\t\t\t// show it again, and so on\n\t\t\t//vscroll.Hide();\n\t\t}\n\t\telse\n\t\t\tSetupScrollbarRange();\n\t\t\t\n\t\tlayout.AreaGroup.Invalidate();\n\t}\n\n\t///<summary>Handle the Configure Event</summary>\n\tvoid OnConfigured (object o, ConfigureEventArgs args)\n\t{\n\t\tif (widgetRealized == false)\n\t\t\treturn;\n\t\t\n\t\tGdk.EventConfigure conf = args.Event;\n\n\t\tResize(conf.Width, conf.Height);\n\n\t\t// make sure the current offset is visible\n\t\tMakeOffsetVisible(dataView.Offset, ShowType.Start);\n\t}\n\n\t///<summary>Handle the Expose Event</summary>\n\tvoid OnExposed (object o, ExposeEventArgs args)\n\t{\n\t\tlayout.AreaGroup.Render(true);\n\t}\n\n\t///<summary>Handle the Realized Event</summary>\n\tvoid OnRealized (object o, EventArgs args)\n\t{\n\t\t// Create some default areas\n\t\tlayout.Realize(drawingArea);\n\t\twidgetRealized = true;\n\n\t\t// now we can configure properly\n\t\tGdk.Rectangle alloc = ((Widget)o).Allocation;\n\t\tResize(alloc.Width, alloc.Height);\n\t}\n\n\t///<summary>Handle scrolling</summary>\n\tvoid OnScrolled (object o, EventArgs args)\n\t{\n\t\tint bpr = 0;\n\t\tif (layout.AreaGroup.Areas.Count > 0)\n\t\t\tbpr = ((Area)layout.AreaGroup.Areas[0]).BytesPerRow;\n\n\t\tlong offset = (long)vscroll.Adjustment.Value * bpr;\n\t\tlayout.AreaGroup.Offset = offset;\n\t}\n\n\t///<summary>Scroll the view so that offset is visible</summary>\n\tpublic void MakeOffsetVisible(long offset, ShowType type)\n\t{\n\t\tif (layout.AreaGroup.Areas.Count <= 0)\n\t\t\treturn;\n\n\t\tint\tbpr = ((Area)layout.AreaGroup.Areas[0]).BytesPerRow;\n\t\tif (bpr == 0)\n\t\t\treturn ;\n\n\t\tlong curOffset = layout.AreaGroup.Offset;\n\t\tint h = ((Area)layout.AreaGroup.Areas[0]).Height;\n\t\tDrawer font = ((Area)layout.AreaGroup.Areas[0]).Drawer;\n\t\tint nrows = h / font.Height;\n\n\t\tlong curOffsetRow = curOffset / bpr;\n\t\tlong curOffsetEndRow = curOffsetRow + nrows - 1;\n\t\tlong offsetRow = offset / bpr;\n\n\t\t//System.Console.WriteLine(\"curOffRow: {0} curOffEndRow: {1} offRow: {2}\",\n\t\t//\t\t\t\t\t\tcurOffsetRow, curOffsetEndRow, offsetRow);\n\n\t\tif (type == ShowType.Closest) {\n\t\t\t// if already visible do nothing\n\t\t\t//if (offsetRow >= curOffsetRow && offsetRow <= curOffsetEndRow)\n\t\t\t//\t;\n\t\t\tif (curOffsetRow > offsetRow)\n\t\t\t\ttype = ShowType.Start;\n\t\t\telse if (curOffsetEndRow < offsetRow)\n\t\t\t\ttype = ShowType.End;\n\t\t}\n\n\t\t// Make sure scrollbar range is updated.\n\t\t// We need to call this here because\n\t\t// a buffer change does not immediately\n\t\t// update the range (eg callback goes through GLib.Idle)\n\t\t// and a call to MakeOffsetVisible before\n\t\t// the update will not behave correctly.\n\t\t// eg see DataView.Paste()\n\t\tSetupScrollbarRange();\n\n\t\tif (type == ShowType.Cursor) {\n\t\t\tlong cursorRow = layout.AreaGroup.CursorOffset / bpr;\n\t\t\tint diff = (int)(cursorRow - curOffsetRow);\n\n\t\t\tif (diff <= nrows && diff >= 0)\n\t\t\t\tvscroll.Value = offsetRow - diff;\n\t\t\t// else if diff is outside of a full screen range...\n\t\t\telse if (diff > nrows)\n\t\t\t\ttype = ShowType.End;\n\t\t\telse if (diff < 0)\n\t\t\t\ttype = ShowType.Start;\n\t\t}\n\n\t\tif (type == ShowType.Start) {\n\t\t\tvscroll.Value = offsetRow;\n\t\t}\n\t\telse if (type == ShowType.End) {\n\t\t\tif (offsetRow - nrows >= 0)\n\t\t\t\tvscroll.Value = offsetRow - nrows + 1;\n\t\t\telse\n\t\t\t\tvscroll.Value = 0;\n\t\t}\n\t}\n\n\t///<summary>\n\t/// Show a warning that the file has been changed\n\t/// outside of the respective DataView\n\t///</summary>\n\tpublic void ShowFileChangedBar()\n\t{\n\t\tif (fileChangedBar == null) {\n\t\t\tfileChangedBar = new FileChangedBar(this.View);\n\t\t\tthis.PackStart(fileChangedBar, false, false, 0);\n\t\t}\n\n\t\tthis.ReorderChild(fileChangedBar, 0);\n\t\tfileChangedBar.ShowAll();\n\t}\n\n\tpublic void Cleanup()\n\t{\n\t\tlayout.DisposePixmaps();\n\t\tlayout = null;\n\t\tdataView = null;\n\t\tdvControl = null;\n\t}\n\n\tpublic void GrabKeyboardFocus()\n\t{\n\t\tif (!drawingArea.HasFocus)\n\t\t\tdrawingArea.GrabFocus();\n\t}\n\n\n\n\tprivate void ConnectToControl()\n\t{\n\t\tif (dvControl == null)\n\t\t\treturn;\n\n\t\tdrawingArea.ButtonPressEvent += dvControl.OnButtonPress;\n\t\tdrawingArea.ButtonReleaseEvent += dvControl.OnButtonRelease;\n\t\tdrawingArea.MotionNotifyEvent += dvControl.OnMotionNotify;\n\t\tdrawingArea.KeyPressEvent += dvControl.OnKeyPress;\n\t\tdrawingArea.KeyReleaseEvent += dvControl.OnKeyRelease;\n\t\tdrawingArea.ScrollEvent += dvControl.OnMouseWheel;\n\t\tdrawingArea.FocusInEvent += dvControl.OnFocusInEvent;\n\t\tdrawingArea.FocusOutEvent += dvControl.OnFocusOutEvent;\n\t}\n\n\tprivate void DisconnectFromControl()\n\t{\n\t\t// disconnect previous control\n\t\tif (dvControl == null)\n\t\t\treturn;\n\t\tdrawingArea.ButtonPressEvent -= dvControl.OnButtonPress;\n\t\tdrawingArea.ButtonReleaseEvent -= dvControl.OnButtonRelease;\n\t\tdrawingArea.MotionNotifyEvent -= dvControl.OnMotionNotify;\n\t\tdrawingArea.KeyPressEvent -= dvControl.OnKeyPress;\n\t\tdrawingArea.KeyReleaseEvent -= dvControl.OnKeyRelease;\n\t\tdrawingArea.ScrollEvent -= dvControl.OnMouseWheel;\n\t\tdrawingArea.FocusInEvent -= dvControl.OnFocusInEvent;\n\t\tdrawingArea.FocusOutEvent -= dvControl.OnFocusOutEvent;\n\t}\n\n}// end DataView\n\n}//namespace\n"
  },
  {
    "path": "src/gui/FileChangedBar.cs",
    "content": "// created on 4/29/2005 at 1:36 PM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing System;\nusing Gtk;\nusing Bless.Gui.Dialogs;\nusing Mono.Unix;\n\nnamespace Bless.Gui\n{\n\n///<summary>\n/// A widget that notifies the user that the file has changed\n/// and prompts them to reload or ignore.\n///</summary>\npublic class FileChangedBar : Gtk.HBox\n{\n\tDataView dataView;\n\n\tpublic FileChangedBar(DataView dv)\n\t{\n\t\tdataView = dv;\n\n\t\tthis.BorderWidth = 3;\n\n\t\tGtk.Image img = new Gtk.Image(Gtk.Stock.DialogWarning, Gtk.IconSize.SmallToolbar);\n\n\t\tGtk.Label label = new Gtk.Label(Catalog.GetString(\"This file has been changed on disk. You may choose to ignore the changes but reloading is the only safe option.\"));\n\t\tlabel.LineWrap = true;\n\t\tlabel.Wrap = true;\n\n\t\tGtk.Button buttonIgnore = new Gtk.Button(Catalog.GetString(\"Ignore\"));\n\t\tbuttonIgnore.Clicked += OnFileChangedIgnore;\n\n\t\tGtk.Button buttonReload = new Gtk.Button(Catalog.GetString(\"Reload\"));\n\t\tbuttonReload.Clicked += OnFileChangedReload;\n\n\t\tthis.PackStart(img, false, false, 4);\n\t\tthis.PackStart(label, false, false, 10);\n\t\tthis.PackStart(buttonIgnore, false, false, 10);\n\t\tthis.PackStart(buttonReload, false, false, 10);\n\t}\n\n\tvoid OnFileChangedIgnore(object o, EventArgs args)\n\t{\n\t\tWarningAlert wa = new WarningAlert(Catalog.GetString(\"Are you sure you want to ignore the changes?\"), Catalog.GetString(\"Due to the way Bless handles files, ignoring these changes may corrupt your data.\"), null);\n\t\tResponseType res = (ResponseType)wa.Run();\n\t\twa.Destroy();\n\n\t\tif (res == ResponseType.Ok) {\n\t\t\tthis.Visible = false;\n\t\t\tdataView.Notification = false;\n\t\t\tdataView.Buffer.FileOperationsAllowed = true;\n\t\t}\n\t}\n\n\tvoid OnFileChangedReload(object o, EventArgs args)\n\t{\n\t\tthis.Visible = false;\n\t\tdataView.Buffer.FileOperationsAllowed = true;\n\t\tdataView.Notification = false;\n\n\t\tdataView.Revert();\n\t}\n}\n\n\n} // end namespace\n"
  },
  {
    "path": "src/gui/FileService.cs",
    "content": "// created on 4/29/2006 at 3:37 PM\n/*\n *   Copyright (c) 2006, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing Gtk;\nusing Bless.Buffers;\nusing Bless.Gui.Dialogs;\nusing Bless.Tools;\nusing Bless.Util;\nusing System;\nusing System.IO;\nusing System.Collections;\nusing Mono.Unix;\n\nnamespace Bless.Gui\n{\n\npublic class FileService\n{\n\tDataBook dataBook;\n\tWindow mainWindow;\n\n\n\tpublic FileService(DataBook db, Window mw)\n\t{\n\t\tdataBook = db;\n\t\tmainWindow = mw;\n\t}\n\n\t///<summary>\n\t/// Create and setup a DataView\n\t///</summary>\n\tpublic DataView CreateDataView(ByteBuffer bb)\n\t{\n\t\tDataView dv = new DataView();\n\n\t\tstring layoutFile = string.Empty;\n\n\t\t// try to load default (from user preferences) layout file\n\t\ttry {\n\t\t\tlayoutFile = Preferences.Instance[\"Default.Layout.File\"];\n\t\t\tstring useCurrent = Preferences.Instance[\"Default.Layout.UseCurrent\"];\n\t\t\tif (useCurrent == \"True\" && dataBook.NPages > 0) {\n\t\t\t\tDataViewDisplay dvd = (DataViewDisplay)dataBook.CurrentPageWidget;\n\t\t\t\tlayoutFile = dvd.Layout.FilePath;\n\t\t\t}\n\n\t\t\tif (layoutFile != string.Empty)\n\t\t\t\tdv.Display.Layout = new Bless.Gui.Layout(layoutFile);\n\t\t}\n\t\tcatch (Exception ex) {\n\t\t\tstring msg = string.Format(Catalog.GetString(\"Error loading layout '{0}'. Loading default layout instead.\"), layoutFile);\n\t\t\tErrorAlert ea = new ErrorAlert(msg, ex.Message , mainWindow);\n\t\t\tea.Run();\n\t\t\tea.Destroy();\n\t\t}\n\n\t\tif (Preferences.Instance[\"Default.EditMode\"] == \"Insert\")\n\t\t\tdv.Overwrite = false;\n\t\telse if (Preferences.Instance[\"Default.EditMode\"] == \"Overwrite\")\n\t\t\tdv.Overwrite = true;\n\n\t\tdv.Buffer = bb;\n\n\t\treturn dv;\n\t}\n\n\t///<summary>If file has changed ask whether to save it.\n\t/// Returns true if file saved or the user doesn't want to save it.</summary>\n\tprivate bool AskForSaveIfFileChanged(DataView dv)\n\t{\n\t\tByteBuffer bb = dv.Buffer;\n\n\t\tif (bb == null)\n\t\t\treturn true;\n\n\t\tif (bb.HasChanged) {\n\t\t\tSaveConfirmationAlert sca = new SaveConfirmationAlert(bb.Filename, mainWindow);\n\t\t\tResponseType res = (ResponseType)sca.Run();\n\t\t\tsca.Destroy();\n\n\t\t\tif (res == ResponseType.Ok) {\n\t\t\t\treturn SaveFile(dv, null, false, true);\n\t\t\t}\n\t\t\telse if (res == ResponseType.No){\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse /*if (res==ResponseType.Cancel)*/\n\t\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t///<summary>If any file has changed ask whether to save it.\n\t/// Returns true if all changed files are saved or the user doesn't want to save them.</summary>\n\tprivate bool AskForSaveIfFilesChanged()\n\t{\n\t\tArrayList list = new ArrayList();\n\n\t\t// create a list with the changed files\n\t\tint i = 0;\n\t\tforeach (DataViewDisplay dv in dataBook.Children) {\n\t\t\tByteBuffer bb = dv.View.Buffer;\n\t\t\tif (bb.HasChanged)\n\t\t\t\tlist.Add(new SaveFileItem(true, bb.Filename, i));\n\t\t\ti++;\n\t\t}\n\n\t\tif (list.Count == 0)\n\t\t\treturn true;\n\n\t\t// special handling if only one file changed\n\t\tif (list.Count == 1) {\n\t\t\tint page = ((SaveFileItem)list[0]).Page;\n\t\t\t// make the page active\n\t\t\tdataBook.Page = page;\n\n\t\t\tDataView dv = ((DataViewDisplay)dataBook.GetNthPage(page)).View;\n\t\t\treturn AskForSaveIfFileChanged(dv);\n\t\t}\n\n\t\t// show the confirmation alert\n\t\tSaveFileItem[] array = (SaveFileItem[])list.ToArray(typeof(SaveFileItem));\n\n\t\tSaveConfirmationMultiAlert sca = new SaveConfirmationMultiAlert(array, mainWindow);\n\t\tResponseType res = (ResponseType)sca.Run();\n\t\tsca.Destroy();\n\n\t\t// handle responses\n\t\tif (res == ResponseType.Ok) {\n\t\t\tbool allSaved = true;\n\n\t\t\t// save the files the user specified\n\t\t\tforeach(SaveFileItem item in array) {\n\t\t\t\tif (item.Save == true) {\n\t\t\t\t\tDataView dv = ((DataViewDisplay)dataBook.GetNthPage(item.Page)).View;\n\t\t\t\t\t// make page active\n\t\t\t\t\tdataBook.Page = item.Page;\n\t\t\t\t\t// try to save the file\n\t\t\t\t\tif (SaveFile(dv, null, false, true) == false)\n\t\t\t\t\t\tallSaved = false;\n\t\t\t\t\telse {\n\t\t\t\t\t\t//UpdateTabLabel(dv);\n\t\t\t\t\t\t//UpdateWindowTitle(dv);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn allSaved;\n\t\t}\n\t\telse if (res == ResponseType.No){\n\t\t\treturn true;\n\t\t}\n\t\telse /*if (res==ResponseType.Cancel)*/\n\t\t\treturn false;\n\t}\n\n\n\t///<summary>\n\t/// Create new file\n\t///</summary>\n\tpublic ByteBuffer NewFile()\n\t{\n\t\tByteBuffer bb = new ByteBuffer();\n\t\tbb.UseGLibIdle = true;\n\n\t\tif (Preferences.Instance[\"ByteBuffer.TempDir\"] != \"\")\n\t\t\tbb.TempDir = Preferences.Instance[\"ByteBuffer.TempDir\"];\n\n\t\treturn bb;\n\t}\n\n\t///<summary>\n\t/// Try to open the file as a ByteBuffer\n\t///</summary>\n\tpublic ByteBuffer OpenFile(string filename)\n\t{\n\t\tUri uri = null;\n\t\t\n\t\t// first try filename as a URI\n\t\ttry {\t\n\t\t\turi = new Uri(filename);\n\t\t}\n\t\tcatch { }\n\t\t\n\t\t// if filename is a valid URI\n\t\tif (uri != null) {\n\t\t\n\t\t\t// try to open the URI as an unescaped path\n\t\t\ttry {\n\t\t\t\treturn OpenFileInternal(uri.LocalPath, false);\n\t\t\t}\n\t\t\tcatch (FileNotFoundException) {\n\t\t\t\t\n\t\t\t}\n\t\t\t\n\t\t\t// try to open the URI as an escaped path\n\t\t\ttry {\n\t\t\t\treturn OpenFileInternal(uri.AbsolutePath, false);\n\t\t\t}\n\t\t\tcatch (FileNotFoundException) {\n\t\t\t\t\n\t\t\t}\n\t\t}\n\t\t\n\t\t// filename is not a valid URI... (eg the path contains invalid URI characters like ':')\n\t\t// try to expand it as a local path\n\t\ttry {\n\t\t\tstring fullPath = Path.GetFullPath(filename);\n\t\t\treturn OpenFileInternal(fullPath, true);\n\t\t}\n\t\tcatch (Exception ex) {\n\t\t\tstring msg = string.Format(Catalog.GetString(\"Error opening file '{0}'\"), filename);\n\t\t\tErrorAlert ea = new ErrorAlert(msg, ex.Message, mainWindow);\n\t\t\tea.Run();\n\t\t\tea.Destroy();\n\t\t\treturn null;\n\t\t}\n\t}\n\t\n\tprivate ByteBuffer OpenFileInternal(string fullPath, bool handleFileNotFound)\n\t{\n\t\ttry {\n\t\t\tByteBuffer bb = ByteBuffer.FromFile(fullPath);\n\t\t\tbb.UseGLibIdle = true;\n\t\t\tif (Preferences.Instance[\"ByteBuffer.TempDir\"] != \"\")\n\t\t\t\tbb.TempDir = Preferences.Instance[\"ByteBuffer.TempDir\"];\n\t\t\tstring msg = string.Format(Catalog.GetString(\"Loaded file '{0}'\"), fullPath);\n\t\t\tServices.UI.Info.DisplayMessage(msg);\n\t\t\tHistory.Instance.Add(fullPath);\n\t\t\treturn bb;\n\t\t}\n\t\tcatch (UnauthorizedAccessException) {\n\t\t\tstring msg = string.Format(Catalog.GetString(\"Error opening file '{0}'\"), fullPath);\n\t\t\tErrorAlert ea = new ErrorAlert(msg, Catalog.GetString(\"You do not have read permissions for the file you requested.\"), mainWindow);\n\t\t\tea.Run();\n\t\t\tea.Destroy();\n\t\t}\n\t\tcatch (System.IO.FileNotFoundException) {\n\t\t\tif (handleFileNotFound == false)\n\t\t\t\tthrow;\n\t\t\tstring msg = string.Format(Catalog.GetString(\"Error opening file '{0}'\"), fullPath);\n\t\t\tErrorAlert ea = new ErrorAlert(msg, Catalog.GetString(\"The file you requested does not exist.\"), mainWindow);\n\t\t\tea.Run();\n\t\t\tea.Destroy();\n\t\t}\n\t\tcatch (System.IO.IOException ex) {\n\t\t\tstring msg = string.Format(Catalog.GetString(\"Error opening file '{0}'\"), fullPath);\n\t\t\tErrorAlert ea = new ErrorAlert(msg, ex.Message, mainWindow);\n\t\t\tea.Run();\n\t\t\tea.Destroy();\n\t\t}\n\t\tcatch (System.ArgumentException ex) {\n\t\t\tstring msg = string.Format(Catalog.GetString(\"Error opening file '{0}'\"), fullPath);\n\t\t\tErrorAlert ea = new ErrorAlert(msg, ex.Message, mainWindow);\n\t\t\tea.Run();\n\t\t\tea.Destroy();\n\t\t}\n\t\tcatch (System.NotSupportedException ex) {\n\t\t\tstring msg = string.Format(Catalog.GetString(\"Error opening file '{0}'\"), fullPath);\n\t\t\tErrorAlert ea = new ErrorAlert(msg, ex.Message, mainWindow);\n\t\t\tea.Run();\n\t\t\tea.Destroy();\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t///<summary>\n\t/// Manage high-level file saving procedures (eg confirm file overwrites, get filenames etc)\n\t///</summary>\n\tpublic bool SaveFile(DataView dv, string filename, bool forceSaveAs, bool synchronous)\n\t{\n\t\tByteBuffer bb = dv.Buffer;\n\n\t\tif (!dv.Buffer.FileOperationsAllowed) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// if a filename is given, save the file under the specified filename\n\t\tif (!forceSaveAs && filename != null)\n\t\t\treturn SaveFileInternal(dv, filename, synchronous);\n\n\t\t// if a filename is not given but buffer\n\t\t// has a file associated with it, save it under the same filename\n\t\tif (!forceSaveAs && filename == null && bb.HasFile == true && bb.Filename.Length != 0)\n\t\t\treturn SaveFileInternal(dv, bb.Filename, synchronous);\n\n\t\t// otherwise prompt user for a name\n\t\tGtk.FileChooserDialog fs = new Gtk.FileChooserDialog(Catalog.GetString(\"Save File As\"), mainWindow, FileChooserAction.Save,\n\t\t\t\t\t\t\t\t   Gtk.Stock.Cancel, ResponseType.Cancel,\n\t\t\t\t\t\t\t\t   Gtk.Stock.Save, ResponseType.Accept);\n\n\t\tbool done = false;\n\t\tbool fileSaved = true;\n\n\t\tdo {\n\t\t\tResponseType response = (ResponseType)fs.Run();\n\t\t\tfs.Hide();\n\t\t\tif (response == ResponseType.Accept) {\n\t\t\t\t// check to see whether file exists and prompt user to confirm\n\t\t\t\tif (File.Exists(fs.Filename)) {\n\t\t\t\t\tFileOverwriteAlert ea = new FileOverwriteAlert(fs.Filename, mainWindow);\n\t\t\t\t\tResponseType response1 = (ResponseType)ea.Run();\n\t\t\t\t\tea.Destroy();\n\t\t\t\t\tif (response1 == ResponseType.Ok) {\n\t\t\t\t\t\tfileSaved = SaveFileInternal(dv, fs.Filename, synchronous);\n\t\t\t\t\t\tdone = true;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t\tdone = false;\n\t\t\t\t}\n\t\t\t\telse{ // !File.Exists(fs.Filename)\n\t\t\t\t\tfileSaved = SaveFileInternal(dv, fs.Filename, synchronous);\n\t\t\t\t\tdone = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse { // response!=ResponseType.OK\n\t\t\t\tdone = true;\n\t\t\t\tfileSaved = false;\n\t\t\t}\n\t\t} while (!done);\n\n\t\tfs.Destroy();\n\n\t\t//UpdateRevert(dv);\n\n\t\treturn fileSaved;\n\t}\n\n\n\t///<summary>\n\t/// Manage low-level file saving procedures\n\t///</summary>\n\tprivate bool SaveFileInternal(DataView dv, string filename, bool synchronous)\n\t{\n\t\tByteBuffer bb = dv.Buffer;\n\n\t\tstring fullPath = null;\n\n\t\t// get the full path\n\t\ttry {\n\t\t\tfullPath = Path.GetFullPath(filename);\n\t\t}\n\t\tcatch (Exception ex) {\n\t\t\tstring msg = string.Format(Catalog.GetString(\"Error saving file '{0}'\"), filename);\n\t\t\tErrorAlert ea = new ErrorAlert(msg, ex.Message, mainWindow);\n\t\t\tea.Run();\n\t\t\tea.Destroy();\n\t\t}\n\n\t\t// if we can't get full path, return\n\t\tif (fullPath == null)\n\t\t\treturn false;\n\n\t\ttry {\n\t\t\tstring msg;\n\t\t\tif (fullPath != bb.Filename)\n\t\t\t\tmsg\t= string.Format(Catalog.GetString(\"Saving file '{0}' as '{1}'\"), bb.Filename, fullPath);\n\t\t\telse\n\t\t\t\tmsg = string.Format(Catalog.GetString(\"Saving file '{0}'\"), bb.Filename);\n\n\t\t\tServices.UI.Info.DisplayMessage(msg + \"...\");\n\n\n\t\t\tIAsyncResult ar;\n\n\t\t\t// Decide whether to save or save as\n\t\t\tif (fullPath != bb.Filename)\n\t\t\t\tar = bb.BeginSaveAs(fullPath, Services.UI.Progress.NewCallback(), new AsyncCallback(SaveFileAsyncCallback));\n\t\t\telse\n\t\t\t\tar = bb.BeginSave(Services.UI.Progress.NewCallback(), new AsyncCallback(SaveFileAsyncCallback));\n\n\t\t\t// if save is synchronous wait for save to finish\n\t\t\tif (synchronous) {\n\t\t\t\t// while waiting update the gui\n\t\t\t\twhile (ar.AsyncWaitHandle.WaitOne(50, true) == false) {\n\t\t\t\t\twhile ( Application.EventsPending() ) {\n\t\t\t\t\t\tApplication.RunIteration();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// find out if save succeeded\n\t\t\t\tSaveAsOperation bbs = (SaveAsOperation)ar.AsyncState;\n\t\t\t\tif (bbs.Result != SaveAsOperation.OperationResult.Finished)\n\t\t\t\t\treturn false;\n\t\t\t\t// add to history\n\t\t\t\tHistory.Instance.Add(bbs.SavePath);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\tcatch (IOException ex) {\n\t\t\tstring file;\n\t\t\tif (fullPath != bb.Filename)\n\t\t\t\tfile = fullPath;\n\t\t\telse\n\t\t\t\tfile = bb.Filename;\n\t\t\tstring msg = string.Format(Catalog.GetString(\"Error saving file '{0}'\"), file);\n\t\t\tErrorAlert ea = new ErrorAlert(msg, ex.Message, mainWindow);\n\t\t\tea.Run();\n\t\t\tea.Destroy();\n\n\t\t\tmsg = string.Format(Catalog.GetString(\"The file '{0}' has NOT been saved\"), file);\n\t\t\tServices.UI.Info.DisplayMessage(msg);\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t///<summary>\n\t/// Callback to call when a save operation has finished\n\t///</summary>\n\tvoid SaveFileAsyncCallback(IAsyncResult ar)\n\t{\n\t\tISaveState ss = (ISaveState)ar.AsyncState;\n\n\t\tif (ss.Result == ThreadedAsyncOperation.OperationResult.Finished) { // save went ok\n\t\t\tstring msg;\n\t\t\tif (ss.SavePath != ss.Buffer.Filename)\n\t\t\t\tmsg = string.Format(Catalog.GetString(\"The file has been saved as '{0}'\"), ss.SavePath);\n\t\t\telse\n\t\t\t\tmsg = string.Format(Catalog.GetString(\"The file '{0}' has been saved\"), ss.SavePath);\n\n\t\t\tServices.UI.Info.DisplayMessage(msg);\n\t\t\t// add to history\n\t\t\tHistory.Instance.Add(ss.SavePath);\n\n\t\t\treturn;\n\t\t}\n\t\telse if (ss.Result == ThreadedAsyncOperation.OperationResult.Cancelled) { // save cancelled\n\n\t\t}\n\t\telse if (ss.Result == ThreadedAsyncOperation.OperationResult.CaughtException) {\n\t\t\t// * UnauthorizedAccessException\n\t\t\t// * System.ArgumentException\n\t\t\t// * System.IO.IOException\n\t\t\tstring msg = string.Format(Catalog.GetString(\"Error saving file '{0}'\"), ss.SavePath);\n\t\t\tErrorAlert ea = new ErrorAlert(msg, ss.ThreadException.Message, mainWindow);\n\t\t\tea.Run();\n\t\t\tea.Destroy();\n\t\t}\n\n\t\t{\n\t\t\tstring msg = string.Format(Catalog.GetString(\"The file '{0}' has NOT been saved\"), ss.SavePath);\n\t\t\tServices.UI.Info.DisplayMessage(msg);\n\t\t}\n\t}\n\n\tpublic void CloseFile(DataView dv)\n\t{\n\t\tif (!dv.Buffer.FileOperationsAllowed)\n\t\t\treturn;\n\n\t\t// if user decides not to close after all\n\t\tif (AskForSaveIfFileChanged(dv) == false)\n\t\t\treturn;\n\n\t\tdataBook.RemoveView(dv);\n\n\t\t// promptly free resources memory (eg pixmaps)\n\t\tdv.Buffer.CloseFile();\n\t\tdv.Cleanup();\n\n\t\t// Make sure the new current DataView has the focus\n\t\tDataViewDisplay dvd = (DataViewDisplay)dataBook.CurrentPageWidget;\n\t\tif (dvd != null)\n\t\t\tdvd.GrabKeyboardFocus();\n\t\telse {\n\t\t\t// there is no dataview left,\n\t\t\t// update title and statusbars\n\t\t\tmainWindow.Title = \"Bless - Gtk# Hex Editor\";\n\t\t\tServices.UI.Info.ClearMessage();\n\t\t}\n\t}\n\n\t///<summary>\n\t/// Try to quit. Ask user to save files before quitting and\n\t/// save the current session.\n\t///</summary>\n\tpublic void TryQuit()\n\t{\n\t\tif (AskForSaveIfFilesChanged()) {\n\t\t\tstring blessConfDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), \"bless\");\n\t\t\ttry {\n\t\t\t\tServices.Session.Save(Path.Combine(blessConfDir, \"last.session\"));\n\t\t\t\tHistory.Instance.Save(Path.Combine(blessConfDir, \"history.xml\"));\n\t\t\t}\n\t\t\tcatch (Exception ex) { System.Console.WriteLine(ex.Message); }\n\t\t\tApplication.Quit ();\n\t\t}\n\t}\n\n\t///<summary>\n\t/// Load the files specified\n\t///</summary>\n\tpublic void LoadFiles(string[] files)\n\t{\n\t\t// should we replace the current page or create a new one?\n\t\tbool replaceCurrentPage = dataBook.CanReplacePage(dataBook.CurrentPage);\n\n\t\tforeach(string file in files) {\n\t\t\t// try to open the file\n\t\t\tByteBuffer bb = OpenFile(file);\n\n\t\t\t// if open was successful\n\t\t\tif (bb != null) {\n\t\t\t\tDataView newDv = CreateDataView(bb);\n\t\t\t\tif (replaceCurrentPage) { // replace current page\n\t\t\t\t\tDataView dv = ((DataViewDisplay)dataBook.CurrentPageWidget).View;\n\n\t\t\t\t\tdataBook.ReplaceView(dv, newDv, new CloseViewDelegate(CloseFile), Path.GetFileName(bb.Filename));\n\n\t\t\t\t\t// promptly free resources memory (eg pixmaps)\n\t\t\t\t\tdv.Buffer.CloseFile();\n\t\t\t\t\tdv.Cleanup();\n\n\t\t\t\t\treplaceCurrentPage = false;\n\t\t\t\t}\n\t\t\t\telse { // create new page\n\t\t\t\t\t// create and setup a  DataView\n\t\t\t\t\tdataBook.AppendView(newDv, new CloseViewDelegate(CloseFile), Path.GetFileName(bb.Filename));\n\t\t\t\t}\n\n\t\t\t}\n\t\t}\n\t}\n}\n\n\n\n}\n\n"
  },
  {
    "path": "src/gui/Layout.cs",
    "content": "// Configured on 6/26/2004 at 1:42 PM\n/*\n *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System.Collections.Generic;\nusing System;\nusing System.Xml;\nusing System.IO;\nusing Gtk;\nusing Bless.Gui.Areas;\nusing Bless.Gui.Drawers;\nusing Bless.Buffers;\n\nnamespace Bless.Gui {\n\n///<summary>\n/// A class that keeps information about how the data will be\n/// placed and shown on screen.\n///</summary>\npublic class Layout {\n\n\tAreaGroup areaGroup;\n\tXmlDocument layoutDoc;\n\tDrawer font;\n\tstring filePath;\n\tDateTime timeStamp;\n\n\tpublic AreaGroup AreaGroup {\n\t\tget {return areaGroup;}\n\t}\n\n\tpublic string FilePath {\n\t\tget { return filePath; }\n\t}\n\n\tpublic DateTime TimeStamp {\n\t\tget { return timeStamp; }\n\t}\n\n\tpublic Layout()\n\t{\n\t\tareaGroup = new AreaGroup();\n\t\tlayoutDoc = new XmlDocument();\n\t\tfilePath = null;\n\t}\n\n\tpublic Layout(string name): this()\n\t{\n\t\tLoad(name);\n\t}\n\n\t///<summary>Loads the layout from a file containing xml</summary>\n\tpublic void Load(string name)\n\t{\n\t\tusing (XmlReader xmlReader = XmlReader.Create(name)) {\n\t\t\tlayoutDoc.Load(xmlReader);\n\t\t\tConfigure();\n\t\t\tfilePath = name;\n\t\t\ttimeStamp = File.GetLastWriteTime(name);\n\t\t}\n\t}\n\n\t///<summary>Loads the layout from string containing xml</summary>\n\tpublic void LoadXml(string xml)\n\t{\n\t\tlayoutDoc.LoadXml(xml);\n\t}\n\n\t///<summary>\n\t/// Create and configure the areas, as defined in the layout file.\n\t///</summary>\n\tvoid Configure()\n\t{\n\t\tXmlNodeList areaList = layoutDoc.GetElementsByTagName(\"area\");\n\n\t\tforeach(XmlNode areaNode in areaList) {\n\t\t\tXmlAttributeCollection attrColl =  areaNode.Attributes;\n\t\t\tstring type = attrColl[\"type\"].Value;\n\n\t\t\tArea area = Area.Factory(type, areaGroup);\n\t\t\tif (area == null)\n\t\t\t\tcontinue;\n\n\t\t\tareaGroup.Areas.Add(area);\n\t\t\tarea.Configure(areaNode);\n\t\t}\n\n\t\t// give the focus to the first applicable area\n\t\tforeach(Area a in areaGroup.Areas) {\n\t\t\tif (a.Type != \"offset\" && a.Type != \"separator\") {\n\t\t\t\ta.HasCursorFocus = true;\n\t\t\t\tareaGroup.FocusedArea = a;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t// reset cursor\n\t\tareaGroup.SetCursor(0, 0);\n\t}\n\n\t///<summary>\n\t/// Realizes the areas.\n\t///</summary>\n\tpublic void Realize(Gtk.DrawingArea da)\n\t{\n\t\tareaGroup.DrawingArea = da;\n\t\tforeach(Area a in areaGroup.Areas)\n\t\t\ta.Realize();\n\t}\n\n\t///<summary>Dispose the pixmap resources used by the layout</summary>\n\tpublic void DisposePixmaps()\n\t{\n\t\tforeach(Area a in areaGroup.Areas) {\n\t\t\ta.DisposePixmaps();\n\t\t}\n\t}\n}\n\n}//namespace\n"
  },
  {
    "path": "src/gui/MainWindow.cs",
    "content": "// project created on 6/3/2004 at 8:34 PM\n/*\n *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing System;\nusing System.Collections;\nusing System.Threading;\nusing System.IO;\nusing Gtk;\nusing Bless.Buffers;\nusing Bless.Gui;\nusing Bless.Gui.Areas;\nusing Bless.Gui.Dialogs;\nusing Bless.Tools.Find;\nusing Bless.Tools;\nusing Bless.Util;\nusing Bless.Plugins;\nusing Mono.Unix;\n\npublic class BlessMain\n{\n\t[Gtk.Builder.Object] Gtk.HBox DataViewBox;\n\t[Gtk.Builder.Object] Gtk.Window MainWindow;\n\t[Gtk.Builder.Object] Gtk.VBox MainVBox;\n\n\tconst string uiXml =\n\t\t\"<menubar>\" +\n\t\t\"\t<menu action=\\\"File\\\" />\" +\n\t\t\"\t<menu action=\\\"Edit\\\" />\" +\n\t\t\"\t<menu action=\\\"View\\\">\" +\n\t\t\"\t\t<menuitem name=\\\"Toolbar\\\" action=\\\"ToolbarAction\\\" />\" +\n\t\t\"\t</menu>\" +\n\t\t\"\t<menu action=\\\"Search\\\" />\" +\n\t\t\"\t<menu action=\\\"Tools\\\" />\" +\n\t\t\"\t<menu action=\\\"Help\\\" />\" +\n\t\t\"</menubar>\" +\n\t\t\"<toolbar>\" +\n\t\t\"\t<placeholder name=\\\"FileItems\\\" />\" +\n\t\t\"\t<separator/>\" +\n\t\t\"\t<placeholder name=\\\"EditItems\\\" />\" +\n\t\t\"\t<separator/>\" +\n\t\t\"\t<placeholder name=\\\"SearchItems\\\" />\" +\n\t\t\"</toolbar>\";\n\n\tActionEntry[] actionEntries;\n\n\tUIManager uiManager;\n\n\tGtk.AccelGroup editAccelGroup; // the group of accelerators for the edit menu\n\tDataBook dataBook;\n\n\n\t// the kinds of MIME type targets we are accepting\n\tstatic TargetEntry[] dropTargets = new TargetEntry[]{\n\t\t\t\t\t\t\t\t\t\t   new TargetEntry(\"text/uri-list\", 0, 0)\n\t\t\t\t\t\t\t\t\t   };\n\n\tpublic static void Main (string[] args)\n\t{\n\t\tnew BlessMain(args);\n\t}\n\n\tpublic BlessMain (string[] args)\n\t{\n\t\tApplication.Init();\n\t\t\n\t\t//\n\t\tCatalog.Init(ConfigureDefines.GETTEXT_PACKAGE, ConfigureDefines.LOCALE_DIR);\n\n\t\ttry {\n\t\t\tPortable.AddLocalFontFile(FileResourcePath.GetDataPath(\"bless-courier.ttf\"));\n\t\t}\n\t\tcatch (Exception) {\n\t\t\tSystem.Console.WriteLine(\"Warning: Could not add built-in Courier font, will fall back to system Courier font as needed.\");\n\t\t}\n\n\t\t// load main window from GtkBuilder XML\n\t\tGtk.Builder builder = new Gtk.Builder();\n\t\tbuilder.AddFromFile(FileResourcePath.GetDataPath(\"ui\", \"MainWindow.ui\"));\n\t\tbuilder.Autoconnect(this);\n\n\t\t// set the application icon\n\t\tMainWindow.Icon = new Gdk.Pixbuf(FileResourcePath.GetDataPath(\"bless-48x48.png\"));\n\n\t\tstring blessConfDir = FileResourcePath.GetUserPath();\n\n\t\t// make sure local configuration directory exists\n\t\ttry {\n\t\t\tif (!Directory.Exists(blessConfDir)) {\n\t\t\t\tDirectory.CreateDirectory(blessConfDir);\n\t\t\t}\n\t\t}\n\t\tcatch (Exception ex){\n\t\t\tErrorAlert ea = new ErrorAlert(Catalog.GetString(\"Cannot create user configuration directory\"), ex.Message + Catalog.GetString(\"\\n\\nSome features of Bless may not work properly.\"), MainWindow);\n\t\t\tea.Run();\n\t\t\tea.Destroy();\n\t\t}\n\n\t\tPreferences.Proxy.Enable = false;\n\t\t// load default preferences\n\t\tPreferences.Default.Load(FileResourcePath.GetDataPath(\"default-preferences.xml\"));\n\t\tPreferences.Default[\"Default.Layout.File\"] = FileResourcePath.GetDataPath(\"bless-default.layout\");\n\n\t\t// load user preferences\n\t\tLoadPreferences(Path.Combine(blessConfDir, \"preferences.xml\"));\n\t\tPreferences.Instance.AutoSavePath = Path.Combine(blessConfDir, \"preferences.xml\");\n\n\t\t// add the (empty) Menubar and toolbar\n\t\tuiManager = new UIManager();\n\t\tMainWindow.AddAccelGroup(uiManager.AccelGroup);\n\t\tuiManager.AddUiFromString(uiXml);\n\n\t\tactionEntries = new ActionEntry[] {\n\t\t\tnew ActionEntry (\"File\", null, Catalog.GetString(\"_File\"), null, null, null),\n\t\t\tnew ActionEntry (\"Edit\", null, Catalog.GetString(\"_Edit\"), null, null, null),\n\t\t\tnew ActionEntry (\"View\", null, Catalog.GetString(\"_View\"), null, null, null),\n\t\t\tnew ActionEntry (\"Search\", null, Catalog.GetString(\"_Search\"), null, null, null),\n\t\t\tnew ActionEntry (\"Tools\", null, Catalog.GetString(\"_Tools\"), null, null, null),\n\t\t\tnew ActionEntry (\"Help\", null, Catalog.GetString(\"_Help\"), null, null, null)\n\t\t};\n\n\t\tActionGroup group = new ActionGroup (\"MainMenuActions\");\n\t\tgroup.Add (actionEntries);\n\t\tgroup.Add ( new ToggleActionEntry[] {\n\t\t\t\t\t\tnew ToggleActionEntry (\"ToolbarAction\", null, Catalog.GetString(\"Toolbar\"), null, null,\n\t\t\t\t\t\t\t\t\t\t\t   new EventHandler(OnViewToolbarToggled), false)\n\t\t\t\t\t});\n\n\t\tuiManager.InsertActionGroup(group, 0);\n\n\t\tWidget mb = uiManager.GetWidget(\"/menubar\");\n\t\tMainVBox.PackStart(mb, false, false, 0);\n\t\tMainVBox.ReorderChild(mb, 0);\n\t\tWidget tb = uiManager.GetWidget(\"/toolbar\");\n\t\ttb.Visible = false;\n\t\tMainVBox.PackStart(tb, false, false, 0);\n\t\tMainVBox.ReorderChild(tb, 1);\n\n\t\t// create the DataBook\n\t\tdataBook = new DataBook();\n\t\tdataBook.PageAdded += new DataView.DataViewEventHandler(OnDataViewAdded);\n\t\tdataBook.Removed += new RemovedHandler(OnDataViewRemoved);\n\t\tdataBook.SwitchPage += new SwitchPageHandler(OnSwitchPage);\n\n\t\tDataViewBox.PackStart(dataBook);\n\n\n\t\t// create the widget groups that hold utility widgets\n\t\tWidgetGroup widgetGroup0 = new WidgetGroup();\n\t\tWidgetGroup widgetGroup1 = new WidgetGroup();\n\t\tWidgetGroup sideWidgetGroup0 = new WidgetGroup();\n\t\tWidgetGroup sideWidgetGroup1 = new WidgetGroup();\n\t\twidgetGroup0.Show();\n\t\twidgetGroup1.Show();\n\t\tsideWidgetGroup0.Show();\n\t\tsideWidgetGroup1.Show();\n\n\t\tMainVBox.PackStart(widgetGroup0, false, false, 0);\n\t\tMainVBox.ReorderChild(widgetGroup0, 3);\n\t\tMainVBox.PackStart(widgetGroup1, false, false, 0);\n\t\tMainVBox.ReorderChild(widgetGroup1, 4);\n\n\t\tDataViewBox.PackStart(sideWidgetGroup0, false, false, 0);\n\t\tDataViewBox.ReorderChild(sideWidgetGroup0, 0);\n\t\tDataViewBox.PackEnd(sideWidgetGroup1, false, false, 0);\n\t\t//MainVBox.ReorderChild(widgetGroup1, 4);\n\n\n\t\tServices.File = new FileService(dataBook, MainWindow);\n\t\tServices.Session = new SessionService(dataBook, MainWindow);\n\t\tServices.UI = new UIService(uiManager);\n\t\t//Services.Info=new InfoService(infobar);\n\n\t\t// Add area plugins\n\t\tPluginManager.AddForType(typeof(AreaPlugin), new object[0]);\n\t\tPluginManager areaPlugins = PluginManager.GetForType(typeof(AreaPlugin));\n\t\tforeach (AreaPlugin p in areaPlugins.Plugins) {\n\t\t\tArea.AddFactoryItem(p.Name, p.CreateArea);\n\t\t}\n\n\t\t// Load GUI plugins\n\t\tPluginManager.AddForType(typeof(GuiPlugin), new object[]{MainWindow, uiManager});\n\t\tPluginManager guiPlugins = PluginManager.GetForType(typeof(GuiPlugin));\n\t\t\n\t\tforeach (Plugin p in guiPlugins.Plugins) {\n\t\t\tguiPlugins.LoadPlugin(p);\n\t\t}\n\n\t\t// load recent file history\n\t\ttry {\n\t\t\tHistory.Instance.Load(Path.Combine(blessConfDir, \"history.xml\"));\n\t\t}\n\t\tcatch (Exception e) {\n\t\t\tSystem.Console.WriteLine(e.Message);\n\t\t}\n\n\t\t// if user specified files on the command line\n\t\t// try to load them\n\t\tif (args.Length > 0) {\n\t\t\tServices.File.LoadFiles(args);\n\t\t}\n\t\telse if (Preferences.Instance[\"Session.LoadPrevious\"] == \"True\") {\n\t\t\tbool loadIt = true;\n\t\t\tstring prevSessionFile = Path.Combine(blessConfDir, \"last.session\");\n\n\t\t\tif (Preferences.Instance[\"Session.AskBeforeLoading\"] == \"True\"\n\t\t\t\t\t&& File.Exists(prevSessionFile)) {\n\t\t\t\tMessageDialog md = new MessageDialog (MainWindow,\n\t\t\t\t\t\t\t\t\t\t\t\t\t  DialogFlags.DestroyWithParent,\n\t\t\t\t\t\t\t\t\t\t\t\t\t  MessageType.Question,\n\t\t\t\t\t\t\t\t\t\t\t\t\t  ButtonsType.YesNo, Catalog.GetString(\"Do you want to load your previous session?\"));\n\n\t\t\t\tResponseType result = (ResponseType)md.Run ();\n\t\t\t\tmd.Destroy();\n\n\t\t\t\tif (result == ResponseType.Yes)\n\t\t\t\t\tloadIt = true;\n\t\t\t\telse\n\t\t\t\t\tloadIt = false;\n\n\t\t\t}\n\t\t\t// try to load previous session\n\t\t\tif (loadIt)\n\t\t\t\tServices.Session.Load(prevSessionFile);\n\t\t}\n\n\t\t// if nothing has been loaded, create a new file\n\t\tif (dataBook.NPages == 0) {\n\t\t\tByteBuffer bb = Services.File.NewFile();\n\n\t\t\t// create and setup a  DataView\n\t\t\tDataView dv = Services.File.CreateDataView(bb);\n\n\t\t\t// append the DataView to the DataBook\n\t\t\tdataBook.AppendView(dv, new CloseViewDelegate(Services.File.CloseFile), Path.GetFileName(bb.Filename));\n\t\t}\n\n\t\tPreferencesChangedHandler handler = new PreferencesChangedHandler(OnPreferencesChanged);\n\t\tPreferences.Proxy.Subscribe(\"View.Toolbar.Show\", \"mainwin\", handler);\n\n\n\t\t// register drag and drop of files\n\t\tMainWindow.DragDataReceived += OnDragDataReceived;\n\t\tGtk.Drag.DestSet(MainWindow, DestDefaults.Motion | DestDefaults.Drop, dropTargets, Gdk.DragAction.Copy | Gdk.DragAction.Move);\n\n\t\tDataViewBox.ShowAll();\n\n\t\tPreferences.Proxy.Enable = true;\n\t\t// fire the preferences changed event\n\t\t// so things are setup according to the preferences\n\t\tPreferences.Proxy.NotifyAll();\n\n\t\tApplication.Run();\n\t}\n\n\t///<summary>\n\t/// Handles drag and drop of files\n\t///</summary>\n\tvoid OnDragDataReceived(object o, DragDataReceivedArgs args)\n\t{\n\t\tstring uriStr = System.Text.Encoding.Default.GetString(args.SelectionData.Data);\n\n\t\t// get individual uris...\n\t\t// according to text/uri-list, uris are separated\n\t\t// by \"\\r\\n\"\n\t\turiStr = uriStr.Trim();\n\t\turiStr = uriStr.Replace(\"\\r\\n\", \"\\n\");\n\t\tstring[] uris = uriStr.Split('\\n');\n\n\t\t// we are done\n\t\tGtk.Drag.Finish (args.Context, false, false, args.Time);\n\n\t\t// load the files\n\t\tServices.File.LoadFiles(uris);\n\t}\n\n\n\t///<summary>\n\t/// Updates the window's title with data from the specified DataView,\n\t/// if the specified DataView is active\n\t///</summary>\n\tvoid UpdateWindowTitle(DataView dv)\n\t{\n\t\tif (dataBook.NPages == 0)\n\t\t\treturn;\n\n\t\tDataView curdv = ((DataViewDisplay)dataBook.CurrentPageWidget).View;\n\t\tByteBuffer curbb = curdv.Buffer;\n\n\t\tByteBuffer bb = dv.Buffer;\n\n\t\t// if DataView is active\n\t\tif (curbb == bb) {\n\t\t\tif (bb.HasChanged && !MainWindow.Title.EndsWith(\"* - Bless\"))\n\t\t\t\tMainWindow.Title = bb.Filename + \" * - Bless\";\n\t\t\telse if (!bb.HasChanged)\n\t\t\t\tMainWindow.Title = bb.Filename + \" - Bless\";\n\t\t}\n\t}\n\n\t///<summary>\n\t/// Load the preferences from the specified file\n\t///</summary>\n\tvoid LoadPreferences(string path)\n\t{\n\t\ttry {\n\t\t\tPreferences.Instance.Load(Preferences.Default);\n\t\t\tPreferences.Instance.Load(path);\n\t\t}\n\t\tcatch (Exception e) {\n\t\t\tSystem.Console.WriteLine(e.Message);\n\t\t}\n\t}\n\n\tvoid OnPreferencesChanged(Preferences prefs)\n\t{\n\t\tToggleAction viewToolbarAction = (ToggleAction)uiManager.GetAction(\"/menubar/View/Toolbar\");\n\n\t\tif (prefs[\"View.Toolbar.Show\"] == \"True\")\n\t\t\tviewToolbarAction.Active = true;\n\t\telse\n\t\t\tviewToolbarAction.Active = false;\n\t}\n\n\t///<summary>\n\t/// Callback for SwitchPage DataBook event\n\t///</summary>\n\tvoid OnSwitchPage(object o, SwitchPageArgs args)\n\t{\n\t\tDataView dv = ((DataViewDisplay)dataBook.GetNthPage((int)args.PageNum)).View;\n\n\t\tUpdateWindowTitle(dv);\n\n\t\tdv.Display.GrabKeyboardFocus();\n\t}\n\n\tvoid OnDataViewAdded(DataView dv)\n\t{\n\t\tdv.Buffer.Changed += new ByteBuffer.ChangedHandler(OnBufferContentsChanged);\n\t\tdv.BufferChanged += new DataView.DataViewEventHandler(OnBufferChanged);\n\t}\n\n\tvoid OnDataViewRemoved(object o, RemovedArgs args)\n\t{\n\t\tDataView dv = ((DataViewDisplay)args.Widget).View;\n\t\tdv.Buffer.Changed -= new ByteBuffer.ChangedHandler(OnBufferContentsChanged);\n\t\tdv.BufferChanged -= new DataView.DataViewEventHandler(OnBufferChanged);\n\t}\n\n\tvoid OnBufferChanged(DataView dv)\n\t{\n\t\tUpdateWindowTitle(dv);\n\t}\n\n\t///<summary>Handle ByteBuffer changes</summary>\n\tvoid OnBufferContentsChanged(ByteBuffer bb)\n\t{\n\t\tGtk.Application.Invoke(delegate {\n\t\t\tDataView dv = null;\n\n\t\t\t// find DataView that owns bb\n\t\t\tforeach (DataViewDisplay dvtemp in dataBook.Children) {\n\t\t\t\tif (dvtemp.View.Buffer == bb) {\n\t\t\t\t\tdv = dvtemp.View;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tUpdateWindowTitle(dv);\n\t\t});\n\t}\n\n\n\t///<summary>Handle the View->Toolbar command</summary>\n\tpublic void OnViewToolbarToggled(object o, EventArgs args)\n\t{\n\t\tToggleAction viewToolbarAction = (ToggleAction)uiManager.GetAction(\"/menubar/View/Toolbar\");\n\n\t\tPreferences.Proxy.Change(\"View.Toolbar.Show\", viewToolbarAction.Active.ToString(), \"mainwin\");\n\n\t\tWidget mainToolbar = uiManager.GetWidget(\"/toolbar\");\n\n\t\tif (viewToolbarAction.Active)\n\t\t\tmainToolbar.Visible = true;\n\t\telse\n\t\t\tmainToolbar.Visible = false;\n\t}\n\n\t///<summary>Handle the Benchmark Toolbar button command (Hidden)</summary>\n\tpublic void OnBenchmark(object o, EventArgs args)\n\t{\n\t\tif (dataBook.NPages > 0) {\n\t\t\tDataViewDisplay dvd = (DataViewDisplay)dataBook.CurrentPageWidget;\n\t\t\tdvd.Benchmark();\n\t\t}\n\t}\n\n\t///<summary>Handle Main Window Delete Event</summary>\n\tpublic void OnMainWindowDeleteEvent (object o, DeleteEventArgs args)\n\t{\n\t\t// make sure we can quit safely:\n\t\t// 1. no file operations are currently going on (eg save, replace etc)\n\t\t// 2. user has saved or doesn't want to save their modified files\n\t\tMenuItem FileQuitMenuItem = (MenuItem)uiManager.GetWidget(\"/menubar/File/Quit\");\n\t\tif (FileQuitMenuItem.Sensitive)\n\t\t\tServices.File.TryQuit();\n\t\targs.RetVal = true;\n\t}\n\n} // end bless main\n\n"
  },
  {
    "path": "src/gui/Services.cs",
    "content": "// created on 4/30/2006 at 11:49 AM\n/*\n *   Copyright (c) 2006, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nnamespace Bless.Gui\n{\n\npublic class Services\n{\n\tstatic FileService fileService;\n\tstatic SessionService sessionService;\n\tstatic UIService uiService;\n\n\tpublic static FileService File {\n\t\tget { return fileService; }\n\t\tset { fileService = value; }\n\t}\n\n\tpublic static SessionService Session {\n\t\tget { return sessionService; }\n\t\tset { sessionService = value; }\n\t}\n\n\tpublic static UIService UI {\n\t\tget { return uiService; }\n\t\tset { uiService = value; }\n\t}\n}\n\n}"
  },
  {
    "path": "src/gui/SessionService.cs",
    "content": "// created on 4/30/2006 at 11:57 AM\n/*\n *   Copyright (c) 2006, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System;\nusing Gtk;\nusing Bless.Tools;\nusing Bless.Buffers;\nusing Bless.Gui.Dialogs;\nusing System.IO;\n\nnamespace Bless.Gui\n{\n\npublic class SessionService\n{\n\tDataBook dataBook;\n\tWindow mainWindow;\n\n\tpublic SessionService(DataBook db, Window mw)\n\t{\n\t\tdataBook = db;\n\t\tmainWindow = mw;\n\t}\n\n\t///<summary>\n\t/// Save the current session to the specified file.\n\t///</summary>\n\tpublic void Save(string path)\n\t{\n\t\tSession session = new Session();\n\t\tGdk.Rectangle alloc = mainWindow.Allocation;\n\n\t\t// save the window size\n\t\tsession.WindowHeight = alloc.Height;\n\t\tsession.WindowWidth = alloc.Width;\n\n\t\t// save information about the currently open files\n\t\tforeach(DataViewDisplay dvd in dataBook.Children) {\n\t\t\tDataView dv = dvd.View;\n\t\t\t// add to session only if buffer is related to a file\n\t\t\tif (dv.Buffer.HasFile) {\n\t\t\t\tsession.AddFile(dv.Buffer.Filename, dv.Offset, dv.CursorOffset, dv.CursorDigit, dvd.Layout.FilePath, 0);\n\t\t\t\tif (dv == ((DataViewDisplay)dataBook.CurrentPageWidget).View) {\n\t\t\t\t\tsession.ActiveFile = dv.Buffer.Filename;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tsession.Save(path);\n\t}\n\n\t///<summary>\n\t/// Load a session from the specified file.\n\t///</summary>\n\tpublic void Load(string path)\n\t{\n\t\tSession session = new Session();\n\n\t\t// try to load session file\n\t\ttry {\n\t\t\tsession.Load(path);\n\t\t}\n\t\tcatch (Exception ex) {\n\t\t\tSystem.Console.WriteLine(ex.Message);\n\t\t\treturn;\n\t\t}\n\n\t\t// set the size of main window\n\t\tif (Preferences.Instance[\"Session.RememberWindowGeometry\"] == \"True\")\n\t\t\tmainWindow.Resize(session.WindowWidth, session.WindowHeight);\n\n\t\t// add files to the DataBook\n\t\tforeach(SessionFileInfo sfi in session.Files) {\n\t\t\tByteBuffer bb = Services.File.OpenFile(sfi.Path);\n\t\t\t// if file was opened successfully\n\t\t\tif (bb != null) {\n\t\t\t\tDataView dv = Services.File.CreateDataView(bb);\n\t\t\t\t// try to load layout file\n\t\t\t\ttry {\n\t\t\t\t\tdv.Display.Layout = new Bless.Gui.Layout(sfi.Layout);\n\t\t\t\t}\n\t\t\t\tcatch (Exception ex) {\n\t\t\t\t\tErrorAlert ea = new ErrorAlert(\"Error loading layout '\" + sfi.Layout + \"' for file '\" + sfi.Path + \"'. Loading default layout.\", ex.Message , mainWindow);\n\t\t\t\t\tea.Run();\n\t\t\t\t\tea.Destroy();\n\t\t\t\t}\n\n\t\t\t\tlong cursorOffset = sfi.CursorOffset;\n\n\t\t\t\t// sanity check cursor offset and view offset\n\t\t\t\tif (cursorOffset > bb.Size)\n\t\t\t\t\tcursorOffset = bb.Size;\n\n\n\t\t\t\tlong offset = sfi.Offset;\n\t\t\t\tif (offset >= bb.Size)\n\t\t\t\t\toffset = 0;\n\n\t\t\t\tif (Preferences.Instance[\"Session.RememberCursorPosition\"] == \"True\") {\n\t\t\t\t\tdv.MoveCursor(cursorOffset, sfi.CursorDigit);\n\t\t\t\t\tdv.Offset = offset;\n\t\t\t\t}\n\n\t\t\t\tdataBook.AppendView(dv, new CloseViewDelegate(Services.File.CloseFile), Path.GetFileName(bb.Filename));\n\t\t\t\t//OnBufferChanged(bb);\n\t\t\t}\n\t\t}\n\n\t\tforeach(DataViewDisplay dvd in dataBook.Children) {\n\t\t\tDataView dv = dvd.View;\n\t\t\tif (dv.Buffer.Filename == session.ActiveFile) {\n\t\t\t\tdataBook.CurrentPage = dataBook.PageNum(dvd);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n\n}"
  },
  {
    "path": "src/gui/UIService.cs",
    "content": "// created on 4/1/2007 at 2:12 PM\n/*\n *   Copyright (c) 2007, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing Gtk;\nusing Bless.Util;\n\nnamespace Bless.Gui\n{\n\npublic interface IInfoDisplay\n{\n\tvoid DisplayMessage(string message);\n\tvoid ClearMessage();\n}\n\npublic interface IProgressDisplay\n{\n\tProgressCallback NewCallback();\n}\n\n\n///<summary>\n/// Provides services related to the UI\n///</summary>\npublic class UIService\n{\n\tUIManager uiManager;\n\tIInfoDisplay infoDisplay;\n\tIProgressDisplay progressDisplay;\n\n\tpublic UIService(UIManager uim)\n\t{\n\t\tuiManager = uim;\n\t}\n\n\t///<summary>\n\t/// Service for showing status messages\n\t///</summary>\n\tpublic IInfoDisplay Info {\n\t\tget { return infoDisplay; }\n\t\tset { infoDisplay = value; }\n\t}\n\n\t///<summary>\n\t/// Service for displaying the progress of various actions\n\t///</summary>\n\tpublic IProgressDisplay Progress {\n\t\tget { return progressDisplay; }\n\t\tset { progressDisplay = value; }\n\t}\n\n\t///<summary>\n\t/// The global UIManager\n\t///</summary>\n\tpublic UIManager Manager {\n\t\tget { return uiManager;}\n\t}\n\n}\n\n} // end namespace"
  },
  {
    "path": "src/gui/WidgetGroup.cs",
    "content": "/*\n *   Copyright (c) 2006, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System;\nusing Gtk;\n\nnamespace Bless.Gui\n{\n\npublic class WidgetGroup : HBox\n{\n\n\tpublic WidgetGroup()\n\t{\n\t}\n\n\tprotected override void OnAdded(Widget w)\n\t{\n\t\tw.Hide();\n\t\tw.Shown += OnWidgetShown;\n\n\n\t\tbase.OnAdded(w);\n\t}\n\n\tprotected override void OnRemoved(Widget w)\n\t{\n\t\tw.Shown -= OnWidgetShown;\n\n\t\tbase.OnRemoved(w);\n\t}\n\n\n\tvoid OnWidgetShown(object sender, EventArgs e)\n\t{\n\t\tWidget w = (Widget)sender;\n\t\t// Make sure only one widget is visible\n\t\tforeach(Widget child in Children) {\n\t\t\tif (child != w)\n\t\t\t\tchild.Hide();\n\t\t}\n\n\t\t// don't use ShowAll(): causes loop\n\t\tthis.Show();\n\t}\n}\n\n}\n"
  },
  {
    "path": "src/gui/areas/Area.cs",
    "content": "// created on 6/14/2004 at 10:39 PM\n/*\n *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing Bless.Gui.Drawers;\nusing Bless.Util;\nusing Bless.Buffers;\nusing Bless.Tools.Find;\nusing System.Collections.Generic;\nusing System.Xml;\n\nnamespace Bless.Gui.Areas {\n\n/// <summary>\n/// An area on the screen that displays data in a specific way.\n/// </summary>\npublic abstract class Area\n{\n\tprotected AreaGroup areaGroup;\n\tprotected Drawer drawer;\n\tprotected Drawer.Information drawerInformation;\n\tprotected string type;\n\n\t// display\n\tprotected int x;\n\tprotected int y;\n\tprotected int width;\n\tprotected int height;\n\tprotected int bpr;\n\tprotected int dpb; // digits per byte\n\tprotected int fixedBpr;\n\tprotected Gdk.Drawable backPixmap;\n\tprotected bool manualDoubleBuffer;\n\tprotected bool isAreaRealized;\n\n\t// GC's\n\tprotected Gdk.GC cursorGC;\n\tprotected Gdk.GC activeCursorGC;\n\tprotected Gdk.GC inactiveCursorGC;\n\n\t\n\tprotected int cursorDigit;\n\tprotected bool cursorFocus;\n\tprotected bool canFocus;\n\t\n\tpublic enum RenderMergeFlags {None = 0, Left = 1, Right = 2}\n\t// Abstract methods\n\t\n\t/// <summary>\n\t/// Render (a part of) a row normally (without highlighting)\n\t/// </summary>\n\t/// <param name=\"i\">\n\t/// The row to render.\n\t/// </param>\n\t/// <param name=\"p\">\n\t/// The offset of the byte in the row to start rendering.\n\t/// </param>\n\t/// <param name=\"n\">\n\t/// The number of bytes to render.\n\t/// </param>\n\t/// <param name=\"blank\">\n\t/// Whether to blank the background before rendering.\n\t/// </param>\n\tabstract protected void RenderRowNormal(int i, int p, int n, bool blank);\n\t\n\t/// <summary>\n\t/// Render (a part of) a row with highlighting.\n\t/// </summary>\n\t/// <param name=\"i\">\n\t/// The row to render.\n\t/// </param>\n\t/// <param name=\"p\">\n\t/// The offset of the byte in the row to start rendering.\n\t/// </param>\n\t/// <param name=\"n\">\n\t/// The number of bytes to render.\n\t/// </param>\n\t/// <param name=\"blank\">\n\t/// Whether to blank the background before rendering.\n\t/// </param>\n\tabstract protected void RenderRowHighlight(int i, int p, int n, bool blank, Drawer.HighlightType ht);\n\n\t/// <summary>\n\t/// Get info about where a specified buffer offset is currently displayed.\n\t/// </summary>\n\t/// <param name=\"off\">\n\t/// The offset to query.\n\t/// </param>\n\t/// <param name=\"orow\">\n\t/// The row the offset is displayed in.\n\t/// </param>\n\t/// <param name=\"obyte\">\n\t/// The byte in the row the offset is displayed on.\n\t/// </param>\n\t/// <param name=\"ox\">\n\t/// The X coordinate of the displayed position.\n\t/// </param>\n\t/// <param name=\"oy\">\n\t/// The Y coordinate of the displayed position.\n\t/// </param>\n\tabstract public void GetDisplayInfoByOffset(long off, out int orow, out int obyte, out int ox, out int oy);\n\n\t/// <summary>\n\t/// Flags containing extra info about positions in the view. \n\t/// </summary>\n\tpublic enum GetOffsetFlags {\n\t\t/// <summary>Position is beyond the end of file</summary>\n\t\tEof = 1,\n\t\t/// <summary>Position is between bytes (in the so-called abyss)</summary>\n\t\tAbyss = 2\n\t}\n\t\n\t/// <summary>\n\t/// Gets the offset in the buffer that is displayed at specified location in the area\n\t/// </summary>\n\t/// <param name=\"x\">\n\t/// The X coordinate of the queried location.\n\t/// </param>\n\t/// <param name=\"y\">\n\t/// The Y coordinate of the queried location.\n\t/// </param>\n\t/// <param name=\"digit\">\n\t/// The digit of the byte at the specified location.\n\t/// </param>\n\t/// <param name=\"rflags\">\n\t/// Some flags with additional info about the location (<see cref=\"GetOffsetFlags\"/>).\n\t/// </param>\n\t/// <returns>\n\t/// The offset of the byte at the specified location.\n\t/// </returns>\n\tabstract public long GetOffsetByDisplayInfo(int x, int y, out int digit, out GetOffsetFlags rflags);\n\n\t/// <summary>\n\t/// Special key handler for the area. \n\t/// </summary>\n\t/// <param name=\"key\">\n\t/// The key that was pressed.\n\t/// </param>\n\t/// <param name=\"overwrite\">\n\t/// Whether we are in overwrite mode.\n\t/// </param>\n\t/// <returns>\n\t/// Whether the key was actually handled.\n\t/// </returns>\n\tvirtual public bool HandleKey(Gdk.Key key, bool overwrite)\n\t{\n\t\treturn false;\n\t}\n\n\t///<summary>\n\t/// Calculates the width in pixels the\n\t/// area will occupy with n bytes per row.\n\t///</summary>\n\tabstract public int CalcWidth(int n, bool force);\n\n\t/// <summary>\n\t/// A delegate that creates instances of area types.\n\t/// </summary>\n\tpublic delegate Area AreaCreatorFunc(AreaGroup ag);\n\t\n\t/// <summary>\n\t/// A dictionary to hold area type names and creation functions\n\t/// </summary>\n\tstatic private Dictionary<string, AreaCreatorFunc> pluginTable;\n\t\n\t/// <summary>\n\t/// Adds a new area type to the factory.\n\t/// </summary>\n\t/// <param name=\"name\">\n\t/// The name of the area type\n\t/// </param>\n\t/// <param name=\"createArea\">\n\t/// The delegate to call to create an instance of this area type.\n\t/// </param>\n\t/// <remarks>This is used by plugins to register new area types.</remarks>\n\tstatic public void AddFactoryItem(string name, AreaCreatorFunc createArea)\n\t{\n\t\tif (pluginTable == null) {\n\t\t\tpluginTable = new Dictionary<string, AreaCreatorFunc>();\n\t\t}\n\t\t// System.Console.WriteLine(\"Adding plugin name {0}\", name);\n\t\tpluginTable.Add(name, createArea);\n\t}\n\n\t/// <summary>\n\t/// Factory method to create instances of area types by name.\n\t/// </summary>\n\t/// <param name=\"name\">\n\t/// The name of the type of the area to create.\n\t/// </param>\n\t/// <param name=\"ag\">\n\t/// The <see cref=\"AreaGroup\"/> this area will belong in.\n\t/// </param>\n\t/// <returns>\n\t/// The created area.\n\t/// </returns>\n\tstatic public Area Factory(string name, AreaGroup ag)\n\t{\n\t\ttry {\n\t\t\tAreaCreatorFunc acf = pluginTable[name];\n\t\t\treturn acf(ag);\n\t\t}\n\t\tcatch (KeyNotFoundException e) {\n\t\t\tSystem.Console.WriteLine(e.Message);\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t\n\t/// <summary>\n\t/// Create an area.\n\t/// </summary>\n\t/// <param name=\"areaGroup\">\n\t/// The <see cref=\"AreaGroup\"/> this area will belong in.\n\t/// </param>\n\tpublic Area(AreaGroup areaGroup)\n\t{\n\t\tthis.areaGroup = areaGroup;\n\t\t\n\t\tdrawerInformation = new Drawer.Information();\n\n\t\tcanFocus = false;\n\t\tdpb = 0;\n\t\tfixedBpr = -1;\n\t\tisAreaRealized = false;\n\t}\n\n\t/// <summary>\n\t/// Configure an area using an xml configuration.\n\t/// </summary>\n\t/// <param name=\"parentNode\">\n\t/// The <see cref=\"XmlNode\"/> that holds the configuration for this area.\n\t/// </param>\n\t/// <remarks>This is overriden by inherited classes to accept extra options</remarks>\n\tpublic virtual void Configure(XmlNode parentNode)\n\t{\n\t\tXmlNodeList childNodes = parentNode.ChildNodes;\n\t\tforeach(XmlNode node in childNodes) {\n\t\t\tif (node.Name == \"bpr\")\n\t\t\t\tthis.FixedBytesPerRow = System.Convert.ToInt32(node.InnerText);\n\t\t\tif (node.Name == \"display\")\n\t\t\t\tParseDisplay(node, drawerInformation);\n\t\t}\n\t}\n\n\t///<summary>Parse the <display> tag in layout files</summary>\n\tvoid ParseDisplay(XmlNode parentNode, Drawer.Information info)\n\t{\n\t\tXmlNodeList childNodes = parentNode.ChildNodes;\n\t\tforeach(XmlNode node in childNodes) {\n\t\t\tif (node.Name == \"evenrow\")\n\t\t\t\tParseDisplayRow(node, info, Drawer.RowType.Even);\n\t\t\telse if (node.Name == \"oddrow\")\n\t\t\t\tParseDisplayRow(node, info, Drawer.RowType.Odd);\n\t\t\telse if (node.Name == \"font\")\n\t\t\t\tinfo.FontName = node.InnerText;\n\t\t}\n\t}\n\n\tvoid ParseDisplayRow(XmlNode parentNode, Drawer.Information info, Drawer.RowType rowType)\n\t{\n\t\tDrawer.Color fg, bg;\n\t\tXmlNodeList childNodes = parentNode.ChildNodes;\n\t\tforeach(XmlNode node in childNodes) {\n\t\t\tParseDisplayType(node, out fg, out bg);\n\t\t\tif (node.Name == \"evencolumn\") {\n\t\t\t\tif (bg != null)\n\t\t\t\t\tinfo.bgNormal[(int)rowType, (int)Drawer.ColumnType.Even] = bg;\n\t\t\t\tif (fg != null)\n\t\t\t\t\tinfo.fgNormal[(int)rowType, (int)Drawer.ColumnType.Even] = fg;\n\t\t\t}\n\t\t\telse if (node.Name == \"oddcolumn\") {\n\t\t\t\tif (bg != null)\n\t\t\t\t\tinfo.bgNormal[(int)rowType, (int)Drawer.ColumnType.Odd] = bg;\n\t\t\t\tif (fg != null)\n\t\t\t\t\tinfo.fgNormal[(int)rowType, (int)Drawer.ColumnType.Odd] = fg;\n\t\t\t}\n\t\t\telse if (node.Name == \"selectedcolumn\") {\n\t\t\t\tif (bg != null)\n\t\t\t\t\tinfo.bgHighlight[(int)rowType, (int)Drawer.HighlightType.Selection] = bg;\n\t\t\t\tif (fg != null)\n\t\t\t\t\tinfo.fgHighlight[(int)rowType, (int)Drawer.HighlightType.Selection] = fg;\n\t\t\t}\n\t\t\telse if (node.Name == \"patternmatchcolumn\") {\n\t\t\t\tif (bg != null)\n\t\t\t\t\tinfo.bgHighlight[(int)rowType, (int)Drawer.HighlightType.PatternMatch] = bg;\n\t\t\t\tif (fg != null)\n\t\t\t\t\tinfo.fgHighlight[(int)rowType, (int)Drawer.HighlightType.PatternMatch] = fg;\n\t\t\t}\n\t\t}\n\t}\n\n\t///<summary>Parse a font type</summary>\n\tvoid ParseDisplayType(XmlNode parentNode, out Drawer.Color fg, out Drawer.Color bg)\n\t{\n\t\tfg = null;\n\t\tbg = null;\n\t\tXmlNodeList childNodes = parentNode.ChildNodes;\n\t\tforeach(XmlNode node in childNodes) {\n\t\t\tGdk.Color col = new Gdk.Color();\n\t\t\tif (node.Name == \"foreground\") {\n\t\t\t\tGdk.Color.Parse(node.InnerText, ref col);\n\t\t\t\tGdk.Colormap.System.AllocColor(ref col, false, true);\n\t\t\t\tfg = new Drawer.Color(col);\n\t\t\t}\n\t\t\tif (node.Name == \"background\") {\n\t\t\t\tGdk.Color.Parse(node.InnerText, ref col);\n\t\t\t\tGdk.Colormap.System.AllocColor(ref col, false, true);\n\t\t\t\tbg = new Drawer.Color(col);\n\t\t\t}\n\t\t}\n\t}\n\n\t///<summary>\n\t/// Realize the area.\n\t///</summary>\n\tpublic virtual void Realize()\n\t{\n\t\tGtk.DrawingArea da = areaGroup.DrawingArea;\n\n\t\tbackPixmap = da.GdkWindow;\n\n\t\tactiveCursorGC = new Gdk.GC(da.GdkWindow);\n\t\tinactiveCursorGC = new Gdk.GC(da.GdkWindow);\n\n\t\tGdk.Color col = new Gdk.Color();\n\n\n\t\tGdk.Color.Parse(\"red\", ref col);\n\t\tactiveCursorGC.RgbFgColor = col;\n\t\tGdk.Color.Parse(\"gray\", ref col);\n\t\tinactiveCursorGC.RgbFgColor = col;\n\t\tcursorGC = activeCursorGC;\n\n\t\tisAreaRealized = true;\n\t}\n\n\t// Properties\n\t//\n\tpublic int X {\n\t\tset { x = value; }\n\t\tget\t{ return x; }\n\t}\n\n\tpublic int Y {\n\t\tset { y = value; }\n\t\tget\t{ return y; }\n\t}\n\n\tpublic int Width {\n\t\tset { width = value; }\n\t\tget\t{ return width; }\n\t}\n\n\tpublic int Height {\n\t\tset { height = value; }\n\t\tget\t{ return height; }\n\t}\n\n\tpublic int BytesPerRow {\n\t\tset { bpr = value; }\n\t\tget\t{ return bpr; }\n\t}\n\n\tpublic int FixedBytesPerRow {\n\t\tset { fixedBpr = value; }\n\t\tget { return fixedBpr; }\n\t}\n\n\tpublic int DigitsPerByte {\n\t\tget\t{ return dpb; }\n\t}\n\n\tpublic int CursorDigit {\n\t\tget { return cursorDigit; }\n\t\tset { if (value >= dpb) cursorDigit = dpb - 1; else cursorDigit = value; }\n\t}\n\t\n\tpublic bool HasCursorFocus {\n\t\tset { cursorFocus = value; }\n\t\tget { return cursorFocus;}\n\t}\n\n\tpublic bool CanFocus {\n\t\tget { return canFocus;}\n\t}\n\n\tpublic Drawer.Information DrawerInformation\n\t{\n\t\tget { return drawerInformation; }\n\t\tset { drawerInformation = value; }\n\t}\n\n\tpublic virtual Drawer Drawer {\n\t\tget { return drawer; }\n\t}\n\n\tpublic string Type {\n\t\tget { return type; }\n\t}\n\n\tpublic bool IsActive {\n\t\tset {\n\t\t\tif (value == true)\n\t\t\t\tcursorGC = activeCursorGC;\n\t\t\telse\n\t\t\t\tcursorGC = inactiveCursorGC;\n\n\t\t\t// doesn't actually change cursor position\n\t\t\t// just redraws it with correct color\n\t\t\t//MoveCursor(cursorOffset, cursorDigit);\n\t\t}\n\n\t\tget { return cursorGC == activeCursorGC; }\n\t}\n\n\t/// <summary>\n\t/// This method is only called to draw extra stuff when doing a complete\n\t/// redraw of the area\n\t/// </summary>\n\tinternal protected virtual void RenderExtra()\n\t{\n\t\n\t}\n\t\n\t\n\tvoid RenderRangeHelper(Drawer.HighlightType ht, int rstart, int bstart, int len)\n\t{\n\t\tif (ht != Drawer.HighlightType.Normal)\n\t\t\tRenderRowHighlight(rstart, bstart, len, false, ht);\n\t\telse\n\t\t\tRenderRowNormal(rstart, bstart, len, false);\n\t}\n\n\n\t/// <summary>\n\t/// Render the bytes in the highlight range.\n\t/// </summary>\n\t/// <param name=\"h\">\n\t/// A <see cref=\"Highlight\"/>\n\t/// </param>\n\t/// <param name=\"merge\">\n\t/// Whether to visually merge the highlight with adjacent ones left and/or right.\n\t/// </param>\n\t/// <remarks>\n\t/// This method doesn't check whether the merge flags are correct (eg there is indeed\n\t/// a similar adjacent highlight). It just draws the highlight in such a way as \n\t/// to appear merged to any similar highlights if they exist.\n\t///</remarks>\n\tinternal protected virtual void RenderHighlight(Highlight h, Drawer.HighlightType left, Drawer.HighlightType right)\n\t{\n\t\tif (isAreaRealized == false)\n\t\t\treturn;\n\t\t\n\t\tint rstart, bstart, xstart, ystart;\n\t\tint rend, bend, xend, yend;\n\t\tbool odd;\n\t\tGdk.GC gc;\n\t\tGdk.GC oddGC;\n\t\tGdk.GC evenGC;\n\t\tGdk.GC leftGC;\n\t\tGdk.GC rightGC;\n\t\t\n\t\toddGC = drawer.GetBackgroundGC(Drawer.RowType.Odd, h.Type);\n\t\tevenGC = drawer.GetBackgroundGC(Drawer.RowType.Even, h.Type);\n\t\t\n\n\t\tGetDisplayInfoByOffset(h.Start, out rstart, out bstart, out xstart, out ystart);\n\t\tGetDisplayInfoByOffset(h.End, out rend, out bend, out xend, out yend);\n\t\t\n\t\t//System.Console.WriteLine(\"Start {0:x} {1} {2} x:{3} y:{4}\", h.Start, rstart, bstart, xstart, ystart);\n\t\t//System.Console.WriteLine(\"End {0:x} {1} {2} x:{3} y:{4}\", h.End, rend, bend, xend, yend);\n\t\tbool drawLeft = false;\n\t\tint dxstart = xstart;\n\t\t\n\t\tif (bstart > 0) {\n\t\t\tint digit;\n\t\t\tGetOffsetFlags gof;\n\t\t\tGetOffsetByDisplayInfo(xstart - 1, ystart, out digit, out gof);\n\t\t\tif ((gof & GetOffsetFlags.Abyss) != 0) {\n\t\t\t\tdxstart -= drawer.Width;\n\t\t\t\tdrawLeft = true;\n\t\t\t}\n\t\t}\n\t\t\n\t\tbool drawRight = false;\n\t\tint dxend = xend;\n\t\t\n\t\tif (bend < bpr - 1) {\n\t\t\tint digit;\n\t\t\tGetOffsetFlags gof;\n\t\t\tGetOffsetByDisplayInfo(xend + dpb*drawer.Width, yend, out digit, out gof);\n\t\t\tif ((gof & GetOffsetFlags.Abyss) != 0) {\n\t\t\t\tdxend += drawer.Width;\n\t\t\t\tdrawRight = true;\n\t\t\t}\n\t\t}\n\t\t\n\t\t// if the whole range is on one row\n\t\tif (rstart == rend) {\n\t\t\tif (areaGroup.ManualDoubleBuffer) {\n\t\t\t\tBeginPaint(x + dxstart, y + ystart, dxend - dxstart + dpb*drawer.Width, drawer.Height);\n\t\t\t}\n\t\t\t// odd row?\n\t\t\todd = (((h.Start / bpr) % 2) == 1);\n\t\t\tif (odd) {\n\t\t\t\tgc = oddGC;\n\t\t\t\tleftGC = drawer.GetBackgroundGC(Drawer.RowType.Odd, left);\n\t\t\t\trightGC = drawer.GetBackgroundGC(Drawer.RowType.Odd, right);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tgc = evenGC;\n\t\t\t\tleftGC = drawer.GetBackgroundGC(Drawer.RowType.Even, left);\n\t\t\t\trightGC = drawer.GetBackgroundGC(Drawer.RowType.Even, right);\n\t\t\t}\n\t\t\t\n\t\t\t//render\n\t\t\tif (drawLeft)\n\t\t\t\tbackPixmap.DrawRectangle(leftGC, true, x + dxstart, y + ystart, drawer.Width, drawer.Height);\n\t\t\tif (drawRight)\n\t\t\t\tbackPixmap.DrawRectangle(rightGC, true, x + xend + dpb*drawer.Width, y + yend, drawer.Width, drawer.Height);\n\t\t\t\n\t\t\tbackPixmap.DrawRectangle(gc, true, x + xstart, y + ystart, xend - xstart + dpb*drawer.Width, drawer.Height);\n\n\t\t\tRenderRangeHelper(h.Type, rstart, bstart, bend - bstart + 1);\n\t\t}\n\t\telse { // multi-row range\n\n\t\t\tif (areaGroup.ManualDoubleBuffer) {\n\t\t\t\t// handle double-buffering\n\t\t\t\tGdk.Region paintRegion = new Gdk.Region();\n\n\t\t\t\tGdk.Rectangle rectStart = new Gdk.Rectangle(x + dxstart, y + ystart, width - dxstart, drawer.Height);\n\n\t\t\t\tGdk.Rectangle rectMiddle;\n\t\t\t\tif (rend > rstart + 1)\n\t\t\t\t\trectMiddle = new Gdk.Rectangle(x, y + ystart + drawer.Height, width, yend - ystart - drawer.Height);\n\t\t\t\telse\n\t\t\t\t\trectMiddle = Gdk.Rectangle.Zero;\n\n\t\t\t\tGdk.Rectangle rectEnd = new Gdk.Rectangle(x, y + yend, dxend + dpb*drawer.Width, drawer.Height);\n\n\t\t\t\tpaintRegion.UnionWithRect(rectStart);\n\t\t\t\tpaintRegion.UnionWithRect(rectMiddle);\n\t\t\t\tpaintRegion.UnionWithRect(rectEnd);\n\n\t\t\t\tBeginPaintRegion(paintRegion);\n\t\t\t}\n\n\t\t\t// render first row\n\t\t\todd = (((h.Start / bpr) % 2) == 1);\n\t\t\tif (odd) {\n\t\t\t\tgc = oddGC;\n\t\t\t\tleftGC = drawer.GetBackgroundGC(Drawer.RowType.Odd, left);\n\t\t\t\trightGC = drawer.GetBackgroundGC(Drawer.RowType.Odd, right);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tgc = evenGC;\n\t\t\t\tleftGC = drawer.GetBackgroundGC(Drawer.RowType.Even, left);\n\t\t\t\trightGC = drawer.GetBackgroundGC(Drawer.RowType.Even, right);\n\t\t\t}\n\t\t\t\n\t\t\tif (drawLeft)\n\t\t\t\tbackPixmap.DrawRectangle(leftGC, true, x + dxstart, y + ystart, drawer.Width, drawer.Height);\n\t\t\tbackPixmap.DrawRectangle(gc, true, x + xstart, y + ystart, width - xstart, drawer.Height);\n\n\t\t\tRenderRangeHelper(h.Type, rstart, bstart, bpr - bstart);\n\n\t\t\tlong curOffset = h.Start + bpr - bstart;\n\n\t\t\t// render middle rows\n\t\t\tfor (int i = rstart + 1;i < rend;i++) {\n\t\t\t\todd = (((curOffset / bpr) % 2) == 1);\n\t\t\t\tif (odd)\n\t\t\t\t\tgc = oddGC;\n\t\t\t\telse\n\t\t\t\t\tgc = evenGC;\n\t\t\t\tbackPixmap.DrawRectangle(gc, true, x, y + i*drawer.Height, width, drawer.Height);\n\t\t\t\tRenderRangeHelper(h.Type, i, 0, bpr);\n\t\t\t\tcurOffset += bpr;\n\t\t\t}\n\n\t\t\t// render last row\n\t\t\todd = (((h.End / bpr) % 2) == 1);\n\t\t\tif (odd) {\n\t\t\t\tgc = oddGC;\n\t\t\t\tleftGC = drawer.GetBackgroundGC(Drawer.RowType.Odd, left);\n\t\t\t\trightGC = drawer.GetBackgroundGC(Drawer.RowType.Odd, right);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tgc = evenGC;\n\t\t\t\tleftGC = drawer.GetBackgroundGC(Drawer.RowType.Even, left);\n\t\t\t\trightGC = drawer.GetBackgroundGC(Drawer.RowType.Even, right);\n\t\t\t}\n\t\t\t\n\t\t\tif (drawRight)\n\t\t\t\tbackPixmap.DrawRectangle(rightGC, true, x + xend + dpb*drawer.Width, y + yend, drawer.Width, drawer.Height);\n\t\t\tbackPixmap.DrawRectangle(gc, true, x, y + yend, xend + dpb*drawer.Width, drawer.Height);\n\t\t\tRenderRangeHelper(h.Type, rend, 0, bend + 1);\n\t\t}\n\n\t\tif (areaGroup.ManualDoubleBuffer) {\n\t\t\tEndPaint();\n\t\t}\n\n\t}\n\t\n\t/// <summary>\n\t/// Blanks the selected offset\n\t/// </summary>\n\t/// <param name=\"offs\">\n\t/// A <see cref=\"System.Int64\"/>\n\t/// </param>\n\tinternal protected void BlankOffset(long offs)\n\t{\n\t\tif (isAreaRealized == false) \n\t\t\treturn; \n\n\t\tint nrows = height / drawer.Height; \n\t\tlong bytesInView = nrows * bpr; \n\n\t\tif (offs >= areaGroup.Offset && offs < areaGroup.Offset + bytesInView) {\n\t\t\tint pcRow, pcByte, pcX, pcY; \n\t\t\tGetDisplayInfoByOffset(offs, out pcRow, out pcByte, out pcX, out pcY); \n\t\t\tGdk.GC backEvenGC = drawer.GetBackgroundGC(Drawer.RowType.Even, Drawer.HighlightType.Normal); \n\t\t\tbackPixmap.DrawRectangle(backEvenGC, true, x + pcX, y + pcY, drawer.Width*dpb, drawer.Height); \n\t\t} \n\t\n\t}\n\t\n\t///<summary>Render the cursor</summary>\n\tinternal protected void RenderCursor()\n\t{\n\t\tif (isAreaRealized == false)\n\t\t\treturn;\n\n\t\tint cRow, cByte, cX, cY;\n\t\tGetDisplayInfoByOffset(areaGroup.CursorOffset, out cRow, out cByte, out cX, out cY);\n\n\t\tbackPixmap.DrawRectangle(cursorGC, true, x + cX, y + cY + drawer.Height - 2, drawer.Width*dpb, 2);\n\t\tif (cursorFocus) {\n\t\t\tbackPixmap.DrawRectangle(cursorGC, true, x + cX + cursorDigit*drawer.Width, y + cY, 1, drawer.Height - 2);\n\t\t}\n\t}\n\t\n\t/// <summary>\n\t/// Dispose the (server side) pixmaps used by this area.\n\t/// </summary>\n\tpublic void DisposePixmaps()\n\t{\n\t\tif (isAreaRealized == false)\n\t\t\treturn;\n\n\t\tbackPixmap.Dispose();\n\t\tdrawer.DisposePixmaps();\n\t}\n\n\t\n\tvoid BeginPaintRegion(Gdk.Region r)\n\t{\n\t\tGdk.Window win = areaGroup.DrawingArea.GdkWindow;\n\n\t\twin.BeginPaintRegion(r);\n\t}\n\n\tvoid BeginPaint()\n\t{\n\t\tBeginPaint(this.x, this.y, this.width, this.height);\n\t}\n\n\tvoid BeginPaint(int x, int y, int w, int h)\n\t{\n\t\tGdk.Window win = areaGroup.DrawingArea.GdkWindow;\n\n\t\twin.BeginPaintRect(new Gdk.Rectangle(x, y, w, h));\n\t}\n\n\tvoid EndPaint()\n\t{\n\t\tareaGroup.DrawingArea.GdkWindow.EndPaint();\n\t}\n\n\tinternal virtual void BlankBackground()\n\t{\n\t\tGdk.GC backEvenGC = drawer.GetBackgroundGC(Drawer.RowType.Even, Drawer.HighlightType.Normal);\n\t\tbackPixmap.DrawRectangle(backEvenGC, true, x, y, width, height);\n\t}\n\t\n\tinternal virtual void BlankEof()\n\t{\n\t\tint pcRow, pcByte, pcX, pcY;\n\t\tGetDisplayInfoByOffset(areaGroup.Buffer.Size, out pcRow, out pcByte, out pcX, out pcY);\n\t\tGdk.GC backEvenGC = drawer.GetBackgroundGC(Drawer.RowType.Even, Drawer.HighlightType.Normal);\n\t\tbackPixmap.DrawRectangle(backEvenGC, true, x + pcX, y + pcY, drawer.Width*dpb, drawer.Height);\n\t}\n\t\n\tpublic virtual void ShowPopup(Gtk.UIManager uim)\n\t{\n\t\tGtk.Widget popup = uim.GetWidget(\"/DefaultAreaPopup\");\n\t\t(popup as Gtk.Menu).Popup();\n\t}\n\n}// Area\n\n\n} //namespace\n"
  },
  {
    "path": "src/gui/areas/AreaGroup.cs",
    "content": "// Created on 12:43 AM 19/3/2008\n/*\n *   Copyright (c) 2008, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing System;\nusing System.Collections.Generic;\nusing Bless.Buffers;\nusing Bless.Util;\nusing Bless.Gui.Drawers;\n\nnamespace Bless.Gui.Areas\n{\n\n/// <summary>\n/// An atomic highlight\n/// </summary>\nclass AtomicHighlight : Highlight\n{\n\tIList<Highlight> containers;\n\t\n\tpublic IList<Highlight> Containers {\n\t\tget { return containers; }\n\t}\n\t\n\t/// <summary>\n\t/// Adds a highlight as a container of this atomic highlight\n\t/// </summary>\n\t/// <remarks>The highlight is added only if it has lower or equal priority than this highlight</remarks>\n\tpublic void AddContainer(Highlight h)\n\t{\n\t\tif (h.Type > type)\n\t\t\treturn;\n\t\t\n\t\t// insertion sort (higher priority first)\n\t\tfor (int i = 0; i < containers.Count; i++) {\n\t\t\tif (h.Type >= containers[i].Type) {\n\t\t\t\tcontainers.Insert(i, h);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\t\n\t\tcontainers.Add(h);\n\t}\n\t\n\t/// <summary>\n\t/// \n\t/// </summary>\n\tpublic void GetAbyssHighlights(out Drawer.HighlightType left, out Drawer.HighlightType right)\n\t{\t\t\n\t\tleft = Drawer.HighlightType.Sentinel;\n\t\tright = Drawer.HighlightType.Sentinel;\n\n\t\tforeach(Highlight h in containers) {\n\t\t\tif (left == Drawer.HighlightType.Sentinel && h.Contains(start - 1))\n\t\t\t\tleft = h.Type;\n\t\t\t\n\t\t\tif (right == Drawer.HighlightType.Sentinel && h.Contains(end + 1))\n\t\t\t\tright = h.Type;\n\t\t}\n\t\t\n\t\tif (left == Drawer.HighlightType.Sentinel)\n\t\t\tleft = Drawer.HighlightType.Normal;\n\t\t\n\t\tif (right == Drawer.HighlightType.Sentinel)\n\t\t\tright = Drawer.HighlightType.Normal;\n\t}\n\t\n\tpublic AtomicHighlight(Highlight parent) : base(parent)\n\t{\n\t\tthis.containers = new System.Collections.Generic.List<Highlight>(1);\n\t\tthis.containers.Add(parent);\t\n\t}\n\t\n\tpublic AtomicHighlight(AtomicHighlight h) : base(h)\n\t{\n\t\tthis.containers = new System.Collections.Generic.List<Highlight>(h.containers);\n\t}\n\t\n\tpublic override string ToString()\n\t{\n\t\tstring str =  base.ToString() + \" Containers: \";\n\t\t\n\t\tforeach(Highlight h in containers) {\n\t\t\tstr += h.ToString() + \", \";\n\t\t}\n\t\t\n\t\tDrawer.HighlightType left, right;\n\t\t\n\t\tthis.GetAbyssHighlights(out left, out right);\n\t\t\n\t\tstr += string.Format(\"Left: {0} Right: {0}\", left, right);\n\t\t\n\t\treturn str;\n\t}\n}\n\n/// <summary>\n/// A group of areas that display data from the same source\n/// and are synchronized.\n/// </summary>\npublic class AreaGroup\n{\n\tIList<Area> areas;\n\tByteBuffer byteBuffer;\n\tGtk.DrawingArea drawingArea;\n\tArea focusedArea;\n\t\n\tIntervalTree<Highlight> highlights;\n\t\n\tenum Changes { Offset = 1, Cursor = 2, Highlights = 4}\n\t\n\tChanges changes;\n\tbool manualDoubleBuffer;\n\t\n\t// current offset of view in the buffer\n\tlong offset; \n\t\n\t// current cursor\n\tlong cursorOffset;\n\t\n\t// track changes\n\tlong prevCursorOffset;\n\t\n\tbyte[] bufferCache;\n\t\n\t/// <value>\n\t/// The previous atomic highlight ranges of the view.\n\t/// These are non-overlapping ranges that describe the highlighting of the whole view\n\t/// and can be used to render it quickly. They are also used to minimize\n\t/// redrawing when possible (<see cref=\"AreaGroup.RenderHighlightDiffs\"/>)\n\t/// </value>\n\tIntervalTree<AtomicHighlight> prevAtomicHighlights;\n\t\n\t\n\tHighlight selection;\n\t\n\tpublic IList<Area> Areas {\n\t\tget { return areas; }\n\t}\n\t\n\tpublic Area FocusedArea {\n\t\tget { return focusedArea; }\n\t\tset { UpdateFocusedArea(value); }\n\t}\n\t\n\tpublic long Offset {\n\t\tget { return offset;}\n\t\tset {\n\t\t\tif (offset == value)\n\t\t\t\treturn;\n\t\t\toffset = value; \n\t\t\tSetChanged(Changes.Offset);\n\t\t}\n\t\t\n\t}\n\n\tpublic long CursorOffset {\n\t\tget { return cursorOffset;}\n\t}\n\t\n\tpublic int CursorDigit {\n\t\tget {\n\t\t\tif (focusedArea != null)\n\t\t\t\treturn focusedArea.CursorDigit;\n\t\t\telse\n\t\t\t\treturn 0;\n\t\t}\n\t}\n\t\n\tpublic long PrevCursorOffset {\n\t\tget { return prevCursorOffset;}\n\t}\n\t\n\tpublic ByteBuffer Buffer {\n\t\tget { return byteBuffer; }\n\t\tset { byteBuffer = value; SetChanged(Changes.Offset);}\n\t}\n\t\n\tpublic Gtk.DrawingArea DrawingArea {\n\t\tget { return drawingArea; }\n\t\tset { drawingArea = value; }\n\t}\n\t\n\tpublic Util.Range Selection {\n\t\tget { return selection; }\n\t\tset { \n\t\t\tif (selection == value)\n\t\t\t\treturn;\n\t\t\thighlights.Delete(selection);\n\t\t\tselection.Start = value.Start; selection.End = value.End;\n\t\t\t\n\t\t\t// make sure the cursor is also updated (because it may \n\t\t\t// not have changed position so SetCursor() won't render it \n\t\t\t// but it may have to become visible again eg when a selection is cleared)\n\t\t\tSetChanged(Changes.Highlights | Changes.Cursor);\n\t\t}\n\t}\n\t\n\tinternal bool ManualDoubleBuffer {\n\t\tget { return manualDoubleBuffer; }\n\t}\n\t\n\tpublic void SetCursor(long coffset, int cdigit)\n\t{\n\t\tprevCursorOffset = cursorOffset;\n\t\t\n\t\t// if there is no change ignore...\n\t\tif (cursorOffset == coffset && this.CursorDigit == cdigit)\n\t\t\treturn;\n\t\t\n\t\tcursorOffset = coffset;\n\t\tforeach(Area a in areas)\n\t\t\ta.CursorDigit = cdigit;\n\t\t\n\t\tSetChanged(Changes.Cursor);\n\t}\n\t\n\tpublic byte GetCachedByte(long pos)\n\t{\n\t\treturn bufferCache[pos - offset];\n\t}\n\t\n\tpublic AreaGroup()\n\t{\n\t\tareas = new System.Collections.Generic.List<Area>();\n\t\thighlights = new IntervalTree<Highlight>();\n\t\tselection = new Highlight(Drawer.HighlightType.Selection);\n\t\tprevAtomicHighlights = new IntervalTree<AtomicHighlight>();\n\t\tbufferCache = new byte[0];\n\t}\n\t\n\t\n\t/// <summary>\n\t/// Get the range of bytes and the number of rows that \n\t/// are displayed in the current view.\n\t/// </summary>\n\tpublic Util.Range GetViewRange(out int nrows)\n\t{\n\t\t// find out number of rows, bytes in current view\n\t\t\n\t\tint minRows = int.MaxValue;\n\t\tint minBpr = int.MaxValue;\n\t\tforeach (Area a in areas) {\n\t\t\tminRows = Math.Min(minRows, a.Height / a.Drawer.Height);\n\t\t\tminBpr = Math.Min(minBpr, a.BytesPerRow);\n\t\t}\n\t\t\n\t\tnrows = minRows;\n\t\t\n\t\tlong bleft = minRows * minBpr;\n\n\t\tif (bleft + offset >= byteBuffer.Size)\n\t\t\tbleft = byteBuffer.Size - offset;\n\t\t\n\t\t// make sure we get an empty clipping Range when bleft==0\n\t\tif (bleft > 0)\n\t\t\treturn new Util.Range(offset, offset + bleft - 1);\n\t\telse\n\t\t\treturn new Util.Range();\n\t}\n\t\n\t/// <summary>\n\t/// Whether a <see cref=\"Changes\"/> has changed.\n\t/// </summary>\n\tprivate bool HasChanged(Changes c)\n\t{\n\t\treturn ((changes & c) != 0);\n\t}\n\t\n\t/// <summary>\n\t/// Whether anything has changed.\n\t/// </summary>\n\tprivate bool HasAnythingChanged()\n\t{\n\t\treturn changes != 0;\n\t}\n\t\n\t/// <summary>\n\t/// Clear all changes\n\t/// </summary>\n\tprivate void ClearChanges()\n\t{\n\t\tchanges = 0;\n\t}\n\t\n\t/// <summary>\n\t/// Set a  <see cref=\"Changes\"/> as changed.\n\t/// </summary>\n\t/// <param name=\"c\">\n\t/// A <see cref=\"Changes\"/>\n\t/// </param>\n\t///<remarks>This causes the group to be rendered again.</remarks>\n\tprivate void SetChanged(Changes c)\n\t{\n\t\tchanges |= c;\n\t\t\n\t\t\t\n\t\tGtk.Application.Invoke(delegate {\n\t\t\tif (drawingArea == null || drawingArea.GdkWindow == null)\n\t\t\t\treturn;\n\n\t\t\tif (HasChanged(Changes.Offset)) {\n\t\t\t\tGdk.Rectangle view = drawingArea.Allocation;\n\t\t\t\tview.X = 0;\n\t\t\t\tview.Y = 0;\n\t\t\t\tdrawingArea.GdkWindow.BeginPaintRect(view);\n\t\t\t\tRender(false);\n\t\t\t\tdrawingArea.GdkWindow.EndPaint();\n\t\t\t}\n\t\t\telse \n\t\t\t\tExposeManually();\n\t\t});\n\t}\n\t\n\t/// <summary>\n\t/// Render this group, manually handling the double buffering\n\t/// </summary>\n\tprivate void ExposeManually()\n\t{\n\t\tmanualDoubleBuffer = true;\n\t\tRender(false);\n\t\tmanualDoubleBuffer = false;\n\t}\n\t\n\t/// <summary>\n\t/// Invalidate this group (visually). This forces a complete redraw\n\t/// on the next Render().\n\t/// </summary>\n\tpublic void Invalidate()\n\t{\n\t\tchanges |= Changes.Offset;\n\t}\n\t\n\t/// <summary>\n\t/// Invalidate this group (visually). This forces a complete redraw\n\t/// on the next Render().\n\t/// </summary>\n\tpublic void RedrawNow()\n\t{\n\t\tSetChanged(Changes.Offset);\n\t}\n\t\n\tprivate void InitializeHighlights()\n\t{\n\t\tClearHighlights();\n\t\tif (!selection.IsEmpty())\n\t\t\thighlights.Insert(selection);\n\t}\n\t\n\t/// <summary>\n\t/// Adds a highlight on a range of data.\n\t/// </summary>\n\tpublic void AddHighlight(long start, long end, Drawer.HighlightType ht)\n\t{\n\t\thighlights.Insert(new Highlight(start, end, ht));\n\t\tchanges |= Changes.Highlights;\n\t}\n\t\n\tprivate void ClearHighlights()\n\t{\n\t\thighlights.Clear();\n\t}\n\t\n\tprivate void SetupBufferCache()\n\t{\n\t\tint nrows;\n\t\tUtil.Range view = GetViewRange(out nrows);\n\t\tif (view.Size != bufferCache.Length)\n\t\t\tbufferCache = new byte[view.Size];\n\t\t\n\t\tfor(int i = 0; i < view.Size; i++)\n\t\t\tbufferCache[i] = byteBuffer[view.Start + i];\n\t}\n\t\n\tpublic void CycleFocus()\n\t{\n\t\tint faIndex; \n\t\tfor (faIndex = 0; faIndex < areas.Count; faIndex++)\n\t\t\tif (focusedArea == areas[faIndex])\n\t\t\t\tbreak;\n\t\t\n\t\tif (faIndex >= areas.Count)\n\t\t\tfaIndex = -1;\n\t\t\n\t\tint end = faIndex + areas.Count;\n\t\t\n\t\t// use < instead of != so this will work correctly\n\t\t// even when faIndex = -1 in which case we should check\n\t\t// all areas (instead of only the rest areas.Count - 1 \n\t\t// areas when there is already a focused area)\n\t\tfor (faIndex++; faIndex < end; faIndex++) {\n\t\t\tArea a = (areas[faIndex%areas.Count] as Area);\n\t\t\tif (a.CanFocus == true) {\n\t\t\t\tUpdateFocusedArea(a);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\t\n\t\tfocusedArea = null;\n\t}\n\t\n\tprivate void UpdateFocusedArea(Area fa)\n\t{\n\t\tfocusedArea = fa;\n\t\t\n\t\tforeach(Area a in areas)\n\t\t\ta.HasCursorFocus = false;\n\t\t\n\t\tfocusedArea.HasCursorFocus = true;\n\t\t\n\t\t// set the previous cursor so that when\n\t\t// the screen is rendered the byte under the\n\t\t// cursor is properly cleared (before being drawn\n\t\t// again)\n\t\tprevCursorOffset = cursorOffset;\n\t\t\n\t\tSetChanged(Changes.Cursor);\n\t}\n\t\n\t/// <summary>\n\t/// Renders the extra (data independent) portions of the view \n\t/// </summary>\n\tprivate void RenderExtra()\n\t{\n\t\tforeach(Area a in areas) {\n\t\t\ta.RenderExtra();\n\t\t}\n\t}\n\t/// <summary>\n\t/// Renders a <see cref=\"Util.Range\"/> of data using a specified <see cref=\"Drawer.HighlightType\"/>\n\t/// </summary>\n\tprivate void RenderHighlight(AtomicHighlight h)\n\t{\n\t\tDrawer.HighlightType left;\n\t\tDrawer.HighlightType right;\n\t\th.GetAbyssHighlights(out left, out right);\n\t\t\n\t\t//System.Console.WriteLine(\"  Rendering {0}  ({1} {2})\", h, left, right);\n\t\tforeach(Area a in areas) {\n\t\t\ta.RenderHighlight(h, left, right);\n\t\t}\n\t}\n\t\n\t/// <summary>\n\t/// Blanks the view background\n\t/// </summary>\n\tprivate void BlankBackground()\n\t{\n\t\tforeach(Area a in areas) {\n\t\t\ta.BlankBackground();\n\t\t}\n\t}\n\t\n\tprivate AtomicHighlight[] SplitAtomicPrioritized(AtomicHighlight q, Highlight r)\n\t{\n\t\tAtomicHighlight[] ha;\n\t\t\n\t\tif (q.Type > r.Type) {\n\t\t\tha = new AtomicHighlight[3]{new AtomicHighlight(r), new AtomicHighlight(q), new AtomicHighlight(r)};\n\t\t\tUtil.Range.SplitAtomic(ha, r, q);\n\t\t\tha[1].AddContainer(r);\n\t\t}\n\t\telse {\n\t\t\tha = new AtomicHighlight[3]{new AtomicHighlight(q), new AtomicHighlight(r), new AtomicHighlight(q)};\n\t\t\tUtil.Range.SplitAtomic(ha, q, r);\n\t\t\tforeach (Highlight h in q.Containers)\n\t\t\t\tha[1].AddContainer(h);\n\t\t}\n\t\t\n\t\treturn ha;\n\t}\n\t\n\t/// <summary>\n\t/// Breaks down a base highlight and produces atomic highlights \n\t/// </summary>\n\tprivate IntervalTree<AtomicHighlight> BreakDownHighlights(Highlight s, IList<Highlight> lst)\n\t{\n\t\t//System.Console.WriteLine(\"breaking down {0}\", s);\n\t\tIntervalTree<AtomicHighlight> it = new IntervalTree<AtomicHighlight>();\n\t\t\n\t\tif (!s.IsEmpty())\n\t\t\tit.Insert(new AtomicHighlight(s));\n\t\t\n\t\tforeach(Highlight r in lst) {\n\t\t\t//System.Console.WriteLine(\"  Processing {0}\", r);\n\t\t\tIList<AtomicHighlight> overlaps = it.SearchOverlap(r);\n\t\t\tforeach(AtomicHighlight q in overlaps) {\n\t\t\t\tit.Delete(q);\n\t\t\t\t//System.Console.WriteLine(\"    Overlap {0}\", q);\n\t\t\t\tAtomicHighlight[] ha = SplitAtomicPrioritized(q, r);\t\t\t\n\t\t\t\tforeach(AtomicHighlight h in ha) {\n\t\t\t\t\t// Keep only common parts to avoid duplications.\n\t\t\t\t\t// This also has the useful side effect that everything\n\t\t\t\t\t// is clipped inside s\n\t\t\t\t\th.Intersect(q);\n\t\t\t\t\t//System.Console.WriteLine(\"      Atomic {0}\", h);\n\t\t\t\t\tif (!h.IsEmpty()) {\n\t\t\t\t\t\tit.Insert(h);\n\t\t\t\t\t}\n\t\t\t\t}\t\n\t\t\t}\n\t\t}\n\t\t\n\t\t//foreach(AtomicHighlight ah in it.GetValues()) {\n\t\t//\tSystem.Console.WriteLine(\"  \" + ah);\n\t\t//}\n\t\t\n\t\treturn it;\n\t}\n\t\t\n\t\n\t/// <summary>\n\t/// Gets the atomic highlight ranges of the current view.\n\t/// (Non-overlapping ranges that describe the highlighting of the whole view)\n\t/// </summary>\n\tprivate IntervalTree<AtomicHighlight> GetAtomicHighlights()\n\t{\n\t\tint nrows;\n\t\tUtil.Range clip = GetViewRange(out nrows);\n\t\tHighlight view = new Highlight(clip, Drawer.HighlightType.Normal);\n\t\t\n\t\t// get all highlights in current view\n\t\tIList<Highlight> viewableHighlights = highlights.SearchOverlap(view);\n\t\t\n\t\treturn BreakDownHighlights(view, viewableHighlights);\n\t}\n\t\n\t/// <summary>\n\t/// Renders the area group based on the specified atomic highlights.\n\t/// </summary>\n\tprivate void RenderAtomicHighlights(IntervalTree<AtomicHighlight> atomicHighlights)\n\t{\n\t\tIList<AtomicHighlight> hl = atomicHighlights.GetValues();\n\t\t\n\t\tforeach(AtomicHighlight h in hl) {\n\t\t\tRenderHighlight(h);\n\t\t}\n\t}\n\t\n\t/// <summary>\n\t/// Render the whole view.\n\t/// </summary>\n\t/// <param name=\"atomicHighlights\">\n\t/// The current atomic highlight ranges\n\t/// </param>\n\tprivate void RenderAll(IntervalTree<AtomicHighlight> atomicHighlights)\n\t{\n\t\tSetupBufferCache();\n\t\t\n\t\t// blank the background\n\t\tBlankBackground();\n\t\t\n\t\tRenderExtra();\n\t\t\n\t\tRenderAtomicHighlights(atomicHighlights);\n\t\t\n\t\tRenderCursor(atomicHighlights);\n\t}\n\t\n\t/// <summary>\n\t/// Render the new highlights taking into consideration the old highlights\n\t/// (this means that only the differences are actually rendered)\n\t/// </summary>\n\tprivate void RenderHighlightDiffs(IntervalTree<AtomicHighlight> atomicHighlights)\n\t{\n\t\t//System.Console.WriteLine(\"Rendering highlight diffs\");\n\t\tIList<AtomicHighlight> hl = atomicHighlights.GetValues();\n\t\t\n\t\tforeach(AtomicHighlight h in hl) {\n\t\t\t//System.Console.WriteLine(\"  Checking {0}\", h);\n\t\t\tIList<AtomicHighlight> overlaps = prevAtomicHighlights.SearchOverlap(h);\n\t\t\tforeach(AtomicHighlight overlap in overlaps) {\n\t\t\t\t\n\t\t\t\tAtomicHighlight hTmp = new AtomicHighlight(h);\n\t\t\t\thTmp.Intersect(overlap);\n\t\t\t\tAtomicHighlight oTmp = new AtomicHighlight(overlap);\n\t\t\t\toTmp.Intersect(h);\n\t\t\t\t//System.Console.WriteLine(\"    Overlaps with {0}\", oTmp);\n\t\t\t\t\n\t\t\t\tbool diffType = oTmp.Type != hTmp.Type;\n\t\t\t\t\n\t\t\t\tDrawer.HighlightType left, right, oleft, oright;\n\t\t\t\t\t\t\t\t\n\t\t\t\thTmp.GetAbyssHighlights(out left, out right);\n\t\t\t\toTmp.GetAbyssHighlights(out oleft, out oright);\n\t\t\t\t\n\t\t\t\tbool diffAbyss = (left != oleft) || (right != oright);\n\t\t\t\t\n\t\t\t\tif (diffType || diffAbyss) {\n\t\t\t\t\t//System.Console.Write(diffType?\"      DiffType> \":\"      DiffFlags> \");\n\t\t\t\t\t//System.Console.WriteLine(hTmp);\n\t\t\t\t\tRenderHighlight(hTmp);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t\n\tprivate void RenderCursor(IntervalTree<AtomicHighlight> atomicHighlights)\n\t{\n\t\t// find the kind of highlight the cursor was previously on\n\t\t// if we don't find an overlap this means that either\n\t\t// 1. the prev cursor position is not visible on the screen\n\t\t// 2. the prev cursor position is at or beyond the end of the file\n\t\tIList<AtomicHighlight> overlaps = atomicHighlights.SearchOverlap(new Util.Range(prevCursorOffset, prevCursorOffset));\n\t\t\n\t\tAtomicHighlight h = null;\n\t\t\n\t\t// if we find an overlap create a highlight\n\t\t// to use to restore the prev position\n\t\tif (overlaps.Count > 0) {\n\t\t\th = new AtomicHighlight(overlaps[0]);\n\t\t\th.Start = prevCursorOffset;\n\t\t\th.End = prevCursorOffset;\n\t\t}\n\t\t\n\t\tbool prevCursorBeyondEof =  prevCursorOffset >= byteBuffer.Size;\n\t\t\n\t\tif (h != null) {\n\t\t\tRenderHighlight(h);\n\t\t}\n\t\telse if (prevCursorBeyondEof) { // case 2\n\t\t\tforeach(Area a in areas)\n\t\t\t\ta.BlankOffset(prevCursorOffset);\n\t\t}\n\t\t\n\t\tif (selection.IsEmpty())\n\t\t\tforeach(Area a in areas)\n\t\t\t\ta.RenderCursor();\n\t}\n\t\n\t/// <summary>\n\t/// Render this area group.\n\t/// </summary>\n\t/// <param name=\"force\">\n\t/// Whether to force a complete redraw of the group.\n\t/// </param>\n\t/// <remarks>\n\t/// If force is false this method tries to redraw as little\n\t/// as possible by drawing only the parts of the screen that\n\t/// have changed (eg when changing the selection)\n\t/// </remarks>\n\tpublic void Render(bool force)\n\t{\n\t\t// sanity check\n\t\tif (byteBuffer == null)\n\t\t\treturn;\n\t\t\n\t\tInitializeHighlights();\n\t\t\n\t\tif (PreRenderEvent != null)\n\t\t\tPreRenderEvent(this);\n\t\t\n\t\t/* This breaks the RenderExtra() optimizations in OffsetArea and SeparatorArea\n\t\t\n\t\t// if we are forced to redraw but nothing\n\t\t// has changed, just redraw the previous atomic highlights\n\t\tif (force && !HasAnythingChanged()) {\n\t\t\t//System.Console.WriteLine(\"Not changed\");\n\t\t\tRenderAtomicHighlights(prevAtomicHighlights);\n\t\t\treturn;\n\t\t}*/\n\t\t\n\t\t// get the current atomic highlights\n\t\tIntervalTree<AtomicHighlight> atomicHighlights;\n\t\t\n\t\t// if atomic highlights have not changed, reuse them\n\t\tif (!force && !HasChanged(Changes.Highlights) && !HasChanged(Changes.Offset))\n\t\t\tatomicHighlights = prevAtomicHighlights; \n\t\telse {\n\t\t\t//System.Console.WriteLine(\"Re-eval atomic highs\");\n\t\t\tatomicHighlights = GetAtomicHighlights();\n\t\t}\n\t\t\n\t\t// if we are forced to redraw or the view has scrolled (the offset has changed)\n\t\t// redraw everything\n\t\tif (force || HasChanged(Changes.Offset)) {\n\t\t\t//System.Console.WriteLine(\"Scroll\");\n\t\t\tRenderAll(atomicHighlights);\n\t\t} // otherwise redraw only what is needed\n\t\telse if (HasChanged(Changes.Highlights)) {\n\t\t\t//System.Console.WriteLine(\"Diffs\");\n\t\t\tRenderHighlightDiffs(atomicHighlights);\n\t\t}\n\t\t\n\t\tif (HasChanged(Changes.Cursor)) {\n\t\t\t//System.Console.WriteLine(\"Cursor\");\n\t\t\tRenderCursor(atomicHighlights);\n\t\t}\n\t\t\n\t\t// update prevAtomicHighlights\n\t\tprevAtomicHighlights = atomicHighlights;\n\t\t\n\t\tClearChanges();\n\t}\n\t\n\tpublic delegate void PreRenderHandler(AreaGroup ag);\n\n\tpublic event PreRenderHandler PreRenderEvent;\n}\n\n} // end namespace\n"
  },
  {
    "path": "src/gui/areas/AsciiArea.cs",
    "content": "// created on 6/15/2004 at 4:10 PM\n/*\n *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System;\nusing Gtk;\nusing Gdk;\nusing Bless.Gui.Drawers;\nusing Bless.Plugins;\n\nnamespace Bless.Gui.Areas.Plugins {\n\npublic class AsciiAreaPlugin : AreaPlugin\n{\n\tpublic AsciiAreaPlugin()\n\t{\n\t\tname = \"ascii\";\n\t\tauthor = \"Alexandros Frantzis\";\n\t}\n\n\tpublic override Area CreateArea(AreaGroup ag)\n\t{\n\t\treturn new AsciiArea(ag);\n\t}\n}\n\n///<summary>An area that displays ascii</summary>\npublic class AsciiArea : Area {\n\n\n\tpublic AsciiArea(AreaGroup ag)\n\t\t\t: base(ag)\n\t{\n\t\ttype = \"ascii\";\n\t\tdpb = 1;\n\t\tcanFocus = true;\n\t}\n\n\tprotected override void RenderRowNormal(int i, int p, int n, bool blank)\n\t{\n\t\tint rx = 0 + x;\n\t\tint ry = i * drawer.Height + y;\n\t\tlong roffset = areaGroup.Offset + i * bpr + p;\n\t\tbool odd;\n\t\tGdk.GC backEvenGC = drawer.GetBackgroundGC(Drawer.RowType.Even, Drawer.HighlightType.Normal);\n\t\tGdk.GC backOddGC = drawer.GetBackgroundGC(Drawer.RowType.Odd, Drawer.HighlightType.Normal);\n\n\n\t\t// odd row?\n\t\todd = (((roffset / bpr) % 2) == 1);\n\n\t\tif (blank == true) {\n\t\t\tif (odd)\n\t\t\t\tbackPixmap.DrawRectangle(backOddGC, true, rx, ry, width, drawer.Height);\n\t\t\telse\n\t\t\t\tbackPixmap.DrawRectangle(backEvenGC, true, rx, ry, width, drawer.Height);\n\t\t}\n\n\t\tDrawer.RowType rowType;\n\n\t\tif (odd)\n\t\t\trowType = Drawer.RowType.Odd;\n\t\telse\n\t\t\trowType = Drawer.RowType.Even;\n\n\t\tint pos = 0;\n\n\t\twhile (true) {\n\n\t\t\tif (pos >= p) { //don't draw until we reach p\n\t\t\t\tdrawer.DrawNormal(backEvenGC, backPixmap, rx, ry, areaGroup.GetCachedByte(roffset++), rowType, Drawer.ColumnType.Even);\n\t\t\t\tif (--n <= 0)\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\trx = rx + drawer.Width;\n\n\t\t\tpos++;\n\t\t}\n\t}\n\n\tprotected override void RenderRowHighlight(int i, int p, int n, bool blank, Drawer.HighlightType ht)\n\t{\n\t\tint rx = 0 + x;\n\t\tint ry = i * drawer.Height + y;\n\t\tlong roffset = areaGroup.Offset + i * bpr + p;\n\t\tbool odd;\n\t\tGdk.GC backEvenGC = drawer.GetBackgroundGC(Drawer.RowType.Even, Drawer.HighlightType.Normal);\n\t\tGdk.GC backOddGC = drawer.GetBackgroundGC(Drawer.RowType.Odd, Drawer.HighlightType.Normal);\n\n\t\t// odd row?\n\t\todd = (((roffset / bpr) % 2) == 1);\n\n\t\tif (blank == true) {\n\t\t\tif (odd)\n\t\t\t\tbackPixmap.DrawRectangle(backOddGC, true, rx, ry, width, drawer.Height);\n\t\t\telse\n\t\t\t\tbackPixmap.DrawRectangle(backEvenGC, true, rx, ry, width, drawer.Height);\n\t\t}\n\n\t\tDrawer.RowType rowType;\n\n\t\tif (odd)\n\t\t\trowType = Drawer.RowType.Odd;\n\t\telse\n\t\t\trowType = Drawer.RowType.Even;\n\n\t\tint pos = 0;\n\n\t\twhile (true) {\n\n\t\t\tif (pos >= p) { //don't draw until we reach p\n\t\t\t\tdrawer.DrawHighlight(backEvenGC, backPixmap, rx, ry, areaGroup.GetCachedByte(roffset++), rowType, ht);\n\t\t\t\tif (--n <= 0)\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\trx = rx + drawer.Width;\n\n\t\t\tpos++;\n\t\t}\n\t}\n\n\tpublic override int CalcWidth(int n, bool force)\n\t{\n\t\tif (fixedBpr > 0 && n > fixedBpr && !force)\n\t\t\treturn -1;\n\t\telse\n\t\t\treturn n*drawer.Width;\n\t}\n\n\tpublic override void GetDisplayInfoByOffset(long off, out int orow, out int obyte, out int ox, out int oy)\n\t{\n\t\torow = (int)((off - areaGroup.Offset) / bpr);\n\t\tobyte = (int)((off - areaGroup.Offset) % bpr);\n\n\t\toy = orow * drawer.Height;\n\n\t\tox = obyte * drawer.Width;\n\t}\n\n\tpublic override long GetOffsetByDisplayInfo(int x, int y, out int digit, out GetOffsetFlags flags)\n\t{\n\t\tflags = 0;\n\t\tint row = y / drawer.Height;\n\t\tint col = x / drawer.Width;\n\t\tlong off = (row * bpr + col) + areaGroup.Offset;\n\n\t\tif (off >= areaGroup.Buffer.Size)\n\t\t\tflags |= GetOffsetFlags.Eof;\n\n\t\tdigit = 0;\n\n\t\treturn off;\n\t}\n\n\tpublic override bool HandleKey(Gdk.Key key, bool overwrite)\n\t{\n\t\t//System.Console.WriteLine(\"Ascii: {0}\", key);\n\t\tbyte[] ba = null;\n\n\t\tif (key >= Gdk.Key.space && key <= Gdk.Key.asciitilde)\n\t\t\tba = new byte[]{(byte)key};\n\t\telse if (key >= Gdk.Key.KP_0 && key <= Gdk.Key.KP_9)\n\t\t\tba = new byte[]{(byte)(key - Gdk.Key.KP_0 + Gdk.Key.Key_0)};\n\n\t\tif (ba != null) {\n\t\t\tif (areaGroup.CursorOffset == areaGroup.Buffer.Size)\n\t\t\t\tareaGroup.Buffer.Append(ba, 0, ba.LongLength);\n\t\t\telse if (overwrite == true)\n\t\t\t\tareaGroup.Buffer.Replace(areaGroup.CursorOffset, areaGroup.CursorOffset, ba);\n\t\t\telse if (overwrite == false)\n\t\t\t\tareaGroup.Buffer.Insert(areaGroup.CursorOffset, ba, 0, ba.LongLength);\n\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t}\n\n\tpublic override void Realize()\n\t{\n\t\tGtk.DrawingArea da = areaGroup.DrawingArea;\n\t\tdrawer = new AsciiDrawer(da, drawerInformation);\n\t\tbase.Realize();\n\t}\n\n}\n\n\n}//namespace\n"
  },
  {
    "path": "src/gui/areas/BinaryArea.cs",
    "content": "// created on 6/24/2004 at 2:32 PM\n/*\n *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing Bless.Plugins;\nusing Bless.Gui.Drawers;\nusing Gtk;\n\nnamespace Bless.Gui.Areas.Plugins {\n\npublic class BinaryAreaPlugin : AreaPlugin\n{\n\tpublic BinaryAreaPlugin()\n\t{\n\t\tname = \"binary\";\n\t\tauthor = \"Alexandros Frantzis\";\n\t}\n\n\tpublic override Area CreateArea(AreaGroup ag)\n\t{\n\t\treturn new BinaryArea(ag);\n\t}\n}\n\n///<summary>An area that displays binary</summary>\npublic class BinaryArea : GroupedArea {\n\n\tpublic BinaryArea(AreaGroup ag)\n\t\t\t: base(ag)\n\t{\n\t\ttype = \"binary\";\n\t\tdpb = 8;\n\t}\n\n\tpublic override bool HandleKey(Gdk.Key key, bool overwrite)\n\t{\n\t\t//System.Console.WriteLine(\"Binary: {0}\", key);\n\n\t\tif (key == Gdk.Key.Key_0 || key == Gdk.Key.Key_1 || key == Gdk.Key.KP_0 || key == Gdk.Key.KP_1) {\n\t\t\tbyte orig;\n\n\t\t\t// if we are after the end of the buffer, assume\n\t\t\t// a 0 byte\n\t\t\tif (areaGroup.CursorOffset == areaGroup.Buffer.Size || (overwrite == false && areaGroup.CursorDigit == 0))\n\t\t\t\torig = 0;\n\t\t\telse\n\t\t\t\torig = areaGroup.Buffer[areaGroup.CursorOffset];\n\n\t\t\tbyte repl;\n\n\t\t\tif (key == Gdk.Key.Key_1 || key == Gdk.Key.KP_1 )\n\t\t\t\trepl = (byte)((1 << (dpb - areaGroup.CursorDigit - 1)) | orig);\n\t\t\telse\n\t\t\t\trepl = (byte)((~(1 << (dpb - areaGroup.CursorDigit - 1))) & orig);\n\n\t\t\tbyte[] ba = new byte[]{repl};\n\n\t\t\tif (areaGroup.CursorOffset == areaGroup.Buffer.Size)\n\t\t\t\tareaGroup.Buffer.Append(ba, 0, ba.LongLength);\n\t\t\telse if (overwrite == false && areaGroup.CursorDigit == 0)\n\t\t\t\tareaGroup.Buffer.Insert(areaGroup.CursorOffset, ba, 0, ba.LongLength);\n\t\t\telse /*(if (overwrite==true || cursorDigit > 0)*/\n\t\t\t\tareaGroup.Buffer.Replace(areaGroup.CursorOffset, areaGroup.CursorOffset, ba);\n\n\n\t\t\treturn true;\n\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t}\n\n\tpublic override void Realize ()\n\t{\n\t\tGtk.DrawingArea da = areaGroup.DrawingArea;\n\t\tdrawer = new BinaryDrawer(da, drawerInformation);\n\t\tbase.Realize();\n\t}\n}\n\n}//namespace\n"
  },
  {
    "path": "src/gui/areas/DecimalArea.cs",
    "content": "// created on 7/1/2004 at 8:06 PM\n/*\n *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing Bless.Plugins;\nusing Bless.Gui.Drawers;\nusing Gtk;\n\nnamespace Bless.Gui.Areas.Plugins {\n\npublic class DecimalAreaPlugin : AreaPlugin\n{\n\tpublic DecimalAreaPlugin()\n\t{\n\t\tname = \"decimal\";\n\t\tauthor = \"Alexandros Frantzis\";\n\t}\n\n\tpublic override Area CreateArea(AreaGroup ag)\n\t{\n\t\treturn new DecimalArea(ag);\n\t}\n}\n\n///<summary>An area that displays decimal</summary>\npublic class DecimalArea : GroupedArea {\n\n\tpublic DecimalArea(AreaGroup ag)\n\t\t\t: base(ag)\n\t{\n\t\ttype = \"decimal\";\n\t\tdpb = 3;\n\t}\n\n\tpublic override bool HandleKey(Gdk.Key key, bool overwrite)\n\t{\n\t\t//System.Console.WriteLine(\"Decimal: {0}\", key);\n\n\t\tif ((key >= Gdk.Key.Key_0 && key <= Gdk.Key.Key_9) || (key >= Gdk.Key.KP_0 && key <= Gdk.Key.KP_9)) {\n\t\t\tbyte b;\n\t\t\tif (key >= Gdk.Key.Key_0 && key <= Gdk.Key.Key_9)\n\t\t\t\tb = (byte)(key - Gdk.Key.Key_0);\n\t\t\telse\n\t\t\t\tb = (byte)(key - Gdk.Key.KP_0);\n\n\t\t\tbyte orig;\n\n\t\t\t// if we are after the end of the buffer, assume\n\t\t\t// a 0 byte\n\t\t\tif (areaGroup.CursorOffset == areaGroup.Buffer.Size || (overwrite == false && areaGroup.CursorDigit == 0))\n\t\t\t\torig = 0;\n\t\t\telse\n\t\t\t\torig = areaGroup.Buffer[areaGroup.CursorOffset];\n\n\t\t\tbyte orig1 = (byte)(orig % 10);\n\t\t\tbyte orig10 = (byte)((orig / 10) % 10);\n\t\t\tbyte orig100 = (byte)((orig / 100) % 10);\n\n\t\t\tif (areaGroup.CursorDigit == 0)\n\t\t\t\torig100 = b;\n\t\t\telse if (areaGroup.CursorDigit == 1)\n\t\t\t\torig10 = b;\n\t\t\telse if (areaGroup.CursorDigit == 2)\n\t\t\t\torig1 = b;\n\n\t\t\tint repl = orig100 * 100 + orig10 * 10 + orig1;\n\t\t\tif (repl > 255)\n\t\t\t\treturn false;\n\n\t\t\tbyte[] ba = new byte[]{(byte)repl};\n\n\t\t\tif (areaGroup.CursorOffset == areaGroup.Buffer.Size)\n\t\t\t\tareaGroup.Buffer.Append(ba, 0, ba.LongLength);\n\t\t\telse if (overwrite == false && areaGroup.CursorDigit == 0)\n\t\t\t\tareaGroup.Buffer.Insert(areaGroup.CursorOffset, ba, 0, ba.LongLength);\n\t\t\telse /*(if (overwrite==true || areaGroup.CursorDigit > 0)*/\n\t\t\t\tareaGroup.Buffer.Replace(areaGroup.CursorOffset, areaGroup.CursorOffset, ba);\n\n\n\t\t\treturn true;\n\n\t\t} else\n\t\t\treturn false;\n\t}\n\n\tpublic override void Realize ()\n\t{\n\t\tGtk.DrawingArea da = areaGroup.DrawingArea;\n\t\tdrawer = new DecimalDrawer(da, drawerInformation);\n\t\tbase.Realize();\n\t}\n}\n\n}//namespace\n"
  },
  {
    "path": "src/gui/areas/GroupedArea.cs",
    "content": "// created on 7/16/2004 at 7:54 PM\n/*\n *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System;\nusing Gtk;\nusing Gdk;\nusing Bless.Gui.Drawers;\nusing System.Xml;\n\nnamespace Bless.Gui.Areas.Plugins {\n\n///<summary>An area that displays grouped bytes</summary>\nabstract public class GroupedArea : Area {\n\n\tint grouping;\n\n\tpublic GroupedArea(AreaGroup ag)\n\t\t\t: base(ag)\n\t{\n\t\tgrouping = 1;\n\t\tcanFocus = true;\n\t}\n\n\n\tpublic int Grouping {\n\t\tset {  grouping = value; }\n\t\tget {  return grouping; }\n\n\t}\n\n\tprotected override void RenderRowNormal(int i, int p, int n, bool blank)\n\t{\n\t\tint rx = 0 + x;\n\t\tint ry = i * drawer.Height + y;\n\t\tlong roffset = areaGroup.Offset + i * bpr + p;\n\t\tbool odd;\n\t\tGdk.GC backEvenGC = drawer.GetBackgroundGC(Drawer.RowType.Even, Drawer.HighlightType.Normal);\n\t\tGdk.GC backOddGC = drawer.GetBackgroundGC(Drawer.RowType.Odd, Drawer.HighlightType.Normal);\n\n\t\t// odd row?\n\t\todd = (((roffset / bpr) % 2) == 1);\n\n\t\tif (blank == true) {\n\t\t\tif (odd)\n\t\t\t\tbackPixmap.DrawRectangle(backOddGC, true, rx, ry, width, drawer.Height);\n\t\t\telse\n\t\t\t\tbackPixmap.DrawRectangle(backEvenGC, true, rx, ry, width, drawer.Height);\n\t\t}\n\n\t\tDrawer.ColumnType colType;\n\t\tDrawer.RowType rowType;\n\n\t\tif (odd)\n\t\t\trowType = Drawer.RowType.Odd;\n\t\telse\n\t\t\trowType = Drawer.RowType.Even;\n\n\t\tint pos = 0;\n\t\t// draw bytes\n\t\twhile (true) {\n\n\t\t\tif (pos >= p) { //don't draw until we reach p\n\t\t\t\tif ((pos / grouping) % 2 == 0)\n\t\t\t\t\tcolType = Drawer.ColumnType.Even;\n\t\t\t\telse\n\t\t\t\t\tcolType = Drawer.ColumnType.Odd;\n\n\t\t\t\tdrawer.DrawNormal(backEvenGC, backPixmap, rx, ry, areaGroup.GetCachedByte(roffset++), rowType, colType);\n\t\t\t\tif (--n <= 0)\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// space if necessary\n\t\t\tif (pos % grouping == grouping - 1)\n\t\t\t\trx = rx + (dpb + 1) * drawer.Width;\n\t\t\telse\n\t\t\t\trx = rx + dpb * drawer.Width;\n\n\t\t\tpos++;\n\t\t}\n\t}\n\n\tprotected override void RenderRowHighlight(int i, int p, int n, bool blank, Drawer.HighlightType ht)\n\t{\n\t\tint rx = 0 + x;\n\t\tint ry = i * drawer.Height + y;\n\t\tlong roffset = areaGroup.Offset + i * bpr + p;\n\t\tbool odd;\n\t\tGdk.GC backEvenGC = drawer.GetBackgroundGC(Drawer.RowType.Even, Drawer.HighlightType.Normal);\n\t\tGdk.GC backOddGC = drawer.GetBackgroundGC(Drawer.RowType.Odd, Drawer.HighlightType.Normal);\n\n\t\t// odd row?\n\t\todd = (((roffset / bpr) % 2) == 1);\n\n\t\tif (blank == true) {\n\t\t\tif (odd)\n\t\t\t\tbackPixmap.DrawRectangle(backOddGC, true, rx, ry, width, drawer.Height);\n\t\t\telse\n\t\t\t\tbackPixmap.DrawRectangle(backEvenGC, true, rx, ry, width, drawer.Height);\n\t\t}\n\n\t\tDrawer.RowType rowType;\n\n\t\tif (odd)\n\t\t\trowType = Drawer.RowType.Odd;\n\t\telse\n\t\t\trowType = Drawer.RowType.Even;\n\n\t\tint pos = 0;\n\t\t// draw bytes\n\t\twhile (true) {\n\n\t\t\tif (pos >= p) { //don't draw until we reach p\n\t\t\t\tdrawer.DrawHighlight(backEvenGC, backPixmap, rx, ry, areaGroup.GetCachedByte(roffset++), rowType, ht);\n\t\t\t\tif (--n <= 0)\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// space if necessary\n\t\t\tif (pos % grouping == grouping - 1)\n\t\t\t\trx = rx + (dpb + 1) * drawer.Width;\n\t\t\telse\n\t\t\t\trx = rx + dpb * drawer.Width;\n\n\t\t\tpos++;\n\t\t}\n\t}\n\n\tpublic override int CalcWidth(int n, bool force)\n\t{\n\t\tif (n == 0)\n\t\t\treturn 0;\n\t\tif (fixedBpr > 0 && n > fixedBpr && !force) // must adhere to fixed length\n\t\t\treturn -1;\n\t\tif (n % grouping != 0 && !force) // can't break the grouping\n\t\t\treturn -1;\n\n\t\tint ngroups = n / grouping;\n\t\tint groupWidth = grouping * dpb * drawer.Width;\n\n\t\treturn ngroups*groupWidth + (ngroups - 1)*drawer.Width;\n\t}\n\n\tpublic override void GetDisplayInfoByOffset(long off, out int orow, out int obyte, out int ox, out int oy)\n\t{\n\t\torow = (int)((off - areaGroup.Offset) / bpr);\n\t\tobyte = (int)((off - areaGroup.Offset) % bpr);\n\n\t\toy = orow * drawer.Height;\n\n\t\tint group = obyte / grouping;\n\t\tint groupOffset = obyte % grouping;\n\t\tox = group * (grouping * dpb * drawer.Width + drawer.Width) + dpb * drawer.Width * groupOffset;\n\t}\n\n\tpublic override long GetOffsetByDisplayInfo(int x, int y, out int digit, out GetOffsetFlags flags)\n\t{\n\t\tflags = 0;\n\t\tint groupWidth = (grouping * dpb * drawer.Width + drawer.Width);\n\n\t\tint row = y / drawer.Height;\n\t\tint group = x / groupWidth;\n\t\tint groupByte = (x - group * groupWidth) / (dpb * drawer.Width);\n\n\t\tdigit = (x - group * groupWidth - groupByte * dpb * drawer.Width) / drawer.Width;\n\n\t\tif (groupByte >= grouping) {\n\t\t\tgroupByte = grouping - 1;\n\t\t\tflags |= GetOffsetFlags.Abyss;\n\t\t}\n\n\t\tlong off = row * bpr + (group * grouping + groupByte) + areaGroup.Offset;\n\t\tif (off >= areaGroup.Buffer.Size)\n\t\t\tflags |= GetOffsetFlags.Eof;\n\n\t\treturn off;\n\n\t}\n\n\tpublic override void Configure(XmlNode parentNode)\n\t{\n\t\tbase.Configure(parentNode);\n\n\t\tXmlNodeList childNodes = parentNode.ChildNodes;\n\t\tforeach(XmlNode node in childNodes) {\n\t\t\tif (node.Name == \"grouping\")\n\t\t\t\tthis.Grouping = Convert.ToInt32(node.InnerText);\n\t\t}\n\t}\n\n}// end GroupedArea\n\n}//end namespace"
  },
  {
    "path": "src/gui/areas/HexArea.cs",
    "content": "// created on 6/15/2004 at 4:10 PM\n/*\n *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System.Xml;\nusing Bless.Plugins;\nusing Bless.Gui.Drawers;\nusing Gtk;\n\nnamespace Bless.Gui.Areas.Plugins {\n\npublic class HexAreaPlugin : AreaPlugin\n{\n\tpublic HexAreaPlugin()\n\t{\n\t\tname = \"hexadecimal\";\n\t\tauthor = \"Alexandros Frantzis\";\n\t}\n\n\tpublic override Area CreateArea(AreaGroup ag)\n\t{\n\t\treturn new HexArea(ag);\n\t}\n}\n///<summary>An area that displays hexadecimal</summary>\npublic class HexArea : GroupedArea {\n\n\n\tpublic HexArea(AreaGroup ag)\n\t\t\t: base(ag)\n\t{\n\t\ttype = \"hexadecimal\";\n\t\tdpb = 2;\n\t}\n\n\tprivate int KeyToHex(Gdk.Key key)\n\t{\n\t\tif (key >= Gdk.Key.Key_0 && key <= Gdk.Key.Key_9)\n\t\t\treturn key - Gdk.Key.Key_0;\n\t\telse if (key >= Gdk.Key.A && key <= Gdk.Key.F)\n\t\t\treturn key - Gdk.Key.A + 10;\n\t\telse if (key >= Gdk.Key.a && key <= Gdk.Key.f)\n\t\t\treturn key - Gdk.Key.a + 10;\n\t\telse if (key >= Gdk.Key.KP_0 && key <= Gdk.Key.KP_9)\n\t\t\treturn key - Gdk.Key.KP_0;\n\t\telse\n\t\t\treturn -1;\n\t}\n\n\tpublic override bool HandleKey(Gdk.Key key, bool overwrite)\n\t{\n\t\tint hex = KeyToHex(key);\n\n\t\tif (hex != -1) {\n\t\t\tbyte b = (byte)hex;\n\t\t\tbyte orig;\n\n\t\t\t// if we are after the end of the buffer, assume\n\t\t\t// a 0 byte\n\t\t\tif (areaGroup.CursorOffset == areaGroup.Buffer.Size || (overwrite == false && areaGroup.CursorDigit == 0))\n\t\t\t\torig = 0;\n\t\t\telse\n\t\t\t\torig = areaGroup.Buffer[areaGroup.CursorOffset];\n\n\t\t\tbyte orig1 = (byte)(orig % 16);\n\t\t\tbyte orig16 = (byte)((orig / 16) % 16);\n\n\n\t\t\tif (areaGroup.CursorDigit == 0)\n\t\t\t\torig16 = b;\n\t\t\telse if (areaGroup.CursorDigit == 1)\n\t\t\t\torig1 = b;\n\n\t\t\tbyte repl = (byte)(orig16 * 16 + orig1);\n\n\t\t\tbyte[] ba = new byte[]{repl};\n\n\t\t\tif (areaGroup.CursorOffset == areaGroup.Buffer.Size)\n\t\t\t\tareaGroup.Buffer.Append(ba, 0, ba.LongLength);\n\t\t\telse if (overwrite == false && areaGroup.CursorDigit == 0)\n\t\t\t\tareaGroup.Buffer.Insert(areaGroup.CursorOffset, ba, 0, ba.LongLength);\n\t\t\telse /*(if (overwrite==true || areaGroup.CursorDigit > 0)*/\n\t\t\t\tareaGroup.Buffer.Replace(areaGroup.CursorOffset, areaGroup.CursorOffset, ba);\n\n\n\t\t\treturn true;\n\n\t\t} else\n\t\t\treturn false;\n\t}\n\n\tpublic override void Configure(XmlNode parentNode)\n\t{\n\t\tbase.Configure(parentNode);\n\n\t\tXmlNodeList childNodes = parentNode.ChildNodes;\n\t\tforeach(XmlNode node in childNodes) {\n\t\t\tif (node.Name == \"case\")\n\t\t\t\tdrawerInformation.Uppercase = (node.InnerText == \"upper\");\n\t\t}\n\t}\n\n\tpublic override void Realize ()\n\t{\n\t\tGtk.DrawingArea da = areaGroup.DrawingArea;\n\t\tdrawer = new HexDrawer(da, drawerInformation);\n\t\tbase.Realize();\n\t}\n}\n\n}//namespace\n"
  },
  {
    "path": "src/gui/areas/Highlight.cs",
    "content": "// created on 19/3/2008 at 6:14 PM\n/*\n *   Copyright (c) 2008, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System;\nusing System.Collections.Generic;\nusing Bless.Util;\nusing Bless.Gui.Drawers;\n\nnamespace Bless.Gui.Areas\n{\n\npublic class Highlight : Util.Range, IEquatable<Highlight>\n{\n\tprotected Drawer.HighlightType type;\n\t\n\tpublic Drawer.HighlightType Type {\n\t\tget { return type; }\n\t}\n\t\n\tpublic Highlight() : base()\n\t{\n\t\ttype = Drawer.HighlightType.Normal;\n\t}\n\t\n\tpublic Highlight(Drawer.HighlightType ht) : base()\n\t{\n\t\ttype = ht;\t\n\t}\n\t\n\tpublic Highlight(IRange r, Drawer.HighlightType ht) : base(r)\n\t{\n\t\ttype = ht;\t\n\t}\n\t\n\tpublic Highlight(long start, long end, Drawer.HighlightType ht) : base(start, end)\n\t{\n\t\ttype = ht;\n\t}\n\t\n\tpublic Highlight(Highlight h) : this(h, h.Type)\n\t{\n\t\n\t}\n\t\n\tpublic bool Equals(Highlight h)\n\t{\n\t\treturn this.Start == h.Start && this.End == h.End && this.Type == h.Type; \n\t}\n\t\n\tpublic override bool Equals(object obj)\n\t{\n\t\tHighlight h = obj as Highlight;\n\t\tif (h != null)\n\t\t\treturn Equals(h);\n\t\telse\n\t\t\treturn false;\n\t}\n\t\n\tpublic override int GetHashCode()\n\t{\n\t\treturn (start.GetHashCode() ^ end.GetHashCode() ^ type.GetHashCode());\n\t}\n\t\n\tpublic override string ToString()\n\t{\n\t\treturn base.ToString() + \" Type: \" + type;\n\t}\n\t\n}\n\n} // end namespace"
  },
  {
    "path": "src/gui/areas/OctalArea.cs",
    "content": "// created on 7/1/2004 at 8:39 PM\n/*\n *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing Bless.Plugins;\nusing Bless.Gui.Drawers;\nusing Gtk;\n\nnamespace Bless.Gui.Areas.Plugins {\n\npublic class OctalAreaPlugin : AreaPlugin\n{\n\tpublic OctalAreaPlugin()\n\t{\n\t\tname = \"octal\";\n\t\tauthor = \"Alexandros Frantzis\";\n\t}\n\n\tpublic override Area CreateArea(AreaGroup ag)\n\t{\n\t\treturn new OctalArea(ag);\n\t}\n}\n\n///<summary>An area that displays octal</summary>\npublic class OctalArea : GroupedArea {\n\n\tpublic OctalArea(AreaGroup ag)\n\t\t\t: base(ag)\n\t{\n\t\ttype = \"octal\";\n\t\tdpb = 3;\n\t}\n\n\tpublic override bool HandleKey(Gdk.Key key, bool overwrite)\n\t{\n\t\t//System.Console.WriteLine(\"Octal: {0}\", key);\n\n\t\tif (key >= Gdk.Key.Key_0 && key <= Gdk.Key.Key_7 || (key >= Gdk.Key.KP_0 && key <= Gdk.Key.KP_7)) {\n\t\t\tbyte b;\n\t\t\tif (key >= Gdk.Key.Key_0 && key <= Gdk.Key.Key_7)\n\t\t\t\tb = (byte)(key - Gdk.Key.Key_0);\n\t\t\telse\n\t\t\t\tb = (byte)(key - Gdk.Key.KP_0);\n\n\t\t\tbyte orig;\n\n\t\t\t// if we are after the end of the buffer, assume\n\t\t\t// a 0 byte\n\t\t\tif (areaGroup.CursorOffset == areaGroup.Buffer.Size || (overwrite == false && areaGroup.CursorDigit == 0))\n\t\t\t\torig = 0;\n\t\t\telse\n\t\t\t\torig = areaGroup.Buffer[areaGroup.CursorOffset];\n\n\t\t\tbyte orig1 = (byte)(orig % 8);\n\t\t\tbyte orig8 = (byte)((orig / 8) % 8);\n\t\t\tbyte orig64 = (byte)((orig / 64) % 8);\n\n\t\t\tif (areaGroup.CursorDigit == 0)\n\t\t\t\torig64 = b;\n\t\t\telse if (areaGroup.CursorDigit == 1)\n\t\t\t\torig8 = b;\n\t\t\telse if (areaGroup.CursorDigit == 2)\n\t\t\t\torig1 = b;\n\n\t\t\tint repl = orig64 * 64 + orig8 * 8 + orig1;\n\n\t\t\tif (repl > 255)\n\t\t\t\treturn false;\n\n\t\t\tbyte[] ba = new byte[]{(byte)repl};\n\n\t\t\tif (areaGroup.CursorOffset == areaGroup.Buffer.Size)\n\t\t\t\tareaGroup.Buffer.Append(ba, 0, ba.LongLength);\n\t\t\telse if (overwrite == false && areaGroup.CursorDigit == 0)\n\t\t\t\tareaGroup.Buffer.Insert(areaGroup.CursorOffset, ba, 0, ba.LongLength);\n\t\t\telse /*(if (overwrite==true || areaGroup.CursorDigit > 0)*/\n\t\t\t\tareaGroup.Buffer.Replace(areaGroup.CursorOffset, areaGroup.CursorOffset, ba);\n\n\n\t\t\treturn true;\n\n\t\t} else\n\t\t\treturn false;\n\t}\n\n\tpublic override void Realize ()\n\t{\n\t\tGtk.DrawingArea da = areaGroup.DrawingArea;\n\t\tdrawer = new OctalDrawer(da, drawerInformation);\n\t\tbase.Realize();\n\t}\n}\n\n}//namespace\n"
  },
  {
    "path": "src/gui/areas/OffsetArea.cs",
    "content": "// created on 6/14/2004 at 11:05 PM\n/*\n *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing System;\nusing Gtk;\nusing Gdk;\nusing Bless.Gui.Drawers;\nusing Bless.Util;\nusing System.Xml;\nusing Bless.Plugins;\n\nnamespace Bless.Gui.Areas.Plugins {\n\npublic class OffsetAreaPlugin : AreaPlugin\n{\n\tpublic OffsetAreaPlugin()\n\t{\n\t\tname = \"offset\";\n\t\tauthor = \"Alexandros Frantzis\";\n\t}\n\n\tpublic override Area CreateArea(AreaGroup ag)\n\t{\n\t\treturn new OffsetArea(ag);\n\t}\n}\n\n///<summary>An area that display the offsets</summary>\npublic class OffsetArea : Area {\n\n\tint bytes;\n\n\tpublic int Bytes {\n\t\tget { return bytes; }\n\t\tset { bytes = value; }\n\t}\n\n\tpublic OffsetArea(AreaGroup ag)\n\t\t\t: base(ag)\n\t{\n\t\ttype = \"offset\";\n\t\tbytes = 4;\n\t}\n\n\tprotected override void RenderExtra()\n\t{\n\t\tif (bpr <= 0)\n\t\t\treturn;\n\n\t\tint nrows = height / drawer.Height;\n\t\tlong bleft = nrows * bpr;\n\t\tint rfull = 0;\n\t\tint blast = 0;\n\n\t\tif (bleft + areaGroup.Offset > areaGroup.Buffer.Size)\n\t\t\tbleft = areaGroup.Buffer.Size - areaGroup.Offset + 1; \n\n\t\t// calculate number of full rows\n\t\t// and number of bytes in last (non-full)\n\t\trfull = (int)(bleft / bpr);\n\t\tblast = (int)(bleft % bpr);\n\n\t\tif (blast > 0)\n\t\t\trfull++;\n\n\t\tfor (int i = 0; i < rfull; i++)\n\t\t\tRenderRowNormal(i, 0, bpr, true);\n\t}\n\t\n\tprotected override void RenderHighlight(Highlight h, Drawer.HighlightType left, Drawer.HighlightType right)\n\t{\n\t}\n\t\n\tprotected override void RenderRowNormal(int i, int p, int n, bool blank)\n\t{\n\t\tint rx = (bytes - 1) * 2 * drawer.Width + x;\n\t\tint ry = i * drawer.Height + y;\n\t\tlong roffset = areaGroup.Offset + i * bpr;\n\t\tbool odd;\n\t\tGdk.GC backEvenGC = drawer.GetBackgroundGC(Drawer.RowType.Even, Drawer.HighlightType.Normal);\n\t\tGdk.GC backOddGC = drawer.GetBackgroundGC(Drawer.RowType.Odd, Drawer.HighlightType.Normal);\n\n\t\t// odd row?\n\t\todd = (((roffset / bpr) % 2) == 1);\n\n\t\tif (blank == true) {\n\t\t\tif (odd)\n\t\t\t\tbackPixmap.DrawRectangle(backOddGC, true, x, ry, width, drawer.Height);\n\t\t\telse\n\t\t\t\tbackPixmap.DrawRectangle(backEvenGC, true, x, ry, width, drawer.Height);\n\t\t}\n\n\t\tDrawer.RowType rowType;\n\n\t\tif (odd)\n\t\t\trowType = Drawer.RowType.Odd;\n\t\telse\n\t\t\trowType = Drawer.RowType.Even;\n\n\t\t// if nothing to draw return\n\t\tif (n == 0)\n\t\t\treturn;\n\n\t\t// draw offsets\n\t\tfor (int j = 0; j < bytes; j++) {\n\t\t\tdrawer.DrawNormal(backEvenGC, backPixmap, rx, ry, (byte)(roffset & 0xff), rowType, Drawer.ColumnType.Even);\n\t\t\troffset = roffset >> 8;\n\t\t\trx = rx - 2 * drawer.Width;\n\t\t}\n\t}\n\n\tprotected override void RenderRowHighlight(int i, int p, int n, bool blank, Drawer.HighlightType ht)\n\t{\n\t\tRenderRowNormal(i, p, n, blank);\n\t}\n\n\tpublic override int CalcWidth(int n, bool force)\n\t{\n\t\treturn 2*bytes*drawer.Width;\n\t}\n\n\tpublic override void GetDisplayInfoByOffset(long off, out int orow, out int obyte, out int ox, out int oy)\n\t{\n\t\torow = (int)((off - areaGroup.Offset) / bpr);\n\t\tobyte = (int)((off - areaGroup.Offset) % bpr);\n\n\t\toy = orow * drawer.Height;\n\n\t\tox = 0;\n\t}\n\n\tpublic override long GetOffsetByDisplayInfo(int x, int y, out int digit, out GetOffsetFlags flags)\n\t{\n\t\tflags = 0;\n\t\tint row = y / drawer.Height;\n\t\tlong off = row * bpr + areaGroup.Offset;\n\t\tif (off >= areaGroup.Buffer.Size)\n\t\t\tflags |= GetOffsetFlags.Eof;\n\n\t\tdigit = 0;\n\n\t\treturn off;\n\t}\n\n\tpublic override void Configure(XmlNode parentNode)\n\t{\n\t\tbase.Configure(parentNode);\n\n\t\tXmlNodeList childNodes = parentNode.ChildNodes;\n\t\tforeach(XmlNode node in childNodes) {\n\t\t\tif (node.Name == \"case\")\n\t\t\t\tdrawerInformation.Uppercase = (node.InnerText == \"upper\");\n\t\t\tif (node.Name == \"bytes\")\n\t\t\t\tthis.Bytes = Convert.ToInt32(node.InnerText);\n\t\t}\n\t}\n\n\tpublic override void Realize ()\n\t{\n\t\tGtk.DrawingArea da = areaGroup.DrawingArea;\n\t\tdrawer = new HexDrawer(da, drawerInformation);\n\t\tbase.Realize();\n\t}\n}\n\n\n}//namespace\n"
  },
  {
    "path": "src/gui/areas/SeparatorArea.cs",
    "content": "// created on 6/18/2004 at 7:46 PM\n/*\n *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System;\nusing Gtk;\nusing Gdk;\nusing Bless.Gui.Drawers;\nusing Bless.Util;\nusing Bless.Plugins;\n\nnamespace Bless.Gui.Areas.Plugins {\n\npublic class SeparatorAreaPlugin : AreaPlugin\n{\n\tpublic SeparatorAreaPlugin()\n\t{\n\t\tname = \"separator\";\n\t\tauthor = \"Alexandros Frantzis\";\n\t}\n\n\tpublic override Area CreateArea(AreaGroup ag)\n\t{\n\t\treturn new SeparatorArea(ag);\n\t}\n}\n\n///<summary>An area that contains a vertical separator line</summary>\npublic class SeparatorArea : Area\n{\n\tGdk.GC lineGC;\n\n\tpublic SeparatorArea(AreaGroup ag)\n\t\t\t: base(ag)\n\t{\n\t\ttype = \"separator\";\n\t}\n\n\tpublic override void Realize()\n\t{\n\t\tGtk.DrawingArea da = areaGroup.DrawingArea;\n\t\t\n\t\tdrawer = new DummyDrawer(da, drawerInformation);\n\n\t\tlineGC = new Gdk.GC(da.GdkWindow);\n\n\t\tlineGC.RgbFgColor = drawer.Info.fgNormal[(int)Drawer.RowType.Even, (int)Drawer.ColumnType.Even].GdkColor;\n\t\t\n\t\tbase.Realize();\n\t}\n\t\n\tprotected override void RenderHighlight(Highlight h, Drawer.HighlightType left, Drawer.HighlightType right)\n\t{\n\t}\n\t\n\tprotected override void RenderRowNormal(int i, int p, int n, bool blank)\n\t{\n\t}\n\n\tprotected override void RenderRowHighlight(int i, int p, int n, bool blank, Drawer.HighlightType ht)\n\t{\n\t}\n\n\tprotected override void RenderExtra() \n\t{\n\t\tif (isAreaRealized == false)\n\t\t\treturn; \n\n\t\tint nrows = height / drawer.Height;\n\t\tlong bleft = nrows * bpr;\n\t\tint rfull = 0; \n\t\tint blast = 0; \n\n\t\tif (bpr > 0) {\n\t\t\tif (bleft + areaGroup.Offset > areaGroup.Buffer.Size)\n\t\t\t\tbleft = areaGroup.Buffer.Size - areaGroup.Offset + 1; \n \t\t\t\n\t\t\t// calculate number of full rows\n\t\t\t// and number of bytes in last (non-full) \n\t\t\trfull = (int)(bleft / bpr); \n\t\t\tblast = (int)(bleft % bpr);\n\n\t\t\tif (blast != 0) \n\t\t\t\trfull++; \n\t\t}\n\n\t\tif (rfull == 0) \n\t\t\treturn; \n\n\t\t// draw seperator \n\t\tbackPixmap.DrawLine(lineGC, x + drawer.Width / 2, 0, x + drawer.Width / 2, drawer.Height*rfull);\n\t}\n\n\tpublic override int CalcWidth(int n, bool force)\n\t{\n\t\treturn drawer.Width;\n\t}\n\n\tpublic override void GetDisplayInfoByOffset(long off, out int orow, out int obyte, out int ox, out int oy)\n\t{\n\t\torow = (int)((off - areaGroup.Offset) / bpr);\n\t\tobyte = (int)((off - areaGroup.Offset) % bpr);\n\n\t\toy = orow * drawer.Height;\n\n\t\tox = 0;\n\t}\n\n\tpublic override long GetOffsetByDisplayInfo(int x, int y, out int digit, out  GetOffsetFlags flags)\n\t{\n\t\tflags = 0;\n\t\tint row = y / drawer.Height;\n\t\tlong off = row * bpr + areaGroup.Offset;\n\t\tif (off >= areaGroup.Buffer.Size)\n\t\t\tflags |= GetOffsetFlags.Eof;\n\n\t\tdigit = 0;\n\n\t\treturn off;\n\t}\n}\n\n\n}//namespace\n"
  },
  {
    "path": "src/gui/dialogs/AboutDialog.cs",
    "content": "// created on 1/21/2005 at 2:32 PM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing System;\nusing Gtk;\nusing Gdk;\nusing Bless.Util;\nusing Mono.Unix;\n\nnamespace Bless.Gui.Dialogs {\n\npublic class AboutDialog: Gtk.AboutDialog\n{\n\tpublic AboutDialog()\n\t{\n\t\tArtists = new string[] {\"Michael Iatrou\"};\n\t\tAuthors = new string[] {\"Alexandros Frantzis\"};\n\t\tCopyright =  Catalog.GetString(\"Copyright 2004 - 2020 Alexandros Frantzis and contributors\");\n\t\tProgramName = \"Bless\";\n\t\tVersion = ConfigureDefines.VERSION;\n\t\tComments = Catalog.GetString(\"Bless is a Hex Editor for Gtk#\");\n\t\tWebsite = \"https://github.com/afrantzis/bless\";\n\t\tLogo =  new Gdk.Pixbuf(FileResourcePath.GetDataPath(\"bless-about.png\"));\n\t}\n}\n\n} //end namespace\n"
  },
  {
    "path": "src/gui/dialogs/Alert.cs",
    "content": "// created on 7/28/2004 at 7:09 PM\n/*\n *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System;\nusing Gtk;\n\n\nnamespace Bless.Gui.Dialogs {\n\n///<summary>An alert dialog box as recommended in the Gnome HIG</summary>\nabstract public class Alert : Gtk.Dialog\n{\n\tprotected Gtk.HBox hbox;\n\tprotected Gtk.VBox labelBox;\n\tprotected Gtk.Image image;\n\tprotected Gtk.Label labelPrimary;\n\tprotected Gtk.Label labelSecondary;\n\n\tpublic Alert(string primary, string secondary, Gtk.Window parent)\n\t\t\t: base(\"\", parent, Gtk.DialogFlags.DestroyWithParent)\n\t{\n\t\t// set-up alert\n\t\tthis.Modal = true;\n\t\t//this.TypeHint=Gdk.WindowTypeHint.Utility;\n\t\tthis.BorderWidth = 6;\n\t\tthis.HasSeparator = false;\n\t\tthis.Resizable = false;\n\n\t\tthis.VBox.Spacing = 12;\n\n\t\thbox = new Gtk.HBox();\n\t\thbox.Spacing = 12;\n\t\thbox.BorderWidth = 6;\n\t\tthis.VBox.Add(hbox);\n\n\t\t// set-up image\n\t\timage = new Gtk.Image();\n\t\timage.Yalign = 0.0F;\n\t\thbox.Add(image);\n\n\t\t// set-up labels\n\t\tlabelPrimary = new Gtk.Label();\n\t\tlabelPrimary.Yalign = 0.0F;\n\t\tlabelPrimary.Xalign = 0.0F;\n\t\tlabelPrimary.UseMarkup = true;\n\t\tlabelPrimary.Wrap = true;\n\n\t\tlabelSecondary = new Gtk.Label();\n\t\tlabelSecondary.Yalign = 0.0F;\n\t\tlabelSecondary.Xalign = 0.0F;\n\t\tlabelSecondary.UseMarkup = true;\n\t\tlabelSecondary.Wrap = true;\n\n\t\tlabelPrimary.Markup = \"<span weight=\\\"bold\\\" size=\\\"larger\\\">\" + primary + \"</span>\";\n\t\tlabelSecondary.Markup = \"\\n\" + secondary;\n\n\t\tlabelBox = new VBox();\n\t\tlabelBox.Add(labelPrimary);\n\t\tlabelBox.Add(labelSecondary);\n\n\t\thbox.Add(labelBox);\n\t}\n\n}\n\n\n\n}"
  },
  {
    "path": "src/gui/dialogs/ErrorAlert.cs",
    "content": "// created on 7/28/2004 at 7:33 PM\n/*\n *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System;\nusing Gtk;\n\nnamespace Bless.Gui.Dialogs {\n\n///<summary>An alert dialog box as recommended in the Gnome HIG</summary>\npublic class ErrorAlert : Alert\n{\n\n\tpublic ErrorAlert(string primary, string secondary, Gtk.Window parent)\n\t\t\t: base(primary, secondary, parent)\n\t{\n\t\timage.SetFromStock(Gtk.Stock.DialogError, Gtk.IconSize.Dialog);\n\t\tthis.AddButton(Gtk.Stock.Ok, ResponseType.Ok);\n\n\t\tthis.ShowAll();\n\t}\n\n}\n\n\n\n}"
  },
  {
    "path": "src/gui/dialogs/ExportDialog.cs",
    "content": "// created on 12/4/2006 at 1:25 AM\n/*\n *   Copyright (c) 2006, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System;\nusing System.Threading;\nusing System.IO;\nusing Gtk;\nusing Bless.Plugins;\nusing Bless.Tools.Export;\nusing Bless.Gui;\nusing Bless.Util;\nusing Bless.Buffers;\nusing Mono.Unix;\n\nnamespace Bless.Gui.Dialogs\n{\n\npublic class ExportDialog : Dialog\n{\n\tPluginManager pluginManager;\n\tDataBook dataBook;\n\tGtk.Window mainWindow;\n\n\t[Gtk.Builder.Object] Gtk.VBox ExportDialogVBox;\n\t[Gtk.Builder.Object] Gtk.ComboBox ExportAsCombo;\n\t[Gtk.Builder.Object] Gtk.ComboBoxEntry ExportPatternComboEntry;\n\t[Gtk.Builder.Object] Gtk.ProgressBar ExportProgressBar;\n\t[Gtk.Builder.Object] Gtk.Entry ExportFileEntry;\n\t[Gtk.Builder.Object] Gtk.RadioButton WholeFileRadio;\n\t[Gtk.Builder.Object] Gtk.RadioButton CurrentSelectionRadio;\n\t[Gtk.Builder.Object] Gtk.RadioButton RangeRadio;\n\t[Gtk.Builder.Object] Gtk.Entry RangeFromEntry;\n\t[Gtk.Builder.Object] Gtk.Entry RangeToEntry;\n\t[Gtk.Builder.Object] Gtk.HBox ProgressHBox;\n\tGtk.Button CloseButton;\n\tGtk.Button ExportButton;\n\n\tAutoResetEvent exportFinishedEvent;\n\treadonly public object LockObj = new object();\n\n\tbool cancelClicked;\n\n\tpublic ExportDialog(DataBook db, Gtk.Window mw)\n\t\t\t: base(Catalog.GetString(\"Export Bytes\"), null, 0)\n\t{\n\t\tGtk.Builder builder = new Gtk.Builder();\n\t\tbuilder.AddFromFile(FileResourcePath.GetDataPath(\"ui\", \"ExportDialog.ui\"));\n\t\tbuilder.Autoconnect(this);\n\n\t\tdataBook = db;\n\t\tmainWindow = mw;\n\t\tpluginManager = PluginManager.GetForType(typeof(ExportPlugin));\n\t\t\n\t\t// initialize plugins if we have to\n\t\tif (pluginManager == null) {\n\t\t\tPluginManager.AddForType(typeof(ExportPlugin), new object[0]);\n\t\t\tpluginManager = PluginManager.GetForType(typeof(ExportPlugin));\n\t\t}\n\t\t\n\t\texportFinishedEvent = new AutoResetEvent(false);\n\n\t\tSetupExportPlugins();\n\n\t\tExportPatternComboEntry.Model = new ListStore (typeof (string));\n\t\tExportPatternComboEntry.TextColumn = 0;\n\t\tLoadFromPatternFile((ListStore)ExportPatternComboEntry.Model);\n\n\t\tProgressHBox.Visible = false;\n\t\tcancelClicked = false;\n\n\t\tthis.Modal = false;\n\t\tthis.BorderWidth = 6;\n\t\tthis.HasSeparator = false;\n\t\tCloseButton = (Gtk.Button)this.AddButton(Gtk.Stock.Close, ResponseType.Close);\n\t\tExportButton = (Gtk.Button)this.AddButton(Catalog.GetString(\"Export\"), ResponseType.Ok);\n\t\tthis.Response += new ResponseHandler(OnDialogResponse);\n\t\tthis.VBox.Add(ExportDialogVBox);\n\t}\n\n\tprivate void SetupExportPlugins()\n\t{\n\t\tListStore model = new ListStore(typeof(string), typeof(ExportPlugin));\n\n\t\tforeach(ExportPlugin plugin in pluginManager.Plugins) {\n\t\t\tmodel.AppendValues(plugin.Description, plugin);\n\t\t}\n\n\t\tGtk.CellRenderer renderer = new Gtk.CellRendererText();\n\n\t\tExportAsCombo.PackStart(renderer, false);\n\t\tExportAsCombo.AddAttribute(renderer, \"text\", 0);\n\t\tExportAsCombo.Model = model;\n\t\tExportAsCombo.Active = 0;\n\t}\n\n\tprivate Util.Range GetCurrentRange(DataView dv)\n\t{\n\t\tif (WholeFileRadio.Active == true)\n\t\t\treturn new Util.Range(0, dv.Buffer.Size - 1);\n\t\telse if (CurrentSelectionRadio.Active == true)\n\t\t\treturn dv.Selection;\n\t\telse if (RangeRadio.Active == true)\n\t\t\treturn new Util.Range(BaseConverter.Parse(RangeFromEntry.Text), BaseConverter.Parse(RangeToEntry.Text));\n\n\t\treturn new Util.Range();\n\t}\n\n\tprivate void OnSelectFileButtonClicked(object o, EventArgs args)\n\t{\n\t\tFileChooserDialog fcd = new FileChooserDialog(Catalog.GetString(\"Select file\"), mainWindow, FileChooserAction.Save,  Catalog.GetString(\"Cancel\"), ResponseType.Cancel,\n\t\t\t\t\t\t\t\tCatalog.GetString(\"Select\"), ResponseType.Accept);\n\t\tif ((ResponseType)fcd.Run() == ResponseType.Accept)\n\t\t\tExportFileEntry.Text = fcd.Filename;\n\t\tfcd.Destroy();\n\t}\n\n\tprivate void OnRangeRadioToggled(object o, EventArgs args)\n\t{\n\t\tRangeFromEntry.Sensitive = RangeRadio.Active;\n\t\tRangeToEntry.Sensitive = RangeRadio.Active;\n\t}\n\n\tprivate void OnExportCancelClicked(object o, EventArgs args)\n\t{\n\t\tcancelClicked = true;\n\t}\n\n\n\tprivate void OnDeletePatternButtonClicked(object o, EventArgs args)\n\t{\n\t\tstring pattern = ExportPatternComboEntry.Entry.Text;\n\n\t\tif (pattern != \"\") {\n\t\t\tListStore ls = (ListStore)ExportPatternComboEntry.Model;\n\t\t\tTreeIter iter;\n\t\t\tint index = FindPattern(ls, pattern, out iter);\n\t\t\tif (index >= 0) {\n\t\t\t\tls.Remove(ref iter);\n\t\t\t\tUpdatePatternFile(ls);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate void OnSavePatternButtonClicked(object o, EventArgs args)\n\t{\n\t\tstring pattern = ExportPatternComboEntry.Entry.Text;\n\n\t\tif (pattern != \"\") {\n\t\t\tListStore ls = (ListStore)ExportPatternComboEntry.Model;\n\t\t\tTreeIter iter;\n\t\t\tif (FindPattern(ls, pattern, out iter) < 0) {\n\t\t\t\tls.AppendValues(pattern);\n\t\t\t\tUpdatePatternFile(ls);\n\t\t\t}\n\t\t}\n\n\t}\n\n\tprivate int FindPattern(ListStore ls, string pattern, out TreeIter ti)\n\t{\n\t\tti = new TreeIter();\n\t\tTreeIter iter;\n\t\tif (ls.GetIterFirst(out iter) == false)\n\t\t\treturn -1;\n\n\t\tstring val;\n\t\tint i = 0;\n\n\t\twhile ((val = (ls.GetValue(iter, 0) as string)) != null) {\n\t\t\tif (pattern == val) {\n\t\t\t\tti = iter;\n\t\t\t\treturn i;\n\t\t\t}\n\t\t\tls.IterNext(ref iter);\n\t\t\ti++;\n\t\t}\n\n\t\treturn -1;\n\t}\n\n\tprivate FileStream GetPatternFile(FileMode mode, FileAccess access)\n\t{\n\t\tstring patternDir = FileResourcePath.GetUserPath();\n\n\t\tFileStream fs = new FileStream(System.IO.Path.Combine(patternDir, \"export_patterns\"), mode, access);\n\n\t\treturn fs;\n\t}\n\n\tprivate void LoadFromPatternFile(ListStore ls)\n\t{\n\t\tStreamReader reader;\n\n\t\ttry {\n\t\t\tFileStream fs = GetPatternFile(FileMode.Open, FileAccess.Read);\n\t\t\treader = new StreamReader(fs);\n\t\t}\n\t\tcatch (Exception e) {\n\t\t\tSystem.Console.WriteLine(e.Message);\n\t\t\treturn;\n\t\t}\n\n\t\tstring pattern;\n\t\twhile ((pattern = reader.ReadLine()) != null) {\n\t\t\tls.AppendValues(pattern);\n\t\t}\n\n\n\t\treader.BaseStream.Close();\n\t}\n\n\tprivate void UpdatePatternFile(ListStore ls)\n\t{\n\t\tStreamWriter writer;\n\n\t\ttry {\n\t\t\tFileStream fs = GetPatternFile(FileMode.Create, FileAccess.Write);\n\t\t\twriter = new StreamWriter(fs);\n\t\t}\n\t\tcatch (Exception e) {\n\t\t\tSystem.Console.WriteLine(e.Message);\n\t\t\treturn;\n\t\t}\n\n\t\tforeach (object[] row in ls)\n\t\twriter.WriteLine(row[0] as string);\n\n\t\twriter.Flush();\n\t\twriter.BaseStream.Close();\n\t}\n\n\n\tprivate IAsyncResult BeginExport(IExporter exporter, IBuffer buf, long start, long end)\n\t{\n\t\texportFinishedEvent.Reset();\n\n\t\tExportOperation eo = new ExportOperation(exporter, buf, start, end, ExportProgressCallback, OnExportFinished);\n\n\t\tCloseButton.Sensitive = false;\n\t\tExportButton.Sensitive = false;\n\n\t\t// start export thread\n\t\tThread exportThread = new Thread(eo.OperationThread);\n\t\texportThread.IsBackground = true;\n\t\texportThread.Start();\n\n\t\treturn new ThreadedAsyncResult(eo, exportFinishedEvent, false);\n\t}\n\n\tprivate void OnExportFinished(IAsyncResult ar)\n\t{\n\t\tlock (LockObj) {\n\t\t\tExportOperation eo = (ExportOperation)ar.AsyncState;\n\n\t\t\tif (eo.Result == ExportOperation.OperationResult.Finished) {\n\t\t\t\tServices.UI.Info.DisplayMessage(string.Format(Catalog.GetString(\"Exported data to '{0}'\"),  (eo.Exporter.Builder.OutputStream as FileStream).Name));\n\t\t\t\tthis.Hide();\n\t\t\t}\n\t\t\telse if (eo.Result == ExportOperation.OperationResult.CaughtException) {\n\t\t\t\tErrorAlert ea;\n\t\t\t\tif (eo.ThreadException.GetType() == typeof(FormatException))\n\t\t\t\t\tea = new ErrorAlert(Catalog.GetString(\"Export Pattern Error\"), eo.ThreadException.Message, mainWindow);\n\t\t\t\telse\n\t\t\t\t\tea = new ErrorAlert(Catalog.GetString(\"Exporting Error\"), eo.ThreadException.Message, mainWindow);\n\n\t\t\t\tea.Run();\n\t\t\t\tea.Destroy();\n\t\t\t}\n\n\t\t\tif (eo.Exporter.Builder.OutputStream != null)\n\t\t\t\teo.Exporter.Builder.OutputStream.Close();\n\n\t\t\tCloseButton.Sensitive = true;\n\t\t\tExportButton.Sensitive = true;\n\t\t}\n\t}\n\n\tprivate bool ExportProgressCallback(object o, ProgressAction action)\n\t{\n\t\tif (action == ProgressAction.Hide) {\n\t\t\tProgressHBox.Visible = false;\n\t\t\treturn false;\n\t\t}\n\t\telse if (action == ProgressAction.Show) {\n\t\t\tProgressHBox.Visible = true;\n\t\t\treturn false;\n\t\t}\n\n\n\t\tif ((double)o > 1.0)\n\t\t\to = 1.0;\n\n\t\tExportProgressBar.Fraction = (double)o;\n\n\t\treturn cancelClicked;\n\t}\n\n\tvoid OnDialogResponse(object o, Gtk.ResponseArgs args)\n\t{\n\t\tlock (LockObj) {\n\t\t\tif (args.ResponseId == ResponseType.Ok && dataBook != null && dataBook.NPages > 0) {\n\t\t\t\tDataView dv = ((DataViewDisplay)dataBook.CurrentPageWidget).View;\n\n\t\t\t\tIExportBuilder builder = null;\n\t\t\t\tTreeIter iter;\n\t\t\t\tExportAsCombo.GetActiveIter(out iter);\n\t\t\t\tExportPlugin plugin = (ExportPlugin) ExportAsCombo.Model.GetValue(iter, 1);\n\n\n\t\t\t\tUtil.Range range;\n\n\t\t\t\ttry {\n\t\t\t\t\trange = GetCurrentRange(dv);\n\t\t\t\t}\n\t\t\t\tcatch (FormatException ex) {\n\t\t\t\t\tErrorAlert ea = new ErrorAlert(Catalog.GetString(\"Error in custom range\"), ex.Message, mainWindow);\n\t\t\t\t\tea.Run();\n\t\t\t\t\tea.Destroy();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tUtil.Range bufferRange;\n\t\t\t\tif (dv.Buffer.Size == 0)\n\t\t\t\t\tbufferRange = new Util.Range();\n\t\t\t\telse\n\t\t\t\t\tbufferRange = new Util.Range(0, dv.Buffer.Size - 1);\n\n\t\t\t\tif (!bufferRange.Contains(range.Start) || !bufferRange.Contains(range.End)) {\n\t\t\t\t\tErrorAlert ea = new ErrorAlert(Catalog.GetString(\"Error in range\"), Catalog.GetString(\"Range is out of file's limits\"), mainWindow);\n\t\t\t\t\tea.Run();\n\t\t\t\t\tea.Destroy();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tStream stream = null;\n\t\t\t\ttry {\n\t\t\t\t\tstream = new FileStream(ExportFileEntry.Text, FileMode.Create, FileAccess.Write);\n\t\t\t\t\tbuilder = plugin.CreateBuilder(stream);\n\n\t\t\t\t\tInterpretedPatternExporter exporter = new InterpretedPatternExporter(builder);\n\t\t\t\t\texporter.Pattern = ExportPatternComboEntry.Entry.Text;\n\n\t\t\t\t\tcancelClicked = false;\n\t\t\t\t\tBeginExport(exporter, dv.Buffer, range.Start, range.End);\n\n\t\t\t\t}\n\t\t\t\tcatch (Exception ex) {\n\t\t\t\t\tif (stream != null)\n\t\t\t\t\t\tstream.Close();\n\n\t\t\t\t\tErrorAlert ea = new ErrorAlert(Catalog.GetString(\"Error saving to file\"), ex.Message, mainWindow);\n\t\t\t\t\tea.Run();\n\t\t\t\t\tea.Destroy();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (args.ResponseId == ResponseType.Close)\n\t\t\t\tthis.Hide();\n\t\t}\n\t}\n\n}\n\n\n} // end namespace\n"
  },
  {
    "path": "src/gui/dialogs/FileOverwriteAlert.cs",
    "content": "// created on 10/28/2004 at 10:55 AM\n/*\n *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System;\nusing Gtk;\nusing Mono.Unix;\n\nnamespace Bless.Gui.Dialogs {\n\n///<summary>An alert dialog box as recommended in the Gnome HIG</summary>\npublic class FileOverwriteAlert : Alert\n{\n\tstatic readonly string msg1 = Catalog.GetString(\"A file named '{0}' already exists\");\n\tstatic readonly string msg2 = Catalog.GetString(\"Do you want to replace it with the one you are saving?\");\n\n\tpublic FileOverwriteAlert(string primary, Gtk.Window parent)\n\t\t\t: base(string.Format(msg1, primary), msg2, parent)\n\t{\n\t\timage.SetFromStock(Gtk.Stock.DialogWarning, Gtk.IconSize.Dialog);\n\n\t\tthis.AddButton(Gtk.Stock.Cancel, ResponseType.Cancel);\n\t\tthis.AddButton(Catalog.GetString(\"Replace\"), ResponseType.Ok);\n\n\t\tthis.DefaultResponse = ResponseType.Cancel;\n\n\t\tthis.ShowAll();\n\t}\n\n}\n\n\n\n}"
  },
  {
    "path": "src/gui/dialogs/InformationAlert.cs",
    "content": "// created on 2/5/2005 at 4:21 PM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System;\nusing Gtk;\n\nnamespace Bless.Gui.Dialogs {\n\n///<summary>An alert dialog box as recommended in the Gnome HIG</summary>\npublic class InformationAlert : Alert\n{\n\n\tpublic InformationAlert(string primary, string secondary, Gtk.Window parent)\n\t\t\t: base(primary, secondary, parent)\n\t{\n\t\timage.SetFromStock(Gtk.Stock.DialogInfo, Gtk.IconSize.Dialog);\n\t\tthis.AddButton(Gtk.Stock.Ok, ResponseType.Ok);\n\n\t\tthis.ShowAll();\n\t}\n\n}\n\n\n\n} // namespace\n"
  },
  {
    "path": "src/gui/dialogs/LayoutSelectionDialog.cs",
    "content": "// created on 6/28/2004 at 12:58 PM\n/*\n *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System;\nusing System.IO;\nusing Gtk;\nusing Bless.Gui.Areas;\nusing Bless.Buffers;\nusing Bless.Util;\nusing Mono.Unix;\n\nnamespace Bless.Gui.Dialogs {\n\n///<summary>\n/// A dialog that lets the user select one of the available layouts\n///</summary>\npublic class LayoutSelectionDialog : Dialog {\n\n\tDataBook dataBook;\n\tDataView dataPreview;\n\t[Gtk.Builder.Object] Gtk.TreeView LayoutList;\n\t[Gtk.Builder.Object] Gtk.Frame PreviewFrame;\n\t[Gtk.Builder.Object] Gtk.Paned LayoutSelectionPaned;\n\tTreeIter selectedLayoutIter;\n\tstring selectedLayout;\n\tstring layoutDir;\n\n\tpublic string SelectedLayout {\n\t\tget { return selectedLayout; }\n\t}\n\n\tenum LayoutColumn { Filename, Path }\n\n\tpublic LayoutSelectionDialog(DataBook db)\n\t\t\t: base(Catalog.GetString(\"Select Layout\"), null, 0)\n\t{\n\t\tGtk.Builder builder = new Gtk.Builder();\n\t\tbuilder.AddFromFile(FileResourcePath.GetDataPath(\"ui\", \"LayoutSelectionDialog.ui\"));\n\t\tbuilder.Autoconnect(this);\n\n\t\tdataBook = db;\n\n\t\t// create the preview area\n\t\tdataPreview = new DataView();\n\t\tByteBuffer bb = new ByteBuffer();\n\t\tbb.Append(new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, 0, 16);\n\t\tbb.Append(new byte[]{16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}, 0, 16);\n\t\tdataPreview.Buffer = bb;\n\n\t\tPreviewFrame.Add(dataPreview.Display);\n\t\tPreviewFrame.ShowAll();\n\n\t\tlayoutDir = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), \"bless\");\n\t\tlayoutDir = System.IO.Path.Combine(layoutDir, \"layouts\");\n\n\t\t// Initialize list\n\t\tPopulateLayoutList();\n\n\t\tthis.DefaultWidth = 600;\n\t\tthis.DefaultHeight = 300;\n\t\tthis.Modal = false;\n\t\tthis.BorderWidth = 6;\n\t\tthis.HasSeparator = false;\n\t\tthis.AddButton(Gtk.Stock.Close, ResponseType.Close);\n\t\tthis.AddButton(Gtk.Stock.Ok, ResponseType.Ok);\n\t\tthis.Response += new ResponseHandler(OnDialogResponse);\n\t\tthis.VBox.Add(LayoutSelectionPaned);\n\t}\n\n\t///<summary>Populate the layout list</summary>\n\tvoid PopulateLayoutList()\n\t{\n\t\t// specify the column types\n\t\tTreeStore ts = new TreeStore(typeof(string), typeof(string));\n\n\t\tTreeIter ti = ts.AppendValues(Catalog.GetString(\"System-wide Layouts\"), string.Empty);\n\n\t\t// fill list from bless data dir\n\t\tstring dataDir = FileResourcePath.GetDataPath(\"data\");\n\t\tif (Directory.Exists(dataDir)) {\n\t\t\tstring[] files = Directory.GetFiles(dataDir, \"*.layout\");\n\t\t\tforeach (string s in files) {\n\t\t\t\tts.AppendValues(ti, System.IO.Path.GetFileName(s), s);\n\t\t\t}\n\t\t}\n\n\t\tti = ts.AppendValues(Catalog.GetString(\"User Layouts\"), string.Empty);\n\n\t\t// fill list from user layout dir\n\t\tif (Directory.Exists(layoutDir)) {\n\t\t\tstring[] files = Directory.GetFiles(layoutDir, \"*.layout\");\n\t\t\tforeach (string s in files) {\n\t\t\t\tts.AppendValues(ti, System.IO.Path.GetFileName(s), s);\n\t\t\t}\n\t\t}\n\n\t\t// Create the treeview\n\t\tLayoutList.Model = ts;\n\t\tLayoutList.AppendColumn(\"Layout\", new CellRendererText (), \"text\", (int)LayoutColumn.Filename);\n\t\tLayoutList.ExpandAll();\n\t\tLayoutList.Selection.Changed += OnLayoutListSelectionChanged;\n\t}\n\n\t///<summary>Handle list selection changed event</summary>\n\tpublic void OnLayoutListSelectionChanged (object o, EventArgs args)\n\t{\n\t\tTreeSelection sel = (TreeSelection)o;\n\t\tTreeModel tm;\n\t\tTreeIter ti;\n\n\t\tif (sel.GetSelected(out tm, out ti)) {\n\t\t\tstring val = (string) tm.GetValue (ti, (int)LayoutColumn.Path);\n\n\t\t\t// if there is not path, it means user clicked on a header row\n\t\t\tif (val == string.Empty) {\n\t\t\t\tif (selectedLayout != null)\n\t\t\t\t\tsel.SelectIter(selectedLayoutIter);\n\t\t\t\telse\n\t\t\t\t\tsel.UnselectIter(ti);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// try to load layout from file\n\t\t\ttry {\n\t\t\t\tdataPreview.Display.Layout = new Layout(val);\n\t\t\t\tselectedLayoutIter = ti;\n\t\t\t\tselectedLayout = val;\n\t\t\t}\n\t\t\tcatch (System.Xml.XmlException ex) {\n\t\t\t\tstring msg = string.Format(Catalog.GetString(\"Error parsing layout file '{0}'\"), val);\n\t\t\t\tErrorAlert ea = new ErrorAlert(msg, ex.Message, this);\n\t\t\t\tea.Run();\n\t\t\t\tea.Destroy();\n\t\t\t\tif (selectedLayout != null)\n\t\t\t\t\tsel.SelectIter(selectedLayoutIter);\n\t\t\t\telse\n\t\t\t\t\tsel.UnselectIter(ti);\n\t\t\t}\n\t\t\tfinally {\n\t\t\t\tdataPreview.Display.Redraw();\n\t\t\t}\n\n\t\t}\n\t}\n\n\tvoid OnDialogResponse(object o, Gtk.ResponseArgs args)\n\t{\n\t\tif (args.ResponseId == ResponseType.Ok && selectedLayout != null) {\n\t\t\t// get current dataview\n\t\t\tif (dataBook != null && dataBook.NPages > 0) {\n\t\t\t\tDataView dv = ((DataViewDisplay)dataBook.CurrentPageWidget).View;\n\t\t\t\tdv.Display.Layout = new Layout(selectedLayout);\n\t\t\t}\n\t\t}\n\n\t\t// dispose preview Area pixmaps\n\t\tdataPreview.Cleanup();\n\n\t\tthis.Destroy();\n\t}\n}\n\n\n}//namespace\n"
  },
  {
    "path": "src/gui/dialogs/PreferencesDialog.cs",
    "content": "// created on 6/3/2005 at 12:21 PM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System;\nusing System.IO;\nusing System.Collections.Generic;\nusing Gtk;\nusing Bless.Tools;\nusing Bless.Util;\nusing Mono.Unix;\nusing Bless.Plugins;\n\nnamespace Bless.Gui.Dialogs {\n\n///<summary>\n/// A dialog that lets user choose preferences for Bless\n///</summary>\npublic class PreferencesDialog : Dialog\n{\n\tWindow mainWindow;\n\tGeneralPreferences generalPreferences;\n\tSessionPreferences sessionPreferences;\n\tUndoPreferences undoPreferences;\n\tTreeIter selectedIter;\n\n\t[Gtk.Builder.Object] Paned PreferencesPaned;\n\t[Gtk.Builder.Object] TreeView PreferencesTreeView;\n\t\n\n\tpublic PreferencesDialog(Window parent)\n\t\t\t: base (Catalog.GetString(\"Bless Preferences\"), parent, DialogFlags.DestroyWithParent)\n\t{\n\t\tGtk.Builder builder = new Gtk.Builder();\n\t\tbuilder.AddFromFile(FileResourcePath.GetDataPath(\"ui\", \"PreferencesDialog.ui\"));\n\t\tbuilder.Autoconnect(this);\n\t\t\n\t\tmainWindow = parent;\n\t\t\n\t\tgeneralPreferences = new GeneralPreferences(mainWindow);\n\t\tsessionPreferences = new SessionPreferences(mainWindow);\n\t\tundoPreferences = new UndoPreferences(mainWindow);\n\t\tLoadPreferencesTreeView();\n\n\t\tthis.Modal = false;\n\t\tthis.TransientFor = parent;\n\t\tthis.BorderWidth = 6;\n\t\tthis.AddButton(Gtk.Stock.Close, ResponseType.Close);\n\t\tthis.Response += new ResponseHandler(OnDialogResponse);\n\t\tthis.VBox.Add(PreferencesPaned);\n\t\tthis.VBox.ShowAll();\n\t}\n\t\n\tvoid LoadPreferencesTreeView()\n\t{\n\t\tTreeStore store = new TreeStore(typeof(string), typeof(IPluginPreferences));\n\t\t\n\t\tstore.AppendValues(Catalog.GetString(\"General\"), generalPreferences);\n\t\tstore.AppendValues(Catalog.GetString(\"Undo\"), undoPreferences);\n\t\tstore.AppendValues(Catalog.GetString(\"Session\"), sessionPreferences);\n\t\t\n\t\tTreeIter ti = store.AppendValues(Catalog.GetString(\"Plugins\"), null);\n\t\t\n\t\t// Get all plugins from all managers that have preferences\n\t\tforeach(KeyValuePair<Type, PluginManager> kvp in PluginManager.AllManagers)\n\t\t\tforeach(Plugin p in kvp.Value.Plugins) \n\t\t\t\tif (p.PluginPreferences != null)\n\t\t\t\t\tstore.AppendValues(ti, p.Name, p.PluginPreferences);\n\t\t\n\t\tPreferencesTreeView.Model = store;\n\t\tPreferencesTreeView.AppendColumn(\"\", new CellRendererText (), \"text\", 0);\n\t\tPreferencesTreeView.HeadersVisible = false;\n\t\tPreferencesTreeView.Selection.Changed += OnPreferencesTreeViewSelectionChanged;\n\t\tPreferencesTreeView.Selection.SelectPath(new TreePath(\"0\"));\n\t}\n\t\n\tvoid OnPreferencesTreeViewSelectionChanged (object o, EventArgs args)\n\t{\n\t\tTreeSelection sel = (TreeSelection)o;\n\t\tTreeModel tm;\n\t\tTreeIter ti;\n\n\t\tif (sel.GetSelected(out tm, out ti)) {\n\t\t\tIPluginPreferences ipp = (IPluginPreferences) tm.GetValue (ti, 1);\n\n\t\t\t// If user tried to select a header row, keep the previous selection\n\t\t\tif (ipp == null) {\n\t\t\t\tsel.SelectIter(selectedIter);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (PreferencesPaned.Child2 != null)\n\t\t\t\tPreferencesPaned.Remove(PreferencesPaned.Child2);\n\n\t\t\tPreferencesPaned.Pack2(ipp.Widget, true, false);\n\t\t\tipp.LoadPreferences();\t\n\t\t\tipp.Widget.ShowAll();\n\n\t\t\tselectedIter = ti;\n\t\t}\n\t}\n\t\n\tvoid OnDialogResponse(object o, Gtk.ResponseArgs args)\n\t{\n\t\t// If the widget is not removed we can not show it again\n\t\t// at a later invocation of PreferencesDialog\n\t\tif (PreferencesPaned.Child2 != null)\n\t\t\tPreferencesPaned.Remove(PreferencesPaned.Child2);\n\n\t\tthis.Destroy();\n\t}\n\n}\n\nclass GeneralPreferences : IPluginPreferences\n{\n\t[Gtk.Builder.Object] Gtk.VBox GeneralPreferencesVBox;\n\n\t[Gtk.Builder.Object] Entry LayoutFileEntry;\n\t[Gtk.Builder.Object] CheckButton UseCurrentLayoutCheckButton;\n\t[Gtk.Builder.Object] ComboBox DefaultEditModeComboBox;\n\t[Gtk.Builder.Object] Entry TempDirEntry;\n\t[Gtk.Builder.Object] Button SelectTempDirButton;\n\t[Gtk.Builder.Object] Button SelectLayoutButton;\n\t\t\n\tenum EditModeEnum { Insert, Overwrite }\n\tenum NumberBaseEnum { Hexadecimal, Decimal, Octal }\n\n\tWindow mainWindow;\n\tPreferences prefs;\n\n\tpublic GeneralPreferences(Window mw)\n\t{\n\t\tmainWindow = mw;\n\t\tprefs = Preferences.Instance;\n\t} \n\t\n\tpublic Widget Widget {\n\t\tget {\n\t\t\tif (GeneralPreferencesVBox == null)\n\t\t\t\tInitWidget();\n\t\t\t\n\t\t\treturn GeneralPreferencesVBox;\n\t\t}\n\t}\n\n\tpublic void LoadPreferences()\n\t{\n\t\tif (GeneralPreferencesVBox == null)\n\t\t\tInitWidget();\n\n\t\tstring val;\n\n\t\t//\n\t\t//\n\t\tval = prefs[\"Default.Layout.File\"];\n\t\tLayoutFileEntry.Text = val;\n\n\t\tLoadCheckButtonPreference(\n\t\t\t\"Default.Layout.UseCurrent\",\n\t\t\tUseCurrentLayoutCheckButton,\n\t\t\tfalse);\n\n\t\t//\n\t\t//\n\t\t//\n\t\tval = prefs[\"Default.EditMode\"];\n\t\tif (val != \"Insert\" && val != \"Overwrite\")\n\t\t\tval = \"Insert\";\n\n\t\t{\n\t\t\tEditModeEnum index;\n\t\t\tif (val == \"Insert\")\n\t\t\t\tindex = EditModeEnum.Insert;\n\t\t\telse\n\t\t\t\tindex = EditModeEnum.Overwrite;\n\n\t\t\tDefaultEditModeComboBox.Active = (int)index;\n\t\t}\n\n\t\t//\n\t\t//\n\t\tif (prefs[\"ByteBuffer.TempDir\"] != System.IO.Path.GetTempPath())\n\t\t\tTempDirEntry.Text = prefs[\"ByteBuffer.TempDir\"];\n\t\telse\n\t\t\tTempDirEntry.Text = \"\";\n\n\t}\n\t\n\tpublic void SavePreferences()\n\t{\n\t\t// All preferences are applied instantly...\n\t\t// No need to save them here\n\t}\n\n\tvoid InitWidget()\n\t{\n\t\tGtk.Builder builder = new Gtk.Builder();\n\t\tbuilder.AddFromFile(FileResourcePath.GetDataPath(\"ui\", \"PreferencesDialog.ui\"));\n\t\tbuilder.Autoconnect(this);\n\n\t\tSelectTempDirButton.Clicked += OnSelectTempDirButtonClicked;\n\t\tSelectLayoutButton.Clicked += OnSelectLayoutClicked;\n\n\t\tLayoutFileEntry.Changed += OnLayoutFileChanged;\n\t\tUseCurrentLayoutCheckButton.Toggled += OnUseCurrentLayoutToggled;\n\t\tDefaultEditModeComboBox.Changed += OnDefaultEditModeChanged;\n\t\tTempDirEntry.FocusOutEvent += OnTempDirFocusOutEvent;\n\t}\n\t\n\tvoid LoadCheckButtonPreference(string key, CheckButton cb, bool defaultValue)\n\t{\n\t\tstring val = prefs[key];\n\n\t\ttry {\n\t\t\tbool b = Convert.ToBoolean(val);\n\t\t\tcb.Active = b;\n\t\t}\n\t\tcatch (FormatException e) {\n\t\t\tSystem.Console.WriteLine(e.Message);\n\t\t\tcb.Active = defaultValue;\n\t\t}\n\n\t}\n\n\tvoid OnSelectLayoutClicked(object o, EventArgs args)\n\t{\n\t\tLayoutSelectionDialog lsd = new LayoutSelectionDialog(null);\n\t\tGtk.ResponseType response = (Gtk.ResponseType)lsd.Run();\n\n\t\tif (response == Gtk.ResponseType.Ok && lsd.SelectedLayout != null) {\n\t\t\tLayoutFileEntry.Text = lsd.SelectedLayout;\n\t\t}\n\n\t\tlsd.Destroy();\n\t}\n\n\n\tprivate void OnSelectTempDirButtonClicked(object o, EventArgs args)\n\t{\n\t\tFileChooserDialog fcd = new FileChooserDialog(Catalog.GetString(\"Select Directory\"), mainWindow, FileChooserAction.CreateFolder,  Catalog.GetString(\"Cancel\"), ResponseType.Cancel,\n\t\t\t\t\t\t\t\tCatalog.GetString(\"Select\"), ResponseType.Accept);\n\t\tif ((ResponseType)fcd.Run() == ResponseType.Accept)\n\t\t\tTempDirEntry.Text = fcd.Filename;\n\t\tfcd.Destroy();\n\t}\n\n\tprivate void OnLayoutFileChanged(object o, EventArgs args)\n\t{\n\t\tprefs[\"Default.Layout.File\"] = LayoutFileEntry.Text;\n\t}\n\n\tprivate void OnUseCurrentLayoutToggled(object o, EventArgs args)\n\t{\n\t\tprefs[\"Default.Layout.UseCurrent\"] = UseCurrentLayoutCheckButton.Active.ToString();\n\t}\n\n\n\tprivate void OnDefaultEditModeChanged(object o, EventArgs args)\n\t{\n\t\tTreeIter iter;\n\n\t\tif (DefaultEditModeComboBox.GetActiveIter (out iter))\n\t\t\tprefs[\"Default.EditMode\"] = (string) DefaultEditModeComboBox.Model.GetValue (iter, 0);\n\t}\n\n\tprivate void OnTempDirFocusOutEvent(object o, Gtk.FocusOutEventArgs a)\n\t{\n\t\tprefs[\"ByteBuffer.TempDir\"] = TempDirEntry.Text;\n\t}\n}\n\nclass SessionPreferences : IPluginPreferences\n{\n\tPreferences prefs;\n\n\t[Gtk.Builder.Object] Gtk.VBox SessionPreferencesVBox;\n\t\n\t[Gtk.Builder.Object] CheckButton LoadPreviousSessionCheckButton;\n\t[Gtk.Builder.Object] CheckButton AskBeforeLoadingSessionCheckButton;\n\t[Gtk.Builder.Object] CheckButton RememberCursorPositionCheckButton;\n\t[Gtk.Builder.Object] CheckButton RememberWindowGeometryCheckButton;\n\t\n\tpublic SessionPreferences(Window mw)\n\t{\n\t\tprefs = Preferences.Instance;\n\t} \n\t\n\tpublic Widget Widget {\n\t\tget {\n\t\t\tif (SessionPreferencesVBox == null)\n\t\t\t\tInitWidget();\n\t\t\t\n\t\t\treturn SessionPreferencesVBox;\n\t\t}\n\t}\n\t\n\n\tpublic void LoadPreferences()\n\t{\n\t\tif (SessionPreferencesVBox == null)\n\t\t\tInitWidget();\n\n\t\tLoadCheckButtonPreference(\n\t\t\t\"Session.LoadPrevious\",\n\t\t\tLoadPreviousSessionCheckButton,\n\t\t\ttrue);\n\n\t\tLoadCheckButtonPreference(\n\t\t\t\"Session.AskBeforeLoading\",\n\t\t\tAskBeforeLoadingSessionCheckButton,\n\t\t\tfalse);\n\n\t\tLoadCheckButtonPreference(\n\t\t\t\"Session.RememberCursorPosition\",\n\t\t\tRememberCursorPositionCheckButton,\n\t\t\ttrue);\n\n\t\tLoadCheckButtonPreference(\n\t\t\t\"Session.RememberWindowGeometry\",\n\t\t\tRememberWindowGeometryCheckButton,\n\t\t\ttrue);\n\t}\n\t\n\tpublic void SavePreferences()\n\t{\n\t\t// All preferences are applied instantly...\n\t\t// No need to save them here\n\t}\n\n\tvoid LoadCheckButtonPreference(string key, CheckButton cb, bool defaultValue)\n\t{\n\t\tstring val = prefs[key];\n\n\t\ttry {\n\t\t\tbool b = Convert.ToBoolean(val);\n\t\t\tcb.Active = b;\n\t\t}\n\t\tcatch (FormatException e) {\n\t\t\tSystem.Console.WriteLine(e.Message);\n\t\t\tcb.Active = defaultValue;\n\t\t}\n\n\t}\n\n\tvoid InitWidget()\n\t{\n\t\tGtk.Builder builder = new Gtk.Builder();\n\t\tbuilder.AddFromFile(FileResourcePath.GetDataPath(\"ui\", \"PreferencesDialog.ui\"));\n\t\tbuilder.Autoconnect(this);\n\n\t\tLoadPreviousSessionCheckButton.Toggled += OnLoadPreviousSessionToggled;\n\t\tAskBeforeLoadingSessionCheckButton.Toggled += AskBeforeLoadingSessionToggled;\n\t\tRememberCursorPositionCheckButton.Toggled += RememberCursorPositionToggled;\n\t\tRememberWindowGeometryCheckButton.Toggled += RememberWindowGeometryToggled;\n\t}\n\n\tvoid OnLoadPreviousSessionToggled(object o, EventArgs args)\n\t{\n\t\tif (LoadPreviousSessionCheckButton.Active) {\n\t\t\tAskBeforeLoadingSessionCheckButton.Sensitive = true;\n\t\t\tRememberCursorPositionCheckButton.Sensitive = true;\n\t\t\tRememberWindowGeometryCheckButton.Sensitive = true;\n\t\t}\n\t\telse {\n\t\t\tAskBeforeLoadingSessionCheckButton.Sensitive = false;\n\t\t\tRememberCursorPositionCheckButton.Sensitive = false;\n\t\t\tRememberWindowGeometryCheckButton.Sensitive = false;\n\t\t}\n\n\n\t\tprefs[\"Session.LoadPrevious\"] = LoadPreviousSessionCheckButton.Active.ToString();\n\t} \n\n\tvoid AskBeforeLoadingSessionToggled(object o, EventArgs args)\n\t{\n\t\tprefs[\"Session.AskBeforeLoading\"] = AskBeforeLoadingSessionCheckButton.Active.ToString();\n\t}\n\n\tvoid RememberCursorPositionToggled(object o, EventArgs args)\n\t{\n\t\tprefs[\"Session.RememberCursorPosition\"] = RememberCursorPositionCheckButton.Active.ToString();\n\t}\n\n\tvoid RememberWindowGeometryToggled(object o, EventArgs args)\n\t{\n\t\tprefs[\"Session.RememberWindowGeometry\"] = RememberWindowGeometryCheckButton.Active.ToString();\n\t}\n}\n\nclass UndoPreferences : IPluginPreferences\n{\n\tPreferences prefs;\n\n\t[Gtk.Builder.Object] Gtk.VBox UndoPreferencesVBox;\n\t\n\t[Gtk.Builder.Object] RadioButton UndoLimitedRadioButton;\n\t[Gtk.Builder.Object] RadioButton UndoUnlimitedRadioButton;\n\t[Gtk.Builder.Object] SpinButton UndoActionsSpinButton;\n\t\n\t[Gtk.Builder.Object] RadioButton KeepUndoAlwaysRadioButton;\n\t[Gtk.Builder.Object] RadioButton KeepUndoMemoryRadioButton;\n\t[Gtk.Builder.Object] RadioButton KeepUndoNeverRadioButton;\n\t\n\tpublic UndoPreferences(Window mw)\n\t{\n\t\tprefs = Preferences.Instance;\n\t} \n\t\n\tpublic Widget Widget {\n\t\tget {\n\t\t\tif (UndoPreferencesVBox == null)\n\t\t\t\tInitWidget();\n\t\t\t\n\t\t\treturn UndoPreferencesVBox;\n\t\t}\n\t}\n\t\n\n\tpublic void LoadPreferences()\n\t{\n\t\tstring val;\n\n\t\t//\n\t\tval = prefs[\"Undo.Limited\"];\n\n\t\ttry {\n\t\t\tbool limited = Convert.ToBoolean(val);\n\t\t\tUndoLimitedRadioButton.Active = limited;\n\t\t\tUndoUnlimitedRadioButton.Active = !limited;\n\t\t}\n\t\tcatch (FormatException e) {\n\t\t\tSystem.Console.WriteLine(e.Message);\n\t\t\tUndoLimitedRadioButton.Active = true;\n\t\t}\n\n\t\t//\n\t\tval = prefs[\"Undo.Actions\"];\n\n\t\ttry {\n\t\t\tint actions = Convert.ToInt32(val);\n\t\t\tUndoActionsSpinButton.Value = actions;\n\t\t}\n\t\tcatch (FormatException e) {\n\t\t\tSystem.Console.WriteLine(e.Message);\n\t\t\tUndoActionsSpinButton.Value = 100;\n\t\t}\n\n\t\t//\n\t\tval = prefs[\"Undo.KeepAfterSave\"];\n\n\t\tKeepUndoAlwaysRadioButton.Active = false;\n\t\tKeepUndoMemoryRadioButton.Active = false;\n\t\tKeepUndoNeverRadioButton.Active = false;\n\n\t\tswitch(val.ToLower()) {\n\t\t\tcase \"always\":\n\t\t\t\tKeepUndoAlwaysRadioButton.Active = true;\n\t\t\t\tbreak;\n\n\t\t\tcase \"never\":\n\t\t\t\tKeepUndoNeverRadioButton.Active = true;\n\t\t\t\tbreak;\t\n\t\t\t\n\t\t\tcase \"memory\":\n\t\t\tdefault:\n\t\t\t\tKeepUndoMemoryRadioButton.Active = true;\n\t\t\t\tbreak;\n\t\t}\n\t}\n\t\n\tpublic void SavePreferences()\n\t{\n\t\t// All preferences are applied instantly...\n\t\t// No need to save them here\n\t}\n\n\tvoid LoadCheckButtonPreference(string key, CheckButton cb, bool defaultValue)\n\t{\n\t\tstring val = prefs[key];\n\n\t\ttry {\n\t\t\tbool b = Convert.ToBoolean(val);\n\t\t\tcb.Active = b;\n\t\t}\n\t\tcatch (FormatException e) {\n\t\t\tSystem.Console.WriteLine(e.Message);\n\t\t\tcb.Active = defaultValue;\n\t\t}\n\n\t}\n\n\tvoid InitWidget()\n\t{\n\t\tGtk.Builder builder = new Gtk.Builder();\n\t\tbuilder.AddFromFile(FileResourcePath.GetDataPath(\"ui\", \"PreferencesDialog.ui\"));\n\t\tbuilder.Autoconnect(this);\n\n\t\tUndoLimitedRadioButton.Toggled += OnUndoLimitedToggled;\n\t\tUndoActionsSpinButton.ValueChanged += OnUndoActionsValueChanged;\n\n\t\tKeepUndoAlwaysRadioButton.Toggled += OnKeepUndoAlwaysToggled;\n\t\tKeepUndoMemoryRadioButton.Toggled += OnKeepUndoMemoryToggled;\n\t\tKeepUndoNeverRadioButton.Toggled += OnKeepUndoNeverToggled;\n\t}\n\n\tprivate void OnUndoLimitedToggled(object o, EventArgs args)\n\t{\n\t\tprefs[\"Undo.Limited\"] = UndoLimitedRadioButton.Active.ToString();\n\t}\n\n\tprivate void OnUndoActionsValueChanged(object o, EventArgs args)\n\t{\n\t\tprefs[\"Undo.Actions\"] = UndoActionsSpinButton.ValueAsInt.ToString();\n\t}\n\t\n\tprivate void OnKeepUndoAlwaysToggled(object o, EventArgs args) \n\t{\n\t\tif (KeepUndoAlwaysRadioButton.Active)\n\t\t\tprefs[\"Undo.KeepAfterSave\"] = \"Always\";\n\t}\n\n\tprivate void OnKeepUndoMemoryToggled(object o, EventArgs args) \n\t{\n\t\tif (KeepUndoMemoryRadioButton.Active)\n\t\t\tprefs[\"Undo.KeepAfterSave\"] = \"Memory\";\n\t}\n\n\tprivate void OnKeepUndoNeverToggled(object o, EventArgs args) \n\t{\n\t\tif (KeepUndoNeverRadioButton.Active)\n\t\t\tprefs[\"Undo.KeepAfterSave\"] = \"Never\";\n\t}\n}\n\n} // end namespace\n"
  },
  {
    "path": "src/gui/dialogs/ProgressDialog.cs",
    "content": "// created on 3/20/2005 at 2:47 PM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System;\nusing Gtk;\nusing Bless.Tools.Find;\nusing Bless.Util;\n\nnamespace Bless.Gui.Dialogs {\n\n///<summary>\n/// A customizable progress dialog\n///</summary>\npublic class ProgressDialog : Gtk.Window {\n\n\t[Gtk.Builder.Object] Gtk.VBox ProgressVBox;\n\t[Gtk.Builder.Object] Gtk.ProgressBar ProgressBar;\n\t[Gtk.Builder.Object] Gtk.Label MessageLabel;\n\t[Gtk.Builder.Object] Gtk.Label DetailsLabel;\n\n\tbool cancelClicked;\n\n\tpublic ProgressDialog(string primary, Gtk.Window main) : base(primary)\n\t{\n\t\tGtk.Builder builder = new Gtk.Builder();\n\t\tbuilder.AddFromFile(FileResourcePath.GetDataPath(\"ui\", \"ProgressDialog.ui\"));\n\t\tbuilder.Autoconnect(this);\n\n\t\t// setup window\n\t\tthis.SkipTaskbarHint = false;\n\t\tthis.TypeHint = Gdk.WindowTypeHint.Dialog;\n\t\tthis.TransientFor = main;\n\t\tthis.BorderWidth = 6;\n\n\t\tMessageLabel.Markup = \"<span weight=\\\"bold\\\" size=\\\"larger\\\">\" + primary + \"</span>\";\n\n\t\tthis.Add(ProgressVBox);\n\t\tthis.Hide();\n\t}\n\n\tpublic bool Update(object o, ProgressAction action)\n\t{\n\t\tif (action == ProgressAction.Hide) {\n\t\t\tthis.Visible = false;\n\t\t\treturn false;\n\t\t}\n\t\telse if (action == ProgressAction.Show) {\n\t\t\tthis.Visible = true;\n\t\t\treturn false;\n\t\t}\n\t\telse if (action == ProgressAction.Message) {\n\t\t\tthis.Title = (string)o;\n\t\t\tMessageLabel.Markup = \"<span weight=\\\"bold\\\" size=\\\"larger\\\">\" + (string)o + \"</span>\";\n\t\t\treturn false;\n\t\t}\n\t\telse if (action == ProgressAction.Details) {\n\t\t\tDetailsLabel.Text = (string)o;\n\t\t\treturn false;\n\t\t}\n\t\telse if (action == ProgressAction.Destroy) {\n\t\t\tthis.Destroy();\n\t\t\treturn false;\n\t\t}\n\n\t\tProgressBar.Fraction = (double)o;\n\n\t\tif (cancelClicked == true) {\n\t\t\tcancelClicked = false;\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t}\n\n\tpublic void OnCancelButtonClicked(object o, EventArgs args)\n\t{\n\t\tcancelClicked = true;\n\t}\n\n\tprotected override bool OnDeleteEvent(Gdk.Event e)\n\t{\n\t\tcancelClicked = true;\n\t\treturn true;\n\t}\n}\n\n\n}// end namespace\n"
  },
  {
    "path": "src/gui/dialogs/RevertConfirmationAlert.cs",
    "content": "// created on 2/8/2005 at 2:52 PM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System;\nusing Gtk;\nusing Mono.Unix;\n\nnamespace Bless.Gui.Dialogs {\n\n///<summary>An alert dialog box as recommended in the Gnome HIG</summary>\npublic class RevertConfirmationAlert : Alert\n{\n\n\tpublic RevertConfirmationAlert(string primary, Gtk.Window parent)\n\t\t\t: base(string.Format(Catalog.GetString(\"Revert file '{0}' to its last saved state?\"), primary),\n\t\t\t\t   Catalog.GetString(\"If you revert, all changes made since the last save will be lost.\"), parent)\n\t{\n\t\timage.SetFromStock(Gtk.Stock.DialogWarning, Gtk.IconSize.Dialog);\n\n\t\tthis.AddButton(Gtk.Stock.Cancel, ResponseType.Cancel);\n\t\tthis.AddButton(Gtk.Stock.RevertToSaved, ResponseType.Ok);\n\n\t\tthis.ShowAll();\n\t}\n\n}\n\n} // namespace\n"
  },
  {
    "path": "src/gui/dialogs/SaveConfirmationAlert.cs",
    "content": "// created on 10/26/2004 at 7:01 PM\n/*\n *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System;\nusing Gtk;\nusing Mono.Unix;\n\nnamespace Bless.Gui.Dialogs {\n\n///<summary>An alert dialog box as recommended in the Gnome HIG</summary>\npublic class SaveConfirmationAlert : Alert\n{\n\tpublic SaveConfirmationAlert(string primary, Gtk.Window parent)\n\t\t\t: base(string.Format(Catalog.GetString(\"Save changes to file '{0}' before closing?\"), primary),\n\t\t\t\t   Catalog.GetString(\"If you don't save, all changes made since the last save will be lost.\"), parent)\n\t{\n\t\timage.SetFromStock(Gtk.Stock.DialogWarning, Gtk.IconSize.Dialog);\n\n\t\tthis.AddButton(Catalog.GetString(\"Close without Saving\"), ResponseType.No);\n\t\tthis.AddButton(Gtk.Stock.Cancel, ResponseType.Cancel);\n\t\tthis.AddButton(Gtk.Stock.Save, ResponseType.Ok);\n\n\t\tthis.DefaultResponse = ResponseType.Cancel;\n\n\t\tthis.ShowAll();\n\t}\n\n}\n\n\n\n}"
  },
  {
    "path": "src/gui/dialogs/SaveConfirmationMultiAlert.cs",
    "content": "// created on 12/25/2004 at 6:33 PM\n/*\n *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System;\nusing Gtk;\nusing Mono.Unix;\n\nnamespace Bless.Gui.Dialogs {\n\npublic class SaveFileItem\n{\n\tpublic bool Save;\n\tpublic string Name;\n\tpublic int Page;\n\tpublic SaveFileItem(bool s, string n, int p) {Save = s; Name = n; Page = p;}\n}\n\n///<summary>An alert dialog box as recommended in the Gnome HIG</summary>\npublic class SaveConfirmationMultiAlert : Alert\n{\n\tTreeView treeView;\n\tSaveFileItem[] fileList;\n\n\tpublic SaveConfirmationMultiAlert(SaveFileItem[] list, Gtk.Window parent)\n\t\t\t: base(string.Format(\n\t\t\t\t\t\tCatalog.GetPluralString(\"There is {0} file with unsaved changes.\", \"There are {0} files with unsaved changes.\", list.Length) +\n\t\t\t\t\t\t\" \" + Catalog.GetString(\"Save changes before closing?\"),\n\t\t\t\t\t\tlist.Length),\n\t\t\t\t\tCatalog.GetString(\"If you don't save, all changes made since the last save will be lost.\"),\n\t\t\t\t\tparent)\n\t{\n\t\tfileList = list;\n\n\t\timage.SetFromStock(Gtk.Stock.DialogWarning, Gtk.IconSize.Dialog);\n\n\t\tLabel label = new Label(Catalog.GetString(\"\\nSelect the files you want to save:\\n\"));\n\t\tlabel.Xalign = 0.0f;\n\n\t\tVBox vb = new VBox();\n\t\tvb.PackStart(label);\n\t\ttreeView = CreateView(list);\n\t\tvb.PackStart(treeView);\n\n\t\tlabelBox.PackStart(vb);\n\t\tlabelBox.ReorderChild(vb, 1);\n\n\t\tthis.AddButton(Catalog.GetString(\"Close without Saving\"), ResponseType.No);\n\t\tthis.AddButton(Gtk.Stock.Cancel, ResponseType.Cancel);\n\t\tthis.AddButton(Gtk.Stock.Save, ResponseType.Ok);\n\n\t\tthis.DefaultResponse = ResponseType.Cancel;\n\n\t\tthis.ShowAll();\n\t}\n\n\tprivate TreeView CreateView(SaveFileItem[] list)\n\t{\n\t\tListStore store = new ListStore (typeof (bool), typeof (string));\n\t\tTreeView tv = new TreeView();\n\n\t\ttv.Model = store;\n\t\ttv.HeadersVisible = false;\n\n\t\tCellRendererToggle crt = new CellRendererToggle();\n\t\tcrt.Activatable = true;\n\t\tcrt.Toggled += OnItemToggled;\n\n\t\ttv.AppendColumn (\"Save\", crt, \"active\", 0);\n\t\ttv.AppendColumn (\"Name\", new CellRendererText(), \"text\", 1);\n\n\t\tforeach (SaveFileItem item in list) {\n\t\t\titem.Save = true;\n\t\t\tstore.AppendValues(item.Save, item.Name);\n\t\t}\n\n\t\treturn tv;\n\t}\n\n\tprivate void OnItemToggled (object o, ToggledArgs args)\n\t{\n\t\tListStore store = (ListStore)treeView.Model;\n\n\t\tGtk.TreeIter iter;\n\t\tif (store.GetIterFromString (out iter, args.Path)) {\n\t\t\tbool val = (bool) store.GetValue (iter, 0);\n\t\t\tstore.SetValue (iter, 0, !val);\n\n\t\t\tint row = Convert.ToInt32(args.Path);\n\t\t\tfileList[row].Save = !fileList[row].Save;\n\t\t}\n\t}\n\n}\n\n\n\n}\n"
  },
  {
    "path": "src/gui/dialogs/WarningAlert.cs",
    "content": "// created on 4/29/2005 at 2:52 PM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System;\nusing Gtk;\n\nnamespace Bless.Gui.Dialogs {\n\n///<summary>An alert dialog box as recommended in the Gnome HIG</summary>\npublic class WarningAlert : Alert\n{\n\n\tpublic WarningAlert(string primary, string secondary, Gtk.Window parent)\n\t\t\t: base(primary, secondary, parent)\n\t{\n\t\timage.SetFromStock(Gtk.Stock.DialogWarning, Gtk.IconSize.Dialog);\n\n\t\tthis.AddButton(Gtk.Stock.Cancel, ResponseType.Cancel);\n\t\tthis.AddButton(Gtk.Stock.Ok, ResponseType.Ok);\n\n\t\tthis.ShowAll();\n\t}\n\n}\n\n\n\n} // namespace\n"
  },
  {
    "path": "src/gui/drawers/AsciiDrawer.cs",
    "content": "// created on 6/28/2004 at 4:46 PM\n/*\n *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nnamespace Bless.Gui.Drawers {\n\n///<summary>Draws the ascii representation of a byte</summary>\npublic class AsciiDrawer : Drawer {\n\n\t// Use the Zero Width Non-Joiner character \\u200c to avoid ligatures\n\tstatic readonly string AsciiTable = \"................................ !\\\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHI\\u200cJKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghi\\u200cjklmnopqrs\\u200ctuvwxyz{|}~.................................................................................................................................\";\n\n\tpublic AsciiDrawer(Gtk.Widget wid, Information inf)\n\t\t\t: base(wid, inf)\n\t{\n\t}\n\n\tprotected override void Draw(Gdk.GC gc, Gdk.Drawable dest, int x, int y, byte b, Gdk.Pixmap pix)\n\t{\n\t\tdest.DrawDrawable(gc, pix, b*width, 0, x, y, width, height);\n\t}\n\n\tprotected override Gdk.Pixmap Create(Gdk.Color fg, Gdk.Color bg)\n\t{\n\t\tGdk.Window win = widget.GdkWindow;\n\n\t\tGdk.GC gc = new Gdk.GC(win);\n\t\tGdk.Pixmap pix = new Gdk.Pixmap(win, 256*width, height, -1);\n\n\t\t// draw the background\n\t\tgc.RgbFgColor = bg;\n\t\tpix.DrawRectangle(gc, true, 0, 0, 256*width, height);\n\n\t\t// render the bytes\n\t\tstring s = AsciiDrawer.AsciiTable;\n\n\t\t//System.Console.WriteLine(s);\n\n\t\tpangoLayout.SetText(s);\n\n\n\t\tgc.RgbFgColor = fg;\n\t\tpix.DrawLayout(gc, 0, 0, pangoLayout);\n\n\t\treturn pix;\n\t}\n\n}\n\n} //namespace\n"
  },
  {
    "path": "src/gui/drawers/BinaryDrawer.cs",
    "content": "// created on 6/28/2004 at 4:48 PM\n/*\n *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nnamespace Bless.Gui.Drawers {\n\n///<summary>Draws the binary representation of a byte</summary>\npublic class BinaryDrawer : Drawer {\n\n\tpublic BinaryDrawer(Gtk.Widget wid, Information inf)\n\t\t\t: base(wid, inf)\n\t{\n\t}\n\n\n\tprotected override void Draw(Gdk.GC gc, Gdk.Drawable dest, int x, int y, byte b, Gdk.Pixmap pix)\n\t{\n\t\t// draw from the end backwards\n\t\tx += 6 * width;\n\t\tfor (int i = 0; i < 4; i++) {\n\t\t\tbyte k = (byte)(b & 3);\n\t\t\tdest.DrawDrawable(gc, pix, k*2*width, 0, x, y, 2*width, height);\n\t\t\tx -= 2 * width;\n\t\t\tb = (byte)(b >> 2);\n\t\t}\n\t}\n\n\tprotected override Gdk.Pixmap Create(Gdk.Color fg, Gdk.Color bg)\n\t{\n\t\tGdk.Window win = widget.GdkWindow;\n\n\t\tGdk.GC gc = new Gdk.GC(win);\n\t\tGdk.Pixmap pix = new Gdk.Pixmap(win, 4*2*width, height, -1);\n\n\t\t// draw the background\n\t\tgc.RgbFgColor = bg;\n\t\tpix.DrawRectangle(gc, true, 0, 0, 4*2*width, height);\n\n\t\t// render the bytes\n\t\tstring s = \"00011011\";\n\n\n\t\t//Console.WriteLine(s);\n\n\t\tpangoLayout.SetText(s);\n\n\n\t\tgc.RgbFgColor = fg;\n\t\tpix.DrawLayout(gc, 0, 0, pangoLayout);\n\n\t\treturn pix;\n\t}\n\n}\n\n} //namespace"
  },
  {
    "path": "src/gui/drawers/DecimalDrawer.cs",
    "content": "// created on 7/1/2004 at 8:10 PM\n/*\n *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nnamespace Bless.Gui.Drawers {\n\n///<summary>Draws the decimal representation of a byte</summary>\npublic class DecimalDrawer : Drawer {\n\n\tstatic readonly string DecimalTable = \"000001002003004005006007008009010011012013014015016017018019020021022023024025026027028029030031032033034035036037038039040041042043044045046047048049050051052053054055056057058059060061062063064065066067068069070071072073074075076077078079080081082083084085086087088089090091092093094095096097098099100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255\";\n\n\tpublic DecimalDrawer(Gtk.Widget wid, Information inf)\n\t\t\t: base(wid, inf)\n\t{\n\t}\n\n\tprotected override void Draw(Gdk.GC gc, Gdk.Drawable dest, int x, int y, byte b, Gdk.Pixmap pix)\n\t{\n\t\tdest.DrawDrawable(gc, pix, b*3*width, 0, x, y, 3*width, height);\n\t}\n\n\tprotected override Gdk.Pixmap Create(Gdk.Color fg, Gdk.Color bg)\n\t{\n\t\tGdk.Window win = widget.GdkWindow;\n\n\t\tGdk.GC gc = new Gdk.GC(win);\n\t\tGdk.Pixmap pix = new Gdk.Pixmap(win, 256*3*width, height, -1);\n\n\t\t// draw the background\n\t\tgc.RgbFgColor = bg;\n\t\tpix.DrawRectangle(gc, true, 0, 0, 256*3*width, height);\n\n\t\t// render the bytes\n\t\tstring s = DecimalDrawer.DecimalTable;\n\n\t\t//System.Console.WriteLine(s);\n\n\t\tpangoLayout.SetText(s);\n\n\n\t\tgc.RgbFgColor = fg;\n\t\tpix.DrawLayout(gc, 0, 0, pangoLayout);\n\n\t\treturn pix;\n\t}\n\n\n\n}\n\n} //namespace"
  },
  {
    "path": "src/gui/drawers/Drawer.cs",
    "content": "// created on 6/14/2004 at 10:55 PM\n/*\n *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing System;\nusing System.Collections.Specialized;\nusing Gtk;\nusing Gdk;\nusing Pango;\n\nnamespace Bless.Gui.Drawers {\n\n///<summary>Fast font drawing class</summary>\npublic abstract class Drawer {\n\n\tpublic class Color {\n\t\tpublic Color(Gdk.Color color)\n\t\t{\n\t\t\tthis.GdkColor = color;\n\t\t}\n\n\t\tpublic Gdk.Color GdkColor;\n\t}\n\n\tpublic class Information {\n\t\tpublic string FontName;\n\t\tpublic string FontLanguage;\n\n\t\tpublic Drawer.Color[,] fgNormal;\n\t\tpublic Drawer.Color[,] bgNormal;\n\n\t\tpublic Drawer.Color[,] fgHighlight;\n\t\tpublic Drawer.Color[,] bgHighlight;\n\n\t\tpublic bool Uppercase;\n\n\t\tpublic Information()\n\t\t{\n\t\t\tFontName = \"BlessCourier, Courier 12\";\n\t\t\tFontLanguage = \"utf-8\";\n\n\t\t\tfgNormal = new Drawer.Color[2, 2];\n\t\t\tbgNormal = new Drawer.Color[2, 2];\n\t\t\t\n\t\t\tfgHighlight = new Drawer.Color[2, (int)HighlightType.Sentinel];\n\t\t\tbgHighlight = new Drawer.Color[2, (int)HighlightType.Sentinel];\n\n\t\t\tfor (int i = 0; i < 2; i++) {\n\t\t\t\tfgNormal[0, i] = new Drawer.Color(Gdk.Color.Zero);\n\t\t\t\tfgNormal[1, i] = new Drawer.Color(Gdk.Color.Zero);\n\t\t\t\tbgNormal[0, i] = new Drawer.Color(Gdk.Color.Zero);\n\t\t\t\tbgNormal[1, i] = new Drawer.Color(Gdk.Color.Zero);\n\t\t\t}\n\n\t\t\t// initialize default colors\n\t\t\tGdk.Color.Parse(\"black\", ref fgNormal[(int)RowType.Even, (int)ColumnType.Even].GdkColor);\n\t\t\tGdk.Color.Parse(\"white\", ref bgNormal[(int)RowType.Even, (int)ColumnType.Even].GdkColor);\n\n\t\t\tGdk.Color.Parse(\"blue\", ref fgNormal[(int)RowType.Even, (int)ColumnType.Odd].GdkColor);\n\t\t\tGdk.Color.Parse(\"white\", ref bgNormal[(int)RowType.Even, (int)ColumnType.Odd].GdkColor);\n\n\t\t\tGdk.Color.Parse(\"black\", ref fgNormal[(int)RowType.Odd, (int)ColumnType.Even].GdkColor);\n\t\t\tGdk.Color.Parse(\"white\", ref bgNormal[(int)RowType.Odd, (int)ColumnType.Even].GdkColor);\n\n\t\t\tGdk.Color.Parse(\"blue\", ref fgNormal[(int)RowType.Odd, (int)ColumnType.Odd].GdkColor);\n\t\t\tGdk.Color.Parse(\"white\", ref bgNormal[(int)RowType.Odd, (int)ColumnType.Odd].GdkColor);\n\n\t\t\t// leave unspecified...\n\t\t\t// if not specified by user they will\n\t\t\t// be set up using theme defaults\n\t\t\tfor (int i = 0; i < (int)HighlightType.Sentinel; i++) {\n\t\t\t\tfgHighlight[(int)RowType.Even, i] = null;\n\t\t\t\tbgHighlight[(int)RowType.Even, i] = null;\n\n\t\t\t\tfgHighlight[(int)RowType.Odd, i] = null;\n\t\t\t\tbgHighlight[(int)RowType.Odd, i] = null;\n\t\t\t}\n\n\t\t\tUppercase = false;\n\t\t}\n\n\t\t// setup unspecified hightlight colors using theme default colors\n\t\tpublic void SetupHighlight(Gtk.Widget widget)\n\t\t{\n\t\t\tGdk.Color selFg;\n\t\t\tGdk.Color selBg;\n\t\t\tGdk.Color patMatchFg;\n\t\t\tGdk.Color patMatchBg;\n\n\t\t\tselFg = widget.Style.TextColors[(int)StateType.Selected];\n\t\t\tselBg = widget.Style.BaseColors[(int)StateType.Selected];\n\t\t\tpatMatchBg = MakeColorLighter(selBg, 0.6);\n\t\t\tpatMatchFg = MakeColorDarker(selFg, 0.4);\n\n\t\t\t// Selection\n\t\t\tif (fgHighlight[(int)RowType.Even, (int)HighlightType.Selection] == null)\n\t\t\t\tfgHighlight[(int)RowType.Even, (int)HighlightType.Selection] = new Drawer.Color(selFg);\n\n\t\t\tif (bgHighlight[(int)RowType.Even, (int)HighlightType.Selection] == null)\n\t\t\t\tbgHighlight[(int)RowType.Even, (int)HighlightType.Selection] = new Drawer.Color(selBg);\n\n\t\t\tif (fgHighlight[(int)RowType.Odd, (int)HighlightType.Selection] == null)\n\t\t\t\tfgHighlight[(int)RowType.Odd, (int)HighlightType.Selection] = new Drawer.Color(selFg);\n\n\t\t\tif (bgHighlight[(int)RowType.Odd, (int)HighlightType.Selection] == null)\n\t\t\t\tbgHighlight[(int)RowType.Odd, (int)HighlightType.Selection] = new Drawer.Color(selBg);\n\n\t\t\t// Secondary selection\n\t\t\tif (fgHighlight[(int)RowType.Even, (int)HighlightType.PatternMatch] == null)\n\t\t\t\tfgHighlight[(int)RowType.Even, (int)HighlightType.PatternMatch] = new Drawer.Color(patMatchFg);\n\n\t\t\tif (bgHighlight[(int)RowType.Even, (int)HighlightType.PatternMatch] == null)\n\t\t\t\tbgHighlight[(int)RowType.Even, (int)HighlightType.PatternMatch] = new Drawer.Color(patMatchBg);\n\n\t\t\tif (fgHighlight[(int)RowType.Odd, (int)HighlightType.PatternMatch] == null)\n\t\t\t\tfgHighlight[(int)RowType.Odd, (int)HighlightType.PatternMatch] = new Drawer.Color(patMatchFg);\n\n\t\t\tif (bgHighlight[(int)RowType.Odd, (int)HighlightType.PatternMatch] == null)\n\t\t\t\tbgHighlight[(int)RowType.Odd, (int)HighlightType.PatternMatch] = new Drawer.Color(patMatchBg);\n\t\t}\n\n\t\t// Make a color lighter while keeping its hue\n\t\tGdk.Color MakeColorLighter(Gdk.Color col, double factor)\n\t\t{\n\t\t\tGdk.Color light = new Gdk.Color();\n\n\t\t\tlight.Red = (ushort)(col.Red + (ushort.MaxValue - col.Red) * factor);\n\t\t\tlight.Blue = (ushort)(col.Blue + (ushort.MaxValue - col.Blue) * factor);\n\t\t\tlight.Green = (ushort)(col.Green + (ushort.MaxValue - col.Green) * factor);\n\t\t\treturn light;\n\t\t}\n\n\t\t// Make a color darker while keeping its hue\n\t\tGdk.Color MakeColorDarker(Gdk.Color col, double factor)\n\t\t{\n\t\t\tGdk.Color dark = new Gdk.Color();\n\n\t\t\tdark.Red = (ushort)(col.Red * factor);\n\t\t\tdark.Blue = (ushort)(col.Blue * factor);\n\t\t\tdark.Green = (ushort)(col.Green * factor);\n\t\t\treturn dark;\n\t\t}\n\t}\n\t\n\t// the order of this enumeration denotes the drawing priority of each highlight type\n\t// For example if a Bookmark and PatternMatch highlight are to be drawn on the same offset\n\t// the PatternMatch type will be drawn. In the same manner the Selection highlight\n\t// is always drawn, whereas the Normal highlight is always drawn over.\n\tpublic enum HighlightType { Normal, Bookmark, PatternMatch, Selection, Sentinel }\n\tpublic enum RowType { Even, Odd }\n\tpublic enum ColumnType { Even, Odd }\n\n\t// the widget the font will finally\n\t// be printed on (used for info only)\n\tprotected Gtk.Widget widget;\n\tprotected Pango.FontDescription fontDescription;\n\tprotected Information info;\n\n\tprotected Gdk.Pixmap[,] pixmapsNormal;\n\tprotected Gdk.Pixmap[,] pixmapsHighlight;\n\tprotected StringCollection pixmapIds;\n\n\t// pango layout used for rendering text\n\tprotected Pango.Layout pangoLayout;\n\n\tprotected Gdk.GC[,] backGC;\n\tprotected int width;\n\tprotected int height;\n\n\t///<summary>Constructor</summary>\n\tpublic Drawer(Gtk.Widget wid, Information inf)\n\t{\n\t\twidget = wid;\n\t\tinfo = inf;\n\t\tpixmapIds = new StringCollection();\n\t\t// make sure highlight colors are set\n\t\tinfo.SetupHighlight(wid);\n\n\t\tfontDescription = Pango.FontDescription.FromString(info.FontName);\n\t\tPango.Language lang = Pango.Language.FromString(info.FontLanguage);\n\n\t\tPango.Context pangoCtx = widget.PangoContext;\n\t\tpangoCtx.FontDescription = fontDescription;\n\t\tpangoCtx.Language = lang;\n\n\t\t// set the font height and width\n\t\tpangoLayout = new Pango.Layout(pangoCtx);\n\t\t// we use a monospaced font, the actual character doesn't matter\n\t\tpangoLayout.SetText(\"X\");\n\t\tpangoLayout.GetPixelSize(out width, out height);\n\t\tpangoLayout.SetText(\"\");\n\n\t\t// create the font pixmaps\n\t\tInitializePixmaps();\n\n\t\tInitializeBackgroundGCs();\n\t}\n\n\tvoid InitializePixmaps()\n\t{\n\t\tpixmapsNormal = new Gdk.Pixmap[2,2];\n\t\tpixmapsHighlight = new Gdk.Pixmap[2,(int)HighlightType.Sentinel];\n\n\t\tDrawer.Color colorFg;\n\t\tDrawer.Color colorBg;\n\n\t\t//even rows\n\t\tcolorFg = info.fgNormal[(int)RowType.Even, (int)ColumnType.Even];\n\t\tcolorBg = info.bgNormal[(int)RowType.Even, (int)ColumnType.Even];\n\t\tpixmapsNormal[(int)RowType.Even, (int)ColumnType.Even] = CreateWrapper(colorFg, colorBg);\n\n\t\tcolorFg = info.fgNormal[(int)RowType.Even, (int)ColumnType.Odd];\n\t\tcolorBg = info.bgNormal[(int)RowType.Even, (int)ColumnType.Odd];\n\t\tpixmapsNormal[(int)RowType.Even, (int)ColumnType.Odd] = CreateWrapper(colorFg, colorBg);\n\n\t\tcolorFg = info.fgHighlight[(int)RowType.Even, (int)HighlightType.Selection];\n\t\tcolorBg = info.bgHighlight[(int)RowType.Even, (int)HighlightType.Selection];\n\t\tpixmapsHighlight[(int)RowType.Even, (int)HighlightType.Selection] = CreateWrapper(colorFg, colorBg);\n\n\t\tcolorFg = info.fgHighlight[(int)RowType.Even, (int)HighlightType.PatternMatch];\n\t\tcolorBg = info.bgHighlight[(int)RowType.Even, (int)HighlightType.PatternMatch];\n\t\tpixmapsHighlight[(int)RowType.Even, (int)HighlightType.PatternMatch] = CreateWrapper(colorFg, colorBg);\n\n\n\t\t//odd rows\n\t\tcolorFg = info.fgNormal[(int)RowType.Odd, (int)ColumnType.Even];\n\t\tcolorBg = info.bgNormal[(int)RowType.Odd, (int)ColumnType.Even];\n\t\tpixmapsNormal[(int)RowType.Odd, (int)ColumnType.Even] = CreateWrapper(colorFg, colorBg);\n\n\t\tcolorFg = info.fgNormal[(int)RowType.Odd, (int)ColumnType.Odd];\n\t\tcolorBg = info.bgNormal[(int)RowType.Odd, (int)ColumnType.Odd];\n\t\tpixmapsNormal[(int)RowType.Odd, (int)ColumnType.Odd] = CreateWrapper(colorFg, colorBg);\n\n\t\tcolorFg = info.fgHighlight[(int)RowType.Odd, (int)HighlightType.Selection];\n\t\tcolorBg = info.bgHighlight[(int)RowType.Odd, (int)HighlightType.Selection];\n\t\tpixmapsHighlight[(int)RowType.Odd, (int)HighlightType.Selection] = CreateWrapper(colorFg, colorBg);\n\n\t\tcolorFg = info.fgHighlight[(int)RowType.Odd, (int)HighlightType.PatternMatch];\n\t\tcolorBg = info.bgHighlight[(int)RowType.Odd, (int)HighlightType.PatternMatch];\n\t\tpixmapsHighlight[(int)RowType.Odd, (int)HighlightType.PatternMatch] = CreateWrapper(colorFg, colorBg);\n\t}\n\n\tvoid InitializeBackgroundGCs()\n\t{\n\t\t// initialize background GCs\n\t\tbackGC = new Gdk.GC[2, (int)Drawer.HighlightType.Sentinel];\n\n\t\tfor (int i = 0; i < 2; i++)\n\t\t\tfor (int j = 0; j < (int)Drawer.HighlightType.Sentinel; j++)\n\t\t\t\tbackGC[i,j] = new Gdk.GC(widget.GdkWindow);\n\n\t\tDrawer.Color col;\n\n\t\t// normal\n\t\tcol = info.bgNormal[(int)RowType.Even, (int)ColumnType.Even];\n\t\tbackGC[(int)RowType.Even, (int)HighlightType.Normal].RgbFgColor = col.GdkColor;\n\n\t\tcol = info.bgNormal[(int)RowType.Odd, (int)ColumnType.Even];\n\t\tbackGC[(int)RowType.Odd, (int)HighlightType.Normal].RgbFgColor = col.GdkColor;\n\n\t\t// selection\n\t\tcol = info.bgHighlight[(int)RowType.Even, (int)HighlightType.Selection];\n\t\tbackGC[(int)RowType.Even, (int)HighlightType.Selection].RgbFgColor = col.GdkColor;\n\n\t\tcol = info.bgHighlight[(int)RowType.Odd, (int)HighlightType.Selection];\n\t\tbackGC[(int)RowType.Odd, (int)HighlightType.Selection].RgbFgColor = col.GdkColor;\n\n\t\t// secondary selection\n\t\tcol = info.bgHighlight[(int)RowType.Even, (int)HighlightType.PatternMatch];\n\t\tbackGC[(int)RowType.Even, (int)HighlightType.PatternMatch].RgbFgColor = col.GdkColor;\n\n\t\tcol = info.bgHighlight[(int)RowType.Odd, (int)HighlightType.PatternMatch];\n\t\tbackGC[(int)RowType.Odd, (int)HighlightType.PatternMatch].RgbFgColor = col.GdkColor;\n\t}\n\n\t///<summary>\n\t/// Wrapper around create to avoid creating pixmaps we already have\n\t///</summary>\n\tprivate Gdk.Pixmap CreateWrapper(Drawer.Color fg, Drawer.Color bg)\n\t{\n\t\tstring id = PixmapManager.Instance.GetPixmapId(this.GetType(), info, fg.GdkColor, bg.GdkColor);\n\n\t\tGdk.Pixmap pix = PixmapManager.Instance.GetPixmap(id);\n\t\tif (pix == null) {\n\t\t\tpix = Create(fg.GdkColor, bg.GdkColor); // can be null for DummyDrawer\n\t\t\tif (pix != null) {\n\t\t\t\tPixmapManager.Instance.AddPixmap(id, pix);\n\t\t\t\tPixmapManager.Instance.ReferencePixmap(id);\n\t\t\t\tpixmapIds.Add(id);\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tPixmapManager.Instance.ReferencePixmap(id);\n\t\t\tpixmapIds.Add(id);\n\t\t}\n\n\t\treturn pix;\n\t}\n\n\t///<summary>Creates a pixmap with the drawn data</summary>\n\tabstract protected Gdk.Pixmap Create(Gdk.Color fg, Gdk.Color bg);\n\n\t///<summary>Draws the a byte</summary>\n\n\tabstract protected void Draw(Gdk.GC gc, Gdk.Drawable dest, int x, int y, byte b, Gdk.Pixmap pix);\n\n\tpublic void DrawNormal(Gdk.GC gc, Gdk.Drawable dest, int x, int y, byte b, RowType rowType, ColumnType colType)\n\t{\n\t\tDraw(gc, dest, x, y, b, pixmapsNormal[(int)rowType, (int)colType]);\n\t}\n\n\tpublic void DrawHighlight(Gdk.GC gc, Gdk.Drawable dest, int x, int y, byte b, RowType rowType, HighlightType ht)\n\t{\n\t\tDraw(gc, dest, x, y, b, pixmapsHighlight[(int)rowType, (int)ht]);\n\t}\n\n\tpublic Gdk.GC GetBackgroundGC(RowType rowType, HighlightType ht)\n\t{\n\t\treturn backGC[(int)rowType, (int)ht];\n\t}\n\n\tpublic void DisposePixmaps()\n\t{\n\t\tforeach(string id in pixmapIds)\n\t\tPixmapManager.Instance.DereferencePixmap(id);\n\n\t\tpixmapIds.Clear();\n\t}\n\n\tpublic int Width{\n\t\tget { return width; }\n\t}\n\n\tpublic int Height{\n\t\tget { return height; }\n\t}\n\n\tpublic Drawer.Information Info{\n\t\tget { return info; }\n\t}\n\n}\n\n///<summary>dummy</summary>\npublic class DummyDrawer : Drawer {\n\n\tpublic DummyDrawer(Gtk.Widget wid, Information inf)\n\t\t\t: base(wid, inf)\n\t{\n\t}\n\n\tprotected override void Draw(Gdk.GC gc, Gdk.Drawable dest, int x, int y, byte b, Gdk.Pixmap pix)\n\t{\n\n\t}\n\n\tprotected override Gdk.Pixmap Create(Gdk.Color fg, Gdk.Color bg)\n\t{\n\t\treturn null;\n\t}\n\n\n\n}\n\n} // end namespace\n"
  },
  {
    "path": "src/gui/drawers/HexDrawer.cs",
    "content": "// created on 6/28/2004 at 4:18 PM\n/*\n *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nnamespace Bless.Gui.Drawers {\n\n///<summary>Draws the hex representation of a byte</summary>\npublic class HexDrawer : Drawer {\n\n\t// Use the Zero Width Non-Joiner character \\u200c to avoid ligatures\n\tstatic readonly string HexTableLower = \"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeef\\u200Cf0f1f2f3f4f5f6f7f8f9fafbfcfdfef\\u200cf\";\n\tstatic readonly string HexTableUpper = \"000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF\";\n\n\tpublic HexDrawer(Gtk.Widget wid, Information inf)\n\t\t\t: base(wid, inf)\n\t{\n\t}\n\n\tprotected override void Draw(Gdk.GC gc, Gdk.Drawable dest, int x, int y, byte b, Gdk.Pixmap pix)\n\t{\n\t\tdest.DrawDrawable(gc, pix, b*2*width, 0, x, y, 2*width, height);\n\t}\n\n\tprotected override Gdk.Pixmap Create(Gdk.Color fg, Gdk.Color bg)\n\t{\n\t\tGdk.Window win = widget.GdkWindow;\n\n\t\tGdk.GC gc = new Gdk.GC(win);\n\t\tGdk.Pixmap pix = new Gdk.Pixmap(win, 256*2*width, height, -1);\n\n\t\t// draw the background\n\t\tgc.RgbFgColor = bg;\n\t\tpix.DrawRectangle(gc, true, 0, 0, 256*2*width, height);\n\n\t\t// render the bytes\n\t\tstring s;\n\n\t\tif (info.Uppercase == false)\n\t\t\ts = HexDrawer.HexTableLower;\n\t\telse\n\t\t\ts = HexDrawer.HexTableUpper;\n\n\t\t//System.Console.WriteLine(s);\n\n\t\tgc.RgbFgColor = fg;\n\n\t\t// Render the text in two parts (256 printable characters each).  We do\n\t\t// this to work around a bug in some drivers that fail to render text\n\t\t// that ends up wider than 4096 pixels.\n\t\tpangoLayout.SetText(s.Substring(0,256));\n\t\tpix.DrawLayout(gc, 0, 0, pangoLayout);\n\t\t\n\t\t// The second part also contains the two Zero Width Non-Joiner\n\t\t// characters, so it's actually 258 string characters, although still\n\t\t// 256 printable characters.\n\t\tpangoLayout.SetText(s.Substring(256));\n\t\tpix.DrawLayout(gc, 128*2*width, 0, pangoLayout);\n\n\t\treturn pix;\n\t}\n\n\n\n}\n\n} //namespace\n"
  },
  {
    "path": "src/gui/drawers/OctalDrawer.cs",
    "content": "// created on 7/1/2004 at 8:41 PM\n/*\n *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nnamespace Bless.Gui.Drawers {\n\n///<summary>Draws the octal representation of a byte</summary>\npublic class OctalDrawer : Drawer {\n\n\tstatic readonly string OctalTable = \"000001002003004005006007010011012013014015016017020021022023024025026027030031032033034035036037040041042043044045046047050051052053054055056057060061062063064065066067070071072073074075076077100101102103104105106107110111112113114115116117120121122123124125126127130131132133134135136137140141142143144145146147150151152153154155156157160161162163164165166167170171172173174175176177200201202203204205206207210211212213214215216217220221222223224225226227230231232233234235236237240241242243244245246247250251252253254255256257260261262263264265266267270271272273274275276277300301302303304305306307310311312313314315316317320321322323324325326327330331332333334335336337340341342343344345346347350351352353354355356357360361362363364365366367370371372373374375376377\";\n\n\tpublic OctalDrawer(Gtk.Widget wid, Information inf)\n\t\t\t: base(wid, inf)\n\t{\n\t}\n\n\tprotected override void Draw(Gdk.GC gc, Gdk.Drawable dest, int x, int y, byte b, Gdk.Pixmap pix)\n\t{\n\t\tdest.DrawDrawable(gc, pix, b*3*width, 0, x, y, 3*width, height);\n\t}\n\n\tprotected override Gdk.Pixmap Create(Gdk.Color fg, Gdk.Color bg)\n\t{\n\t\tGdk.Window win = widget.GdkWindow;\n\n\t\tGdk.GC gc = new Gdk.GC(win);\n\t\tGdk.Pixmap pix = new Gdk.Pixmap(win, 256*3*width, height, -1);\n\n\t\t// draw the background\n\t\tgc.RgbFgColor = bg;\n\t\tpix.DrawRectangle(gc, true, 0, 0, 256*3*width, height);\n\n\t\t// render the bytes\n\t\tstring s = OctalDrawer.OctalTable;\n\n\t\t//System.Console.WriteLine(s);\n\n\t\tpangoLayout.SetText(s);\n\n\n\t\tgc.RgbFgColor = fg;\n\t\tpix.DrawLayout(gc, 0, 0, pangoLayout);\n\n\t\treturn pix;\n\t}\n}\n\n} //namespace"
  },
  {
    "path": "src/gui/drawers/PixmapManager.cs",
    "content": "// created on 12/23/2006 at 3:50 PM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing System.Collections.Generic;\nusing Gdk;\n\nnamespace Bless.Gui.Drawers {\n\n///<summary>\n/// Handles drawer pixmaps in an memory efficient manner\n///</summary>\nclass PixmapManager\n{\n\tstatic private PixmapManager manager;\n\n\tstatic public PixmapManager Instance {\n\t\tget {\n\t\t\tif (manager == null)\n\t\t\t\tmanager = new PixmapManager();\n\n\t\t\treturn manager;\n\t\t}\n\t}\n\n\tDictionary<string, Gdk.Pixmap> pixmaps;\n\tDictionary<string, int> references;\n\n\tprivate PixmapManager()\n\t{\n\t\tpixmaps = new Dictionary<string, Gdk.Pixmap>();\n\t\treferences = new Dictionary<string, int>();\n\t}\n\n\t///<summary>\n\t/// Get the id of the pixmap with the specified properties\n\t///</summary>\n\tpublic string GetPixmapId(System.Type type, Drawer.Information info, Gdk.Color fg, Gdk.Color bg)\n\t{\n\t\treturn string.Format(\"{0}{1}{2}{3}{4}{5}\", type, info.FontName, info.FontLanguage, info.Uppercase, fg.ToString(), bg.ToString());\n\t}\n\n\t///<summary>\n\t/// Get the pixmap with the specified id.\n\t/// Returns null if the pixmap doesn't exist\n\t///</summary>\n\tpublic Gdk.Pixmap GetPixmap(string id)\n\t{\n\t\tGdk.Pixmap pix = null;\n\t\tif (pixmaps.ContainsKey(id))\n\t\t\tpix = pixmaps[id];\n\n\t\treturn pix;\n\t}\n\n\t///<summary>\n\t/// Add the pixmap to the collection\n\t///</summary>\n\tpublic void AddPixmap(string id, Gdk.Pixmap pix)\n\t{\n\t\tpixmaps[id] = pix;\n\t\treferences[id] = 0;\n\t}\n\n\t///<summary>\n\t/// Mark that we are using the pixmap\n\t///</summary>\n\tpublic void ReferencePixmap(string id)\n\t{\n\t\t++references[id];\n\t}\n\n\t///<summary>\n\t/// Mark that we aren't using the pixmap anymore.\n\t/// If nobody uses it, dispose of it\n\t///</summary>\n\tpublic void DereferencePixmap(string id)\n\t{\n\t\t--references[id];\n\t\tif (references[id] <= 0) {\n\t\t\tpixmaps[id].Dispose();\n\t\t\tpixmaps.Remove(id);\n\t\t\treferences.Remove(id);\n\t\t}\n\t}\n\n}\n\n\n\n}"
  },
  {
    "path": "src/gui/plugins/BitwiseOperationsPlugin.cs",
    "content": "// created on 4/3/2007 at 6:30 PM\n/*\n *   Copyright (c) 2007, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System;\nusing System.Text;\nusing System.Threading;\nusing Gtk;\nusing Bless.Util;\nusing Bless.Gui.Dialogs;\nusing Bless.Gui;\nusing Bless.Plugins;\nusing Bless.Buffers;\nusing Mono.Unix;\n\nnamespace Bless.Gui.Plugins {\n\n///<summary>\n/// A plugin to perform bytewise operation on data\n///</summary>\npublic class BitwiseOperationsPlugin : GuiPlugin\n{\n\tBitwiseOperationsWidget widget;\n\tDataBook dataBook;\n\tGtk.Action performAction;\n\n\tconst string uiXml =\n\t\t\"<menubar>\" +\n\t\t\"\t<menu action=\\\"Tools\\\">\" +\n\t\t\"\t\t<menuitem name=\\\"BitwiseOperations\\\" action=\\\"BitwiseOperationsAction\\\" />\" +\n\t\t\"\t</menu>\" +\n\t\t\"</menubar>\" +\n\t\t\"<popup name=\\\"DefaultAreaPopup\\\">\" +\n\t\t\"\t<placeholder name=\\\"ExtraAreaPopupItems\\\" >\" +\n\t\t\"\t\t<menuitem name=\\\"PerformBitwiseOperation\\\" action=\\\"PerformBitwiseOperationAction\\\" />\" +\n\t\t\"\t</placeholder>\" +\n\t\t\"</popup>\";\n\n\tWindow mainWindow;\n\tUIManager uiManager;\n\n\tpublic BitwiseOperationsPlugin(Window mw, UIManager uim)\n\t{\n\t\tmainWindow = mw;\n\t\tuiManager = uim;\n\n\t\tdataBook = (DataBook)GetDataBook(mw);\n\n\t\tname = \"BitwiseOperations\";\n\t\tauthor = \"Alexandros Frantzis\";\n\t\tdescription = \"Bitwise operations on data\";\n\t\tloadAfter.Add(\"EditOperations\");\n\t}\n\n\tpublic override bool Load()\n\t{\n\t\tAddMenuItems(uiManager);\n\n\t\twidget = new BitwiseOperationsWidget((DataBook)GetDataBook(mainWindow), performAction);\n\t\twidget.Visible = false;\n\n\t\tWidgetGroup wgroup = (WidgetGroup)GetWidgetGroup(mainWindow, 0);\n\t\twgroup.Add(widget);\n\n\n\t\tdataBook.PageAdded += new DataView.DataViewEventHandler(OnDataViewAdded);\n\t\tdataBook.Removed += new RemovedHandler(OnDataViewRemoved);\n\t\tdataBook.SwitchPage += new SwitchPageHandler(OnSwitchPage);\n\n\t\tloaded = true;\n\t\treturn true;\n\t}\n\n\tprivate void AddMenuItems(UIManager uim)\n\t{\n\t\tActionEntry[] actionEntries = new ActionEntry[] {\n\t\t\t\t\t\t\t\t\t\t  new ActionEntry (\"BitwiseOperationsAction\", Stock.Execute, Catalog.GetString(\"_Bitwise Operations\"), \"<control>B\", null,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   new EventHandler(OnBitwiseOperationsActivated)),\n\t\t\t\t\t\t\t\t\t\t  new ActionEntry (\"PerformBitwiseOperationAction\", Stock.Execute, Catalog.GetString(\"Perform Operation\"), \"<control><shift>B\", null,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   new EventHandler(OnPerformBitwiseOperation)),\n\t\t\t\t\t\t\t\t\t  };\n\n\t\tActionGroup group = new ActionGroup (\"BitwiseOperationsActions\");\n\t\tgroup.Add (actionEntries);\n\n\t\tuim.InsertActionGroup(group, 0);\n\t\tuim.AddUiFromString(uiXml);\n\n\t\tperformAction = (Gtk.Action)uim.GetAction(\"/DefaultAreaPopup/ExtraAreaPopupItems/PerformBitwiseOperation\");\n\n\t\tuim.EnsureUpdate();\n\n\t}\n\n\tvoid OnDataViewAdded(DataView dv)\n\t{\n\t\tdv.Buffer.Changed += new ByteBuffer.ChangedHandler(OnBufferContentsChanged);\n\t\tdv.BufferChanged += new DataView.DataViewEventHandler(OnBufferChanged);\n\t\tdv.CursorChanged += new DataView.DataViewEventHandler(OnCursorChanged);\n\t\tdv.SelectionChanged += new DataView.DataViewEventHandler(OnSelectionChanged);\n\t}\n\n\tvoid OnDataViewRemoved(object o, RemovedArgs args)\n\t{\n\t\tDataView dv = ((DataViewDisplay)args.Widget).View;\n\t\tdv.Buffer.Changed -= new ByteBuffer.ChangedHandler(OnBufferContentsChanged);\n\t\tdv.BufferChanged -= new DataView.DataViewEventHandler(OnBufferChanged);\n\t\tdv.CursorChanged -= new DataView.DataViewEventHandler(OnCursorChanged);\n\t\tdv.SelectionChanged -= new DataView.DataViewEventHandler(OnSelectionChanged);\n\t}\n\n\tvoid OnBufferChanged(DataView dv)\n\t{\n\t\tUpdateBitwiseOperationsWidget(dv);\n\t}\n\n\tvoid OnBufferContentsChanged(ByteBuffer bb)\n\t{\n\t\tGtk.Application.Invoke(delegate {\n\t\t\tDataView dv = null;\n\n\t\t\t// find DataView that owns bb\n\t\t\tforeach (DataViewDisplay dvtemp in dataBook.Children) {\n\t\t\t\tif (dvtemp.View.Buffer == bb) {\n\t\t\t\t\tdv = dvtemp.View;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tUpdateBitwiseOperationsWidget(dv);\n\t\t});\n\t}\n\n\tvoid OnSwitchPage(object o, SwitchPageArgs args)\n\t{\n\t\tDataView dv = ((DataViewDisplay)dataBook.GetNthPage((int)args.PageNum)).View;\n\n\t\tUpdateBitwiseOperationsWidget(dv);\n\t}\n\n\tvoid OnCursorChanged(DataView dv)\n\t{\n\t\tUpdateBitwiseOperationsWidget(dv);\n\t}\n\n\tvoid OnSelectionChanged(DataView dv)\n\t{\n\t\tUpdateBitwiseOperationsWidget(dv);\n\t}\n\n\tvoid UpdateBitwiseOperationsWidget(DataView dv)\n\t{\n\t\tif (dataBook.NPages == 0)\n\t\t\treturn;\n\n\t\tDataView curdv = ((DataViewDisplay)dataBook.CurrentPageWidget).View;\n\t\tif (curdv != dv)\n\t\t\treturn;\n\n\t\twidget.Update(dv);\n\t}\n\n\t///<summary>Handle the Tools -> Bitwise Operations command</summary>\n\tpublic void OnBitwiseOperationsActivated(object o, EventArgs args)\n\t{\n\t\twidget.Show();\n\t}\n\n\tpublic void OnPerformBitwiseOperation(object o, EventArgs args)\n\t{\n\t\twidget.PerformOperation();\n\t}\n}\n\n///<summary>\n/// A widget for bitwise operations\n///</summary>\npublic class BitwiseOperationsWidget : Gtk.HBox\n{\n\t[Gtk.Builder.Object] Gtk.HBox BitwiseOperationsHBox;\n\t[Gtk.Builder.Object] Gtk.Label SourceLabel;\n\t[Gtk.Builder.Object] Gtk.EventBox SourceLabelEB;\n\t[Gtk.Builder.Object] Gtk.Button DoOperationButton;\n\t[Gtk.Builder.Object] Gtk.ComboBox OperationComboBox;\n\t[Gtk.Builder.Object] Gtk.ComboBox OperandAsComboBox;\n\t[Gtk.Builder.Object] Gtk.Entry OperandEntry;\n\t[Gtk.Builder.Object] Gtk.Button CloseButton;\n\n\n\tDataBook dataBook;\n\tint numberBase;\n\tGtk.Action performAction;\n\n\tenum OperandAsComboIndex { Hexadecimal, Decimal, Octal, Binary, Text }\n\tpublic enum OperationType { And, Or, Xor, Not }\n\n\t///<summary>\n\t/// The number base to use for displaying the source range\n\t///</summary>\n\tpublic int SourceLabelNumberBase {\n\t\tset {\n\t\t\tnumberBase = value;\n\n\t\t\tif (dataBook.NPages > 0) {\n\t\t\t\tDataView curdv = ((DataViewDisplay)dataBook.CurrentPageWidget).View;\n\n\t\t\t\tUpdate(curdv);\n\t\t\t}\n\t\t}\n\n\t\tget {\n\t\t\treturn numberBase;\n\t\t}\n\t}\n\n\tpublic BitwiseOperationsWidget(DataBook db, Gtk.Action action)\n\t{\n\t\tdataBook = db;\n\t\tperformAction = action;\n\n\t\tGtk.Builder builder = new Gtk.Builder();\n\t\tbuilder.AddFromFile(FileResourcePath.GetDataPath(\"ui\", \"BitwiseOperationsPlugin.ui\"));\n\t\tbuilder.Autoconnect(this);\n\n\t\tOperationComboBox.Active = 0;\n\t\tOperandAsComboBox.Active = 0;\n\t\tnumberBase = 16;\n\n\t\t// set button sensitivity\n\t\tOnOperandEntryChanged(null, null);\n\n\t\tthis.Shown += OnWidgetShown;\n\n\t\tthis.Add(BitwiseOperationsHBox);\n\t\tthis.ShowAll();\n\t}\n\n\t///<summary>\n\t/// Whether a widget in the Widget has the focus\n\t///</summary>\n\tbool IsFocusInWidget()\n\t{\n\t\tforeach (Gtk.Widget child in  BitwiseOperationsHBox.Children) {\n\t\t\tWidget realChild = child;\n\n\t\t\tif (child.GetType() == typeof(Gtk.Alignment))\n\t\t\t\trealChild = (child as Gtk.Alignment).Child;\n\n\t\t\tif (realChild.HasFocus)\n\t\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tvoid OnOperandEntryChanged(object o, EventArgs args)\n\t{\n\t\tif (OperandEntry.Text.Length > 0) {\n\t\t\tDoOperationButton.Sensitive = true;\n\t\t\tperformAction.Sensitive = true;\n\t\t}\n\t\telse {\n\t\t\tDoOperationButton.Sensitive = false;\n\t\t\tperformAction.Sensitive = false;\n\t\t}\n\t}\n\n\tvoid OnOperandEntryActivated(object o, EventArgs args)\n\t{\n\t\tif (DoOperationButton.Sensitive == true)\n\t\t\tDoOperationButton.Click();\n\t}\n\n\tvoid OnOperationComboBoxChanged(object o, EventArgs args)\n\t{\n\t\tif ((OperationType)OperationComboBox.Active == OperationType.Not) {\n\t\t\tOperandEntry.Sensitive = false;\n\t\t\tOperandAsComboBox.Sensitive = false;\n\t\t\tDoOperationButton.Sensitive = true;\n\t\t\tperformAction.Sensitive = true;\n\t\t}\n\t\telse {\n\t\t\tOperandEntry.Sensitive = true;\n\t\t\tOperandAsComboBox.Sensitive = true;\n\t\t\tOnOperandEntryChanged(null, null);\n\t\t}\n\t}\n\n\n\t///<summary>\n\t/// Parse the operand according to the selected type\n\t///</summary>\n\tbyte[] ParseOperand()\n\t{\n\t\tbyte[] ba;\n\t\tstring str = OperandEntry.Text;\n\n\t\tswitch ((OperandAsComboIndex)OperandAsComboBox.Active) {\n\t\t\tcase OperandAsComboIndex.Hexadecimal:\n\t\t\t\tba = ByteArray.FromString(str, 16);\n\t\t\t\tbreak;\n\t\t\tcase OperandAsComboIndex.Decimal:\n\t\t\t\tba = ByteArray.FromString(str, 10);\n\t\t\t\tbreak;\n\t\t\tcase OperandAsComboIndex.Octal:\n\t\t\t\tba = ByteArray.FromString(str, 8);\n\t\t\t\tbreak;\n\t\t\tcase OperandAsComboIndex.Binary:\n\t\t\t\tba = ByteArray.FromString(str, 2);\n\t\t\t\tbreak;\n\t\t\tcase OperandAsComboIndex.Text:\n\t\t\t\tba = Encoding.ASCII.GetBytes(str);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tba = new byte[0];\n\t\t\t\tbreak;\n\t\t}\n\n\t\treturn ba;\n\t}\n\n\n\tvoid OnDoOperationClicked(object o, EventArgs args)\n\t{\n\t\tif (dataBook.NPages == 0)\n\t\t\treturn;\n\n\t\tDataView dv = ((DataViewDisplay)dataBook.CurrentPageWidget).View;\n\n\t\t// get the operands as a byte array\n\t\tbyte[] byteArray = null;\n\n\t\ttry {\n\t\t\tbyteArray = ParseOperand();\n\t\t}\n\t\tcatch (FormatException e) {\n\t\t\tErrorAlert ea = new ErrorAlert(Catalog.GetString(\"Error in Operand\"), e.Message, null);\n\t\t\tea.Run();\n\t\t\tea.Destroy();\n\t\t\treturn;\n\t\t}\n\n\t\t/// get the range to apply the operation to\n\t\tUtil.Range range = dv.Selection;\n\n\t\tif (range.IsEmpty()) {\n\t\t\tUtil.Range bbRange = dv.Buffer.Range;\n\n\t\t\trange.Start = dv.CursorOffset;\n\t\t\trange.End = range.Start + byteArray.Length - 1;\n\t\t\trange.Intersect(bbRange);\n\t\t}\n\n\t\t// don't allow buffer modification while the operation is perfoming\n\t\tdv.Buffer.ModifyAllowed = false;\n\t\tdv.Buffer.FileOperationsAllowed = false;\n\n\t\tBitwiseOperation bo = new BitwiseOperation(dv.Buffer, byteArray, range,\n\t\t\t\t\t\t\t  (OperationType)OperationComboBox.Active,\n\t\t\t\t\t\t\t  Services.UI.Progress.NewCallback(), BitwiseOperationAsyncCallback, true);\n\n\t\t// start operation thread\n\t\tThread boThread = new Thread(bo.OperationThread);\n\t\tboThread.IsBackground = true;\n\t\tboThread.Start();\n\t}\n\n\t///<summary>\n\t/// Called when an asynchronous operation finishes.\n\t///</summary>\n\tvoid BitwiseOperationAsyncCallback(IAsyncResult ar)\n\t{\n\t\tBitwiseOperation state = (BitwiseOperation)ar.AsyncState;\n\t\tThreadedAsyncOperation.OperationResult result = state.Result;\n\n\t\t// allow changes to the buffer\n\t\tstate.Buffer.ModifyAllowed = true;\n\t\tstate.Buffer.FileOperationsAllowed = true;\n\n\t\tswitch (result) {\n\t\t\tcase ThreadedAsyncOperation.OperationResult.Finished:\n\t\t\t\tbreak;\n\t\t\tcase ThreadedAsyncOperation.OperationResult.Cancelled:\n\t\t\t\tstate.Buffer.Undo();\n\t\t\t\tbreak;\n\t\t\tcase ThreadedAsyncOperation.OperationResult.CaughtException:\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\n\t\t}\n\t}\n\n\t///<summary>\n\t/// Update the source range label\n\t///</summary>\n\tpublic void Update(DataView dv)\n\t{\n\t\tif (dv == null)\n\t\t\treturn;\n\n\t\tstring str;\n\n\t\tif (dv.Selection.IsEmpty()) {\n\t\t\tstring off1 = BaseConverter.ConvertToString(dv.CursorOffset, numberBase, true, true, 1);\n\t\t\tstr = string.Format(\"({0},{1})\", off1, off1);\n\t\t}\n\t\telse {\n\t\t\tstring off1 = BaseConverter.ConvertToString(dv.Selection.Start, numberBase, true, true, 1);\n\t\t\tstring off2 = BaseConverter.ConvertToString(dv.Selection.End, numberBase, true, true, 1);\n\t\t\tstr = string.Format(\"({0},{1})\", off1, off2);\n\t\t}\n\n\t\tSourceLabel.Text = str;\n\t}\n\n\tpublic void PerformOperation()\n\t{\n\t\tDoOperationButton.Click();\n\t}\n\n\tvoid OnWidgetShown(object o, EventArgs args)\n\t{\n\t\tOperandEntry.GrabFocus();\n\t}\n\n\tprotected override bool OnKeyPressEvent(Gdk.EventKey e)\n\t{\n\t\tif (e.Key == Gdk.Key.Escape) {\n\t\t\tCloseButton.Click();\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t\treturn base.OnKeyPressEvent(e);\n\t}\n\n\t///<summary>\n\t/// Handle the button press events on the source range label (cycles number bases)\n\t///</summary>\n\tvoid OnSourceLabelButtonPress(object o, ButtonPressEventArgs args)\n\t{\n\t\tGdk.EventButton e = args.Event;\n\t\t// ignore double and triple-clicks\n\t\tif (e.Type != Gdk.EventType.ButtonPress)\n\t\t\treturn;\n\n\t\t// cycle 8, 10 and 16 number bases\n\t\tif (this.SourceLabelNumberBase == 8)\n\t\t\tthis.SourceLabelNumberBase = 10;\n\t\telse if (this.SourceLabelNumberBase == 10)\n\t\t\tthis.SourceLabelNumberBase = 16;\n\t\telse if (this.SourceLabelNumberBase == 16)\n\t\t\tthis.SourceLabelNumberBase = 8;\n\t}\n\n\tvoid OnCloseButtonClicked(object o, EventArgs args)\n\t{\n\t\t// give focus to active dataview if the widget has it\n\t\tif (dataBook.NPages > 0 && IsFocusInWidget()) {\n\t\t\tDataViewDisplay curdvd = (DataViewDisplay)dataBook.CurrentPageWidget;\n\t\t\tcurdvd.GrabKeyboardFocus();\n\t\t}\n\n\t\tthis.Hide();\n\t}\n}\n\n///<summary>\n/// Performs a bitwise operation using an asynchronous threaded model\n///</summary>\npublic class BitwiseOperation : ThreadedAsyncOperation\n{\n\tprotected ByteBuffer byteBuffer;\n\tbyte[] byteArray;\n\tUtil.Range range;\n\tlong currentOffset;\n\tBitwiseOperationsWidget.OperationType operationType;\n\n\tpublic ByteBuffer Buffer {\n\t\tget { return byteBuffer; }\n\t}\n\n\tpublic BitwiseOperation(ByteBuffer bb, byte[] ba, Util.Range range, BitwiseOperationsWidget.OperationType ot, ProgressCallback pc,\n\t\t\t\t\t\t\tAsyncCallback ac, bool glibIdle): base(pc, ac, glibIdle)\n\t{\n\t\tbyteBuffer = bb;\n\t\tbyteArray = ba;\n\t\tthis.range = range;\n\t\toperationType = ot;\n\t\tcurrentOffset = range.Start;\n\t}\n\n\tprotected override bool StartProgress()\n\t{\n\t\tprogressCallback(string.Format(\"Applying operation\"), ProgressAction.Message);\n\t\treturn progressCallback(((double)currentOffset - range.Start) / range.Size, ProgressAction.Show);\n\t}\n\n\tprotected override bool UpdateProgress()\n\t{\n\t\treturn progressCallback(((double)currentOffset - range.Start) / range.Size, ProgressAction.Update);\n\t}\n\n\tprotected override bool EndProgress()\n\t{\n\t\treturn progressCallback(((double)currentOffset - range.Start) / range.Size, ProgressAction.Destroy);\n\t}\n\n\tprotected override void DoOperation()\n\t{\n\t\tbyteBuffer.BeginActionChaining();\n\n\t\tif (range.IsEmpty())\n\t\t\treturn;\n\n\t\t// create the operand array\n\t\t// this is either the original byte array\n\t\t// or a new array containing multiple copies of the original\n\t\tbyte[] operandArray;\n\n\t\tif (byteArray.Length > 0) {\n\t\t\tlong numberOfRepetitions = range.Size / byteArray.Length;\n\n\t\t\t// too many repetitions... create new array\n\t\t\tif (numberOfRepetitions > 1024) {\n\t\t\t\tint len = ((4096 / byteArray.Length) + 1) * byteArray.Length;\n\t\t\t\toperandArray = new byte[len];\n\t\t\t\tFillWithPattern(operandArray, byteArray);\n\t\t\t}\n\t\t\telse // use old array\n\t\t\t\toperandArray = byteArray;\n\t\t}\n\t\telse { // we have no operand eg when the operation is a NOT\n\t\t\toperandArray = new byte[4096];\n\t\t}\n\n\t\t// the array to keep the results of the operation\n\t\tbyte[] resultArray = new byte[operandArray.Length];\n\n\t\tlong left = range.Size;\n\t\tcurrentOffset = range.Start;\n\n\t\twhile (left > 0 && !cancelled) {\n\t\t\tint min = (int)((left < resultArray.Length) ? left : resultArray.Length);\n\t\t\t// fill result array\n\t\t\t// ...more efficient way needed, perhaps implement bb.Read\n\t\t\tfor (int i = 0; i < min; i++)\n\t\t\t\tresultArray[i] = byteBuffer[currentOffset + i];\n\n\t\t\t// perform the operation on the data\n\t\t\tDoOperation(resultArray, operandArray, min);\n\n\t\t\tlock (byteBuffer.LockObj) {\n\t\t\t\tbyteBuffer.ModifyAllowed = true;\n\t\t\t\t// write the changed data back\n\t\t\t\tbyteBuffer.Replace(currentOffset, currentOffset + min - 1, resultArray, 0, min);\n\t\t\t\tbyteBuffer.ModifyAllowed = false;\n\t\t\t}\n\n\t\t\tcurrentOffset += min;\n\t\t\tleft -= min;\n\t\t}\n\t}\n\n\tprotected override void EndOperation()\n\t{\n\t\tbyteBuffer.EndActionChaining();\n\t}\n\n\t///<summary>\n\t/// Fill the dest array with the data found in the pattern array\n\t///</summary>\n\tvoid FillWithPattern(byte[] dest, byte[] pattern)\n\t{\n\t\tif (pattern.Length == 0)\n\t\t\treturn;\n\n\t\tint left = dest.Length;\n\t\tint offset = 0;\n\n\t\twhile (left > 0) {\n\t\t\tint min = left < pattern.Length ? left : pattern.Length;\n\n\t\t\tArray.Copy(pattern, 0, dest, offset, min);\n\n\t\t\toffset += min;\n\t\t\tleft -= min;\n\t\t}\n\n\t}\n\n\t///<summary>\n\t/// Perform the operation ba1[i] = ba1[i] op ba2[i]\n\t///</summary>\n\tvoid DoOperation(byte[] ba1, byte[] ba2, int length)\n\t{\n\t\tswitch (operationType) {\n\t\t\tcase BitwiseOperationsWidget.OperationType.And:\n\t\t\t\tfor (int i = 0; i < length; i++)\n\t\t\t\t\tba1[i] = (byte)(ba1[i] & ba2[i]);\n\t\t\t\tbreak;\n\t\t\tcase BitwiseOperationsWidget.OperationType.Or:\n\t\t\t\tfor (int i = 0; i < length; i++)\n\t\t\t\t\tba1[i] = (byte)(ba1[i] | ba2[i]);\n\t\t\t\tbreak;\n\t\t\tcase BitwiseOperationsWidget.OperationType.Xor:\n\t\t\t\tfor (int i = 0; i < length; i++)\n\t\t\t\t\tba1[i] = (byte)(ba1[i] ^ ba2[i]);\n\t\t\t\tbreak;\n\t\t\tcase BitwiseOperationsWidget.OperationType.Not:\n\t\t\t\tfor (int i = 0; i < length; i++)\n\t\t\t\t\tba1[i] = (byte)(~ba1[i]);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t}\n}\n\n} // namespace\n"
  },
  {
    "path": "src/gui/plugins/ConversionTablePlugin.cs",
    "content": "// created on 2/18/2005 at 3:24 PM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System;\nusing System.Text;\nusing Gtk;\nusing Bless.Util;\nusing Bless.Tools;\nusing Bless.Gui;\nusing Bless.Buffers;\nusing Bless.Plugins;\nusing Mono.Unix;\n\nnamespace Bless.Gui.Plugins {\n\npublic class ConversionTablePlugin : GuiPlugin\n{\n\tDataBook dataBook;\n\tConversionTable widget;\n\tWindow mainWindow;\n\tToggleAction conversionTableAction;\n\tUIManager uiManager;\n\n\tconst string uiXml =\n\t\t\"<menubar>\" +\n\t\t\"\t<menu action=\\\"Tools\\\">\" +\n\t\t\"\t\t<menuitem name=\\\"ConversionTable\\\" action=\\\"ConversionTableAction\\\" />\" +\n\t\t\"\t</menu>\" +\n\t\t\"</menubar>\";\n\n\tpublic ConversionTablePlugin(Window mw, UIManager uim)\n\t{\n\t\tmainWindow = mw;\n\t\tuiManager = uim;\n\n\t\tname = \"ConversionTable\";\n\t\tauthor = \"Alexandros Frantzis\";\n\t\tdescription = \"Convert\";\n\t}\n\n\tpublic override bool Load()\n\t{\n\t\tdataBook = (DataBook)GetDataBook(mainWindow);\n\n\t\twidget = new ConversionTable(dataBook);\n\n\t\tWidgetGroup wg1 = (WidgetGroup)GetWidgetGroup(mainWindow, 1);\n\t\twg1.Add(widget);\n\n\t\tAddMenuItems(uiManager);\n\n\n\n\t\tPreferences.Proxy.Subscribe(\"Tools.ConversionTable.Show\", \"ct1\", new PreferencesChangedHandler(OnPreferencesChanged));\n\n\t\tloaded = true;\n\t\treturn true;\n\t}\n\n\n\n\tprivate void AddMenuItems(UIManager uim)\n\t{\n\t\tToggleActionEntry[] toggleActionEntries = new ToggleActionEntry[] {\n\t\t\t\t\tnew ToggleActionEntry (\"ConversionTableAction\", null, Catalog.GetString(\"Conversion Table\"), null, null,\n\t\t\t\t\t\t\t\t\t\t   new EventHandler(OnViewConversionTableToggled), false),\n\t\t\t\t};\n\n\t\tActionGroup group = new ActionGroup (\"ConversionTableActions\");\n\t\tgroup.Add (toggleActionEntries);\n\n\t\tuim.InsertActionGroup(group, 0);\n\t\tuim.AddUiFromString(uiXml);\n\t\tconversionTableAction = (ToggleAction)uim.GetAction(\"/menubar/Tools/ConversionTable\");\n\n\t\tuim.EnsureUpdate();\n\t}\n\n\t///<summary>Handle the View->Conversion Table command</summary>\n\tpublic void OnViewConversionTableToggled(object o, EventArgs args)\n\t{\n\t\tPreferences.Proxy.Change(\"Tools.ConversionTable.Show\", conversionTableAction.Active.ToString(), \"ct1\");\n\t}\n\n\n\tvoid OnPreferencesChanged(Preferences prefs)\n\t{\n\t\tif (prefs[\"Tools.ConversionTable.Show\"] == \"True\")\n\t\t\tconversionTableAction.Active = true;\n\t\telse\n\t\t\tconversionTableAction.Active = false;\n\t}\n}\n\n\n///<summary> A widget to convert the data at the current offset to various types</summary>\npublic class ConversionTable: Gtk.HBox\n{\n\n\t[Gtk.Builder.Object] Gtk.Table ConversionTableWidget;\n\n\t[Gtk.Builder.Object] Gtk.Entry Signed8bitEntry;\n\t[Gtk.Builder.Object] Gtk.Entry Unsigned8bitEntry;\n\t[Gtk.Builder.Object] Gtk.Entry Signed16bitEntry;\n\t[Gtk.Builder.Object] Gtk.Entry Unsigned16bitEntry;\n\t[Gtk.Builder.Object] Gtk.Entry Signed32bitEntry;\n\t[Gtk.Builder.Object] Gtk.Entry Unsigned32bitEntry;\n\t[Gtk.Builder.Object] Gtk.Entry Signed64bitEntry;\n\t[Gtk.Builder.Object] Gtk.Entry Unsigned64bitEntry;\n\t[Gtk.Builder.Object] Gtk.Entry Float32bitEntry;\n\t[Gtk.Builder.Object] Gtk.Entry Float64bitEntry;\n\t[Gtk.Builder.Object] Gtk.Entry HexadecimalEntry;\n\t[Gtk.Builder.Object] Gtk.Entry DecimalEntry;\n\t[Gtk.Builder.Object] Gtk.Entry OctalEntry;\n\t[Gtk.Builder.Object] Gtk.Entry BinaryEntry;\n\t[Gtk.Builder.Object] Gtk.Entry AsciiEntry;\n\n\t[Gtk.Builder.Object] Gtk.CheckButton LittleEndianCheckButton;\n\t[Gtk.Builder.Object] Gtk.CheckButton UnsignedAsHexCheckButton;\n\n\tDataBook dataBook;\n\n\tbool littleEndian;\n\tbool unsignedAsHex;\n\n\tpublic ConversionTable(DataBook db)\n\t{\n\t\tGtk.Builder builder = new Gtk.Builder();\n\t\tbuilder.AddFromFile(FileResourcePath.GetDataPath(\"ui\", \"ConversionTablePlugin.ui\"));\n\t\tbuilder.Autoconnect(this);\n\n\t\tlittleEndian = true;\n\t\tunsignedAsHex = false;\n\t\tdataBook = db;\n\n\t\tforeach(DataViewDisplay dvd in dataBook.Children) {\n\t\t\tOnDataViewAdded(dvd.View);\n\t\t}\n\n\t\tdataBook.PageAdded += new DataView.DataViewEventHandler(OnDataViewAdded);\n\t\tdataBook.Removed += new RemovedHandler(OnDataViewRemoved);\n\t\tdataBook.SwitchPage += new SwitchPageHandler(OnSwitchPage);\n\n\t\tPreferences.Proxy.Subscribe(\"Tools.ConversionTable.Show\", \"ct2\", new PreferencesChangedHandler(OnPreferencesChanged));\n\n\t\tthis.Add(ConversionTableWidget);\n\t\tthis.ShowAll();\n\t}\n\n\tvoid OnDataViewAdded(DataView dv)\n\t{\n\t\tdv.Buffer.Changed += new ByteBuffer.ChangedHandler(OnBufferContentsChanged);\n\t\tdv.BufferChanged += new DataView.DataViewEventHandler(OnBufferChanged);\n\t\tdv.CursorChanged += new DataView.DataViewEventHandler(OnCursorChanged);\n\t}\n\n\tvoid OnDataViewRemoved(object o, RemovedArgs args)\n\t{\n\t\tDataView dv = ((DataViewDisplay)args.Widget).View;\n\t\tdv.Buffer.Changed -= new ByteBuffer.ChangedHandler(OnBufferContentsChanged);\n\t\tdv.BufferChanged -= new DataView.DataViewEventHandler(OnBufferChanged);\n\t\tdv.CursorChanged -= new DataView.DataViewEventHandler(OnCursorChanged);\n\n\t\tUpdate();\n\t}\n\n\tvoid OnBufferChanged(DataView dv)\n\t{\n\t\t// if changed dataview is not the current one just ignore\n\t\tDataViewDisplay dvd = (DataViewDisplay)dataBook.CurrentPageWidget;\n\t\tif (dvd == null || dvd.View != dv)\n\t\t\treturn;\n\n\t\tUpdate();\n\t}\n\n\tvoid OnBufferContentsChanged(ByteBuffer bb)\n\t{\n\t\tGtk.Application.Invoke(delegate {\n\t\t\tDataView dv = null;\n\n\t\t\t// find DataView that owns bb\n\t\t\tforeach (DataViewDisplay dvtemp in dataBook.Children) {\n\t\t\t\tif (dvtemp.View.Buffer == bb) {\n\t\t\t\t\tdv = dvtemp.View;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tDataViewDisplay dvd = (DataViewDisplay)dataBook.CurrentPageWidget;\n\t\t\tif (dvd == null || dvd.View != dv)\n\t\t\t\treturn;\n\n\t\t\tUpdate();\n\t\t});\n\t}\n\n\tvoid OnSwitchPage(object o, SwitchPageArgs args)\n\t{\n\t\tUpdate();\n\t}\n\n\tvoid OnCursorChanged(DataView dv)\n\t{\n\t\tDataView dvcur = ((DataViewDisplay)dataBook.CurrentPageWidget).View;\n\t\tif (dvcur != dv)\n\t\t\treturn;\n\n\t\tUpdate();\n\t}\n\n\t// redefine Hide() method\n\t// to properly handle hiding\n\tprotected override void  OnHidden()\n\t{\n\t\t// if the focus is in the table\n\t\t// give it to the active dataview\n\t\tif (IsFocusInTable()) {\n\t\t\tDataViewDisplay dvd = (DataViewDisplay)dataBook.CurrentPageWidget;\n\t\t\tif (dvd != null)\n\t\t\t\tdvd.GrabKeyboardFocus();\n\t\t}\n\n\t\tPreferences.Proxy.Change(\"Tools.ConversionTable.Show\", \"False\", \"ct2\");\n\t\tbase.OnHidden();\n\t}\n\n\tprotected override void OnShown()\n\t{\n\t\tPreferences.Proxy.Change(\"Tools.ConversionTable.Show\", \"True\", \"ct2\");\n\t\tbase.OnShown();\n\n\t\tUpdate();\n\t}\n\n\n\t// whether a widget in the table has the focus\n\tbool IsFocusInTable()\n\t{\n\t\tforeach (Gtk.Widget child in  ConversionTableWidget.Children) {\n\t\t\tWidget realChild = child;\n\n\t\t\tif (child.GetType() == typeof(Gtk.Alignment))\n\t\t\t\trealChild = (child as Gtk.Alignment).Child;\n\n\t\t\tif (realChild.HasFocus)\n\t\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tvoid OnLittleEndianToggled(object o, EventArgs args)\n\t{\n\t\tlittleEndian = LittleEndianCheckButton.Active;\n\n\t\tPreferences.Proxy.Change(\"Tools.ConversionTable.LEDecoding\", littleEndian.ToString(), \"ct2\");\n\n\t\tUpdate();\n\t}\n\n\tvoid OnUnsignedAsHexToggled(object o, EventArgs args)\n\t{\n\t\tunsignedAsHex = UnsignedAsHexCheckButton.Active;\n\n\t\tPreferences.Proxy.Change(\"Tools.ConversionTable.UnsignedAsHex\", unsignedAsHex.ToString(), \"ct2\");\n\n\t\tUpdate();\n\t}\n\n\tvoid OnPreferencesChanged(Preferences prefs)\n\t{\n\t\tif (prefs[\"Tools.ConversionTable.LEDecoding\"] == \"True\")\n\t\t\tLittleEndianCheckButton.Active = true;\n\t\telse\n\t\t\tLittleEndianCheckButton.Active = false;\n\n\t\tif (prefs[\"Tools.ConversionTable.UnsignedAsHex\"] == \"True\")\n\t\t\tUnsignedAsHexCheckButton.Active = true;\n\t\telse\n\t\t\tUnsignedAsHexCheckButton.Active = false;\n\n\t\tif (prefs[\"Tools.ConversionTable.Show\"] == \"True\")\n\t\t\tthis.Visible = true;\n\t\telse\n\t\t\tthis.Visible = false;\n\t}\n\n\tvoid OnCloseButtonClicked(object o, EventArgs args)\n\t{\n\t\tPreferences.Instance[\"Tools.ConversionTable.Show\"] = \"False\";\n\t}\n\n\tvoid Clear8bit()\n\t{\n\t\tSigned8bitEntry.Text = \"---\";\n\t\tUnsigned8bitEntry.Text = \"---\";\n\t}\n\n\tvoid Clear16bit()\n\t{\n\t\tSigned16bitEntry.Text = \"---\";\n\t\tUnsigned16bitEntry.Text = \"---\";\n\t}\n\n\tvoid Clear32bit()\n\t{\n\t\tSigned32bitEntry.Text = \"---\";\n\t\tUnsigned32bitEntry.Text = \"---\";\n\t}\n\n\tvoid Clear64bit()\n\t{\n\t\tSigned64bitEntry.Text = \"---\";\n\t\tUnsigned64bitEntry.Text = \"---\";\n\t}\n\n\tvoid ClearFloat()\n\t{\n\t\tFloat32bitEntry.Text = \"---\";\n\t\tFloat64bitEntry.Text = \"---\";\n\t}\n\n\tvoid ClearBases()\n\t{\n\t\tHexadecimalEntry.Text = \"---\";\n\t\tDecimalEntry.Text = \"---\";\n\t\tOctalEntry.Text = \"---\";\n\t\tBinaryEntry.Text = \"---\";\n\t\tAsciiEntry.Text = \"---\";\n\t}\n\n\t///<summary>Update the 8bit entries</summary>\n\tvoid Update8bit(DataView dv)\n\t{\n\t\tlong offset = dv.CursorOffset;\n\n\t\t// make sure offset is valid\n\t\tif (offset < dv.Buffer.Size && offset >= 0) {\n\t\t\tbyte uval = dv.Buffer[offset];\n\t\t\tsbyte val = (sbyte)uval;\n\n\t\t\t// set signed\n\t\t\tSigned8bitEntry.Text = val.ToString();\n\n\t\t\t// set unsigned\n\t\t\tif (unsignedAsHex)\n\t\t\t\tUnsigned8bitEntry.Text = string.Format(\"0x{0:x}\", uval);\n\t\t\telse\n\t\t\t\tUnsigned8bitEntry.Text = uval.ToString();\n\t\t}\n\t\telse {\n\t\t\tClear8bit();\n\t\t}\n\t}\n\n\t///<summary>Update the 16bit entries</summary>\n\tvoid Update16bit(DataView dv)\n\t{\n\t\tlong offset = dv.CursorOffset;\n\n\t\t// make sure offset is valid\n\t\tif (offset < dv.Buffer.Size - 1 && offset >= 0) {\n\t\t\tshort val = 0;\n\n\t\t\t// create value according to endianess\n\t\t\tif (littleEndian) {\n\t\t\t\tval += (short)(dv.Buffer[offset+1] << 8);\n\t\t\t\tval += (short)dv.Buffer[offset];\n\t\t\t}\n\t\t\telse {\n\t\t\t\tval += (short)(dv.Buffer[offset] << 8);\n\t\t\t\tval += (short)dv.Buffer[offset+1];\n\t\t\t}\n\n\t\t\tushort uval = (ushort)val;\n\n\t\t\t// set signed\n\t\t\tSigned16bitEntry.Text = val.ToString();\n\n\t\t\t// set unsigned\n\t\t\tif (unsignedAsHex)\n\t\t\t\tUnsigned16bitEntry.Text = string.Format(\"0x{0:x}\", uval);\n\t\t\telse\n\t\t\t\tUnsigned16bitEntry.Text = uval.ToString();\n\t\t}\n\t\telse {\n\t\t\tClear16bit();\n\t\t}\n\t}\n\n\t///<summary>Update the 32bit entries</summary>\n\tvoid Update32bit(DataView dv)\n\t{\n\t\tlong offset = dv.CursorOffset;\n\n\t\t// make sure offset is valid\n\t\tif (offset < dv.Buffer.Size - 3 && offset >= 0) {\n\t\t\tint val = 0;\n\n\t\t\t// create value according to endianess\n\t\t\tif (littleEndian) {\n\t\t\t\tval += dv.Buffer[offset+3] << 24;\n\t\t\t\tval += dv.Buffer[offset+2] << 16;\n\t\t\t\tval += dv.Buffer[offset+1] << 8;\n\t\t\t\tval += dv.Buffer[offset];\n\t\t\t}\n\t\t\telse {\n\t\t\t\tval += dv.Buffer[offset] << 24;\n\t\t\t\tval += dv.Buffer[offset+1] << 16;\n\t\t\t\tval += dv.Buffer[offset+2] << 8;\n\t\t\t\tval += dv.Buffer[offset+3];\n\t\t\t}\n\n\t\t\tuint uval = (uint)val;\n\n\t\t\t// set signed\n\t\t\tSigned32bitEntry.Text = val.ToString();\n\n\t\t\t// set unsigned\n\t\t\tif (unsignedAsHex)\n\t\t\t\tUnsigned32bitEntry.Text = string.Format(\"0x{0:x}\", uval);\n\t\t\telse\n\t\t\t\tUnsigned32bitEntry.Text = uval.ToString();\n\t\t}\n\t\telse {\n\t\t\tClear32bit();\n\t\t}\n\t}\n\n\t///<summary>Update the 64bit entries</summary>\n\tvoid Update64bit(DataView dv)\n\t{\n\t\tlong offset = dv.CursorOffset;\n\n\t\t// make sure offset is valid\n\t\tif (offset < dv.Buffer.Size - 7 && offset >= 0) {\n\t\t\tlong val = 0;\n\n\t\t\t// create buffer for raw bytes\n\t\t\tbyte[] ba = new byte[8];\n\n\t\t\t// fill byte[] according to endianess\n\t\t\tif (littleEndian)\n\t\t\t\tfor (int i = 0; i < 8; i++)\n\t\t\t\t\tba[i] = dv.Buffer[offset+i];\n\t\t\telse\n\t\t\t\tfor (int i = 0; i < 8; i++)\n\t\t\t\t\tba[7-i] = dv.Buffer[offset+i];\n\n\t\t\t// set signed\n\t\t\tval = BitConverter.ToInt64(ba);\n\t\t\tSigned64bitEntry.Text = val.ToString();\n\n\t\t\t// set unsigned\n\t\t\tulong uval = (ulong)val;\n\t\t\tif (unsignedAsHex)\n\t\t\t\tUnsigned64bitEntry.Text = string.Format(\"0x{0:x}\", uval);\n\t\t\telse\n\t\t\t\tUnsigned64bitEntry.Text = uval.ToString();\n\t\t}\n\t\telse {\n\t\t\tClear64bit();\n\t\t}\n\t}\n\n\t///<summary>Update the floating point entries</summary>\n\tvoid UpdateFloat(DataView dv)\n\t{\n\t\tlong offset = dv.CursorOffset;\n\n\t\t// make sure offset is valid for 32 bit float (and 64 bit)\n\t\tif (offset < dv.Buffer.Size - 3 && offset >= 0) {\n\t\t\t// create byte[] with float bytes\n\t\t\tbyte[] ba = new byte[8];\n\n\t\t\t// fill byte[] according to endianess\n\t\t\tif (littleEndian)\n\t\t\t\tfor (int i = 0; i < 4; i++)\n\t\t\t\t\tba[i] = dv.Buffer[offset+i];\n\t\t\telse\n\t\t\t\tfor (int i = 0; i < 4; i++)\n\t\t\t\t\tba[3-i] = dv.Buffer[offset+i];\n\n\t\t\t// set float 32bit\n\t\t\tfloat f = BitConverter.ToSingle(ba, 0);\n\t\t\tFloat32bitEntry.Text = f.ToString();\n\n\t\t\t// make sure offset is valid for 64 bit float\n\t\t\tif (offset < dv.Buffer.Size - 7) {\n\t\t\t\t// fill byte[] according to endianess\n\t\t\t\tif (littleEndian)\n\t\t\t\t\tfor (int i = 4; i < 8; i++)\n\t\t\t\t\t\tba[i] = dv.Buffer[offset+i];\n\t\t\t\telse\n\t\t\t\t\tfor (int i = 0; i < 8; i++)\n\t\t\t\t\t\tba[7-i] = dv.Buffer[offset+i];\n\n\t\t\t\t// set float 64bit\n\t\t\t\tdouble d = BitConverter.ToDouble(ba, 0);\n\t\t\t\tFloat64bitEntry.Text = d.ToString();\n\t\t\t}\n\t\t\telse\n\t\t\t\tFloat64bitEntry.Text = \"---\";\n\t\t}\n\t\telse {\n\t\t\tClearFloat();\n\t\t}\n\n\t}\n\n\t///<summary>Update the number base entries</summary>\n\tvoid UpdateBases(DataView dv)\n\t{\n\t\tlong offset = dv.CursorOffset;\n\t\tlong size;\n\n\t\tif (offset < 0 || offset >= dv.Buffer.Size)\n\t\t\tsize = 0;\n\t\telse {\n\t\t\tsize = dv.Buffer.Size - offset;\n\t\t\tsize = size < 4 ? size : 4;\n\t\t}\n\n\t\tbyte[] ba = new byte[(int)size];\n\t\tfor (int i = 0; i < size; i++)\n\t\t\tba[i] = dv.Buffer[offset+i];\n\n\t\t// make sure offset is valid\n\t\tif (size > 0) {\n\t\t\tHexadecimalEntry.Text = ByteArray.ToString(ba, 16);\n\t\t\tDecimalEntry.Text = ByteArray.ToString(ba, 10);\n\t\t\tOctalEntry.Text = ByteArray.ToString(ba, 8);\n\t\t\tBinaryEntry.Text = ByteArray.ToString(ba, 2);\n\t\t\tAsciiEntry.Text = Encoding.ASCII.GetString(ba);\n\t\t}\n\t\telse {\n\t\t\tClearBases();\n\t\t}\n\t}\n\n\t///<summary>Update all conversion entries</summary>\n\tpublic void Update()\n\t{\n\t\tif (!this.Visible)\n\t\t\treturn;\n\n\t\tDataViewDisplay dvd = (DataViewDisplay)dataBook.CurrentPageWidget;\n\t\tif (dvd == null) {\n\t\t\tClear();\n\t\t\treturn;\n\t\t}\n\n\t\tDataView dv = dvd.View;\n\n\n\t\tUpdate8bit(dv);\n\t\tUpdate16bit(dv);\n\t\tUpdate32bit(dv);\n\t\tUpdate64bit(dv);\n\t\tUpdateFloat(dv);\n\t\tUpdateBases(dv);\n\t}\n\n\t///<summary>Clear all conversion entries</summary>\n\tpublic void Clear()\n\t{\n\t\tif (!this.Visible)\n\t\t\treturn;\n\n\t\tClear8bit();\n\t\tClear16bit();\n\t\tClear32bit();\n\t\tClear64bit();\n\t\tClearFloat();\n\t\tClearBases();\n\t}\n\n}\n\n} // end namespace\n"
  },
  {
    "path": "src/gui/plugins/CopyOffsetPlugin.cs",
    "content": "/*\n *   Copyright (c) 2019, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System;\nusing Gtk;\nusing Bless.Plugins;\nusing Bless.Tools;\nusing Bless.Util;\nusing Mono.Unix;\n\nnamespace Bless.Gui.Plugins {\n\npublic class CopyOffsetPlugin : GuiPlugin\n{\n\tGtk.Action CopyOffsetAction;\n\n\tconst string uiXml =\n\t\t\"<menubar>\" +\n\t\t\"\t<menu action=\\\"Edit\\\">\" +\n\t\t\"\t\t<placeholder name=\\\"Extra\\\">\" +\n\t\t\"\t\t\t<menuitem name=\\\"CopyOffset\\\" action=\\\"CopyOffsetAction\\\" />\" +\n\t\t\"\t\t</placeholder>\" +\n\t\t\"\t</menu>\" +\n\t\t\"</menubar>\" +\n\t\t\"<popup name=\\\"DefaultAreaPopup\\\">\" +\n\t\t\"\t<placeholder name=\\\"ExtraAreaPopupItems\\\" >\" +\n\t\t\"\t\t<menuitem name=\\\"CopyOffset\\\" action=\\\"CopyOffsetAction\\\" />\" +\n\t\t\"\t</placeholder>\" +\n\t\t\"</popup>\";\n\n\tDataBook dataBook;\n\tWindow mainWindow;\n\tUIManager uiManager;\n\tIPluginPreferences pluginPreferences;\n\tint number_base;\n\n\tstatic TargetEntry[] clipboardTargets = new TargetEntry[] {\n\t\t\t\t\t\t\t\t\t\t\t\tnew TargetEntry(\"UTF8_STRING\", 0, 0)\n\t\t\t\t\t\t\t\t\t\t\t};\n\tGtk.Clipboard clipboard;\n\n\tlong saved_offset;\n\tBless.Util.Range saved_selection;\n\n\tpublic CopyOffsetPlugin(Window mw, UIManager uim)\n\t{\n\t\tmainWindow = mw;\n\t\tuiManager = uim;\n\t\tpluginPreferences = new CopyOffsetPreferences();\n\t\tnumber_base = 10;\n\t\tsaved_offset = 0;\n\t\tsaved_selection = new Bless.Util.Range();\n\n\t\tname = \"CopyOffset\";\n\t\tauthor = \"Alexandros Frantzis\";\n\t\tdescription = \"Adds to copy the current offset (or range)\";\n\t\tloadAfter.Add(\"EditOperations\");\n\t}\n\n\tpublic override bool Load()\n\t{\n\t\tclipboard = Gtk.Clipboard.Get(Gdk.Atom.Intern(\"CLIPBOARD\", true));\n\t\tdataBook = (DataBook)GetDataBook(mainWindow);\n\n\t\tPreferences.Proxy.Subscribe(\"CopyOffset.NumberBase\", \"co\",\n\t\t\t\t\t\t\t\t\tnew PreferencesChangedHandler(OnPreferencesChanged));\n\n\t\tAddActions(uiManager);\n\n\t\tloaded = true;\n\t\treturn true;\n\t}\n\n\tprivate void AddActions(UIManager uim)\n\t{\n\t\tActionEntry[] actionEntries = new ActionEntry[] {\n\t\t\tnew ActionEntry(\"CopyOffsetAction\", Stock.Copy, Catalog.GetString(\"Copy Offset(s)\"),\n\t\t\t\t\t\t\t \"<Shift><Ctrl>C\", null, new EventHandler(OnCopyOffsetActivated))\n\t\t\t};\n\n\t\tActionGroup group = new ActionGroup(\"CopyOffsetActions\");\n\t\tgroup.Add (actionEntries);\n\n\t\tuim.InsertActionGroup(group, 0);\n\t\tuim.AddUiFromString(uiXml);\n\n\t\tuim.EnsureUpdate();\n\t}\n\n\tprivate void OnCopyOffsetActivated(object o, EventArgs args)\n\t{\n\t\tif (dataBook.NPages == 0)\n\t\t\treturn;\n\t\tDataView dv = ((DataViewDisplay)dataBook.CurrentPageWidget).View;\n\t\tsaved_offset = dv.CursorOffset;\n\t\tsaved_selection = dv.Selection;\n\n\t\tclipboard.SetWithData(clipboardTargets, new ClipboardGetFunc(OnClipboardGet),\n\t\t\t\t\t\t\t  new ClipboardClearFunc(OnClipboardClear));\n\t}\n\n\tprivate void OnClipboardGet(Clipboard cb, SelectionData sd, uint n)\n\t{\n\t\tif (saved_selection.IsEmpty()) {\n\t\t\tsd.Text = BaseConverter.ConvertToString(saved_offset, number_base, true, true, 1);\n\t\t} else {\n\t\t\tstring start = BaseConverter.ConvertToString(saved_selection.Start, number_base, true, true, 1);\n\t\t\tstring end = BaseConverter.ConvertToString(saved_selection.End, number_base, true, true, 1);\n\t\t\tsd.Text = string.Format(\"{0},{1}\", start, end);\n\t\t}\n\t}\n\n\tprivate void OnClipboardClear(Clipboard cb)\n\t{\n\t}\n\n\tpublic override IPluginPreferences PluginPreferences {\n\t\tget { return pluginPreferences; }\n\t}\n\n\tvoid OnPreferencesChanged(Preferences prefs)\n\t{\n\t\ttry {\n\t\t\tnumber_base = (int) BaseConverter.ConvertToNum(prefs[\"CopyOffset.NumberBase\"], 10);\n\t\t} catch {\n\t\t\tnumber_base = 10;\n\t\t}\n\n\t\tif (number_base != 2 && number_base != 8 && number_base != 10 && number_base != 16)\n\t\t\tnumber_base = 10;\n\t}\n}\n\nclass CopyOffsetPreferences : IPluginPreferences\n{\n\tCopyOffsetPreferencesWidget preferencesWidget;\n\n\tpublic Widget Widget {\n\t\tget {\n\t\t\tif (preferencesWidget == null)\n\t\t\t\tInitWidget();\n\t\t\treturn preferencesWidget;\n\t\t}\n\t}\n\n\tpublic void LoadPreferences()\n\t{\n\t\tif (preferencesWidget == null)\n\t\t\tInitWidget();\n\n\t\tstring base_str = Preferences.Instance[\"CopyOffset.NumberBase\"];\n\n\t\ttry {\n\t\t\tpreferencesWidget.ActiveBase = (int) BaseConverter.ConvertToNum(base_str, 10);\n\t\t} catch {\n\t\t\tpreferencesWidget.ActiveBase = 10;\n\t\t}\n\t}\n\n\tpublic void SavePreferences()\n\t{\n\t}\n\n\tvoid InitWidget()\n\t{\n\t\tpreferencesWidget = new CopyOffsetPreferencesWidget();\n\t\tpreferencesWidget.NumberBaseCombo.Changed += OnNumberBaseChanged;\n\t}\n\n\tvoid OnNumberBaseChanged(object o, EventArgs args)\n\t{\n\t\tPreferences.Instance[\"CopyOffset.NumberBase\"] =\n\t\t\tpreferencesWidget.NumberBaseCombo.ActiveText;\n\t}\n}\n\nclass CopyOffsetPreferencesWidget : Gtk.VBox\n{\n\tGtk.ComboBox numberBaseCombo;\n\n\tint BaseToActiveIndex(int number_base) {\n\t\tswitch (number_base) {\n\t\t\tcase 2: return 0;\n\t\t\tcase 8: return 1;\n\t\t\tcase 10: return 2;\n\t\t\tcase 16: return 3;\n\t\t\tdefault: throw new Exception();\n\t\t}\n\t}\n\n\tpublic Gtk.ComboBox NumberBaseCombo {\n\t\tget { return numberBaseCombo; }\n\t}\n\n\tpublic int ActiveBase\n\t{\n\t\tset {\n\t\t\tnumberBaseCombo.Active = BaseToActiveIndex(value);\n\t\t}\n\t}\n\n\tpublic CopyOffsetPreferencesWidget()\n\t{\n\t\t// Use a hbox inside an vbox to avoid expanding vertically.\n\t\tGtk.HBox hbox = new Gtk.HBox();\n\t\tGtk.Label label = new Gtk.Label(Catalog.GetString(\"Number base:\"));\n\t\tnumberBaseCombo = Gtk.ComboBox.NewText();\n\t\tnumberBaseCombo.AppendText(\"2\");\n\t\tnumberBaseCombo.AppendText(\"8\");\n\t\tnumberBaseCombo.AppendText(\"10\");\n\t\tnumberBaseCombo.AppendText(\"16\");\n\n\t\thbox.PackStart(label, false, false, 6);\n\t\thbox.PackStart(numberBaseCombo, false, false, 6);\n\n\t\tthis.PackStart(hbox, true, false, 6);\n\n\t\tthis.ShowAll();\n\t}\n}\n\n} //end namespace\n"
  },
  {
    "path": "src/gui/plugins/EditOperationsPlugin.cs",
    "content": "// created on 4/30/2006 at 12:59 PM\n/*\n *   Copyright (c) 2006, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System;\nusing System.IO;\nusing Gtk;\nusing Bless.Buffers;\nusing Bless.Gui;\nusing Bless.Plugins;\nusing Bless.Gui.Dialogs;\nusing Bless.Tools;\n\nnamespace Bless.Gui.Plugins {\n\npublic class EditOperationsPlugin : GuiPlugin\n{\n\tGtk.Action UndoAction;\n\tGtk.Action RedoAction;\n\tGtk.Action CutAction;\n\tGtk.Action CopyAction;\n\tGtk.Action PasteAction;\n\tGtk.Action DeleteAction;\n\n\tconst string uiXml =\n\t\t\"<menubar>\" +\n\t\t\"\t<menu action=\\\"Edit\\\">\" +\n\t\t\"\t\t<menuitem name=\\\"Undo\\\" action=\\\"UndoAction\\\" />\" +\n\t\t\"\t\t<menuitem name=\\\"Redo\\\" action=\\\"RedoAction\\\" />\" +\n\t\t\"\t\t<separator/>\" +\n\t\t\"\t\t<menuitem name=\\\"Cut\\\" action=\\\"CutAction\\\" />\" +\n\t\t\"\t\t<menuitem name=\\\"Copy\\\" action=\\\"CopyAction\\\" />\" +\n\t\t\"\t\t<menuitem name=\\\"Paste\\\" action=\\\"PasteAction\\\" />\" +\n\t\t\"\t\t<menuitem name=\\\"Delete\\\" action=\\\"DeleteAction\\\" />\" +\n\t\t\"\t\t<separator/>\" +\n\t\t\"\t\t<placeholder name=\\\"Extra\\\" />\" +\n\t\t\"\t\t<separator/>\" +\n\t\t\"\t\t<menuitem name=\\\"Preferences\\\" action=\\\"PreferencesAction\\\" />\" +\n\t\t\"\t</menu>\" +\n\t\t\"</menubar>\" +\n\t\t\"<toolbar>\" +\n\t\t\"\t<placeholder name=\\\"EditItems\\\">\" +\n\t\t\"\t\t<toolitem name=\\\"Undo\\\" action=\\\"UndoAction\\\"/>\" +\n\t\t\"\t\t<toolitem name=\\\"Redo\\\" action=\\\"RedoAction\\\"/>\" +\n\t\t\"\t\t<separator/>\" +\n\t\t\"\t\t<toolitem name=\\\"Cut\\\" action=\\\"CutAction\\\" />\" +\n\t\t\"\t\t<toolitem name=\\\"Copy\\\" action=\\\"CopyAction\\\" />\" +\n\t\t\"\t\t<toolitem name=\\\"Paste\\\" action=\\\"PasteAction\\\" />\" +\n\t\t\"\t</placeholder>\" +\n\t\t\"</toolbar>\" +\n\t\t\"<popup name=\\\"DefaultAreaPopup\\\">\" +\n\t\t\"\t<menuitem name=\\\"Cut\\\" action=\\\"CutAction\\\" />\" +\n\t\t\"\t<menuitem name=\\\"Copy\\\" action=\\\"CopyAction\\\" />\" +\n\t\t\"\t<menuitem name=\\\"Paste\\\" action=\\\"PasteAction\\\" />\" +\n\t\t\"\t<menuitem name=\\\"Delete\\\" action=\\\"DeleteAction\\\" />\" +\n\t\t\"\t<separator/>\" +\n\t\t\"\t<placeholder name=\\\"ExtraAreaPopupItems\\\" />\" +\n\t\t\"</popup>\";\n\n\tDataBook dataBook;\n\tWindow mainWindow;\n\tUIManager uiManager;\n\tActionGroup editActionGroup;\n\tint editAccelCount = 0;\n\n\tpublic EditOperationsPlugin(Window mw, UIManager uim)\n\t{\n\t\tmainWindow = mw;\n\t\tuiManager = uim;\n\n\t\tname = \"EditOperations\";\n\t\tauthor = \"Alexandros Frantzis\";\n\t\tdescription = \"Provides access to basic edit operations\";\n\t}\n\n\tpublic override bool Load()\n\t{\n\t\tdataBook = (DataBook)GetDataBook(mainWindow);\n\n\t\tAddActions(uiManager);\n\n\t\tdataBook.PageAdded += new DataView.DataViewEventHandler(OnDataViewAdded);\n\t\tdataBook.PageRemoved += new DataView.DataViewEventHandler(OnDataViewRemoved);\n\t\tdataBook.SwitchPage += new SwitchPageHandler(OnSwitchPage);\n\n\t\tloaded = true;\n\t\treturn true;\n\t}\n\n\n\tvoid OnDataViewAdded(DataView dv)\n\t{\n\t\tdv.Buffer.Changed += new ByteBuffer.ChangedHandler(OnBufferContentsChanged);\n\t\tdv.BufferChanged += new DataView.DataViewEventHandler(OnBufferChanged);\n\t\tdv.FocusChanged += new DataView.DataViewEventHandler(OnDataViewFocusChanged);\n\t}\n\n\tvoid OnDataViewRemoved(DataView dv)\n\t{\n\t\tdv.Buffer.Changed -= new ByteBuffer.ChangedHandler(OnBufferContentsChanged);\n\t\tdv.BufferChanged -= new DataView.DataViewEventHandler(OnBufferChanged);\n\t\tdv.FocusChanged -= new DataView.DataViewEventHandler(OnDataViewFocusChanged);\n\t\t// if there are no pages left update the menu\n\t\tif (dataBook.NPages == 0)\n\t\t\tUpdateActions(null);\n\t}\n\n\tvoid OnBufferChanged(DataView dv)\n\t{\n\t\tUpdateActions(dv);\n\t}\n\n\tvoid OnBufferContentsChanged(ByteBuffer bb)\n\t{\n\t\tGtk.Application.Invoke(delegate {\n\t\t\tDataView dv = null;\n\n\t\t\t// find DataView that owns bb\n\t\t\tforeach (DataViewDisplay dvtemp in dataBook.Children) {\n\t\t\t\tif (dvtemp.View.Buffer == bb) {\n\t\t\t\t\tdv = dvtemp.View;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tUpdateActions(dv);\n\t\t});\n\t}\n\n\tvoid OnSwitchPage(object o, SwitchPageArgs args)\n\t{\n\t\tDataView dv = ((DataViewDisplay)dataBook.GetNthPage((int)args.PageNum)).View;\n\n\t\tUpdateActions(dv);\n\t}\n\n\tvoid ConnectEditAccelerators(bool v)\n\t{\n\t\tif (editAccelCount == 0 && v == true) {\n\t\t\tforeach(Gtk.Action a in editActionGroup.ListActions())\n\t\t\ta.ConnectAccelerator();\n\t\t\teditAccelCount = 1;\n\t\t}\n\t\telse if (editAccelCount == 1 && v == false) {\n\t\t\tforeach(Gtk.Action a in editActionGroup.ListActions())\n\t\t\ta.DisconnectAccelerator();\n\t\t\teditAccelCount = 0;\n\t\t}\n\n\t}\n\n\tvoid OnDataViewFocusChanged(DataView dv)\n\t{\n\t\t// if a DataView gained the focus\n\t\t// enable Edit Menu Accelerators\n\t\tif (dv.Display.HasFocus) {\n\t\t\tConnectEditAccelerators(true);\n\n\t\t}\n\t\telse { // disable them, so that key combos in other\n\t\t\t// widgets behave correctly (eg Ctrl+C in Text Entries)\n\t\t\tConnectEditAccelerators(false);\n\t\t}\n\t}\n\n\tprivate void AddActions(UIManager uim)\n\t{\n\t\tActionEntry[] actionEntries = new ActionEntry[] {\n\t\t\t\t\t\t\t\t\t\t  new ActionEntry (\"CutAction\", Stock.Cut, null, \"<control>X\", null,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   new EventHandler(OnCutActivated)),\n\t\t\t\t\t\t\t\t\t\t  new ActionEntry (\"CopyAction\", Stock.Copy, null, \"<control>C\", \"Copy\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   new EventHandler(OnCopyActivated)),\n\t\t\t\t\t\t\t\t\t\t  new ActionEntry (\"PasteAction\", Stock.Paste, null, \"<control>V\", \"Paste\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   new EventHandler(OnPasteActivated)),\n\t\t\t\t\t\t\t\t\t\t  new ActionEntry (\"DeleteAction\", Stock.Delete, null, \"Delete\", \"Delete\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   new EventHandler(OnDeleteActivated))\n\t\t\t\t\t\t\t\t\t  };\n\t\tActionEntry[] miscActionEntries = new ActionEntry[] {\n\t\t\t\t\t\t\t\t\t\t\t  new ActionEntry (\"UndoAction\", Stock.Undo, null, \"<control>Z\", \"Undo\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t   new EventHandler(OnUndoActivated)),\n\t\t\t\t\t\t\t\t\t\t\t  new ActionEntry (\"RedoAction\", Stock.Redo, null, \"<shift><control>Z\", \"Redo\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t   new EventHandler(OnRedoActivated)),\n\t\t\t\t\t\t\t\t\t\t\t  new ActionEntry (\"PreferencesAction\", Stock.Preferences, null, null, \"Preferences\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t   new EventHandler(OnPreferencesActivated))\n\t\t\t\t\t\t\t\t\t\t  };\n\n\t\teditActionGroup = new ActionGroup(\"EditActions\");\n\t\teditActionGroup.Add (actionEntries);\n\t\tActionGroup miscActionGroup = new ActionGroup (\"MiscEditActions\");\n\t\tmiscActionGroup.Add (miscActionEntries);\n\n\t\tuim.InsertActionGroup(editActionGroup, 0);\n\t\tuim.InsertActionGroup(miscActionGroup, 0);\n\n\t\tuim.AddUiFromString(uiXml);\n\t\tUndoAction = (Gtk.Action)uim.GetAction(\"/menubar/Edit/Undo\");\n\t\tRedoAction = (Gtk.Action)uim.GetAction(\"/menubar/Edit/Redo\");\n\t\tCutAction = (Gtk.Action)uim.GetAction(\"/menubar/Edit/Cut\");\n\t\tCopyAction = (Gtk.Action)uim.GetAction(\"/menubar/Edit/Copy\");\n\t\tPasteAction = (Gtk.Action)uim.GetAction(\"/menubar/Edit/Paste\");\n\t\tDeleteAction = (Gtk.Action)uim.GetAction(\"/menubar/Edit/Delete\");\n\n\n\t\tforeach (Gtk.Action a in editActionGroup.ListActions()) {\n\t\t\t// for some reason the accelerators are connected twice\n\t\t\t// ... so disconnect them twice\n\t\t\tfor (int i = 0; i < 2; i++)\n\t\t\t\ta.DisconnectAccelerator();\n\t\t}\n\t\teditAccelCount = 0;\n\t\tuim.EnsureUpdate();\n\n\t}\n\t///<summary>Handle edit->undo command from menu</summary>\n\tpublic void OnUndoActivated(object o, EventArgs args)\n\t{\n\t\tif (dataBook.NPages == 0)\n\t\t\treturn;\n\t\tDataView dv = ((DataViewDisplay)dataBook.CurrentPageWidget).View;\n\t\tdv.Undo();\n\t}\n\n\t///<summary>Handle edit->redo command from menu</summary>\n\tpublic void OnRedoActivated(object o, EventArgs args)\n\t{\n\t\tif (dataBook.NPages == 0)\n\t\t\treturn;\n\t\tDataView dv = ((DataViewDisplay)dataBook.CurrentPageWidget).View;\n\t\tdv.Redo();\n\t}\n\n\t///<summary>Handle edit->cut command from menu</summary>\n\tpublic void OnCutActivated(object o, EventArgs args)\n\t{\n\t\tif (dataBook.NPages == 0)\n\t\t\treturn;\n\t\tDataView dv = ((DataViewDisplay)dataBook.CurrentPageWidget).View;\n\t\tdv.Cut();\n\t}\n\n\t///<summary>Handle edit->copy command from menu</summary>\n\tpublic void OnCopyActivated(object o, EventArgs args)\n\t{\n\t\tif (dataBook.NPages == 0)\n\t\t\treturn;\n\t\tDataView dv = ((DataViewDisplay)dataBook.CurrentPageWidget).View;\n\t\tdv.Copy();\n\t}\n\n\t///<summary>Handle edit->paste command from menu</summary>\n\tpublic void OnPasteActivated(object o, EventArgs args)\n\t{\n\t\tif (dataBook.NPages == 0)\n\t\t\treturn;\n\t\tDataView dv = ((DataViewDisplay)dataBook.CurrentPageWidget).View;\n\t\tdv.Paste();\n\t}\n\n\t///<summary>Handle edit->delete command from menu</summary>\n\tpublic void OnDeleteActivated(object o, EventArgs args)\n\t{\n\t\tif (dataBook.NPages == 0)\n\t\t\treturn;\n\t\tDataView dv = ((DataViewDisplay)dataBook.CurrentPageWidget).View;\n\t\tdv.Delete();\n\t}\n\n\t///<summary>Handle edit->Select Range command from menu</summary>\n\tpublic void OnSelectRange(object o, EventArgs args)\n\t{\n\t\tif (dataBook.NPages == 0)\n\t\t\treturn;\n\t\t//DataView dv=((DataViewDisplay)dataBook.CurrentPageWidget).View;\n\n\t\t//selectRangeWidget.Show();\n\t}\n\n\t///<summary>Handle edit->preferences command from menu</summary>\n\tpublic void OnPreferencesActivated(object o, EventArgs args)\n\t{\n\t\tPreferencesDialog pd = new PreferencesDialog(mainWindow);\n\t\tpd.Show();\n\t}\n\n\t///<summary>\n\t/// Updates various menu items according to the ModifyAllowed\n\t/// permission property of the active ByteBuffer\n\t///</summary>\n\tvoid UpdateActions(DataView dv)\n\t{\n\t\tif (dv == null) {\n\t\t\tCutAction.Sensitive = false;\n\t\t\tPasteAction.Sensitive = false;\n\t\t\tDeleteAction.Sensitive = false;\n\t\t\tUndoAction.Sensitive = false;\n\t\t\tRedoAction.Sensitive = false;\n\t\t\tCopyAction.Sensitive = false;\n\t\t\treturn;\n\t\t}\n\n\t\tDataView curdv = ((DataViewDisplay)dataBook.CurrentPageWidget).View;\n\n\t\tByteBuffer curbb = curdv.Buffer;\n\n\t\tByteBuffer bb = dv.Buffer;\n\n\t\t// if DataView is active\n\t\tif (curbb == bb) {\n\t\t\t// gray various menu items\n\t\t\t// if we are not allowed to modify the buffer\n\t\t\tif (!bb.ModifyAllowed) {\n\t\t\t\tCutAction.Sensitive = false;\n\t\t\t\tPasteAction.Sensitive = false;\n\t\t\t\tDeleteAction.Sensitive = false;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tCutAction.Sensitive = true;\n\t\t\t\tPasteAction.Sensitive = true;\n\t\t\t\tDeleteAction.Sensitive = true;\n\t\t\t}\n\n\t\t\t// gray Undo if there is no undo action\n\t\t\t// or we aren't allowed to modify the file\n\t\t\tif (bb.CanUndo && bb.ModifyAllowed) {\n\t\t\t\tUndoAction.Sensitive = true;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tUndoAction.Sensitive = false;\n\t\t\t}\n\n\t\t\t// gray Redo if there is no redo action\n\t\t\t// or we aren't allowed to modify the file\n\t\t\tif (bb.CanRedo && bb.ModifyAllowed) {\n\t\t\t\tRedoAction.Sensitive = true;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tRedoAction.Sensitive = false;\n\t\t\t}\n\n\t\t\t// gray various menu items\n\t\t\t// if we are not allowed to read from the buffer\n\t\t\tif (!bb.ReadAllowed) {\n\t\t\t\tCopyAction.Sensitive = false;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tCopyAction.Sensitive = true;\n\t\t\t}\n\t\t}\n\t}\n\n}\n\n} //end namespace\n"
  },
  {
    "path": "src/gui/plugins/FileExportPlugin.cs",
    "content": "// created on 12/4/2006 at 1:50 AM\n/*\n *   Copyright (c) 2006, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing Bless.Buffers;\nusing Bless.Gui;\nusing Bless.Plugins;\nusing Bless.Gui.Dialogs;\nusing Bless.Tools;\nusing System;\nusing System.IO;\nusing Gtk;\nusing Mono.Unix;\n\nnamespace Bless.Gui.Plugins {\n\npublic class FileExportPlugin : GuiPlugin\n{\n\tGtk.Action ExportAction;\n\n\tconst string uiXml =\n\t\t\"<menubar>\" +\n\t\t\"\t<menu action=\\\"File\\\">\" +\n\t\t\"\t\t<placeholder name=\\\"Extra\\\">\" +\n\t\t\"\t\t\t<menuitem name=\\\"Export\\\" action=\\\"ExportAction\\\"/>\" +\n\t\t\"\t\t</placeholder>\" +\n\t\t\"\t</menu>\" +\n\t\t\"</menubar>\";\n\n\tDataBook dataBook;\n\tWindow mainWindow;\n\tUIManager uiManager;\n\tExportDialog exportDialog;\n\n\tpublic FileExportPlugin(Window mw, UIManager uim)\n\t{\n\t\tmainWindow = mw;\n\t\tuiManager = uim;\n\n\t\tname = \"FileExport\";\n\t\tauthor = \"Alexandros Frantzis\";\n\t\tdescription = \"Export a file to various formats\";\n\t\tloadAfter.Add(\"FileOperations\");\n\t}\n\n\tpublic override bool Load()\n\t{\n\t\tdataBook = (DataBook) GetDataBook(mainWindow);\n\n\t\tAddMenuItems(uiManager);\n\n\t\tdataBook.PageRemoved += new DataView.DataViewEventHandler(OnDataViewRemoved);\n\t\tdataBook.SwitchPage += new SwitchPageHandler(OnSwitchPage);\n\n\t\texportDialog = new ExportDialog(dataBook, mainWindow);\n\n\t\tloaded = true;\n\t\treturn true;\n\t}\n\n\tvoid OnDataViewRemoved(DataView dv)\n\t{\n\t\t// if there are no pages left update the menu\n\t\tif (dataBook.NPages == 0)\n\t\t\tUpdateActions(null);\n\t}\n\n\tvoid OnSwitchPage(object o, SwitchPageArgs args)\n\t{\n\t\tDataView dv = ((DataViewDisplay)dataBook.GetNthPage((int)args.PageNum)).View;\n\n\t\tUpdateActions(dv);\n\t}\n\n\tprivate void AddMenuItems(UIManager uim)\n\t{\n\t\tActionEntry[] actionEntries = new ActionEntry[] {\n\t\t\t\t\t\t\t\t\t\t  new ActionEntry (\"ExportAction\", null, Catalog.GetString(\"_Export...\"), null, null,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   new EventHandler(OnExportActivated)),\n\t\t\t\t\t\t\t\t\t  };\n\n\t\tActionGroup group = new ActionGroup (\"ExportActions\");\n\t\tgroup.Add (actionEntries);\n\n\t\tuim.InsertActionGroup(group, 0);\n\t\tuim.AddUiFromString(uiXml);\n\n\t\tExportAction = uim.GetAction(\"/menubar/File/Extra/Export\");\n\n\t\tuim.EnsureUpdate();\n\n\t}\n\n\t///<summary>Handle file->export command from menu</summary>\n\tpublic void OnExportActivated(object o, EventArgs args)\n\t{\n\t\texportDialog.Show();\n\t}\n\n\tvoid UpdateActions(DataView dv)\n\t{\n\t\tif (dv == null)\n\t\t\tExportAction.Sensitive = false;\n\t\telse\n\t\t\tExportAction.Sensitive = true;\n\t}\n}\n\n\n\n} //end namespace\n"
  },
  {
    "path": "src/gui/plugins/FileOperationsPlugin.cs",
    "content": "// created on 4/29/2006 at 2:39 PM\n/*\n *   Copyright (c) 2006, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing Bless.Buffers;\nusing Bless.Gui;\nusing Bless.Plugins;\nusing Bless.Gui.Dialogs;\nusing Bless.Tools;\nusing System;\nusing System.IO;\nusing Gtk;\nusing Mono.Unix;\n\nnamespace Bless.Gui.Plugins {\n\npublic class FileOperationsPlugin : GuiPlugin\n{\n\tGtk.Action SaveAction;\n\tGtk.Action SaveAsAction;\n\tGtk.Action CloseAction;\n\tGtk.Action QuitAction;\n\tGtk.Action RevertAction;\n\n\tconst string uiXml =\n\t\t\"<menubar>\" +\n\t\t\"\t<menu action=\\\"File\\\">\" +\n\t\t\"\t\t<menuitem name=\\\"New\\\" action=\\\"NewAction\\\" />\" +\n\t\t\"\t\t<menuitem name=\\\"Open\\\" action=\\\"OpenAction\\\" />\" +\n\t\t\"\t\t<separator/>\" +\n\t\t\"\t\t<menuitem name=\\\"Save\\\" action=\\\"SaveAction\\\" />\" +\n\t\t\"\t\t<menuitem name=\\\"SaveAs\\\" action=\\\"SaveAsAction\\\" />\" +\n\t\t\"\t\t<menuitem name=\\\"Revert\\\" action=\\\"RevertAction\\\" />\" +\n\t\t\"\t\t<separator/>\" +\n\t\t\"\t\t<placeholder name=\\\"Extra\\\"/>\" +\n\t\t\"\t\t<separator/>\" +\n\t\t\"\t\t<placeholder name=\\\"HistoryItems\\\"/>\" +\n\t\t\"\t\t<separator/>\" +\n\t\t\"\t\t<menuitem name=\\\"Close\\\" action=\\\"CloseAction\\\" />\" +\n\t\t\"\t\t<menuitem name=\\\"Quit\\\" action=\\\"QuitAction\\\" />\" +\n\t\t\"\t</menu>\" +\n\t\t\"</menubar>\" +\n\t\t\"<toolbar>\" +\n\t\t\"\t<placeholder name=\\\"FileItems\\\">\" +\n\t\t\"\t\t<toolitem name=\\\"New\\\" action=\\\"NewAction\\\"/>\" +\n\t\t\"\t\t<toolitem name=\\\"Open\\\" action=\\\"OpenAction\\\"/>\" +\n\t\t\"\t\t<toolitem name=\\\"Save\\\" action=\\\"SaveAction\\\"/>\" +\n\t\t\"\t</placeholder>\" +\n\t\t\"</toolbar>\";\n\n\tDataBook dataBook;\n\tWindow mainWindow;\n\tUIManager uiManager;\n\n\tpublic FileOperationsPlugin(Window mw, UIManager uim)\n\t{\n\t\tmainWindow = mw;\n\t\tuiManager = uim;\n\n\t\tname = \"FileOperations\";\n\t\tauthor = \"Alexandros Frantzis\";\n\t\tdescription = \"Provides access to basic file operations\";\n\t}\n\n\tpublic override bool Load()\n\t{\n\t\tdataBook = (DataBook)GetDataBook(mainWindow);\n\n\t\tAddActions(uiManager);\n\n\t\tdataBook.PageAdded += new DataView.DataViewEventHandler(OnDataViewAdded);\n\t\tdataBook.PageRemoved += new DataView.DataViewEventHandler(OnDataViewRemoved);\n\t\tdataBook.SwitchPage += new SwitchPageHandler(OnSwitchPage);\n\n\t\tloaded = true;\n\t\treturn true;\n\t}\n\n\tvoid OnDataViewAdded(DataView dv)\n\t{\n\t\tdv.Buffer.PermissionsChanged += new ByteBuffer.ChangedHandler(OnBufferPermissionsChanged);\n\t\tdv.BufferChanged += new DataView.DataViewEventHandler(OnBufferChanged);\n\t}\n\n\tvoid OnDataViewRemoved(DataView dv)\n\t{\n\t\tdv.Buffer.PermissionsChanged -= new ByteBuffer.ChangedHandler(OnBufferPermissionsChanged);\n\t\tdv.BufferChanged -= new DataView.DataViewEventHandler(OnBufferChanged);\n\t\t// if there are no pages left update the menu\n\t\tif (dataBook.NPages == 0)\n\t\t\tUpdateActions(null);\n\t}\n\n\tvoid OnBufferChanged(DataView dv)\n\t{\n\t\tUpdateActions(dv);\n\t}\n\n\tvoid OnBufferPermissionsChanged(ByteBuffer bb)\n\t{\n\t\tGtk.Application.Invoke(delegate {\n\t\t\tDataView dv = null;\n\n\t\t\t// find DataView that owns bb\n\t\t\tforeach (DataViewDisplay dvtemp in dataBook.Children) {\n\t\t\t\tif (dvtemp.View.Buffer == bb) {\n\t\t\t\t\tdv = dvtemp.View;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tUpdateActions(dv);\n\t\t});\n\t}\n\n\tvoid OnSwitchPage(object o, SwitchPageArgs args)\n\t{\n\t\tDataView dv = ((DataViewDisplay)dataBook.GetNthPage((int)args.PageNum)).View;\n\n\t\tUpdateActions(dv);\n\t}\n\n\tprivate void AddActions(UIManager uim)\n\t{\n\t\tActionEntry[] actionEntries = new ActionEntry[] {\n\t\t\t\t\t\t\t\t\t\t  new ActionEntry (\"NewAction\", Stock.New, null, \"<control>N\", \"New File\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   new EventHandler(OnNewActivated)),\n\t\t\t\t\t\t\t\t\t\t  new ActionEntry (\"OpenAction\", Stock.Open, null, \"<control>O\", \"Open File\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   new EventHandler(OnOpenActivated)),\n\t\t\t\t\t\t\t\t\t\t  new ActionEntry (\"SaveAction\", Stock.Save, null, \"<control>S\", \"Save File\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   new EventHandler(OnSaveActivated)),\n\t\t\t\t\t\t\t\t\t\t  new ActionEntry (\"SaveAsAction\", Stock.SaveAs, null, \"<shift><control>S\", \"Save File As\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   new EventHandler(OnSaveAsActivated)),\n\t\t\t\t\t\t\t\t\t\t  new ActionEntry (\"RevertAction\", Stock.RevertToSaved, null, null, \"Revert File\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   new EventHandler(OnRevertActivated)),\n\t\t\t\t\t\t\t\t\t\t  new ActionEntry (\"CloseAction\", Stock.Close, null, \"<control>W\", \"Close File\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   new EventHandler(OnCloseActivated)),\n\t\t\t\t\t\t\t\t\t\t  new ActionEntry (\"QuitAction\", Stock.Quit, null, \"<control>Q\", \"Quit Application\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   new EventHandler(OnQuitActivated))\n\t\t\t\t\t\t\t\t\t  };\n\n\t\tActionGroup group = new ActionGroup (\"FileActions\");\n\t\tgroup.Add (actionEntries);\n\n\t\tuim.InsertActionGroup(group, 0);\n\t\tuim.AddUiFromString(uiXml);\n\t\tSaveAction = (Gtk.Action)uim.GetAction(\"/menubar/File/Save\");\n\t\tSaveAsAction = (Gtk.Action)uim.GetAction(\"/menubar/File/SaveAs\");\n\t\tCloseAction = (Gtk.Action)uim.GetAction(\"/menubar/File/Close\");\n\t\tQuitAction = (Gtk.Action)uim.GetAction(\"/menubar/File/Quit\");\n\t\tRevertAction = (Gtk.Action)uim.GetAction(\"/menubar/File/Revert\");\n\n\t\tuim.EnsureUpdate();\n\n\t}\n\n\t///<summary>Handle file->new command from menu</summary>\n\tpublic void OnNewActivated(object o, EventArgs args)\n\t{\n\t\tByteBuffer bb = Services.File.NewFile();\n\n\t\t// create and setup a  DataView\n\t\tDataView dv = Services.File.CreateDataView(bb);\n\n\t\tdataBook.AppendView(dv, new CloseViewDelegate(Services.File.CloseFile), Path.GetFileName(bb.Filename));\n\t}\n\n\t///<summary>Handle file->open command from menu</summary>\n\tpublic void OnOpenActivated(object o, EventArgs args)\n\t{\n\t\t// Get path of file(s) to open\n\t\tGtk.FileChooserDialog fs = new Gtk.FileChooserDialog(Catalog.GetString(\"Open File(s)\"), mainWindow, FileChooserAction.Open,\n\t\t\t\t\t\t\t\t   Gtk.Stock.Cancel, ResponseType.Cancel,\n\t\t\t\t\t\t\t\t   Gtk.Stock.Open, ResponseType.Accept);\n\n\t\tfs.SelectMultiple = true;\n\t\tResponseType result = (ResponseType)fs.Run();\n\t\tfs.Hide();\n\n\t\t// if user does not cancel load the file(s)\n\t\tif (result == ResponseType.Accept)\n\t\t\tServices.File.LoadFiles(fs.Filenames);\n\n\t\tfs.Destroy();\n\t}\n\n\t///<summary>Handle file->save command from menu</summary>\n\tpublic void OnSaveActivated(object o, EventArgs args)\n\t{\n\t\tif (dataBook.NPages == 0)\n\t\t\treturn;\n\n\t\tDataView dv = ((DataViewDisplay)dataBook.CurrentPageWidget).View;\n\n\t\tServices.File.SaveFile(dv, null, false, false);\n\t}\n\n\t///<summary>Handle file->save as command from menu</summary>\n\tpublic void OnSaveAsActivated(object o, EventArgs args)\n\t{\n\t\tif (dataBook.NPages == 0)\n\t\t\treturn;\n\n\t\tDataView dv = ((DataViewDisplay)dataBook.CurrentPageWidget).View;\n\n\t\tServices.File.SaveFile(dv, null, true, false);\n\t}\n\n\t///<summary>Handle file->revert command from menu</summary>\n\tpublic void OnRevertActivated(object o, EventArgs args)\n\t{\n\t\tif (dataBook.NPages == 0)\n\t\t\treturn;\n\n\t\tDataView dv = ((DataViewDisplay)dataBook.CurrentPageWidget).View;\n\n\t\tRevertConfirmationAlert rca = new RevertConfirmationAlert(dv.Buffer.Filename, mainWindow);\n\t\tResponseType response = (ResponseType)rca.Run();\n\t\trca.Destroy();\n\n\t\ttry {\n\t\t\tif (response == ResponseType.Ok)\n\t\t\t\tdv.Revert();\n\t\t}\n\t\tcatch (FileNotFoundException ex) {\n\t\t\tstring msg = string.Format(Catalog.GetString(\"The file '{0}' cannot be found. Perhaps it has been recently deleted.\"), ex.Message);\n\t\t\tErrorAlert ea = new ErrorAlert(Catalog.GetString(\"Error reverting file\"), msg, mainWindow);\n\t\t\tea.Run();\n\t\t\tea.Destroy();\n\t\t}\n\t}\n\n\t///<summary>Handle file->close as command from menu</summary>\n\tpublic void OnCloseActivated(object o, EventArgs args)\n\t{\n\t\tif (dataBook.NPages == 0)\n\t\t\treturn;\n\t\tDataView dv = ((DataViewDisplay)dataBook.CurrentPageWidget).View;\n\n\t\tServices.File.CloseFile(dv);\n\t}\n\n\n\t///<summary>Handle file->quit command from menu</summary>\n\tpublic void OnQuitActivated(object o, EventArgs args)\n\t{\n\t\tServices.File.TryQuit();\n\t}\n\n\t///<summary>\n\t/// Updates various menu items according to the FileOperationsAllowed\n\t/// permission property of the active ByteBuffer\n\t///</summary>\n\tvoid UpdateActions(DataView dv)\n\t{\n\t\tif (dv == null) {\n\t\t\tSaveAction.Sensitive = false;\n\t\t\tSaveAsAction.Sensitive = false;\n\t\t\tCloseAction.Sensitive = false;\n\t\t\tRevertAction.Sensitive = false;\n\t\t\treturn;\n\t\t}\n\n\t\tDataView curdv = ((DataViewDisplay)dataBook.CurrentPageWidget).View;\n\t\tByteBuffer curbb = curdv.Buffer;\n\n\t\tByteBuffer bb = dv.Buffer;\n\n\t\t// if DataView is active\n\t\tif (curbb == bb) {\n\t\t\t// gray various menu items\n\t\t\t// if FileOperations aren't allowed\n\t\t\tif (!bb.FileOperationsAllowed) {\n\t\t\t\tSaveAction.Sensitive = false;\n\t\t\t\tSaveAsAction.Sensitive = false;\n\t\t\t\tCloseAction.Sensitive = false;\n\n\t\t\t\t//SaveToolButton.Sensitive=false;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tSaveAction.Sensitive = true;\n\t\t\t\tSaveAsAction.Sensitive = true;\n\t\t\t\tCloseAction.Sensitive = true;\n\n\t\t\t\t//SaveToolButton.Sensitive=true;\n\t\t\t}\n\n\t\t\tif (dv.Buffer.HasFile && dv.Buffer.ModifyAllowed)\n\t\t\t\tRevertAction.Sensitive = true;\n\t\t\telse\n\t\t\t\tRevertAction.Sensitive = false;\n\t\t}\n\n\n\t\t// If even one ByteBuffer in the dataBook\n\t\t// doesn't allow file operations\n\t\t// gray the Quit menu item.\n\t\tQuitAction.Sensitive = true; // set initially to true\n\n\t\tforeach (DataViewDisplay dd in dataBook.Children) {\n\t\t\tif (!dd.View.Buffer.FileOperationsAllowed) {\n\t\t\t\tQuitAction.Sensitive = false;\n\t\t\t\tdataBook.SetCloseSensitivity(dd, false);\n\t\t\t}\n\t\t\telse\n\t\t\t\tdataBook.SetCloseSensitivity(dd, true);\n\t\t}\n\t}\n\n}\n\n}\n"
  },
  {
    "path": "src/gui/plugins/FindReplacePlugin.cs",
    "content": "// created on 6/15/2005 at 1:29 PM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing System;\nusing Gtk;\nusing Bless.Tools.Find;\nusing Bless.Util;\nusing Bless.Gui;\nusing Bless.Gui.Areas;\nusing Bless.Buffers;\nusing Bless.Gui.Dialogs;\nusing System.Text;\nusing Bless.Plugins;\nusing Mono.Unix;\n\nnamespace Bless.Gui.Plugins {\n\npublic class FindReplacePlugin : GuiPlugin\n{\n\tDataBook dataBook;\n\tFindReplaceWidget widget;\n\n\tGtk.Action FindAction;\n\tGtk.Action FindNextAction;\n\tGtk.Action FindPreviousAction;\n\tGtk.Action ReplaceAction;\n\n\tIFinder finder;\n\tWindow mainWindow;\n\tUIManager uiManager;\n\n\tconst string uiXml =\n\t\t\"<menubar>\" +\n\t\t\"\t<menu action=\\\"Search\\\">\" +\n\t\t\"\t\t<menuitem name=\\\"Find\\\" action=\\\"FindAction\\\" />\" +\n\t\t\"\t\t<menuitem name=\\\"FindNext\\\" action=\\\"FindNextAction\\\" />\" +\n\t\t\"\t\t<menuitem name=\\\"FindPrevious\\\" action=\\\"FindPreviousAction\\\" />\" +\n\t\t\"\t\t<menuitem name=\\\"Replace\\\" action=\\\"ReplaceAction\\\" />\" +\n\t\t\"\t\t<separator/>\" +\n\t\t\"\t</menu>\" +\n\t\t\"</menubar>\" +\n\t\t\"<toolbar>\" +\n\t\t\"\t<placeholder name=\\\"SearchItems\\\">\" +\n\t\t\"\t\t<toolitem name=\\\"Find\\\" action=\\\"FindAction\\\" />\" +\n\t\t\"\t\t<toolitem name=\\\"Replace\\\" action=\\\"ReplaceAction\\\" />\" +\n\t\t\"\t</placeholder>\" +\n\t\t\"</toolbar>\";\n\n\tpublic FindReplacePlugin(Window mw, UIManager uim)\n\t{\n\t\tmainWindow = mw;\n\t\tuiManager = uim;\n\n\t\tname = \"FindReplace\";\n\t\tauthor = \"Alexandros Frantzis\";\n\t\tdescription = \"Adds a firefox like find/replace bar\";\n\t}\n\n\tpublic override bool Load()\n\t{\n\t\tdataBook = (DataBook)GetDataBook(mainWindow);\n\n\t\t// create the finder object\n\t\tProgressDialog findProgressDialog = new ProgressDialog(\"\", mainWindow);\n\t\tfinder = new DataBookFinder(dataBook, findProgressDialog.Update);\n\t\tfinder.Strategy = new BMFindStrategy();\n\t\tfinder.FirstFind += OnFirstFind;\n\n\t\t// create the FindReplaceWidget (hidden)\n\t\twidget = new FindReplaceWidget(dataBook, finder);\n\t\twidget.Visible = false;\n\n\t\tWidgetGroup wgroup = (WidgetGroup)GetWidgetGroup(mainWindow, 0);\n\t\twgroup.Add(widget);\n\n\t\t// add the menu items\n\t\tAddActions(uiManager);\n\n\t\tdataBook.PageAdded += new DataView.DataViewEventHandler(OnDataViewAdded);\n\t\tdataBook.PageRemoved += new DataView.DataViewEventHandler(OnDataViewRemoved);\n\t\tdataBook.SwitchPage += new SwitchPageHandler(OnSwitchPage);\n\n\t\tloaded = true;\n\t\treturn true;\n\t}\n\n\tvoid OnDataViewAdded(DataView dv)\n\t{\n\t\tdv.Buffer.Changed += new ByteBuffer.ChangedHandler(OnBufferContentsChanged);\n\t\tdv.BufferChanged += new DataView.DataViewEventHandler(OnBufferChanged);\n\t}\n\n\tvoid OnDataViewRemoved(DataView dv)\n\t{\n\t\tdv.Buffer.Changed -= new ByteBuffer.ChangedHandler(OnBufferContentsChanged);\n\t\tdv.BufferChanged -= new DataView.DataViewEventHandler(OnBufferChanged);\n\t\t// if there are no pages left update the menu\n\t\tif (dataBook.NPages == 0)\n\t\t\tUpdateActions(null);\n\t}\n\n\tvoid OnBufferChanged(DataView dv)\n\t{\n\t\tUpdateActions(dv);\n\t}\n\n\tvoid OnBufferContentsChanged(ByteBuffer bb)\n\t{\n\t\tGtk.Application.Invoke(delegate {\n\t\t\tDataView dv = null;\n\n\t\t\t// find DataView that owns bb\n\t\t\tforeach (DataViewDisplay dvtemp in dataBook.Children) {\n\t\t\t\tif (dvtemp.View.Buffer == bb) {\n\t\t\t\t\tdv = dvtemp.View;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tUpdateActions(dv);\n\t\t});\n\t}\n\n\tvoid OnSwitchPage(object o, SwitchPageArgs args)\n\t{\n\t\tDataView dv = ((DataViewDisplay)dataBook.GetNthPage((int)args.PageNum)).View;\n\n\t\tUpdateActions(dv);\n\t}\n\tprivate void AddActions(UIManager uim)\n\t{\n\t\tActionEntry[] actionEntries = new ActionEntry[] {\n\t\t\t\t\t\t\t\t\t\t  new ActionEntry (\"FindAction\", Stock.Find, null, \"<control>F\", \"Find\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   new EventHandler(OnFindActivated)),\n\t\t\t\t\t\t\t\t\t\t  new ActionEntry (\"FindNextAction\", null, Catalog.GetString(\"Find _Next\"), \"F3\", null,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   new EventHandler(OnFindNextActivated)),\n\t\t\t\t\t\t\t\t\t\t  new ActionEntry (\"FindPreviousAction\", null, Catalog.GetString(\"Find _Previous\"), \"<shift>F3\", null,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   new EventHandler(OnFindPreviousActivated)),\n\t\t\t\t\t\t\t\t\t\t  new ActionEntry (\"ReplaceAction\", Stock.FindAndReplace, null, \"<control>R\", \"Replace\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   new EventHandler(OnReplaceActivated))\n\t\t\t\t\t\t\t\t\t  };\n\n\t\tActionGroup group = new ActionGroup (\"SearchActions\");\n\t\tgroup.Add (actionEntries);\n\n\t\tuim.InsertActionGroup(group, 0);\n\t\tuim.AddUiFromString(uiXml);\n\n\t\tFindAction = (Gtk.Action)uim.GetAction(\"/menubar/Search/Find\");\n\t\tFindNextAction = (Gtk.Action)uim.GetAction(\"/menubar/Search/FindNext\");\n\t\tFindPreviousAction = (Gtk.Action)uim.GetAction(\"/menubar/Search/FindPrevious\");\n\t\tReplaceAction = (Gtk.Action)uim.GetAction(\"/menubar/Search/Replace\");\n\n\t\tuim.EnsureUpdate();\n\n\t}\n\n\tprivate void OnFindActivated(object o, EventArgs args)\n\t{\n\t\t// get pattern from current selection...\n\t\tif (dataBook.NPages > 0) {\n\t\t\tDataView dv = ((DataViewDisplay)dataBook.CurrentPageWidget).View;\n\t\t\twidget.LoadWithSelection(dv);\n\t\t}\n\n\t\twidget.SearchVisible = true;\n\t\twidget.ReplaceVisible = false;\n\n\t\twidget.Show();\n\t}\n\n\tprivate void OnReplaceActivated(object o, EventArgs args)\n\t{\n\t\t// get pattern from current selection...\n\t\tif (dataBook.NPages > 0) {\n\t\t\tDataView dv = ((DataViewDisplay)dataBook.CurrentPageWidget).View;\n\t\t\twidget.LoadWithSelection(dv);\n\t\t}\n\n\t\twidget.SearchVisible = true;\n\t\twidget.ReplaceVisible = true;\n\n\t\twidget.Show();\n\t}\n\n\t///<summary>Handle the Search->Find Next command</summary>\n\tpublic void OnFindNextActivated(object o, EventArgs args)\n\t{\n\t\tfinder.FindNext(FindNextAsyncCallback);\n\t}\n\n\tvoid FindNextAsyncCallback(IAsyncResult ar)\n\t{\n\t\tThreadedAsyncResult tar = (ThreadedAsyncResult) ar;\n\n\t\tFindNextOperation state = (FindNextOperation)tar.AsyncState;\n\t\tif (state.Result == FindNextOperation.OperationResult.Finished && state.Match == null) {\n\t\t\tInformationAlert ia = new InformationAlert(Catalog.GetString(\"The pattern you requested was not found.\"), Catalog.GetString(\"End of file reached.\"), mainWindow);\n\t\t\tia.Run();\n\t\t\tia.Destroy();\n\t\t}\n\t}\n\n\t///<summary>Handle the Search->Find Previous command</summary>\n\tpublic void OnFindPreviousActivated(object o, EventArgs args)\n\t{\n\t\tfinder.FindPrevious(FindPreviousAsyncCallback);\n\t}\n\n\tvoid FindPreviousAsyncCallback(IAsyncResult ar)\n\t{\n\t\tThreadedAsyncResult tar = (ThreadedAsyncResult) ar;\n\n\t\tFindPreviousOperation state = (FindPreviousOperation)tar.AsyncState;\n\t\tif (state.Result == FindPreviousOperation.OperationResult.Finished && state.Match == null) {\n\t\t\tInformationAlert ia = new InformationAlert(Catalog.GetString(\"The pattern you requested was not found.\"), Catalog.GetString(\"Beginning of file reached.\"), mainWindow);\n\t\t\tia.Run();\n\t\t\tia.Destroy();\n\t\t}\n\t}\n\n\t//\n\t// called the first time a pattern is sought\n\t//\n\tvoid OnFirstFind()\n\t{\n\t\t//SearchFindNextAction.Sensitive=true;\n\t\t//SearchFindPreviousAction.Sensitive=true;\n\t}\n\n\tvoid UpdateActions(DataView dv)\n\t{\n\t\tif (dv == null) {\n\t\t\tFindAction.Sensitive = false;\n\t\t\tFindNextAction.Sensitive = false;\n\t\t\tFindPreviousAction.Sensitive = false;\n\t\t\tReplaceAction.Sensitive = false;\n\t\t\treturn;\n\t\t}\n\n\t\tFindAction.Sensitive = true;\n\t\tFindNextAction.Sensitive = true;\n\t\tFindPreviousAction.Sensitive = true;\n\t\tReplaceAction.Sensitive = true;\n\t}\n}\n\n///<summary>\n/// A widget for find and replace operations\n///</summary>\npublic class FindReplaceWidget : Gtk.HBox\n{\n\tDataBook dataBook;\n\tIFinder finder;\n\n\tbool searchPatternChanged;\n\tbool replacePatternChanged;\n\n\tbyte[] replacePattern;\n\n\t[Gtk.Builder.Object] Gtk.Table FindReplaceTable;\n\t[Gtk.Builder.Object] Gtk.Button FindNextButton;\n\t[Gtk.Builder.Object] Gtk.Button FindPreviousButton;\n\t[Gtk.Builder.Object] Gtk.Button ReplaceButton;\n\t[Gtk.Builder.Object] Gtk.Button ReplaceAllButton;\n\n\t[Gtk.Builder.Object] Gtk.Label SearchLabel;\n\t[Gtk.Builder.Object] Gtk.Entry SearchPatternEntry;\n\t[Gtk.Builder.Object] Gtk.Label SearchAsLabel;\n\t[Gtk.Builder.Object] Gtk.ComboBox SearchAsComboBox;\n\n\t[Gtk.Builder.Object] Gtk.Label ReplaceLabel;\n\t[Gtk.Builder.Object] Gtk.Entry ReplacePatternEntry;\n\t[Gtk.Builder.Object] Gtk.Label ReplaceAsLabel;\n\t[Gtk.Builder.Object] Gtk.ComboBox ReplaceAsComboBox;\n\n\t[Gtk.Builder.Object] Gtk.Button CloseButton;\n\n\tGtk.Widget previouslyFocused;\n\n\tenum ComboIndex { Hexadecimal, Decimal, Octal, Binary, Text }\n\n\t///<summary>\n\t/// Whether search-related widgets are visible\n\t///</summary>\n\tpublic bool SearchVisible {\n\t\tset {\n\t\t\tSearchLabel.Visible = value;\n\t\t\tSearchPatternEntry.Visible = value;\n\t\t\tSearchAsLabel.Visible = value;\n\t\t\tSearchAsComboBox.Visible = value;\n\t\t\tFindNextButton.Visible = value;\n\t\t\tFindPreviousButton.Visible = value;\n\t\t\tif (value)\n\t\t\t\tSearchPatternEntry.GrabFocus();\n\t\t}\n\t}\n\n\t///<summary>\n\t/// Whether replace related widgets are visible\n\t///</summary>\n\tpublic bool ReplaceVisible {\n\t\tset {\n\t\t\tReplaceLabel.Visible = value;\n\t\t\tReplacePatternEntry.Visible = value;\n\t\t\tReplaceAsLabel.Visible = value;\n\t\t\tReplaceAsComboBox.Visible = value;\n\t\t\tReplaceButton.Visible = value;\n\t\t\tReplaceAllButton.Visible = value;\n\t\t\tif (value && SearchPatternEntry.Text.Length > 0)\n\t\t\t\tReplacePatternEntry.GrabFocus();\n\t\t}\n\t}\n\n\tpublic FindReplaceWidget(DataBook db, IFinder iFinder)\n\t{\n\t\tfinder = iFinder;\n\t\tdataBook = db;\n\n\t\tGtk.Builder builder = new Gtk.Builder();\n\t\tbuilder.AddFromFile(FileResourcePath.GetDataPath(\"ui\", \"FindReplacePlugin.ui\"));\n\t\tbuilder.Autoconnect(this);\n\n\t\tthis.Shown += OnWidgetShown;\n\t\tSearchPatternEntry.Activated += OnSearchPatternEntryActivated;\n\t\tReplacePatternEntry.Activated += OnReplacePatternEntryActivated;\n\n\t\tSearchPatternEntry.FocusGrabbed += OnFocusGrabbed;\n\t\tReplacePatternEntry.FocusGrabbed += OnFocusGrabbed;\n\n\t\tSearchAsComboBox.Active = 0;\n\t\tReplaceAsComboBox.Active = 0;\n\n\t\tSearchPatternEntry.Completion = new EntryCompletion();\n\t\tSearchPatternEntry.Completion.Model = new ListStore (typeof (string));\n\t\tSearchPatternEntry.Completion.TextColumn = 0;\n\n\t\tReplacePatternEntry.Completion = new EntryCompletion();\n\t\tReplacePatternEntry.Completion.Model = new ListStore (typeof (string));\n\t\tReplacePatternEntry.Completion.TextColumn = 0;\n\n\t\t// initialize replace pattern\n\t\treplacePattern = new byte[0];\n\n\t\tthis.Add(FindReplaceTable);\n\t\tthis.ShowAll();\n\t}\n\n\t///<summary>\n\t/// Whether a widget in the FindReplaceWidget has the focus\n\t///</summary>\n\tbool IsFocusInWidget()\n\t{\n\t\tforeach (Gtk.Widget child in  FindReplaceTable.Children) {\n\t\t\tWidget realChild = child;\n\n\t\t\t/*if (child.GetType()==typeof(Gtk.Combo))\n\t\t\t\trealChild=(child as Gtk.Combo).Entry;\n\t\t\t*/\n\n\t\t\tif (realChild.HasFocus)\n\t\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t///<summary>Load the widget with data from the DataView's selection</summary>\n\tpublic void LoadWithSelection(DataView dv)\n\t{\n\t\tByteBuffer bb = dv.Buffer;\n\n\t\t// load selection only if it isn't very large\n\t\tif (this.Sensitive == true && dv.Selection.Size <= 1024 && dv.Selection.Size > 0) {\n\t\t\tBless.Util.Range sel = dv.Selection;\n\n\t\t\tbyte[] ba = new byte[sel.Size];\n\t\t\tfor (int i = 0;i < sel.Size;i++) {\n\t\t\t\tba[i] = bb[sel.Start+i];\n\t\t\t}\n\n\t\t\tbool decodingOk = false;\n\t\t\tArea focusedArea = dv.FocusedArea;\n\n\t\t\tif (focusedArea != null) {\n\t\t\t\tswitch (focusedArea.Type) {\n\t\t\t\t\tcase \"ascii\":\n\t\t\t\t\t\tstring result = Encoding.ASCII.GetString(ba);\n\t\t\t\t\t\t// if the byte sequence cannot be displayed correctly\n\t\t\t\t\t\t// as ascii, eg it contains a zero byte, use hexadecimal\n\t\t\t\t\t\tif (result.IndexOf('\\x00') != -1)\n\t\t\t\t\t\t\tdecodingOk = false;\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tSearchAsComboBox.Active = (int)ComboIndex.Text;\n\t\t\t\t\t\t\tSearchPatternEntry.Text = result;\n\t\t\t\t\t\t\tdecodingOk = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"decimal\":\n\t\t\t\t\t\tSearchAsComboBox.Active = (int)ComboIndex.Decimal;\n\t\t\t\t\t\tSearchPatternEntry.Text = ByteArray.ToString(ba, 10);\n\t\t\t\t\t\tdecodingOk = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"octal\":\n\t\t\t\t\t\tSearchAsComboBox.Active = (int)ComboIndex.Octal;\n\t\t\t\t\t\tSearchPatternEntry.Text = ByteArray.ToString(ba, 8);\n\t\t\t\t\t\tdecodingOk = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"binary\":\n\t\t\t\t\t\tSearchAsComboBox.Active = (int)ComboIndex.Binary;\n\t\t\t\t\t\tSearchPatternEntry.Text = ByteArray.ToString(ba, 2);\n\t\t\t\t\t\tdecodingOk = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}// end switch\n\t\t\t}\n\n\t\t\tif (!decodingOk) {\n\t\t\t\tSearchAsComboBox.Active = (int)ComboIndex.Hexadecimal;\n\t\t\t\tSearchPatternEntry.Text = ByteArray.ToString(ba, 16);\n\t\t\t}\n\t\t}\n\t}\n\n\t///<summary>Update the search pattern from the text entry</summary>\n\tvoid UpdateSearchPattern()\n\t{\n\t\tif (!searchPatternChanged)\n\t\t\treturn;\n\n\t\ttry {\n\t\t\tbyte[] ba;\n\t\t\tswitch ((ComboIndex)SearchAsComboBox.Active) {\n\t\t\t\tcase ComboIndex.Hexadecimal:\n\t\t\t\t\tba = ByteArray.FromString(SearchPatternEntry.Text, 16);\n\t\t\t\t\tbreak;\n\t\t\t\tcase ComboIndex.Decimal:\n\t\t\t\t\tba = ByteArray.FromString(SearchPatternEntry.Text, 10);\n\t\t\t\t\tbreak;\n\t\t\t\tcase ComboIndex.Octal:\n\t\t\t\t\tba = ByteArray.FromString(SearchPatternEntry.Text, 8);\n\t\t\t\t\tbreak;\n\t\t\t\tcase ComboIndex.Binary:\n\t\t\t\t\tba = ByteArray.FromString(SearchPatternEntry.Text, 2);\n\t\t\t\t\tbreak;\n\t\t\t\tcase ComboIndex.Text:\n\t\t\t\t\tba = Encoding.ASCII.GetBytes(SearchPatternEntry.Text);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tba = new byte[0];\n\t\t\t\t\tbreak;\n\t\t\t} //end switch\n\n\t\t\t// if there is something in the text entry but nothing is parsed\n\t\t\t// it means it is full of spaces\n\t\t\tif (ba.Length == 0 && SearchPatternEntry.Text.Length != 0)\n\t\t\t\tthrow new FormatException(Catalog.GetString(\"Strings representing numbers cannot consist of whitespace characters only.\"));\n\t\t\telse\n\t\t\t\tfinder.Strategy.Pattern = ba;\n\n\t\t\t// append string to drop-down list\n\t\t\tListStore ls = (ListStore)SearchPatternEntry.Completion.Model;\n\t\t\tls.AppendValues(SearchPatternEntry.Text);\n\t\t}\n\t\tcatch (FormatException e) {\n\t\t\tErrorAlert ea = new ErrorAlert(Catalog.GetString(\"Invalid Search Pattern\"), e.Message, null);\n\t\t\tea.Run();\n\t\t\tea.Destroy();\n\t\t\tthrow;\n\t\t}\n\t\tsearchPatternChanged = false;\n\t}\n\n\tvoid OnSearchPatternEntryActivated(object o, EventArgs  args)\n\t{\n\t\tif (FindNextButton.Sensitive == true)\n\t\t\tFindNextButton.Click();\n\t}\n\n\tvoid OnSearchPatternEntryChanged(object o, EventArgs args)\n\t{\n\t\tstring pat = SearchPatternEntry.Text;\n\t\tif (pat.Length == 0) {\n\t\t\tFindNextButton.Sensitive = false;\n\t\t\tFindPreviousButton.Sensitive = false;\n\t\t\tReplaceButton.Sensitive = false;\n\t\t\tReplaceAllButton.Sensitive = false;\n\t\t}\n\t\telse {\n\t\t\tFindNextButton.Sensitive = true;\n\t\t\tFindPreviousButton.Sensitive = true;\n\t\t\tReplaceButton.Sensitive = true;\n\t\t\tReplaceAllButton.Sensitive = true;\n\t\t}\n\t\tsearchPatternChanged = true;\n\t}\n\n\tvoid OnSearchAsComboBoxChanged(object o, EventArgs args)\n\t{\n\t\tsearchPatternChanged = true;\n\t}\n\n\tvoid OnFindNextButtonClicked(object o, EventArgs args)\n\t{\n\t\ttry {\n\t\t\tUpdateSearchPattern();\n\n\t\t\tthis.Sensitive = false;\n\t\t\tfinder.FindNext(FindNextAsyncCallback);\n\t\t}\n\t\tcatch (FormatException) { }\n\t}\n\n\tvoid FindNextAsyncCallback(IAsyncResult ar)\n\t{\n\t\tThreadedAsyncResult tar = (ThreadedAsyncResult) ar;\n\n\t\tFindNextOperation state = (FindNextOperation)tar.AsyncState;\n\t\tif (state.Result == FindNextOperation.OperationResult.Finished && state.Match == null) {\n\t\t\tInformationAlert ia = new InformationAlert(\"The pattern you requested was not found.\", \"End of file reached.\", null);\n\t\t\tia.Run();\n\t\t\tia.Destroy();\n\t\t}\n\n\t\tthis.Sensitive = true;\n\t\tthis.Visible = false;\n\t\tthis.Visible = true;\n\t}\n\n\tvoid OnFindPreviousButtonClicked(object o, EventArgs args)\n\t{\n\t\ttry {\n\t\t\tUpdateSearchPattern();\n\n\t\t\tthis.Sensitive = false;\n\t\t\tfinder.FindPrevious(FindPreviousAsyncCallback);\n\t\t}\n\t\tcatch (FormatException) { }\n\t}\n\n\tvoid FindPreviousAsyncCallback(IAsyncResult ar)\n\t{\n\t\tThreadedAsyncResult tar = (ThreadedAsyncResult) ar;\n\n\t\tFindPreviousOperation state = (FindPreviousOperation)tar.AsyncState;\n\t\tif (state.Result == FindPreviousOperation.OperationResult.Finished && state.Match == null) {\n\t\t\tInformationAlert ia = new InformationAlert(Catalog.GetString(\"The pattern you requested was not found.\"), Catalog.GetString(\"Beginning of file reached.\"), null);\n\t\t\tia.Run();\n\t\t\tia.Destroy();\n\t\t}\n\n\t\tthis.Sensitive = true;\n\t\tthis.Visible = false;\n\t\tthis.Visible = true;\n\t}\n\n\t///\n\t//\n\t// Replace related methods\n\t//\n\n\t///<summary>Update the replace pattern from the text entry</summary>\n\tvoid UpdateReplacePattern()\n\t{\n\t\tif (!replacePatternChanged)\n\t\t\treturn;\n\n\t\ttry {\n\t\t\tswitch ((ComboIndex)ReplaceAsComboBox.Active) {\n\t\t\t\tcase ComboIndex.Hexadecimal:\n\t\t\t\t\treplacePattern = ByteArray.FromString(ReplacePatternEntry.Text, 16);\n\t\t\t\t\tbreak;\n\t\t\t\tcase ComboIndex.Decimal:\n\t\t\t\t\treplacePattern = ByteArray.FromString(ReplacePatternEntry.Text, 10);\n\t\t\t\t\tbreak;\n\t\t\t\tcase ComboIndex.Octal:\n\t\t\t\t\treplacePattern = ByteArray.FromString(ReplacePatternEntry.Text, 8);\n\t\t\t\t\tbreak;\n\t\t\t\tcase ComboIndex.Binary:\n\t\t\t\t\treplacePattern = ByteArray.FromString(ReplacePatternEntry.Text, 2);\n\t\t\t\t\tbreak;\n\t\t\t\tcase ComboIndex.Text:\n\t\t\t\t\treplacePattern = Encoding.ASCII.GetBytes(ReplacePatternEntry.Text);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t} //end switch\n\n\t\t\t// if there is something in the text entry but nothing is parsed\n\t\t\t// it means it is full of spaces\n\t\t\tif (replacePattern.Length == 0 && ReplacePatternEntry.Text.Length != 0)\n\t\t\t\tthrow new FormatException(\"Strings representing numbers cannot consist of only whitespace characters. Leave the text entry completely blank for deletion of matched pattern(s).\");\n\n\t\t\t// append string to drop-down list\n\t\t\tListStore ls = (ListStore)ReplacePatternEntry.Completion.Model;\n\t\t\tls.AppendValues(ReplacePatternEntry.Text);\n\t\t}\n\t\tcatch (FormatException e) {\n\t\t\tErrorAlert ea = new ErrorAlert(\"Invalid Replace Pattern\", e.Message, null);\n\t\t\tea.Run();\n\t\t\tea.Destroy();\n\t\t\tthrow;\n\t\t}\n\t\treplacePatternChanged = false;\n\t}\n\n\tvoid OnReplacePatternEntryActivated(object o, EventArgs  args)\n\t{\n\t\tif (ReplaceButton.Sensitive == true)\n\t\t\tReplaceButton.Click();\n\t}\n\n\tvoid OnReplacePatternEntryChanged(object o, EventArgs args)\n\t{\n\t\treplacePatternChanged = true;\n\t}\n\n\tvoid OnReplaceAsComboBoxChanged(object o, EventArgs args)\n\t{\n\t\treplacePatternChanged = true;\n\t}\n\n\n\tvoid OnReplaceButtonClicked(object o, EventArgs args)\n\t{\n\t\ttry {\n\t\t\tUpdateSearchPattern();\n\t\t\tUpdateReplacePattern();\n\n\t\t\tthis.Sensitive = false;\n\t\t\tfinder.Replace(replacePattern);\n\t\t\tfinder.FindNext(FindNextAsyncCallback);\n\t\t}\n\t\tcatch (FormatException) { }\n\t}\n\n\tvoid OnReplaceAllButtonClicked(object o, EventArgs args)\n\t{\n\t\ttry {\n\t\t\tUpdateSearchPattern();\n\t\t\tUpdateReplacePattern();\n\n\t\t\tthis.Sensitive = false;\n\t\t\tfinder.ReplaceAll(replacePattern, ReplaceAllAsyncCallback);\n\t\t}\n\t\tcatch (FormatException) { }\n\t}\n\n\tvoid ReplaceAllAsyncCallback(IAsyncResult ar)\n\t{\n\t\tThreadedAsyncResult tar = (ThreadedAsyncResult) ar;\n\n\t\tReplaceAllOperation state = (ReplaceAllOperation)tar.AsyncState;\n\n\t\tif (state.Result == ReplaceAllOperation.OperationResult.Finished) {\n\t\t\tInformationAlert ia = new InformationAlert(\"Found and replaced \" + state.NumReplaced + \" occurences.\", \"\", null);\n\t\t\tia.Run();\n\t\t\tia.Destroy();\n\t\t}\n\n\t\tthis.Sensitive = true;\n\t\tthis.Visible = false;\n\t\tthis.Visible = true;\n\t}\n\n\tvoid OnCloseButtonClicked(object o, EventArgs args)\n\t{\n\t\tif (dataBook.NPages > 0 && IsFocusInWidget()) {\n\t\t\tDataViewDisplay curdvd = (DataViewDisplay)dataBook.CurrentPageWidget;\n\t\t\tcurdvd.GrabKeyboardFocus();\n\t\t}\n\n\t\tthis.Hide();\n\t\t// forget focus when hiding\n\t\tpreviouslyFocused = null;\n\t}\n\n\tvoid OnFocusGrabbed(object o, EventArgs args)\n\t{\n\t\t// remember which widget has the focus\n\t\tpreviouslyFocused = (Widget)o;\n\t}\n\n\tvoid OnWidgetShown(object o, EventArgs args)\n\t{\n\t\t// when the dialog is shown, select and give the focus\n\t\t// to the previously focused widget\n\t\tif (previouslyFocused != null)\n\t\t\tpreviouslyFocused.GrabFocus();\n\t\telse\n\t\t\tSearchPatternEntry.GrabFocus();\n\t}\n\n\tprotected override bool OnKeyPressEvent(Gdk.EventKey e)\n\t{\n\t\t// Escape hides the widget\n\t\tif (e.Key == Gdk.Key.Escape) {\n\t\t\tCloseButton.Click();\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t\treturn base.OnKeyPressEvent(e);\n\t}\n}\n\n} // end namespace\n"
  },
  {
    "path": "src/gui/plugins/GotoOffsetPlugin.cs",
    "content": "// created on 6/22/2005 at 12:42 PM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing System;\nusing Gtk;\nusing Bless.Util;\nusing Bless.Gui.Dialogs;\nusing Bless.Gui;\nusing Bless.Tools.Find;\nusing Bless.Plugins;\nusing Mono.Unix;\n\nnamespace Bless.Gui.Plugins {\n\npublic class GotoOffsetPlugin : GuiPlugin\n{\n\tGotoOffsetWidget widget;\n\n\tconst string uiXml =\n\t\t\"<menubar>\" +\n\t\t\"\t<menu action=\\\"Search\\\">\" +\n\t\t\"\t\t<menuitem name=\\\"GotoOffset\\\" action=\\\"GotoOffsetAction\\\" />\" +\n\t\t\"\t\t<separator/>\" +\n\t\t\"\t</menu>\" +\n\t\t\"</menubar>\";\n\n\tWindow mainWindow;\n\tUIManager uiManager;\n\n\tpublic GotoOffsetPlugin(Window mw, UIManager uim)\n\t{\n\t\tmainWindow = mw;\n\t\tuiManager = uim;\n\n\t\tname = \"GotoOffset\";\n\t\tauthor = \"Alexandros Frantzis\";\n\t\tdescription = \"Adds a firefox like go to offset bar\";\n\t\tloadAfter.Add(\"FindReplace\");\n\t}\n\n\tpublic override bool Load()\n\t{\n\t\twidget = new GotoOffsetWidget((DataBook)GetDataBook(mainWindow));\n\t\twidget.Visible = false;\n\n\t\tWidgetGroup wgroup = (WidgetGroup)GetWidgetGroup(mainWindow, 0);\n\t\twgroup.Add(widget);\n\n\t\t// add the menu items\n\t\tAddMenuItems(uiManager);\n\n\t\tloaded = true;\n\t\treturn true;\n\t}\n\n\tprivate void AddMenuItems(UIManager uim)\n\t{\n\t\tActionEntry[] actionEntries = new ActionEntry[] {\n\t\t\t\t\t\t\t\t\t\t  new ActionEntry (\"GotoOffsetAction\", Stock.JumpTo, Catalog.GetString(\"_Goto Offset\"), \"<control>G\", null,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   new EventHandler(OnGotoOffsetActivated)),\n\t\t\t\t\t\t\t\t\t  };\n\n\t\tActionGroup group = new ActionGroup (\"GotoActions\");\n\t\tgroup.Add (actionEntries);\n\n\t\tuim.InsertActionGroup(group, 0);\n\t\tuim.AddUiFromString(uiXml);\n\n\t\tuim.EnsureUpdate();\n\n\t}\n\n\t///<summary>Handle the Search->Find Next command</summary>\n\tpublic void OnGotoOffsetActivated(object o, EventArgs args)\n\t{\n\t\twidget.Show();\n\t}\n}\n\n///<summary>\n/// A widget for go to offset operation\n///</summary>\npublic class GotoOffsetWidget : Gtk.HBox\n{\n\t[Gtk.Builder.Object] Gtk.HBox GotoOffsetHBox;\n\t[Gtk.Builder.Object] Gtk.Button GotoOffsetButton;\n\t[Gtk.Builder.Object] Gtk.Entry OffsetEntry;\n\t[Gtk.Builder.Object] Gtk.Button CloseButton;\n\n\tDataBook dataBook;\n\n\n\tpublic GotoOffsetWidget(DataBook db)\n\t{\n\t\tdataBook = db;\n\n\t\tGtk.Builder builder = new Gtk.Builder();\n\t\tbuilder.AddFromFile(FileResourcePath.GetDataPath(\"ui\", \"GotoOffsetPlugin.ui\"));\n\t\tbuilder.Autoconnect(this);\n\n\t\tOffsetEntry.Completion = new EntryCompletion();\n\t\tOffsetEntry.Completion.Model = new ListStore (typeof (string));\n\t\tOffsetEntry.Completion.TextColumn = 0;\n\n\t\t// set button sensitivity\n\t\tOnOffsetEntryChanged(null, null);\n\n\t\tthis.Shown += OnWidgetShown;\n\n\t\tthis.Add(GotoOffsetHBox);\n\t\tthis.ShowAll();\n\t}\n\n\t///<summary>\n\t/// Whether a widget in the GotoOffsetWidget has the focus\n\t///</summary>\n\tbool IsFocusInWidget()\n\t{\n\t\tforeach (Gtk.Widget child in  GotoOffsetHBox.Children) {\n\t\t\tWidget realChild = child;\n\n\t\t\tif (child.GetType() == typeof(Gtk.Alignment))\n\t\t\t\trealChild = (child as Gtk.Alignment).Child;\n\n\t\t\tif (realChild.HasFocus)\n\t\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tvoid OnOffsetEntryChanged(object o, EventArgs args)\n\t{\n\t\tif (OffsetEntry.Text.Length > 0)\n\t\t\tGotoOffsetButton.Sensitive = true;\n\t\telse\n\t\t\tGotoOffsetButton.Sensitive = false;\n\t}\n\n\tvoid OnOffsetEntryActivated(object o, EventArgs args)\n\t{\n\t\tif (GotoOffsetButton.Sensitive == true)\n\t\t\tGotoOffsetButton.Click();\n\t}\n\n\tvoid OnGotoOffsetClicked(object o, EventArgs args)\n\t{\n\t\tif (dataBook.NPages == 0)\n\t\t\treturn;\n\n\t\tDataView dv = ((DataViewDisplay)dataBook.CurrentPageWidget).View;\n\n\t\tlong offset = -1;\n\n\t\ttry {\n\t\t\toffset = BaseConverter.Parse(OffsetEntry.Text);\n\n\t\t\tif (offset >= 0 && offset <= dv.Buffer.Size) {\n\t\t\t\tdv.Display.MakeOffsetVisible(offset, DataViewDisplay.ShowType.Closest);\n\t\t\t\tdv.MoveCursor(offset, 0);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tErrorAlert ea = new ErrorAlert(Catalog.GetString(\"Invalid Offset\"), Catalog.GetString(\"The offset you specified is outside the file's limits.\"), null);\n\t\t\t\tea.Run();\n\t\t\t\tea.Destroy();\n\t\t\t}\n\n\t\t\t// append string to drop-down list\n\t\t\tListStore ls = (ListStore)OffsetEntry.Completion.Model;\n\t\t\tls.AppendValues(OffsetEntry.Text);\n\t\t}\n\t\tcatch (FormatException e) {\n\t\t\tErrorAlert ea = new ErrorAlert(Catalog.GetString(\"Error in Offset Format\"), e.Message, null);\n\t\t\tea.Run();\n\t\t\tea.Destroy();\n\t\t}\n\n\n\t}\n\n\tvoid OnWidgetShown(object o, EventArgs args)\n\t{\n\t\tOffsetEntry.GrabFocus();\n\t}\n\n\tprotected override bool OnKeyPressEvent(Gdk.EventKey e)\n\t{\n\t\tif (e.Key == Gdk.Key.Escape) {\n\t\t\tCloseButton.Click();\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t\treturn base.OnKeyPressEvent(e);\n\t}\n\n\tvoid OnCloseButtonClicked(object o, EventArgs args)\n\t{\n\t\t// give focus to active dataview if the widget has it\n\t\tif (dataBook.NPages > 0 && IsFocusInWidget()) {\n\t\t\tDataViewDisplay curdvd = (DataViewDisplay)dataBook.CurrentPageWidget;\n\t\t\tcurdvd.GrabKeyboardFocus();\n\t\t}\n\n\t\tthis.Hide();\n\t}\n}\n\n} // namespace\n"
  },
  {
    "path": "src/gui/plugins/HelpOperationsPlugin.cs",
    "content": "// created on 10/24/2006 at 12:59 PM\n/*\n *   Copyright (c) 2006, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing Bless.Gui;\nusing Bless.Plugins;\nusing Bless.Gui.Dialogs;\nusing Bless.Util;\nusing System;\nusing Gtk;\nusing Mono.Unix;\n\nnamespace Bless.Gui.Plugins {\n\npublic class HelpOperationsPlugin : GuiPlugin\n{\n\tconst string uiXml =\n\t\t\"<menubar>\" +\n\t\t\"\t<menu action=\\\"Help\\\">\" +\n\t\t\"\t\t<menuitem name=\\\"Contents\\\" action=\\\"ContentsAction\\\" />\" +\n\t\t\"\t\t<menuitem name=\\\"About\\\" action=\\\"AboutAction\\\" />\" +\n\t\t\"\t\t<separator/>\" +\n\t\t\"\t</menu>\" +\n\t\t\"</menubar>\";\n\n\t//DataBook dataBook;\n\t//Window mainWindow;\n\tUIManager uiManager;\n\n\tpublic HelpOperationsPlugin(Window mw, UIManager uim)\n\t{\n\t\t//mainWindow = mw;\n\t\t//dataBook = (DataBook)GetDataBook(mainWindow);\n\t\tuiManager = uim;\n\n\t\tname = \"HelpOperations\";\n\t\tauthor = \"Alexandros Frantzis\";\n\t\tdescription = \"Provides access to basic help operations\";\n\t}\n\n\tpublic override bool Load()\n\t{\n\t\tAddMenuItems(uiManager);\n\n\t\tloaded = true;\n\t\treturn true;\n\t}\n\n\tprivate void AddMenuItems(UIManager uim)\n\t{\n\t\tActionEntry[] actionEntries = new ActionEntry[] {\n\t\t\t\t\t\t\t\t\t\t  new ActionEntry (\"ContentsAction\", Stock.Help, Catalog.GetString(\"_Contents\"), \"F1\", null,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   new EventHandler(OnContentsActivated)),\n\t\t\t\t\t\t\t\t\t\t  new ActionEntry (\"AboutAction\", null, Catalog.GetString(\"_About\"), null, null,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   new EventHandler(OnAboutActivated)),\n\t\t\t\t\t\t\t\t\t  };\n\n\t\tActionGroup group = new ActionGroup (\"HelpActions\");\n\t\tgroup.Add (actionEntries);\n\n\t\tuim.InsertActionGroup(group, 0);\n\t\tuim.AddUiFromString(uiXml);\n\n\t\tuim.EnsureUpdate();\n\n\t}\n\t///<summary>Handle edit->undo command from menu</summary>\n\tpublic void OnContentsActivated(object o, EventArgs args)\n\t{\n#if ENABLE_UNIX_SPECIFIC\n\t\tstring helpScript = FileResourcePath.GetDataPath(\"help_script.sh\");\n\t\tstring helpDir = FileResourcePath.GetHelpDir();\n\t\tSystem.Diagnostics.Process.Start(helpScript, helpDir);\n#endif\n\t}\n\n\t///<summary>Handle edit->redo command from menu</summary>\n\tpublic void OnAboutActivated(object o, EventArgs args)\n\t{\n\t       // if (dataBook.NPages > 0) {\n\t       // \tDataView dv = ((DataViewDisplay)dataBook.CurrentPageWidget).View;\n\t       // \tdv.Display.Benchmark();\n\t       // }\n\t\tGtk.Dialog aboutDialog = new Bless.Gui.Dialogs.AboutDialog();\n\t\taboutDialog.Run();\n\t\taboutDialog.Destroy();\n\t}\n\n}\n\n} //end namespace\n"
  },
  {
    "path": "src/gui/plugins/HistoryPlugin.cs",
    "content": "/*\n *   Copyright (c) 2006, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing System;\nusing System.Text;\nusing Gtk;\nusing Bless.Buffers;\nusing Bless.Plugins;\nusing Bless.Gui;\nusing Bless.Tools;\n\nnamespace Bless.Gui.Plugins {\n\npublic class HistoryPlugin : GuiPlugin\n{\n\tUIManager uiManager;\n\tuint mergeId;\n\tActionGroup historyActionGroup;\n\n\tpublic HistoryPlugin(Window mw, UIManager uim)\n\t{\n\t\tuiManager = uim;\n\n\t\tname = \"HistoryPlugin\";\n\t\tauthor = \"Alexandros Frantzis\";\n\t\tdescription = \"Provides access to recent files\";\n\t\tloadAfter.Add(\"FileOperations\");\n\t}\n\n\tpublic override bool Load()\n\t{\n\t\tHistory.Instance.Changed += OnHistoryChanged;\n\t\thistoryActionGroup = new ActionGroup (\"HistoryActions\");\n\t\tuiManager.InsertActionGroup(historyActionGroup, 0);\n\t\tOnHistoryChanged(History.Instance);\n\n\t\tloaded = true;\n\t\treturn true;\n\t}\n\n\t///<summary>Handle additions to history</summary>\n\tvoid OnHistoryChanged(History h)\n\t{\n\t\t// clear previous list\n\t\tuiManager.RemoveUi(mergeId);\n\t\tuiManager.RemoveActionGroup(historyActionGroup);\n\t\tforeach(Gtk.Action action in historyActionGroup.ListActions()) {\n\t\t\thistoryActionGroup.Remove(action);\n\t\t}\n\n\t\tStringBuilder sb = new StringBuilder(\"<menubar><menu action=\\\"File\\\"><placeholder name=\\\"HistoryItems\\\">\");\n\n\t\tActionEntry[] actionEntries = new ActionEntry[h.Files.Count];\n\n\t\t// add recent files\n\t\tint i = 1;\n\t\tforeach (string file in h.Files) {\n\t\t\tstring actionStr = string.Format(\"{0}RecentFileAction\", i);\n\t\t\tstring menuItemStr = string.Format(\"_{0}. {1}\", i, System.IO.Path.GetFileName(file));\n\t\t\tstring uiMenuStr = string.Format(\"<menuitem name=\\\"RecentFile{0}\\\" action=\\\"{1}\\\" />\", i, actionStr);\n\n\t\t\tsb.Append(uiMenuStr);\n\t\t\tactionEntries[i-1] = new ActionEntry (actionStr, null, menuItemStr, null, null,\n\t\t\t\t\t\t\t\t\t\t\t\t  new EventHandler(OnHistoryMenuItemActivated));\n\t\t\ti++;\n\t\t}\n\n\t\tsb.Append(\"</placeholder></menu></menubar>\");\n\n\t\thistoryActionGroup.Add (actionEntries);\n\t\tuiManager.InsertActionGroup(historyActionGroup, 0);\n\n\t\tmergeId = uiManager.AddUiFromString(sb.ToString());\n\t\tuiManager.EnsureUpdate();\n\t}\n\n\t///<summary>Handle Activated event on a HistoryMenuItem</summary>\n\tvoid OnHistoryMenuItemActivated(object o, EventArgs args)\n\t{\n\t\tGtk.Action action = (Gtk.Action)o;\n\t\tint i = Convert.ToInt32(action.Name.Substring(0, 1));\n\t\tstring filePath = History.Instance.Files[i-1];\n\n\t\tServices.File.LoadFiles(new string[]{filePath});\n\t}\n\n}\n\n} // end namespace\n"
  },
  {
    "path": "src/gui/plugins/InfobarPlugin.cs",
    "content": "// created on 6/10/2005 at 3:15 PM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing Gtk;\nusing System;\nusing Pango;\nusing Bless.Util;\nusing Bless.Gui;\nusing Bless.Plugins;\nusing Bless.Buffers;\nusing Bless.Tools;\nusing Mono.Unix;\n\nnamespace Bless.Gui.Plugins {\n\npublic class InfobarPlugin : GuiPlugin\n{\n\tDataBook dataBook;\n\tInfobar widget;\n\tWindow mainWindow;\n\tUIManager uiManager;\n\tCheckMenuItem viewStatusbarShowMenuItem;\n\tCheckMenuItem viewStatusbarOffsetMenuItem;\n\tCheckMenuItem viewStatusbarSelectionMenuItem;\n\tCheckMenuItem viewStatusbarOverwriteMenuItem;\n\n\tconst string uiXml =\n\t\t\"<menubar>\" +\n\t\t\"\t<menu action=\\\"View\\\">\" +\n\t\t\"\t\t<menu action=\\\"Statusbar\\\" >\" +\n\t\t\"\t\t\t<menuitem name=\\\"Show\\\" action=\\\"StatusbarShowAction\\\" />\" +\n\t\t\"\t\t\t<separator/>\" +\n\t\t\"\t\t\t<menuitem name=\\\"Offset\\\" action=\\\"StatusbarOffsetAction\\\" />\" +\n\t\t\"\t\t\t<menuitem name=\\\"Selection\\\" action=\\\"StatusbarSelectionAction\\\" />\" +\n\t\t\"\t\t\t<menuitem name=\\\"Overwrite\\\" action=\\\"StatusbarOverwriteAction\\\" />\" +\n\t\t\"\t\t</menu>\" +\n\t\t\"\t</menu>\" +\n\t\t\"</menubar>\";\n\n\tpublic InfobarPlugin(Window mw, UIManager uim)\n\t{\n\t\tmainWindow = mw;\n\t\tuiManager = uim;\n\n\t\tname = \"Infobar\";\n\t\tauthor = \"Alexandros Frantzis\";\n\t\tdescription = \"Advanced statusbar\";\n\t}\n\n\tpublic override bool Load()\n\t{\n\t\tdataBook = (DataBook)GetDataBook(mainWindow);\n\n\t\twidget = new Infobar(dataBook);\n\t\twidget.Visible = true;\n\n\t\tServices.UI.Info = widget;\n\n\t\t((VBox)mainWindow.Child).PackEnd(widget, false, false, 0);\n\n\t\tAddMenuItems(uiManager);\n\n\t\tdataBook.PageAdded += new DataView.DataViewEventHandler(OnDataViewAdded);\n\t\tdataBook.Removed += new RemovedHandler(OnDataViewRemoved);\n\t\tdataBook.SwitchPage += new SwitchPageHandler(OnSwitchPage);\n\n\t\tPreferencesChangedHandler handler = new PreferencesChangedHandler(OnPreferencesChanged);\n\t\tPreferences.Proxy.Subscribe(\"View.Statusbar.Show\", \"ib1\", handler);\n\t\tPreferences.Proxy.Subscribe(\"View.Statusbar.Selection\", \"ib1\", handler);\n\t\tPreferences.Proxy.Subscribe(\"View.Statusbar.Overwrite\", \"ib1\", handler);\n\t\tPreferences.Proxy.Subscribe(\"View.Statusbar.Offset\", \"ib1\", handler);\n\n\t\tloaded = true;\n\t\treturn true;\n\t}\n\n\tprivate void AddMenuItems(UIManager uim)\n\t{\n\t\tToggleActionEntry[] toggleActionEntries = new ToggleActionEntry[] {\n\t\t\t\t\tnew ToggleActionEntry (\"StatusbarShowAction\", null, Catalog.GetString(\"Show\"), null, null,\n\t\t\t\t\t\t\t\t\t\t   new EventHandler(OnStatusbarShow), false),\n\t\t\t\t\tnew ToggleActionEntry (\"StatusbarOffsetAction\", null, Catalog.GetString(\"Offset\"), null, null,\n\t\t\t\t\t\t\t\t\t\t   new EventHandler(OnStatusbarOffset), false),\n\t\t\t\t\tnew ToggleActionEntry (\"StatusbarSelectionAction\", null, Catalog.GetString(\"Selection\"), null, null,\n\t\t\t\t\t\t\t\t\t\t   new EventHandler(OnStatusbarSelection), false),\n\t\t\t\t\tnew ToggleActionEntry (\"StatusbarOverwriteAction\", null, Catalog.GetString(\"Overwrite\"), null, null,\n\t\t\t\t\t\t\t\t\t\t   new EventHandler(OnStatusbarOverwrite), false)\n\t\t\t\t};\n\n\t\tActionEntry[] actionEntries = new ActionEntry[] {\n\t\t\t\t\t\t\t\t\t\t  new ActionEntry (\"Statusbar\", null, Catalog.GetString(\"Statusbar\"), null, null, null)\n\t\t\t\t\t\t\t\t\t  };\n\n\t\tActionGroup group = new ActionGroup (\"StatusbarActions\");\n\t\tgroup.Add (toggleActionEntries);\n\t\tgroup.Add (actionEntries);\n\n\t\tuim.InsertActionGroup(group, 0);\n\t\tuim.AddUiFromString(uiXml);\n\n\t\tviewStatusbarShowMenuItem = (CheckMenuItem)uim.GetWidget(\"/menubar/View/Statusbar/Show\");\n\t\tviewStatusbarOffsetMenuItem = (CheckMenuItem)uim.GetWidget(\"/menubar/View/Statusbar/Offset\");\n\t\tviewStatusbarSelectionMenuItem = (CheckMenuItem)uim.GetWidget(\"/menubar/View/Statusbar/Selection\");\n\t\tviewStatusbarOverwriteMenuItem = (CheckMenuItem)uim.GetWidget(\"/menubar/View/Statusbar/Overwrite\");\n\n\t\tuim.EnsureUpdate();\n\t}\n\n\tvoid OnDataViewAdded(DataView dv)\n\t{\n\t\tdv.Buffer.Changed += new ByteBuffer.ChangedHandler(OnBufferContentsChanged);\n\t\tdv.BufferChanged += new DataView.DataViewEventHandler(OnBufferChanged);\n\t\tdv.CursorChanged += new DataView.DataViewEventHandler(OnCursorChanged);\n\t\tdv.SelectionChanged += new DataView.DataViewEventHandler(OnSelectionChanged);\n\t}\n\n\tvoid OnDataViewRemoved(object o, RemovedArgs args)\n\t{\n\t\tDataView dv = ((DataViewDisplay)args.Widget).View;\n\t\tdv.Buffer.Changed -= new ByteBuffer.ChangedHandler(OnBufferContentsChanged);\n\t\tdv.BufferChanged -= new DataView.DataViewEventHandler(OnBufferChanged);\n\t\tdv.CursorChanged -= new DataView.DataViewEventHandler(OnCursorChanged);\n\t\tdv.SelectionChanged -= new DataView.DataViewEventHandler(OnSelectionChanged);\n\t}\n\n\tvoid OnBufferChanged(DataView dv)\n\t{\n\t\tUpdateInfobar(dv);\n\t}\n\n\tvoid OnBufferContentsChanged(ByteBuffer bb)\n\t{\n\t\tGtk.Application.Invoke(delegate {\n\t\t\tDataView dv = null;\n\n\t\t\t// find DataView that owns bb\n\t\t\tforeach (DataViewDisplay dvtemp in dataBook.Children) {\n\t\t\t\tif (dvtemp.View.Buffer == bb) {\n\t\t\t\t\tdv = dvtemp.View;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tUpdateInfobar(dv);\n\t\t});\n\t}\n\n\tvoid OnSwitchPage(object o, SwitchPageArgs args)\n\t{\n\t\tDataView dv = ((DataViewDisplay)dataBook.GetNthPage((int)args.PageNum)).View;\n\n\t\tUpdateInfobar(dv);\n\t}\n\n\tvoid OnCursorChanged(DataView dv)\n\t{\n\t\tUpdateInfobar(dv);\n\t}\n\n\tvoid OnSelectionChanged(DataView dv)\n\t{\n\t\tUpdateInfobar(dv);\n\t}\n\n\tpublic void OnStatusbarShow(object o, EventArgs args)\n\t{\n\t\tPreferences.Proxy.Change(\"View.Statusbar.Show\", viewStatusbarShowMenuItem.Active.ToString(), \"ib1\");\n\t}\n\n\t///<summary>Handle the View->Statusbar->Offset command</summary>\n\tpublic void OnStatusbarOffset(object o, EventArgs args)\n\t{\n\t\tPreferences.Proxy.Change(\"View.Statusbar.Offset\", viewStatusbarOffsetMenuItem.Active.ToString(), \"ib1\");\n\t}\n\n\t///<summary>Handle the View->Statusbar->Selection command</summary>\n\tpublic void OnStatusbarSelection(object o, EventArgs args)\n\t{\n\t\tPreferences.Proxy.Change(\"View.Statusbar.Selection\", viewStatusbarSelectionMenuItem.Active.ToString(), \"ib1\");\n\t}\n\n\t///<summary>Handle the View->Statusbar->Overwrite command</summary>\n\tpublic void OnStatusbarOverwrite(object o, EventArgs args)\n\t{\n\t\tPreferences.Proxy.Change(\"View.Statusbar.Overwrite\", viewStatusbarOverwriteMenuItem.Active.ToString(), \"ib1\");\n\t}\n\n\n\tvoid UpdateInfobar(DataView dv)\n\t{\n\t\tif (dataBook.NPages == 0)\n\t\t\treturn;\n\n\t\tDataView curdv = ((DataViewDisplay)dataBook.CurrentPageWidget).View;\n\t\tif (curdv != dv)\n\t\t\treturn;\n\n\t\twidget.Update(dv);\n\t}\n\n\tvoid OnPreferencesChanged(Preferences prefs)\n\t{\n\t\tif (prefs[\"View.Statusbar.Show\"] == \"True\") {\n\t\t\tviewStatusbarShowMenuItem.Active = true;\n\t\t\tviewStatusbarOffsetMenuItem.Sensitive = true;\n\t\t\tviewStatusbarSelectionMenuItem.Sensitive = true;\n\t\t\tviewStatusbarOverwriteMenuItem.Sensitive = true;\n\t\t}\n\t\telse {\n\t\t\tviewStatusbarShowMenuItem.Active = false;\n\t\t\tviewStatusbarOffsetMenuItem.Sensitive = false;\n\t\t\tviewStatusbarSelectionMenuItem.Sensitive = false;\n\t\t\tviewStatusbarOverwriteMenuItem.Sensitive = false;\n\t\t}\n\n\t\tif (Preferences.Instance[\"View.Statusbar.Offset\"] == \"True\")\n\t\t\tviewStatusbarOffsetMenuItem.Active = true;\n\t\telse\n\t\t\tviewStatusbarOffsetMenuItem.Active = false;\n\n\t\tif (Preferences.Instance[\"View.Statusbar.Selection\"] == \"True\")\n\t\t\tviewStatusbarSelectionMenuItem.Active = true;\n\t\telse\n\t\t\tviewStatusbarSelectionMenuItem.Active = false;\n\n\t\tif (Preferences.Instance[\"View.Statusbar.Overwrite\"] == \"True\")\n\t\t\tviewStatusbarOverwriteMenuItem.Active = true;\n\t\telse\n\t\t\tviewStatusbarOverwriteMenuItem.Active = false;\n\t}\n}\n\n///<summary>\n/// An advanced statusbar for Bless\n///</summary>\npublic class Infobar : Gtk.HBox, IInfoDisplay\n{\n\tLabel MessageLabel;\n\tLabel OffsetLabel;\n\tLabel SelectionLabel;\n\tLabel OverwriteLabel;\n\n\tDataBook dataBook;\n\n\tint numberBase;\n\n\t///<summary>\n\t///Get or set the visibility of the Offset statusbar\n\t///</summary>\n\tpublic bool OffsetVisible {\n\t\tget { return OffsetLabel.Visible; }\n\t\tset { OffsetLabel.Visible = value; }\n\t}\n\n\t///<summary>\n\t///Get or set the visibility of the Selection statusbar\n\t///</summary>\n\tpublic bool SelectionVisible {\n\t\tget { return SelectionLabel.Visible; }\n\t\tset { SelectionLabel.Visible = value; }\n\t}\n\n\t///<summary>\n\t///Get or set the visibility of the Overwrite statusbar\n\t///</summary>\n\tpublic bool OverwriteVisible {\n\t\tget { return OverwriteLabel.Visible; }\n\t\tset { OverwriteLabel.Visible = value; }\n\t}\n\n\tpublic int NumberBase {\n\t\tset {\n\t\t\tnumberBase = value;\n\n\t\t\tif (dataBook.NPages > 0) {\n\t\t\t\tDataView curdv = ((DataViewDisplay)dataBook.CurrentPageWidget).View;\n\n\t\t\t\tUpdateOffset(curdv);\n\t\t\t\tUpdateSelection(curdv);\n\t\t\t}\n\t\t}\n\n\t\tget {\n\t\t\treturn numberBase;\n\t\t}\n\t}\n\n\tpublic Infobar(DataBook db)\n\t{\n\t\tdataBook = db;\n\n\t\tMessageLabel = new Label();\n\t\tMessageLabel.Ellipsize = Pango.EllipsizeMode.End;\n\t\tMessageLabel.SetAlignment(0.0f, 0.5f);\n\t\tOffsetLabel = new Label();\n\t\tSelectionLabel = new Label();\n\t\tOverwriteLabel = new Label();\n\n\t\tEventBox OffsetEB = new EventBox();\n\t\tOffsetEB.Add(OffsetLabel);\n\t\tOffsetEB.ButtonPressEvent += ChangeNumberBase;\n\n\t\tEventBox SelectionEB = new EventBox();\n\t\tSelectionEB.Add(SelectionLabel);\n\t\tSelectionEB.ButtonPressEvent += ChangeNumberBase;\n\n\t\tEventBox OverwriteEB = new EventBox();\n\t\tOverwriteEB.Add(OverwriteLabel);\n\t\tOverwriteEB.ButtonPressEvent += OnOverwriteLabelPressed;\n\n\t\tthis.PackStart(MessageLabel, true, true, 20);\n\t\tthis.PackStart(OffsetEB, false, false, 20);\n\t\tthis.PackStart(SelectionEB, false, false, 20);\n\t\tthis.PackStart(OverwriteEB, false, false, 20);\n\n\t\tthis.NumberBase = 16;\n\n\t\tPreferencesChangedHandler handler = new PreferencesChangedHandler(OnPreferencesChanged);\n\t\tPreferences.Proxy.Subscribe(\"View.Statusbar.Show\", \"ib2\", handler);\n\t\tPreferences.Proxy.Subscribe(\"View.Statusbar.Selection\", \"ib2\", handler);\n\t\tPreferences.Proxy.Subscribe(\"View.Statusbar.Overwrite\", \"ib2\", handler);\n\t\tPreferences.Proxy.Subscribe(\"View.Statusbar.Offset\", \"ib2\", handler);\n\n\t\tthis.ShowAll();\n\t}\n\n\t///<summary>Displays a message in the infobar (for 5 sec)</summary>\n\tpublic void DisplayMessage(string message)\n\t{\n\t\tMessageLabel.Text = message;\n\t\tGLib.Timeout.Add(5000, ClearStatusMessage);\n\t}\n\n\t///<summary>Clears the status bar message (callback)</summary>\n\tbool ClearStatusMessage()\n\t{\n\t\tMessageLabel.Text = \"\";\n\t\treturn false;\n\t}\n\n\t///<summary>\n\t/// Updates all the information in the infobar with data from the specified DataView,\n\t/// if the specified DataView is active\n\t///</summary>\n\tpublic void Update(DataView dv)\n\t{\n\t\tUpdateOffset(dv);\n\t\tUpdateSelection(dv);\n\t\tUpdateOverwrite(dv);\n\t}\n\n\t///<summary>\n\t/// Updates the cursor status bar with data from the specified DataView,\n\t/// if the specified DataView is active\n\t///</summary>\n\tpublic void UpdateOffset(DataView dv)\n\t{\n\t\tif (dataBook.NPages == 0)\n\t\t\treturn;\n\n\t\tDataView curdv = ((DataViewDisplay)dataBook.CurrentPageWidget).View;\n\t\tif (curdv != dv)\n\t\t\treturn;\n\n\t\tlong coffset = dv.CursorOffset;\n\n\t\tstring coffsetString = BaseConverter.ConvertToString(coffset, numberBase, true, true, 1);\n\t\tstring sizeString = BaseConverter.ConvertToString(dv.Buffer.Size - 1, numberBase, true, true, 1);\n\n\t\tstring str = string.Format(Catalog.GetString(\"Offset: {0} / {1}\"), coffsetString, sizeString);\n\t\tOffsetLabel.Text = str;\n\t}\n\n\t///<summary>\n\t/// Updates the selection status bar with data from the specified DataView,\n\t/// if the specified DataView is active\n\t///</summary>\n\tpublic void UpdateSelection(DataView dv)\n\t{\n\t\tif (dataBook.NPages == 0)\n\t\t\treturn;\n\n\t\tDataView curdv = ((DataViewDisplay)dataBook.CurrentPageWidget).View;\n\t\tif (curdv != dv)\n\t\t\treturn;\n\n\t\tBless.Util.Range sel = dv.Selection;\n\t\t\n\t\tstring str;\n\n\t\tif (sel.IsEmpty() == true)\n\t\t\tstr = Catalog.GetString(\"Selection: None\");\n\t\telse {\n\t\t\tstring startString = BaseConverter.ConvertToString(sel.Start, numberBase, true, true, 1);\n\t\t\tstring endString = BaseConverter.ConvertToString(sel.End, numberBase, true, true, 1);\n\t\t\tstring sizeString = BaseConverter.ConvertToString(sel.Size, numberBase, true, true, 1);\n\n\t\t\tstr = string.Format(Catalog.GetString(\"Selection: {0} to {1}\") + \" \" + Catalog.GetPluralString(\"({2} byte)\", \"({2} bytes)\", (int)sel.Size),\n\t\t\t\t\tstartString, endString, sizeString);\n\t\t}\n\n\t\tSelectionLabel.Text = str;\n\t}\n\n\t///<summary>\n\t/// Updates the overwrite status bar with data from the specified DataView,\n\t/// if the specified DataView is active\n\t///</summary>\n\tpublic void UpdateOverwrite(DataView dv)\n\t{\n\t\tif (dataBook.NPages == 0)\n\t\t\treturn;\n\n\t\tDataView curdv = ((DataViewDisplay)dataBook.CurrentPageWidget).View;\n\t\tif (curdv != dv)\n\t\t\treturn;\n\n\t\tif (dv.Overwrite == true)\n\t\t\tOverwriteLabel.Text = Catalog.GetString(\"OVR\");\n\t\telse\n\t\t\tOverwriteLabel.Text = Catalog.GetString(\"INS\");\n\t}\n\n\t///<summary>\n\t/// Clears the information displayed in the infobar\n\t///</summary>\n\tpublic void ClearMessage()\n\t{\n\t\tOffsetLabel.Text = Catalog.GetString(\"Offset: -\");\n\t\tSelectionLabel.Text = Catalog.GetString(\"Selection: None\");\n\t}\n\n\t///<summary>Handle button press on Ins/Ovr statusbar</summary>\n\tvoid OnOverwriteLabelPressed (object o, ButtonPressEventArgs args)\n\t{\n\t\tif (dataBook.NPages > 0) {\n\t\t\tGdk.EventButton e = args.Event;\n\t\t\t// ignore double and triple-clicks\n\t\t\tif (e.Type != Gdk.EventType.ButtonPress)\n\t\t\t\treturn;\n\n\t\t\t// set edit mode\n\t\t\tDataView dv = ((DataViewDisplay)dataBook.CurrentPageWidget).View;\n\t\t\tdv.Overwrite = !dv.Overwrite;\n\t\t}\n\t}\n\n\tvoid ChangeNumberBase(object o, ButtonPressEventArgs args)\n\t{\n\t\tif (dataBook.NPages == 0)\n\t\t\treturn;\n\n\t\tGdk.EventButton e = args.Event;\n\t\t// ignore double and triple-clicks\n\t\tif (e.Type != Gdk.EventType.ButtonPress)\n\t\t\treturn;\n\n\t\t// cycle 8, 10 and 16 number bases\n\t\tif (this.NumberBase == 8)\n\t\t\tthis.NumberBase = 10;\n\t\telse if (this.NumberBase == 10)\n\t\t\tthis.NumberBase = 16;\n\t\telse if (this.NumberBase == 16)\n\t\t\tthis.NumberBase = 8;\n\t}\n\n\tvoid OnPreferencesChanged(Preferences prefs)\n\t{\n\t\tif (prefs[\"View.Statusbar.Show\"] == \"True\")\n\t\t\tthis.Visible = true;\n\t\telse\n\t\t\tthis.Visible = false;\n\n\t\tif (Preferences.Instance[\"View.Statusbar.Offset\"] == \"True\")\n\t\t\tthis.OffsetVisible = true;\n\t\telse\n\t\t\tthis.OffsetVisible = false;\n\n\t\tif (Preferences.Instance[\"View.Statusbar.Selection\"] == \"True\")\n\t\t\tthis.SelectionVisible = true;\n\t\telse\n\t\t\tthis.SelectionVisible = false;\n\n\t\tif (Preferences.Instance[\"View.Statusbar.Overwrite\"] == \"True\")\n\t\t\tthis.OverwriteVisible = true;\n\t\telse\n\t\t\tthis.OverwriteVisible = false;\n\t}\n}\n\n} // end namespace\n"
  },
  {
    "path": "src/gui/plugins/PatternMatchHighlightPlugin.cs",
    "content": "// created on 20/3/2008 at 9:02 PM\n/*\n *   Copyright (c) 2008, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System;\nusing Gtk;\nusing Bless.Util;\nusing Bless.Tools.Find;\nusing Bless.Tools;\nusing Bless.Gui;\nusing Bless.Buffers;\nusing Bless.Plugins;\nusing Bless.Gui.Areas;\nusing Bless.Gui.Drawers;\n\nnamespace Bless.Gui.Plugins {\n\npublic class PatternMatchHighlightPlugin : GuiPlugin\n{\n\tDataBook dataBook;\n\tPatternHighlighter patternHighlighter;\n\tWindow mainWindow;\n\tIPluginPreferences pluginPreferences;\n\n\tpublic PatternMatchHighlightPlugin(Window mw, UIManager uim)\n\t{\n\t\tmainWindow = mw;\n\t\tpluginPreferences = new PatternMatchPreferences();\n\n\t\tname = \"PatternMatchHighlight\";\n\t\tauthor = \"Alexandros Frantzis\";\n\t\tdescription = \"Highlights all matches of the current selection\";\n\t}\n\n\tpublic override bool Load()\n\t{\n\t\tdataBook = (DataBook)GetDataBook(mainWindow);\n\n\t\tpatternHighlighter = new PatternHighlighter(dataBook);\n\n\t\tPreferences.Proxy.Subscribe(\"Highlight.PatternMatch\", \"ph\", new PreferencesChangedHandler(OnPreferencesChanged));\n\n\t\tloaded = true;\n\t\treturn true;\n\t}\n\n\tpublic override IPluginPreferences PluginPreferences {\n\t\tget { return pluginPreferences; }\n\t}\n\n\tvoid OnPreferencesChanged(Preferences prefs)\n\t{\n\t\tif (prefs[\"Highlight.PatternMatch\"] == \"True\")\n\t\t\tpatternHighlighter.Active = true;\n\t\telse\n\t\t\tpatternHighlighter.Active = false;\n\t}\n}\n\n\nclass PatternHighlighter\n{\n\tDataBook dataBook;\n\tbool active;\n\tIFindStrategy findStrategy;\n\t\n\tpublic bool Active {\n\t\tget { return active; }\n\t\tset { \n\t\t\tactive = value;\n\t\t\tif (dataBook.NPages > 0) {\n\t\t\t\tDataViewDisplay dvd = (DataViewDisplay)dataBook.CurrentPageWidget;\n\t\t\t\tdvd.Redraw();\n\t\t\t}\n\t\t}\n\t}\n\t\n\tpublic PatternHighlighter(DataBook db)\n\t{\n\t\tdataBook = db;\n\t\tfindStrategy = new BMFindStrategy();\n\n\t\tforeach(DataViewDisplay dvd in dataBook.Children) {\n\t\t\tOnDataViewAdded(dvd.View);\n\t\t}\n\n\t\tdataBook.PageAdded += new DataView.DataViewEventHandler(OnDataViewAdded);\n\t\tdataBook.Removed += new RemovedHandler(OnDataViewRemoved);\n\t}\n\n\tvoid OnDataViewAdded(DataView dv)\n\t{\n\t\tdv.Display.Layout.AreaGroup.PreRenderEvent +=  new AreaGroup.PreRenderHandler(BeforeRender);\n\t}\n\n\tvoid OnDataViewRemoved(object o, RemovedArgs args)\n\t{\n\t\tDataViewDisplay dvd = (DataViewDisplay)args.Widget;\n\t\t\n\t\tdvd.Layout.AreaGroup.PreRenderEvent -=  new AreaGroup.PreRenderHandler(BeforeRender);\n\t}\n\n\t/// <summary>\n\t/// Adds pattern match highlights to an area group before it is rendered\n\t/// </summary>\n\tvoid BeforeRender(AreaGroup ag)\n\t{\n\t\tif (!active)\n\t\t\treturn;\n\t\t\t\n\t\tUtil.Range sel = ag.Selection;\n\t\t\n\t\tif (sel.IsEmpty() || sel.Size > 512)\n\t\t\treturn;\n\n\t\tint nrows;\n\t\tUtil.Range view = ag.GetViewRange(out nrows);\n\n\t\tfindStrategy.Buffer = ag.Buffer;\n\t\tfindStrategy.Position = view.Start;\n\t\tfindStrategy.Pattern = ag.Buffer.RangeToByteArray(sel);\n\t\t\n\t\t// Merge overlapping matches\n\t\tUtil.Range match;\n\t\tUtil.Range currentHighlight = new Util.Range();\n\t\t\n\t\twhile ((match = findStrategy.FindNext(view.End)) != null) {\n\t\t\tif (currentHighlight.End >= match.Start)\n\t\t\t\tcurrentHighlight.End = match.End;\n\t\t\telse { \n\t\t\t\tag.AddHighlight(currentHighlight.Start, currentHighlight.End, Drawer.HighlightType.PatternMatch);\n\t\t\t\tcurrentHighlight = match;\n\t\t\t}\n\t\t}\n\t\t\n\t\tag.AddHighlight(currentHighlight.Start, currentHighlight.End, Drawer.HighlightType.PatternMatch);\n\t}\t\n}\n\nclass PatternMatchPreferences : IPluginPreferences\n{\n\tPreferencesWidget preferencesWidget;\n\n\tpublic Widget Widget {\n\t\tget {\n\t\t\tif (preferencesWidget == null)\n\t\t\t\tInitWidget();\n\t\t\treturn preferencesWidget;\n\t\t}\n\t}\n\n\tpublic void LoadPreferences()\n\t{\n\t\tif (preferencesWidget == null)\n\t\t\tInitWidget();\n\n\t\tif (Preferences.Instance[\"Highlight.PatternMatch\"] == \"True\")\n\t\t\tpreferencesWidget.EnableHighlightCheckButton.Active = true;\n\t\telse\n\t\t\tpreferencesWidget.EnableHighlightCheckButton.Active = false;\n\t}\n\n\n\tpublic void SavePreferences()\n\t{\n\n\t}\n\n\tvoid InitWidget()\n\t{\n\t\tpreferencesWidget = new PreferencesWidget();\n\t\tpreferencesWidget.EnableHighlightCheckButton.Toggled += OnEnableHighlightToggled;\n\t}\n\n\tvoid OnEnableHighlightToggled(object o, EventArgs args)\n\t{\n\t\tPreferences.Instance[\"Highlight.PatternMatch\"] = preferencesWidget.EnableHighlightCheckButton.Active.ToString();\n\t}\n}\n\nclass PreferencesWidget : Gtk.HBox\n{\n\tGtk.CheckButton enableHighlightCheckButton;\n\t\n\tpublic Gtk.CheckButton EnableHighlightCheckButton {\n\t\tget { return enableHighlightCheckButton; }\n\t}\n\n\tpublic PreferencesWidget()\n\t{\n\t\tenableHighlightCheckButton = new Gtk.CheckButton(\"Highlight matches of selection pattern\");\n\t\tthis.PackStart(enableHighlightCheckButton, false, false, 6);\n\t\tthis.ShowAll();\n\t}\n}\n\n} // end namespace\n"
  },
  {
    "path": "src/gui/plugins/ProgressDisplayPlugin.cs",
    "content": "// created on 4/5/2007 at 2:06 PM\n/*\n *   Copyright (c) 2007, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing Gtk;\nusing System;\nusing Bless.Util;\nusing Bless.Gui;\nusing Bless.Plugins;\nusing Bless.Buffers;\nusing Mono.Unix;\n\nnamespace Bless.Gui.Plugins {\n\n///<summary>\n/// Plugin to display progress of various events in a uniform way\n///</summary>\npublic class ProgressDisplayPlugin : GuiPlugin\n{\n\tProgressDisplayWidget widget;\n\tWindow mainWindow;\n\n\n\tpublic ProgressDisplayPlugin(Window mw, UIManager uim)\n\t{\n\t\tmainWindow = mw;\n\n\t\tname = \"ProgressDisplay\";\n\t\tauthor = \"Alexandros Frantzis\";\n\t\tdescription = \"Progress Display Bar\";\n\t\tloadAfter.Add(\"Infobar\");\n\t}\n\n\tpublic override bool Load()\n\t{\n\t\twidget = new ProgressDisplayWidget();\n\t\twidget.Visible = true;\n\n\t\t// register the service\n\t\tServices.UI.Progress = widget;\n\n\t\t((VBox)mainWindow.Child).PackEnd(widget, false, false, 0);\n\n\t\tloaded = true;\n\t\treturn true;\n\t}\n\n}\n\n///<summary>\n/// Widget that displays a series of progress bars\n///</summary>\npublic class ProgressDisplayWidget : Gtk.VBox, IProgressDisplay\n{\n\n\tpublic ProgressDisplayWidget()\n\t{\n\n\t}\n\n\t///<summary>\n\t/// Get a callback for a new progress bar\n\t///</summary>\n\tpublic ProgressCallback NewCallback()\n\t{\n\t\tProgressDisplayBar pdb = new ProgressDisplayBar();\n\n\t\tthis.PackStart(pdb);\n\t\tpdb.DestroyEvent += OnProgressDisplayBarDestroyed;\n\n\t\treturn pdb.Update;\n\t}\n\n\tvoid OnProgressDisplayBarDestroyed (object o, DestroyEventArgs args)\n\t{\n\t\tProgressDisplayBar pdb = (ProgressDisplayBar)o;\n\n\t\tpdb.DestroyEvent -= OnProgressDisplayBarDestroyed;\n\n\t\tthis.Remove(pdb);\n\t}\n\n}\n\npublic class ProgressDisplayBar : Gtk.HBox {\n\n\t[Gtk.Builder.Object] Gtk.HBox ProgressBarHBox;\n\t[Gtk.Builder.Object] Gtk.Button CancelButton;\n\t[Gtk.Builder.Object] Gtk.ProgressBar ProgressBar;\n\n\tbool cancelClicked;\n\n\tpublic ProgressDisplayBar()\n\t{\n\t\tGtk.Builder builder = new Gtk.Builder();\n\t\tbuilder.AddFromFile(FileResourcePath.GetDataPath(\"ui\", \"ProgressDisplayPlugin.ui\"));\n\t\tbuilder.Autoconnect(this);\n\n\t\tthis.Add(ProgressBarHBox);\n\t\tthis.Hide();\n\t}\n\n\t///<summary>\n\t/// Handles the various progress actions\n\t///</summary>\n\tpublic bool Update(object o, ProgressAction action)\n\t{\n\t\tif (action == ProgressAction.Hide) {\n\t\t\tthis.Visible = false;\n\t\t\treturn false;\n\t\t}\n\t\telse if (action == ProgressAction.Show) {\n\t\t\tthis.Visible = true;\n\t\t\treturn false;\n\t\t}\n\t\telse if (action == ProgressAction.Message) {\n\t\t\tProgressBar.Text = (string)o;\n\t\t\treturn false;\n\t\t}\n\t\telse if (action == ProgressAction.Destroy) {\n\t\t\tthis.Destroy();\n\t\t\treturn false;\n\t\t}\n\n\t\tProgressBar.Fraction = (double)o;\n\n\t\tif (cancelClicked == true) {\n\t\t\tcancelClicked = false;\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t}\n\n\tpublic void OnCancelButtonClicked(object o, EventArgs args)\n\t{\n\t\tcancelClicked = true;\n\t}\n}\n\n\n\n} // end namespace\n"
  },
  {
    "path": "src/gui/plugins/SelectLayoutPlugin.cs",
    "content": "// created on 10/24/2006 at 12:59 PM\n/*\n *   Copyright (c) 2006, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing Bless.Buffers;\nusing Bless.Gui;\nusing Bless.Plugins;\nusing Bless.Gui.Dialogs;\nusing Bless.Tools;\nusing System;\nusing System.IO;\nusing Gtk;\nusing Mono.Unix;\n\nnamespace Bless.Gui.Plugins {\n\npublic class SelectLayoutPlugin : GuiPlugin\n{\n\tconst string uiXml =\n\t\t\"<menubar>\" +\n\t\t\"\t<menu action=\\\"View\\\">\" +\n\t\t\"\t\t<menuitem name=\\\"Layouts\\\" action=\\\"LayoutsAction\\\" position=\\\"top\\\" />\" +\n\t\t\"\t\t<separator/>\" +\n\t\t\"\t</menu>\" +\n\t\t\"</menubar>\";\n\n\tDataBook dataBook;\n\tWindow mainWindow;\n\tUIManager uiManager;\n\n\tpublic SelectLayoutPlugin(Window mw, UIManager uim)\n\t{\n\t\tmainWindow = mw;\n\t\tuiManager = uim;\n\n\t\tname = \"SelectLayout\";\n\t\tauthor = \"Alexandros Frantzis\";\n\t\tdescription = \"Change the layout of a view\";\n\t}\n\n\tpublic override bool Load()\n\t{\n\t\tdataBook = (DataBook)GetDataBook(mainWindow);\n\n\t\tAddMenuItems(uiManager);\n\n\t\tloaded = true;\n\t\treturn true;\n\t}\n\n\tprivate void AddMenuItems(UIManager uim)\n\t{\n\t\tActionEntry[] actionEntries = new ActionEntry[] {\n\t\t\t\t\t\t\t\t\t\t  new ActionEntry (\"LayoutsAction\", null, Catalog.GetString(\"_Layouts...\"), \"<shift><ctrl>L\", null,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   new EventHandler(OnLayoutsActivated)),\n\t\t\t\t\t\t\t\t\t  };\n\n\t\tActionGroup group = new ActionGroup (\"SelectLayoutActions\");\n\t\tgroup.Add (actionEntries);\n\n\t\tuim.InsertActionGroup(group, 0);\n\t\tuim.AddUiFromString(uiXml);\n\n\t\tuim.EnsureUpdate();\n\n\t}\n\n\t///<summary>Handle view->layouts command from menu</summary>\n\tpublic void OnLayoutsActivated(object o, EventArgs args)\n\t{\n\t\tLayoutSelectionDialog lsd = new LayoutSelectionDialog(dataBook);\n\t\tlsd.Show();\n\t}\n}\n\n\n\n} //end namespace\n"
  },
  {
    "path": "src/gui/plugins/SelectRangePlugin.cs",
    "content": "/*\n *   Copyright (c) 2006, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing System;\nusing Gtk;\nusing Bless.Buffers;\nusing Bless.Util;\nusing Bless.Gui.Dialogs;\nusing Bless.Gui;\nusing Bless.Plugins;\nusing Mono.Unix;\n\nnamespace Bless.Gui.Plugins {\n\npublic class SelectRangePlugin : GuiPlugin\n{\n\tSelectRangeWidget widget;\n\n\tconst string uiXml =\n\t\t\"<menubar>\" +\n\t\t\"\t<menu action=\\\"Edit\\\">\" +\n\t\t\"\t\t<placeholder name=\\\"Extra\\\">\" +\n\t\t\"\t\t\t<menuitem name=\\\"SelectAll\\\" action=\\\"SelectAllAction\\\" />\" +\n\t\t\"\t\t\t<menuitem name=\\\"SelectRange\\\" action=\\\"SelectRangeAction\\\" />\" +\n\t\t\"\t\t</placeholder>\" +\n\t\t\"\t\t<separator/>\" +\n\t\t\"\t</menu>\" +\n\t\t\"</menubar>\";\n\n\tWindow mainWindow;\n\tUIManager uiManager;\n\tDataBook dataBook;\n\n\tpublic SelectRangePlugin(Window mw, UIManager uim)\n\t{\n\t\tmainWindow = mw;\n\t\tuiManager = uim;\n\n\t\tname = \"SelectRange\";\n\t\tauthor = \"Alexandros Frantzis\";\n\t\tdescription = \"Adds a select range bar\";\n\t\tloadAfter.Add(\"EditOperations\");\n\t}\n\n\tpublic override bool Load()\n\t{\n\t\tdataBook = (DataBook)GetDataBook(mainWindow);\n\t\twidget = new SelectRangeWidget(dataBook);\n\t\twidget.Visible = false;\n\n\t\tWidgetGroup wgroup = (WidgetGroup)GetWidgetGroup(mainWindow, 0);\n\t\twgroup.Add(widget);\n\n\t\tAddMenuItems(uiManager);\n\n\t\tloaded = true;\n\t\treturn true;\n\t}\n\n\tprivate void AddMenuItems(UIManager uim)\n\t{\n\t\tActionEntry[] actionEntries = new ActionEntry[] {\n\t\t\t\t\t\t\t\t\t\t  new ActionEntry (\"SelectAllAction\", null, Catalog.GetString(\"Select _All\"), \"<control>A\", null,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   new EventHandler(OnSelectAllActivated)),\n\t\t\t\t\t\t\t\t\t\t  new ActionEntry (\"SelectRangeAction\", Stock.JumpTo, Catalog.GetString(\"_Select Range\"), \"<shift><control>R\", null,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   new EventHandler(OnSelectRangeActivated)),\n\t\t\t\t\t\t\t\t\t  };\n\n\t\tActionGroup group = new ActionGroup (\"SelectRangeActions\");\n\t\tgroup.Add (actionEntries);\n\n\t\tuim.InsertActionGroup(group, 0);\n\t\tuim.AddUiFromString(uiXml);\n\n\t\tuim.EnsureUpdate();\n\n\t}\n\n\t///<summary>Handle the Edit->Select All command</summary>\n\tpublic void OnSelectAllActivated(object o, EventArgs args)\n\t{\n\t\tif (dataBook.NPages == 0)\n\t\t\treturn;\n\n\t\tDataView dv = ((DataViewDisplay)dataBook.CurrentPageWidget).View;\n\t\tdv.Selection = dv.Buffer.Range;\n\t}\n\n\t///<summary>Handle the Edit->Select Range command</summary>\n\tpublic void OnSelectRangeActivated(object o, EventArgs args)\n\t{\n\t\tif (dataBook.NPages > 0) {\n\t\t\tDataView dv = ((DataViewDisplay)dataBook.CurrentPageWidget).View;\n\t\t\twidget.LoadWithSelection(dv);\n\t\t}\n\n\t\twidget.Show();\n\t}\n}\n\n///<summary>\n/// A widget for the select range operation\n///</summary>\npublic class SelectRangeWidget : Gtk.HBox\n{\n\t[Gtk.Builder.Object] Gtk.HBox SelectRangeHBox;\n\t[Gtk.Builder.Object] Gtk.Button SelectButton;\n\t[Gtk.Builder.Object] Gtk.Entry FromEntry;\n\t[Gtk.Builder.Object] Gtk.Entry ToEntry;\n\t[Gtk.Builder.Object] Gtk.Button CloseButton;\n\n\tDataBook dataBook;\n\n\n\tpublic SelectRangeWidget(DataBook db)\n\t{\n\t\tdataBook = db;\n\n\t\tGtk.Builder builder = new Gtk.Builder();\n\t\tbuilder.AddFromFile(FileResourcePath.GetDataPath(\"ui\", \"SelectRangePlugin.ui\"));\n\t\tbuilder.Autoconnect(this);\n\n\t\t// set up entry completions\n\t\tFromEntry.Completion = new EntryCompletion();\n\t\tFromEntry.Completion.Model = new ListStore (typeof (string));\n\t\tFromEntry.Completion.TextColumn = 0;\n\n\t\tToEntry.Completion = new EntryCompletion();\n\t\tToEntry.Completion.Model = new ListStore (typeof (string));\n\t\tToEntry.Completion.TextColumn = 0;\n\n\t\t// set button sensitivity\n\t\tOnEntryChanged(null, null);\n\n\t\tthis.Shown += OnWidgetShown;\n\n\t\tthis.Add(SelectRangeHBox);\n\t\tthis.ShowAll();\n\t}\n\n\t///<summary>Load the widget with data from the DataView's selection</summary>\n\tpublic void LoadWithSelection(DataView dv)\n\t{\n\t\t// load selection only if it isn't very large\n\t\tif (dv.Selection.Size > 0) {\n\t\t\tBless.Util.Range sel = dv.Selection;\n\t\t\t\n\t\t\tFromEntry.Text = sel.Start.ToString();\n\t\t\tToEntry.Text = sel.End.ToString();\n\t\t}\n\t\telse {\n\t\t\tFromEntry.Text = dv.CursorOffset.ToString();\n\t\t}\n\n\t\tFromEntry.GrabFocus();\n\t}\n\n\t///<summary>\n\t/// Whether a widget in the SelectRangeWidget has the focus\n\t///</summary>\n\tbool IsFocusInWidget()\n\t{\n\t\tforeach (Gtk.Widget child in SelectRangeHBox.Children) {\n\t\t\tWidget realChild = child;\n\n\t\t\tif (child.GetType() == typeof(Gtk.Alignment))\n\t\t\t\trealChild = (child as Gtk.Alignment).Child;\n\n\t\t\tif (realChild.HasFocus)\n\t\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tvoid OnEntryChanged(object o, EventArgs args)\n\t{\n\t\tif (ToEntry.Text.Length > 0 && FromEntry.Text.Length > 0)\n\t\t\tSelectButton.Sensitive = true;\n\t\telse\n\t\t\tSelectButton.Sensitive = false;\n\t}\n\n\tvoid OnEntryActivated(object o, EventArgs args)\n\t{\n\t\tif (SelectButton.Sensitive == true)\n\t\t\tSelectButton.Click();\n\t}\n\n\tvoid OnSelectButtonClicked(object o, EventArgs args)\n\t{\n\t\tif (dataBook.NPages == 0)\n\t\t\treturn;\n\n\t\tDataView dv = ((DataViewDisplay)dataBook.CurrentPageWidget).View;\n\n\t\tlong fromOffset = -1;\n\t\tlong toOffset = -1;\n\t\tint relative = 0;\n\n\t\ttry {\n\t\t\tfromOffset = BaseConverter.Parse(FromEntry.Text);\n\t\t}\n\t\tcatch (FormatException e) {\n\t\t\tErrorAlert ea = new ErrorAlert(Catalog.GetString(\"Error in From Offset Format\"), e.Message, null);\n\t\t\tea.Run();\n\t\t\tea.Destroy();\n\t\t\treturn;\n\t\t}\n\n\t\tstring toString = ToEntry.Text.Trim();\n\n\t\tif (toString.StartsWith(\"+\"))\n\t\t\trelative = 1;\n\t\telse if (toString.StartsWith(\"-\"))\n\t\t\trelative = -1;\n\n\t\ttoString = toString.TrimStart(new char[]{'+', '-'});\n\n\t\ttry {\n\t\t\ttoOffset = BaseConverter.Parse(toString);\n\t\t}\n\t\tcatch (FormatException e) {\n\t\t\tErrorAlert ea = new ErrorAlert(Catalog.GetString(\"Error in To Offset Format\"), e.Message, null);\n\t\t\tea.Run();\n\t\t\tea.Destroy();\n\t\t\treturn;\n\t\t}\n\n\t\tif (relative != 0)\n\t\t\ttoOffset = fromOffset + relative * (toOffset - 1);\n\n\t\tif (toOffset >= 0 && toOffset < dv.Buffer.Size &&\n\t\t\t\tfromOffset >= 0 && fromOffset < dv.Buffer.Size) {\n\t\t\tdv.SetSelection(fromOffset, toOffset);\n\t\t\tdv.Display.MakeOffsetVisible(toOffset, DataViewDisplay.ShowType.Closest);\n\t\t\t// append string to drop-down lists\n\t\t\tListStore ls = (ListStore)ToEntry.Completion.Model;\n\t\t\tls.AppendValues(ToEntry.Text);\n\t\t\tls = (ListStore)FromEntry.Completion.Model;\n\t\t\tls.AppendValues(FromEntry.Text);\n\t\t}\n\t\telse {\n\t\t\tErrorAlert ea = new ErrorAlert(Catalog.GetString(\"Invalid Range\"), Catalog.GetString(\"The range you specified is outside the file's limits.\"), null);\n\t\t\tea.Run();\n\t\t\tea.Destroy();\n\t\t}\n\n\t}\n\n\tvoid OnWidgetShown(object o, EventArgs args)\n\t{\n\t\tFromEntry.GrabFocus();\n\t}\n\n\tprotected override bool OnKeyPressEvent(Gdk.EventKey e)\n\t{\n\t\tif (e.Key == Gdk.Key.Escape) {\n\t\t\tCloseButton.Click();\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t\treturn base.OnKeyPressEvent(e);\n\t}\n\n\tvoid OnCloseButtonClicked(object o, EventArgs args)\n\t{\n\t\t// give focus to active dataview if the widget has it\n\t\tif (dataBook.NPages > 0 && IsFocusInWidget()) {\n\t\t\tDataViewDisplay curdvd = (DataViewDisplay)dataBook.CurrentPageWidget;\n\t\t\tcurdvd.GrabKeyboardFocus();\n\t\t}\n\n\t\tthis.Hide();\n\t}\n}\n\n} // namespace\n"
  },
  {
    "path": "src/gui/plugins/StatisticsPlugin.cs",
    "content": "// created on 20/25/2006 at 3:24 PM\n/*\n *   Copyright (c) 2006, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System;\nusing System.Collections;\nusing Cairo;\nusing Gtk;\nusing Bless.Tools;\nusing Bless.Util;\nusing Bless.Gui;\nusing Bless.Gui.Dialogs;\nusing Bless.Buffers;\nusing Bless.Plugins;\n\nnamespace Bless.Gui.Plugins {\n\npublic class StatisticsPlugin : GuiPlugin\n{\n\tDataBook dataBook;\n\tWindow mainWindow;\n\tToggleAction statisticsAction;\n\tUIManager uiManager;\n\tStatisticsWidget sw;\n\n\tconst string uiXml =\n\t\t\"<menubar>\" +\n\t\t\"\t<menu action=\\\"Tools\\\">\" +\n\t\t\"\t\t<menuitem name=\\\"Statistics\\\" action=\\\"StatisticsAction\\\" />\" +\n\t\t\"\t</menu>\" +\n\t\t\"</menubar>\";\n\n\tpublic StatisticsPlugin(Window mw, UIManager uim)\n\t{\n\t\tmainWindow = mw;\n\t\tuiManager = uim;\n\n\t\tname = \"File Statistics\";\n\t\tauthor = \"Alexandros Frantzis\";\n\t\tdescription = \"File statistics\";\n\t}\n\n\tpublic override bool Load()\n\t{\n\t\tdataBook = (DataBook)GetDataBook(mainWindow);\n\t\tWidgetGroup wg = (WidgetGroup)GetWidgetGroup(mainWindow, 1);\n\t\tsw = new StatisticsWidget(dataBook);\n\n\t\twg.Add(sw);\n\n\t\tAddMenuItems(uiManager);\n\n\t\tPreferences.Proxy.Subscribe(\"Tools.Statistics.Show\", \"stats1\", new PreferencesChangedHandler(OnPreferencesChanged));\n\n\t\tloaded = true;\n\t\treturn true;\n\t}\n\n\n\n\tprivate void AddMenuItems(UIManager uim)\n\t{\n\t\tToggleActionEntry[] toggleActionEntries = new ToggleActionEntry[] {\n\t\t\t\t\tnew ToggleActionEntry (\"StatisticsAction\", null, \"File Statistics\", null, null,\n\t\t\t\t\t\t\t\t\t\t   new EventHandler(OnToolsStatisticsActivated), false),\n\t\t\t\t};\n\n\t\tActionGroup group = new ActionGroup (\"StatisticsActions\");\n\t\tgroup.Add (toggleActionEntries);\n\n\t\tuim.InsertActionGroup(group, 0);\n\t\tuim.AddUiFromString(uiXml);\n\t\tstatisticsAction = (ToggleAction)uim.GetAction(\"/menubar/Tools/Statistics\");\n\n\t\tuim.EnsureUpdate();\n\t}\n\n\t///<summary>Handle the View->Conversion Table command</summary>\n\tpublic void OnToolsStatisticsActivated(object o, EventArgs args)\n\t{\n\t\tPreferences.Proxy.Change(\"Tools.Statistics.Show\", statisticsAction.Active.ToString(), \"stats1\");\n\t}\n\n\tvoid OnPreferencesChanged(Preferences prefs)\n\t{\n\t\tConsole.WriteLine(\"Prefs changed stat1\");\n\t\tif (prefs[\"Tools.Statistics.Show\"] == \"True\")\n\t\t\tstatisticsAction.Active = true;\n\t\telse\n\t\t\tstatisticsAction.Active = false;\n\t}\n}\n\npublic class StatisticsInfo\n{\n\tpublic int[] Freqs;\n\tpublic bool Changed;\n\n\tpublic StatisticsInfo()\n\t{\n\t\tFreqs = new int[256];\n\t\tChanged = true;\n\t}\n}\n\npublic class StatisticsWidget : Gtk.HBox\n{\n\tStatisticsDrawWidget  sdw;\n\tDataBook dataBook;\n\tHashtable info;\n\n\tpublic StatisticsWidget(DataBook db)\n\t{\n\t\tinfo = new Hashtable();\n\t\tdataBook = db;\n\t\tdataBook.SwitchPage += new SwitchPageHandler(OnSwitchPage);\n\t\tdataBook.PageAdded += new DataView.DataViewEventHandler(OnDataViewAdded);\n\t\tdataBook.Removed += new RemovedHandler(OnDataViewRemoved);\n\n\t\tforeach(DataViewDisplay dvd in dataBook.Children) {\n\t\t\tdvd.View.Buffer.Changed += new ByteBuffer.ChangedHandler(OnBufferContentsChanged);\n\t\t\tdvd.View.BufferChanged += new DataView.DataViewEventHandler(OnBufferChanged);\n\t\t\tinfo[dvd.View] = new StatisticsInfo();\n\t\t}\n\n\t\tsdw = new StatisticsDrawWidget();\n\n\t\tPreferences.Proxy.Subscribe(\"Tools.Statistics.Show\", \"stats2\", new PreferencesChangedHandler(OnPreferencesChanged));\n\n\t\tthis.Add(sdw);\n\t\tthis.ShowAll();\n\t}\n\n\tvoid OnDialogResponse(object o, Gtk.ResponseArgs args)\n\t{\n\t\tdataBook.SwitchPage -= new SwitchPageHandler(OnSwitchPage);\n\t\tdataBook.PageAdded -= new DataView.DataViewEventHandler(OnDataViewAdded);\n\t\tdataBook.Removed -= new RemovedHandler(OnDataViewRemoved);\n\n\t\tforeach(DataViewDisplay dvd in dataBook.Children) {\n\t\t\tdvd.View.Buffer.Changed -= new ByteBuffer.ChangedHandler(OnBufferContentsChanged);\n\t\t\tdvd.View.BufferChanged -= new DataView.DataViewEventHandler(OnBufferChanged);\n\t\t}\n\n\t\tthis.Destroy();\n\t}\n\n\tvoid OnDataViewAdded(DataView dv)\n\t{\n\t\tdv.Buffer.Changed += new ByteBuffer.ChangedHandler(OnBufferContentsChanged);\n\t\tdv.BufferChanged += new DataView.DataViewEventHandler(OnBufferChanged);\n\t\tinfo[dv] = new StatisticsInfo();\n\t}\n\n\tvoid OnDataViewRemoved(object o, RemovedArgs args)\n\t{\n\t\tDataView dv = ((DataViewDisplay)args.Widget).View;\n\t\tdv.Buffer.Changed -= new ByteBuffer.ChangedHandler(OnBufferContentsChanged);\n\t\tdv.BufferChanged -= new DataView.DataViewEventHandler(OnBufferChanged);\n\t\tinfo.Remove(dv);\n\t}\n\n\tvoid OnBufferChanged(DataView dv)\n\t{\n\t\tif (info.Contains(dv))\n\t\t\t(info[dv] as StatisticsInfo).Changed = true;\n\t\telse {\n\t\t\tStatisticsInfo si = new StatisticsInfo();\n\t\t\tinfo[dv] = si;\n\t\t}\n\n\t\tUpdateStatistics(dv);\n\t}\n\n\tvoid OnBufferContentsChanged(ByteBuffer bb)\n\t{\n\t\tDataView dv = null;\n\n\t\t// find DataView that owns bb\n\t\tforeach (DataViewDisplay dvtemp in dataBook.Children) {\n\t\t\tif (dvtemp.View.Buffer == bb) {\n\t\t\t\tdv = dvtemp.View;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (dv == null)\n\t\t\treturn;\n\n\t\tOnBufferChanged(dv);\n\t}\n\n\tvoid OnSwitchPage(object o, SwitchPageArgs args)\n\t{\n\t\tDataView dv = ((DataViewDisplay)dataBook.GetNthPage((int)args.PageNum)).View;\n\t\tif (dv == null)\n\t\t\treturn;\n\t\tif (!info.Contains(dv))\n\t\t\tinfo[dv] = new StatisticsInfo();\n\n\t\tUpdateStatistics(dv);\n\t}\n\n\tvoid UpdateStatistics(DataView dv)\n\t{\n\t\tDataView curdv = ((DataViewDisplay)dataBook.CurrentPageWidget).View;\n\t\tif (curdv != dv)\n\t\t\treturn;\n\t\tStatisticsInfo si = (info[dv] as StatisticsInfo);\n\t\tif (si.Changed == true) {\n\t\t\tByteBuffer bb = dv.Buffer;\n\n\t\t\tfor (int i = 0;i < si.Freqs.Length;i++) {\n\t\t\t\tsi.Freqs[i] = 0;\n\t\t\t}\n\n\t\t\tfor (int i = 0;i < bb.Size;i++) {\n\t\t\t\t++si.Freqs[bb[i]];\n\t\t\t}\n\n\t\t\tsi.Changed = false;\n\t\t}\n\n\t\tsdw.Update(si.Freqs);\n\t}\n\n\tprotected override void  OnHidden()\n\t{\n\t\tConsole.WriteLine(\"Stats Hide\");\n\t\tPreferences.Proxy.Change(\"Tools.Statistics.Show\", \"False\", \"stats2\");\n\t\tbase.OnHidden();\n\t}\n\n\tprotected override void OnShown()\n\t{\n\t\tPreferences.Proxy.Change(\"Tools.Statistics.Show\", \"True\", \"stats2\");\n\t\tbase.OnShown();\n\t}\n\n\tvoid OnPreferencesChanged(Preferences prefs)\n\t{\n\t\tConsole.WriteLine(\"Prefch STats2\");\n\n\t\tif (prefs[\"Tools.Statistics.Show\"] == \"True\")\n\t\t\tthis.Visible = true;\n\t\telse\n\t\t\tthis.Visible = false;\n\t}\n}\n\n///<summary> A widget to convert the data at the current offset to various types</summary>\npublic class StatisticsDrawWidget: Gtk.DrawingArea\n{\n\tint[] freqs;\n\tint[] dummyFreqs;\n\n\tPointD[] barStart;\n\tPointD[] barEnd;\n\n\tdouble freqWidth;\n\tint previousHighlight;\n\tint currentHighlight;\n\n\tvoid DrawBar(Cairo.Context gr, int b)\n\t{\n\t\tgr.MoveTo(barStart[b]);\n\t\tgr.LineTo (barEnd[b]);\n\t\tgr.Stroke();\n\t}\n\n\tvoid UpdateHighlight()\n\t{\n\t\tGdk.Window win = this.GdkWindow;\n\n\t\tCairo.Context g = Gdk.CairoHelper.Create(win);\n\n\t\tint x, y, w, h, d;\n\t\twin.GetGeometry(out x, out y, out w, out h, out d);\n\n\t\tg.Scale (w, h);\n\t\tg.LineWidth = (1.0 / freqs.Length) * 0.6;\n\n\t\tif (previousHighlight != -1) {\n\t\t\t/*int start=previousHighlight-1;\n\t\t\tint end=previousHighlight+1;\n\t\t\tif (start<0) start=0;\n\t\t\tif (end>=barStart.Length) end=barStart.Length-1;*/\n\t\t\tg.Color = new Color(0.0, 0.0, 0.0);\n\t\t\t//for(int i=start; i<=end; i++)\n\t\t\tDrawBar(g, previousHighlight);\n\t\t}\n\n\t\tif (currentHighlight != -1) {\n\t\t\tg.Color = new Color(1.0, 0.0, 0.0);\n\t\t\tDrawBar(g, currentHighlight);\n\t\t}\n\n\t}\n\n\tvoid Draw (Cairo.Context gr, int width, int height)\n\t{\n\t\tgr.Scale (width, height);\n\t\tgr.Color = new Color(1.0, 1.0, 1.0);\n\t\tgr.Rectangle(0.0, 0.0, 1.0, 1.0);\n\t\tgr.Stroke();\n\t\tgr.Color = new Color(0.0, 0.0, 0.0);\n\n\t\tgr.LineWidth = (1.0 / freqs.Length) * 0.6;\n\n\t\tfor (int i = 0; i < freqs.Length; i++) {\n\t\t\tif (previousHighlight == i)\n\t\t\t\tgr.Color = new Color(1.0, 0.0, 0.0);\n\t\t\tDrawBar(gr, i);\n\t\t\tif (previousHighlight == i)\n\t\t\t\tgr.Color = new Color(0.0, 0.0, 0.0);\n\t\t}\n\n\t}\n\n\tpublic StatisticsDrawWidget()\n\t{\n\t\tdummyFreqs = new int[0];\n\t\tbarStart = new PointD[0];\n\t\tbarEnd = new PointD[0];\n\t\tfreqs = dummyFreqs;\n\n\t\tthis.AddEvents((int)Gdk.EventMask.PointerMotionMask);\n\t\tthis.AddEvents((int)Gdk.EventMask.PointerMotionHintMask);\n\n\t\tthis.MotionNotifyEvent += OnMotionNotify;\n\t\tpreviousHighlight = -1;\n\t\tcurrentHighlight = -1;\n\t}\n\n\tprotected override bool OnExposeEvent (Gdk.EventExpose args)\n\t{\n\t\tGdk.Window win = args.Window;\n\n\t\tCairo.Context g = Gdk.CairoHelper.Create(win);\n\n\t\tint x, y, w, h, d;\n\t\twin.GetGeometry(out x, out y, out w, out h, out d);\n\t\tthis.HeightRequest = w / 5;\n\n\t\tDraw (g, w, h);\n\n\t\treturn true;\n\t}\n\n\t///<summary>Update all conversion entries</summary>\n\tpublic void Update(int[] freqs)\n\t{\n\t\tif (freqs == null)\n\t\t\tthis.freqs = dummyFreqs;\n\t\telse {\n\t\t\tthis.freqs = freqs;\n\t\t\tif (freqs.Length != barStart.Length) {\n\t\t\t\tbarStart = new PointD[freqs.Length];\n\t\t\t\tbarEnd = new PointD[freqs.Length];\n\t\t\t}\n\t\t}\n\n\t\tDoDrawingCalculations();\n\t\tpreviousHighlight = -1;\n\t\tcurrentHighlight = -1;\n\t\tthis.QueueDraw();\n\t}\n\n\tvoid DoDrawingCalculations()\n\t{\n\t\tfreqWidth = (1.0 / freqs.Length);\n\n\t\tint max = 0;\n\n\t\tfor (int i = 0; i < freqs.Length; i++) {\n\t\t\tif (freqs[i] > max) max = freqs[i];\n\t\t}\n\n\t\tfor (int i = 0; i < barStart.Length; i++) {\n\t\t\tbarStart[i].X = i * freqWidth;\n\t\t\tbarStart[i].Y = 1.0;\n\t\t\tbarEnd[i].X = barStart[i].X;\n\t\t\tbarEnd[i].Y = 1.0 - ((double)freqs[i]) / max;\n\n\t\t}\n\n\t}\n\n\tvoid OnMotionNotify(object o, MotionNotifyEventArgs args)\n\t{\n\t\tGdk.EventMotion e = args.Event;\n\t\tint x, y;\n\t\tGdk.ModifierType state;\n\n\t\tif (e.IsHint)\n\t\t\tthis.GdkWindow.GetPointer(out x, out y, out state);\n\t\telse {\n\t\t\tx = (int)e.X;\n\t\t\ty = (int)e.Y;\n\t\t\tstate = e.State;\n\t\t}\n\t\tGdk.Rectangle alloc = this.Allocation;\n\t\t//Console.WriteLine(\"x {0} freq {1} width{2}\", x, freqWidth, alloc.Width);\n\t\tcurrentHighlight = (int)((x / (freqWidth * alloc.Width))) + 1;\n\t\tConsole.WriteLine(currentHighlight);\n\n\t\tif (previousHighlight != currentHighlight) {\n\t\t\tUpdateHighlight();\n\t\t\tpreviousHighlight = currentHighlight;\n\t\t}\n\t}\n}\n\n} // end namespace\n"
  },
  {
    "path": "src/meson.build",
    "content": "src_build_dir = meson.current_build_dir() # Used by tests\nassembly_install_dir = join_paths(get_option('libdir'), meson.project_name())\n\nconf_data = configuration_data()\nconf_data.set('PACKAGE', meson.project_name())\nconf_data.set('VERSION', meson.project_version())\nconf_data.set('GETTEXT_PACKAGE', meson.project_name())\nconf_data.set('datadir', join_paths(get_option('prefix'), get_option('datadir')))\nconf_data.set('blessassemblydir', join_paths(get_option('prefix'), assembly_install_dir))\n\nconfigure_defines_cs = configure_file(\n    input: 'util/ConfigureDefines.cs.tmpl.in',\n    output: 'ConfigureDefines.cs',\n    configuration: conf_data\n)\n\nbless_bin = configure_file(\n    input: 'bless-bin.in',\n    output: 'bless',\n    configuration: conf_data,\n    install_dir: join_paths(get_option('prefix'), get_option('bindir')),\n)\n\nutil_lib = library(\n    'Bless.Util',\n    files(\n        'util/BaseConverter.cs',\n        'util/ByteArray.cs',\n        'util/Deque.cs',\n        'util/FileResourcePath.cs',\n        'util/IntervalTree.cs',\n        'util/List.cs',\n        'util/Portable.cs',\n        'util/ProgressCallback.cs',\n        'util/RangeCollection.cs',\n        'util/Range.cs',\n        'util/RedBlackTree.cs',\n        'util/TempFile.cs',\n        'util/ThreadedAsyncOperation.cs'\n    ) + [configure_defines_cs],\n    dependencies: glib_sharp_2_dep,\n    cs_args: '-r:Mono.Posix',\n    install: true,\n    install_dir: assembly_install_dir,\n)\n\ntools_lib = library(\n    'Bless.Tools',\n    files(\n        'tools/History.cs',\n        'tools/Preferences.cs',\n        'tools/Session.cs',\n    ),\n    install: true,\n    install_dir: assembly_install_dir,\n)\n\nbuffers_lib = library(\n    'Bless.Buffers',\n    files(\n        'buffers/ByteBuffer.cs',\n        'buffers/ByteBufferAction.cs',\n        'buffers/FileBuffer.cs',\n        'buffers/IBuffer.cs',\n        'buffers/ISaveState.cs',\n        'buffers/SaveAsOperation.cs',\n        'buffers/SaveInPlaceOperation.cs',\n        'buffers/SaveOperation.cs',\n        'buffers/Segment.cs',\n        'buffers/SegmentCollection.cs',\n        'buffers/SimpleBuffer.cs'\n    ),\n    dependencies: gtk_sharp_2_dep,\n    cs_args: '-r:Mono.Posix',\n    link_with: [\n        tools_lib,\n        util_lib\n    ],\n    install: true,\n    install_dir: assembly_install_dir,\n)\n\ntools_export_lib = library(\n    'Bless.Tools.Export',\n    files(\n        'tools/export/ExporterOperation.cs',\n        'tools/export/IExportBuilder.cs',\n        'tools/export/IExporter.cs',\n        'tools/export/InterpretedPatternExporter.cs',\n        'tools/export/IPatternExporter.cs',\n    ),\n    cs_args: '-r:Mono.Posix',\n    link_with: [\n        buffers_lib,\n        util_lib\n    ],\n    install: true,\n    install_dir: assembly_install_dir,\n)\n\ntools_find_lib = library(\n    'Bless.Tools.Find',\n    files(\n        'tools/find/BMFindStrategy.cs',\n        'tools/find/FindAsyncResult.cs',\n        'tools/find/FindOperations.cs',\n        'tools/find/IFinder.cs',\n        'tools/find/IFindStrategy.cs',\n    ),\n    link_with: [\n        buffers_lib,\n        util_lib\n    ],\n    install: true,\n    install_dir: assembly_install_dir,\n)\n\ngui_drawers_lib = library(\n    'Bless.Gui.Drawers',\n    files(\n        'gui/drawers/AsciiDrawer.cs',\n        'gui/drawers/BinaryDrawer.cs',\n        'gui/drawers/DecimalDrawer.cs',\n        'gui/drawers/Drawer.cs',\n        'gui/drawers/HexDrawer.cs',\n        'gui/drawers/OctalDrawer.cs',\n        'gui/drawers/PixmapManager.cs',\n    ),\n    dependencies: gtk_sharp_2_dep,\n    install: true,\n    install_dir: assembly_install_dir,\n)\n\ngui_areas_lib = library(\n    'Bless.Gui.Areas',\n    files(\n        'gui/areas/Area.cs',\n        'gui/areas/AreaGroup.cs',\n        'gui/areas/Highlight.cs',\n    ),\n    dependencies: gtk_sharp_2_dep,\n    link_with: [\n        buffers_lib,\n        gui_drawers_lib,\n        tools_find_lib,\n        util_lib\n    ],\n    install: true,\n    install_dir: assembly_install_dir,\n)\n\nplugins_lib = library(\n    'Bless.Plugins',\n    files(\n        'plugins/AreaPlugin.cs',\n        'plugins/ExportPlugin.cs',\n        'plugins/GuiPlugin.cs',\n        'plugins/IPluginPreferences.cs',\n        'plugins/Plugin.cs',\n        'plugins/PluginManager.cs',\n    ),\n    dependencies: gtk_sharp_2_dep,\n    link_with: [\n        gui_areas_lib,\n        tools_export_lib,\n        util_lib\n    ],\n    install: true,\n    install_dir: assembly_install_dir,\n)\n    \ngui_lib = library(\n    'Bless.Gui',\n    files(\n        'gui/DataBook.cs',\n        'gui/DataBookFinder.cs',\n        'gui/DataViewControl.cs',\n        'gui/DataView.cs',\n        'gui/DataViewDisplay.cs',\n        'gui/dialogs/AboutDialog.cs',\n        'gui/dialogs/Alert.cs',\n        'gui/dialogs/ErrorAlert.cs',\n        'gui/dialogs/ExportDialog.cs',\n        'gui/dialogs/FileOverwriteAlert.cs',\n        'gui/dialogs/InformationAlert.cs',\n        'gui/dialogs/LayoutSelectionDialog.cs',\n        'gui/dialogs/PreferencesDialog.cs',\n        'gui/dialogs/ProgressDialog.cs',\n        'gui/dialogs/RevertConfirmationAlert.cs',\n        'gui/dialogs/SaveConfirmationAlert.cs',\n        'gui/dialogs/SaveConfirmationMultiAlert.cs',\n        'gui/dialogs/WarningAlert.cs',\n        'gui/FileChangedBar.cs',\n        'gui/FileService.cs',\n        'gui/Layout.cs',\n        'gui/Services.cs',\n        'gui/SessionService.cs',\n        'gui/UIService.cs',\n        'gui/WidgetGroup.cs',\n    ),\n    dependencies: gtk_sharp_2_dep,\n    cs_args: ['-r:Mono.Posix', '-nowarn:0169'],\n    link_with: [\n        buffers_lib,\n        gui_areas_lib,\n        gui_drawers_lib,\n        plugins_lib,\n        tools_export_lib,\n        tools_find_lib,\n        tools_lib,\n        util_lib,\n    ],\n    install: true,\n    install_dir: assembly_install_dir,\n)\n\ngui_plugins_lib = library(\n    'Bless.Gui.Plugins',\n    files(\n        'gui/plugins/BitwiseOperationsPlugin.cs',\n        'gui/plugins/ConversionTablePlugin.cs',\n        'gui/plugins/CopyOffsetPlugin.cs',\n        'gui/plugins/EditOperationsPlugin.cs',\n        'gui/plugins/FileExportPlugin.cs',\n        'gui/plugins/FileOperationsPlugin.cs',\n        'gui/plugins/FindReplacePlugin.cs',\n        'gui/plugins/GotoOffsetPlugin.cs',\n        'gui/plugins/HelpOperationsPlugin.cs',\n        'gui/plugins/HistoryPlugin.cs',\n        'gui/plugins/InfobarPlugin.cs',\n        'gui/plugins/PatternMatchHighlightPlugin.cs',\n        'gui/plugins/ProgressDisplayPlugin.cs',\n        'gui/plugins/SelectLayoutPlugin.cs',\n        'gui/plugins/SelectRangePlugin.cs',\n    ),\n    dependencies: gtk_sharp_2_dep,\n    cs_args: ['-r:Mono.Posix', '-nowarn:0169'],\n    link_with: [\n        buffers_lib,\n        gui_areas_lib,\n        gui_drawers_lib,\n        gui_lib,\n        plugins_lib,\n        tools_find_lib,\n        tools_lib,\n        util_lib,\n    ],\n    install: true,\n    install_dir: assembly_install_dir,\n)\n\ngui_areas_plugins_lib = library(\n    'Bless.Gui.Areas.Plugins',\n    files(\n        'gui/areas/AsciiArea.cs',\n        'gui/areas/BinaryArea.cs',\n        'gui/areas/DecimalArea.cs',\n        'gui/areas/GroupedArea.cs',\n        'gui/areas/HexArea.cs',\n        'gui/areas/OctalArea.cs',\n        'gui/areas/OffsetArea.cs',\n        'gui/areas/SeparatorArea.cs',\n    ),\n    dependencies: gtk_sharp_2_dep,\n    link_with: [\n        buffers_lib,\n        gui_areas_lib,\n        gui_drawers_lib,\n        plugins_lib,\n        util_lib,\n    ],\n    install: true,\n    install_dir: assembly_install_dir,\n)\n\ntools_export_plugins_lib = library(\n    'Bless.Tools.Export.Plugins',\n    files(\n        'tools/export/plugins/HTMLExportBuilder.cs',\n        'tools/export/plugins/HTMLExportPlugin.cs',\n        'tools/export/plugins/TextExportBuilder.cs',\n        'tools/export/plugins/TextExportPlugin.cs',\n    ),\n    cs_args: ['-r:Mono.Posix'],\n    link_with: [\n        buffers_lib,\n        plugins_lib,\n        tools_export_lib,\n        util_lib,\n    ],\n    install: true,\n    install_dir: assembly_install_dir,\n)\n\nbless = executable(\n    'bless',\n    files('gui/MainWindow.cs'),\n    dependencies: gtk_sharp_2_dep,\n    cs_args: ['-r:Mono.Posix', '-nowarn:0169'],\n    link_with: [\n        buffers_lib,\n        gui_areas_lib,\n        gui_areas_plugins_lib,\n        gui_drawers_lib,\n        gui_lib,\n        gui_plugins_lib,\n        plugins_lib,\n        tools_export_lib,\n        tools_find_lib,\n        tools_lib,\n        util_lib,\n    ],\n    install: true,\n    install_dir: assembly_install_dir,\n)\n"
  },
  {
    "path": "src/plugins/AreaPlugin.cs",
    "content": "// created on 6/7/2007 at 3:50 PM\n/*\n *   Copyright (c) 2006, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System.IO;\nusing Bless.Gui.Areas;\n\nnamespace Bless.Plugins\n{\n\npublic class AreaPlugin : Plugin\n{\n\tprotected AreaPlugin()\n\t{\n\n\t}\n\n\tpublic virtual Area CreateArea(AreaGroup ag)\n\t{\n\t\treturn null;\n\t}\n}\n\n\n\n}"
  },
  {
    "path": "src/plugins/ExportPlugin.cs",
    "content": "/*\n *   Copyright (c) 2006, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System.IO;\nusing Bless.Tools.Export;\n\nnamespace Bless.Plugins\n{\n\npublic class ExportPlugin : Plugin\n{\n\tprotected ExportPlugin()\n\t{\n\n\t}\n\n\tpublic virtual IExportBuilder CreateBuilder(Stream s)\n\t{\n\t\treturn null;\n\t}\n}\n\n\n\n}"
  },
  {
    "path": "src/plugins/GuiPlugin.cs",
    "content": "// created on 4/28/2006 at 4:57 PM\n/*\n *   Copyright (c) 2006, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing Gtk;\n\nnamespace Bless.Plugins\n{\n\npublic class GuiPlugin : Plugin\n{\n\n\tpublic GuiPlugin()\n\t{\n\n\t}\n\n\tprotected Widget GetDataBook(Window win)\n\t{\n\t\tVBox vbox = (VBox)win.Child;\n\t\tforeach (Widget child in vbox.Children) {\n\t\t\t//System.Console.WriteLine(\"Child: {0}\", child.GetType().ToString());\n\t\t\tif (child.GetType() == typeof(HBox)) {\n\t\t\t\tforeach (Widget child1 in ((HBox)child).Children) {\n\t\t\t\t\tif (child1.GetType().ToString() == \"Bless.Gui.DataBook\")\n\t\t\t\t\t\treturn child1;\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\t\treturn null;\n\t}\n\n\tprotected Widget GetMenuBar(Window win)\n\t{\n\t\tVBox vbox = (VBox)win.Child;\n\t\tforeach (Widget child in vbox.Children) {\n\t\t\t//System.Console.WriteLine(\"Child: {0}\", child.GetType().ToString());\n\t\t\tif (child.GetType() == typeof(MenuBar)) {\n\t\t\t\treturn child;\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\tprotected Widget GetWidgetGroup(Window win, int n)\n\t{\n\t\tVBox vbox = (VBox)win.Child;\n\t\tint i = 0;\n\t\tforeach (Widget child in vbox.Children) {\n\t\t\t//System.Console.WriteLine(\"Child: {0}\", child.GetType().ToString());\n\t\t\tif (child.GetType().ToString() == \"Bless.Gui.WidgetGroup\") {\n\t\t\t\tif (i == n)\n\t\t\t\t\treturn child;\n\t\t\t\telse\n\t\t\t\t\ti++;\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\tprotected Widget GetSideWidgetGroup(Window win, int n)\n\t{\n\t\tVBox vbox = (VBox)win.Child;\n\t\tint i = 0;\n\t\tHBox hbox = null;\n\n\t\tforeach (Widget child in vbox.Children) {\n\t\t\tSystem.Console.WriteLine(\"Child: {0}\", child.GetType().ToString());\n\t\t\tif (child.GetType().ToString() == \"Gtk.HBox\") {\n\t\t\t\thbox = (HBox)child;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (hbox == null)\n\t\t\treturn null;\n\n\t\tforeach (Widget child in hbox.Children) {\n\t\t\tSystem.Console.WriteLine(\"Child: {0}\", child.GetType().ToString());\n\t\t\tif (child.GetType().ToString() == \"Bless.Gui.WidgetGroup\") {\n\t\t\t\tif (i == n)\n\t\t\t\t\treturn child;\n\t\t\t\telse\n\t\t\t\t\ti++;\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\n}\n\n\n\n}\n\n\n"
  },
  {
    "path": "src/plugins/IPluginPreferences.cs",
    "content": "/*\n *   Copyright (c) 2008, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\npublic interface IPluginPreferences\n{\n\tGtk.Widget Widget { get; }\t\n\tvoid SavePreferences();\n\tvoid LoadPreferences();\n}\n"
  },
  {
    "path": "src/plugins/Plugin.cs",
    "content": "/*\n *   Copyright (c) 2006, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System;\nusing System.Collections.Generic;\n\nnamespace Bless.Plugins\n{\n\npublic class Plugin\n{\n\tprotected string name;\n\tprotected string author;\n\tprotected string description;\n\tprotected bool loaded;\n\tprotected List<string> dependencies;\n\tprotected List<string> loadAfter;\n\n\tpublic Plugin()\n\t{\n\t\tdependencies = new List<string>();\n\t\tloadAfter = new List<string>();\n\t}\n\n\tpublic virtual bool Load()\n\t{\n\t\treturn false;\n\t}\n\n\tpublic virtual bool UnLoad()\n\t{\n\t\treturn false;\n\t}\n\n\tpublic string Name {\n\t\tget { return name; }\n\t\tset { name = value; }\n\t}\n\n\tpublic string Author {\n\t\tget { return author;}\n\t\tset { author = value; }\n\t}\n\n\tpublic string Description {\n\t\tget { return description; }\n\t\tset { description = value; }\n\t}\n\n\tpublic bool Loaded {\n\t\tget { return loaded; }\n\t}\n\n\tpublic IList<string> Dependencies {\n\t\tget { return dependencies; }\n\t}\n\n\tpublic IList<string> LoadAfter {\n\t\tget { return loadAfter; }\n\t}\n\t\n\tpublic virtual IPluginPreferences PluginPreferences {\n\t\tget { return null; }\n\t}\n}\n\n}\n"
  },
  {
    "path": "src/plugins/PluginManager.cs",
    "content": "/*\n *   Copyright (c) 2006, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Specialized;\nusing System.Reflection;\nusing System.IO;\nusing System.Globalization;\nusing Bless.Util;\n\nnamespace Bless.Plugins\n{\n\npublic class PluginDependencyException : Exception\n{\n\tpublic PluginDependencyException(string msg)\n\t\t\t: base(msg)\n\t{ }\n}\n\npublic class PluginManager\n{\n\tDictionary<string, Plugin> plugins;\n\n\tType[] ctorArgTypes;\n\tobject[] ctorArgs;\n\tType pluginType;\n\n\tprivate PluginManager(Type pluginType, object[] args)\n\t{\n\t\tplugins = new Dictionary<string, Plugin>();\n\t\tthis.pluginType = pluginType;\n\n\t\tctorArgTypes = new Type[args.Length];\n\t\tctorArgs = args;\n\n\t\tfor (int i = 0; i < ctorArgs.Length; i++)\n\t\t\tctorArgTypes[i] = ctorArgs[i].GetType();\n\n\t\t// find system-wide plugins\n\t\tstring systemPluginDir = FileResourcePath.GetBinPath();\n\t\tstring[] systemPluginFiles = Directory.GetFiles(systemPluginDir);\n\t\tCompareInfo compare = CultureInfo.InvariantCulture.CompareInfo;\n\n\t\tforeach (string file in systemPluginFiles) {\n\t\t\tif (compare.IndexOf(file, \"plugin\", CompareOptions.IgnoreCase) >= 0\n\t\t\t\t\t&& file.EndsWith(\".dll\")) {\n\t\t\t\t//Console.WriteLine(\"Searching File {0}\", file);\n\t\t\t\tAddPluginFile(file);\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\t// find local user plugins\n\t\t\tstring userPluginDir = FileResourcePath.GetUserPath(\"plugins\");\n\t\t\tstring[] userPluginFiles = Directory.GetFiles(userPluginDir);\n\n\t\t\tforeach (string file in userPluginFiles) {\n\t\t\t\tif (compare.IndexOf(file, \"plugin\", CompareOptions.IgnoreCase) >= 0\n\t\t\t\t\t\t&& file.EndsWith(\".dll\")) {\n\t\t\t\t\t//Console.WriteLine(\"Searching File {0}\", file);\n\t\t\t\t\tAddPluginFile(file);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tcatch (IOException e) {\n\t\t\tSystem.Console.WriteLine(\"Failed to open plugins directory: \" + e.Message);\n\t\t}\n\n\t}\n\n\tprivate void AddPluginFile(string file)\n\t{\n\t\ttry {\n\t\t\tAssembly asm = Assembly.LoadFile(file);\n\t\t\tType[] types = asm.GetTypes();\n\n\t\t\tforeach(Type t in types) {\n\t\t\t\tif (t.BaseType == pluginType) {\n\t\t\t\t\t//Console.WriteLine(\"    Found Type {0}\", t.FullName);\n\t\t\t\t\tConstructorInfo ctor = t.GetConstructor(ctorArgTypes);\n\t\t\t\t\tAddToPluginCollection((Plugin)ctor.Invoke(ctorArgs));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tcatch (Exception e) {\n\t\t\tSystem.Console.WriteLine(e.Message);\n\t\t}\n\n\t}\n\n\tprivate void AddToPluginCollection(Plugin plugin)\n\t{\n\t\tplugins.Add(plugin.Name, plugin);\n\t\t//System.Console.WriteLine(\"Added plugin {0}\", plugin.Name);\n\t}\n\n\tpublic bool LoadPlugin(Plugin plugin)\n\t{\n\t\tStringCollection visited = new StringCollection();\n\t\treturn LoadPluginInternal(plugin, visited);\n\t}\n\n\tprivate bool LoadPluginInternal(Plugin plugin, StringCollection visited)\n\t{\n\t\tvisited.Add(plugin.Name);\n\t\tif (plugin.Loaded)\n\t\t\treturn true;\n\n\t\tforeach(string dep in plugin.Dependencies) {\n\t\t\tif (visited.Contains(dep))\n\t\t\t\tthrow new PluginDependencyException(\"Cyclic dependency detected!\");\n\t\t\tif (!plugins.ContainsKey(dep))\n\t\t\t\tthrow new PluginDependencyException(string.Format(\"Cannot find plugin '{0}' needed by '{1}'\", dep, plugin.Name));\n\n\t\t\tif (LoadPluginInternal(plugins[dep], visited) == false)\n\t\t\t\treturn false;\n\t\t}\n\n\t\tforeach(string la in plugin.LoadAfter) {\n\t\t\tif (visited.Contains(la))\n\t\t\t\tthrow new PluginDependencyException(\"Cyclic LoadAfter association detected!\");\n\t\t\tif (plugins.ContainsKey(la))\n\t\t\t\tLoadPluginInternal(plugins[la], visited);\n\t\t}\n\n\n\t\treturn plugin.Load();\n\t}\n\n\tpublic Plugin[] Plugins {\n\t\tget {\n\t\t\tPlugin[] pa = new Plugin[plugins.Count];\n\t\t\tint i = 0;\n\t\t\tforeach (Plugin p in plugins.Values)\n\t\t\t\tpa[i++] = p;\n\n\t\t\treturn pa;\n\t\t}\n\n\t}\n\n\tstatic Dictionary<Type, PluginManager> pluginManagers = new Dictionary<Type, PluginManager>(); \n\t\n\tpublic static void AddForType(Type pluginType, object[] args)\n\t{\n\t\tPluginManager pm = new PluginManager(pluginType, args);\n\t\tpluginManagers[pluginType] = pm;\n\t}\n\t\n\tpublic static PluginManager GetForType(Type pluginType)\n\t{\n\t\tPluginManager ret = null;\n\t\t\n\t\tif (pluginManagers.ContainsKey(pluginType)) {\n\t\t\tret = pluginManagers[pluginType];\n\t\t}\n\t\t\n\t\treturn ret;\n\t}\n\n\tpublic static IEnumerable<KeyValuePair<Type, PluginManager>> AllManagers {\n\t\tget { return pluginManagers; }\n\t}\n}\n\n}\n"
  },
  {
    "path": "src/tools/History.cs",
    "content": "// created on 4/20/2005 at 2:14 PM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing System;\nusing System.Collections.Generic;\nusing System.Xml;\nusing System.IO;\n\nnamespace Bless.Tools {\n\n///<summary>\n/// A class that handles recently used files history (singleton)\n///</summary>\npublic class History\n{\n\n\tList<string> files;\n\tint maxSize;\n\tstatic History instance;\n\n\t///<summary>\n\t/// The current history\n\t///</summary>\n\tstatic public History Instance {\n\t\tget {\n\t\t\tif (instance == null)\n\t\t\t\tinstance = new History(5);\n\t\t\treturn instance;\n\t\t}\n\t}\n\n\t///<summary>The file in the history</summary>\n\tpublic List<string> Files {\n\tget { return files; }\n\t}\n\n\t///<summary>The maximum size of the history</summary>\n\tpublic int MaxSize {\n\t\tget { return maxSize; }\n\t}\n\n\t///<summary>Create history with maximum size 'n'</summary>\n\tprivate History(int n)\n\t{\n\t\tfiles = new List<string>(n);\n\t\tmaxSize = n;\n\t}\n\n\t///<summary>Add a file to the history</summary>\n\tpublic void Add(string path)\n\t{\n\t\tif (files.Remove(path) == true) {\n\t\t\tfiles.Insert(0, path);\n\t\t}\n\t\telse {\n\t\t\tif (files.Count == maxSize)\n\t\t\t\tfiles.RemoveAt(files.Count - 1);\n\t\t\tfiles.Insert(0, path);\n\t\t}\n\n\t\tif (Changed != null)\n\t\t\tChanged(this);\n\t}\n\n\t///<summary>Load history from an xml file</summary>\n\tpublic void Load(string path)\n\t{\n\t\tXmlDocument xmlDoc = new XmlDocument();\n\t\txmlDoc.Load(path);\n\n\t\tXmlNodeList fileList = xmlDoc.GetElementsByTagName(\"file\");\n\n\t\tforeach(XmlNode fileNode in fileList) {\n\t\t\tthis.Add(fileNode.InnerText);\n\t\t}\n\t}\n\n\t///<summary>Save history to an xml file</summary>\n\tpublic void Save(string path)\n\t{\n\t\tXmlTextWriter xml = new XmlTextWriter(path, null);\n\t\txml.Formatting = Formatting.Indented;\n\t\txml.Indentation = 1;\n\t\txml.IndentChar = '\\t';\n\n\t\txml.WriteStartDocument(true);\n\n\t\txml.WriteStartElement(null, \"history\", null);\n\n\t\t// save them in reverse order\n\t\t// so that they are loaded normally\n\t\tfor (int i = files.Count - 1; i >= 0 ; i--) {\n\t\t\txml.WriteStartElement(null, \"file\", null);\n\t\t\txml.WriteString(files[i]);\n\t\t\txml.WriteEndElement();\n\t\t}\n\n\t\txml.WriteEndElement();\n\t\txml.WriteEndDocument();\n\t\txml.Close();\n\t}\n\n\tpublic delegate void HistoryChangedHandler(History his);\n\n\t//<summary>Emitted when history changes</summary>\n\tpublic event HistoryChangedHandler Changed;\n}\n\n} // end namespace\n"
  },
  {
    "path": "src/tools/Preferences.cs",
    "content": "// created on 5/24/2005 at 1:14 PM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing System;\nusing System.Xml;\nusing System.Collections;\n\nnamespace Bless.Tools {\n\npublic delegate void PreferencesChangedHandler(Preferences prefs);\n\n///<summary>\n/// A class that holds the application preferences (using singletons)\n///</summary>\npublic class Preferences\n{\n\tHashtable prefs;\n\tstring autoSavePath;\n\n\tstatic Preferences instance = null;\n\tstatic Preferences defaultPrefs = null;\n\tstatic PreferencesProxy proxy = null;\n\n\t///<summary>\n\t/// The current preferences\n\t///</summary>\n\tstatic public Preferences Instance {\n\t\tget {\n\t\t\tif (instance == null)\n\t\t\t\tinstance = new Preferences();\n\t\t\treturn instance;\n\t\t}\n\t}\n\n\t///<summary>\n\t/// The default preferences\n\t///</summary>\n\tstatic public Preferences Default {\n\t\tget {\n\t\t\tif (defaultPrefs == null)\n\t\t\t\tdefaultPrefs = new Preferences();\n\t\t\treturn defaultPrefs;\n\t\t}\n\t}\n\n\tstatic public PreferencesProxy Proxy {\n\t\tget {\n\t\t\tif (proxy == null)\n\t\t\t\tproxy = new PreferencesProxy(Preferences.Instance);\n\t\t\treturn proxy;\n\t\t}\n\t}\n\n\tprivate Preferences()\n\t{\n\t\tprefs = new Hashtable();\n\t\tautoSavePath = null;\n\t\tnotifyWhenSetting = true;\n\t}\n\n\t///<summary>\n\t/// Get or Set the value of a preference\n\t///</summary>\n\tpublic string this[string key] {\n\t\tget {\n\t\t\tstring s = (string)prefs[key];\n\t\t\tif (s == null)\n\t\t\t\ts = string.Empty;\n\t\t\treturn s;\n\t\t}\n\n\t\tset {\n\t\t\tprefs[key] = value;\n\t\t\t// save the preferences if autoSavePath is set\n\t\t\t// ignore exceptions\n\t\t\ttry {\n\t\t\t\tif (autoSavePath != null)\n\t\t\t\t\tSave(autoSavePath);\n\t\t\t}\n\t\t\tcatch (Exception e) {\n\t\t\t\tSystem.Console.WriteLine(e.Message);\n\t\t\t}\n\n\t\t\tif (notifyWhenSetting)\n\t\t\t\tPreferences.Proxy.Change(key, value, \"__Preferences__\");\n\n\t\t}\n\t}\n\n\tpublic string AutoSavePath {\n\tget { return autoSavePath; }\n\t\tset { autoSavePath = value; }\n\t}\n\n\tpublic IEnumerator GetEnumerator()\n\t{\n\t\treturn prefs.GetEnumerator();\n\t}\n\n\tpublic void SetWithoutNotify(string pref, string val)\n\t{\n\t\tnotifyWhenSetting = false;\n\t\tthis[pref] = val;\n\t\tnotifyWhenSetting = true;\n\t}\n\n\t///<summary>\n\t/// Save preferences to an Xml file\n\t///</summary>\n\tpublic void Save(string path)\n\t{\n\t\tusing (XmlTextWriter xml = new XmlTextWriter(path, null)) {\n\t\t\txml.Formatting = Formatting.Indented;\n\t\t\txml.Indentation = 1;\n\t\t\txml.IndentChar = '\\t';\n\n\t\t\txml.WriteStartDocument();\n\t\t\txml.WriteStartElement(null, \"preferences\", null);\n\n\t\t\tforeach (DictionaryEntry entry in prefs) {\n\t\t\t\txml.WriteStartElement(null, \"pref\", null);\n\t\t\t\txml.WriteStartAttribute(null, \"name\", null);\n\t\t\t\txml.WriteString((string)entry.Key);\n\t\t\t\txml.WriteEndAttribute();\n\t\t\t\txml.WriteString((string)entry.Value);\n\t\t\t\txml.WriteEndElement();\n\t\t\t}\n\n\t\t\txml.WriteEndElement();\n\t\t\txml.WriteEndDocument();\n\t\t}\n\t}\n\n\t///<summary>\n\t/// Load preferences from an Xml file\n\t///</summary>\n\tpublic void Load(string path)\n\t{\n\t\tusing (XmlReader xmlReader = XmlReader.Create(path)) {\n\t\t\tXmlDocument xmlDoc = new XmlDocument();\n\t\t\txmlDoc.Load(xmlReader);\n\n\t\t\tXmlNodeList prefList = xmlDoc.GetElementsByTagName(\"pref\");\n\n\t\t\tforeach(XmlNode prefNode in prefList) {\n\t\t\t\tXmlAttributeCollection attrColl = prefNode.Attributes;\n\t\t\t\tstring name = attrColl[\"name\"].Value;\n\t\t\t\tprefs[name] = prefNode.InnerText;\n\t\t\t}\n\t\t}\n\t}\n\n\t///<summary>\n\t/// Load preferences from another Preferences instance\n\t///</summary>\n\tpublic void Load(Preferences p)\n\t{\n\t\tif (p != null) {\n\t\t\tforeach (DictionaryEntry entry in p)\n\t\t\tprefs[entry.Key] = entry.Value;\n\t\t}\n\t}\n\n\t///<summary>\n\t/// Display preferences\n\t///</summary>\n\tpublic void Display()\n\t{\n\t\tforeach (DictionaryEntry entry in prefs) {\n\t\t\tSystem.Console.WriteLine(\"[{0}]: {1}\", entry.Key, entry.Value);\n\t\t}\n\t}\n\n\tprivate bool notifyWhenSetting;\n}\n\npublic class PreferencesProxy\n{\n\tHashtable prefSubscribers;\n\tPreferences prefs;\n\tHashtable currentlyHandling;\n\n\tpublic PreferencesProxy(Preferences prefs)\n\t{\n\t\tprefSubscribers = new Hashtable();\n\t\tcurrentlyHandling = new Hashtable();\n\t\tthis.prefs = prefs;\n\t\tthis.enable = true;\n\t}\n\n\n\tpublic void Subscribe(string pref, string id, PreferencesChangedHandler handler)\n\t{\n\t\tif (!prefSubscribers.Contains(pref))\n\t\t\tprefSubscribers[pref] = new Hashtable();\n\n\t\t(prefSubscribers[pref] as Hashtable).Add(id, handler);\n\t}\n\n\tpublic void Unsubscribe(string pref, string id)\n\t{\n\t\tif (!prefSubscribers.Contains(pref))\n\t\t\treturn;\n\n\t\t(prefSubscribers[pref] as Hashtable).Remove(id);\n\n\t}\n\n\tpublic void Change(string pref, string val, string id)\n\t{\n\t\tif (enable == false)\n\t\t\treturn;\n\n\t\tif (currentlyHandling.Contains(pref))\n\t\t\treturn;\n\n\t\tif (id != \"__Preferences__\") {\n\t\t\tprefs.SetWithoutNotify(pref, val);\n\t\t}\n\n\t\tif (!prefSubscribers.Contains(pref))\n\t\t\treturn;\n\n\n\t\tcurrentlyHandling.Add(pref, null);\n\n\t\tforeach(DictionaryEntry subscriber in (prefSubscribers[pref] as Hashtable))\n\t\tif ((subscriber.Key as string) != id) {\n\t\t\t(subscriber.Value as PreferencesChangedHandler)(prefs);\n\t\t}\n\n\t\tcurrentlyHandling.Remove(pref);\n\t}\n\n\tpublic void NotifyAll()\n\t{\n\t\tif (enable == false)\n\t\t\treturn;\n\n\t\tforeach(DictionaryEntry prefSub in prefSubscribers) {\n\t\t\tcurrentlyHandling.Add(prefSub.Key, null);\n\t\t\tforeach(DictionaryEntry subscriber in (prefSub.Value as Hashtable))\n\t\t\t(subscriber.Value as PreferencesChangedHandler)(prefs);\n\t\t\tcurrentlyHandling.Remove(prefSub.Key);\n\t\t}\n\t}\n\n\tbool enable;\n\n\t///<summary>\n\t/// Enable or disable emission of the Changed event\n\t///</summary>\n\tpublic bool Enable {\n\t\tget { return enable; }\n\t\tset { enable = value; }\n\t}\n\n}\n\n} // end namespace\n"
  },
  {
    "path": "src/tools/Session.cs",
    "content": "// created on 4/15/2005 at 11:44 AM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing System;\nusing System.Collections;\nusing System.Xml;\nusing System.IO;\n\nnamespace Bless.Tools {\n\n///<summary>\n/// Handles the saving and loading of sessions\n/// (files that describe the current workspace)\n///</summary>\npublic class Session\n{\n\tint windowWidth;\n\tint windowHeight;\n\tstring activeFile;\n\n\tArrayList files;\n\n\tpublic ArrayList Files {\n\t\tget { return files; }\n\t}\n\n\tpublic int WindowWidth {\n\t\tget { return windowWidth;}\n\t\tset { windowWidth = value;}\n\t}\n\n\tpublic int WindowHeight {\n\t\tget { return windowHeight;}\n\t\tset { windowHeight = value;}\n\t}\n\n\tpublic string ActiveFile {\n\t\tget { return activeFile; }\n\t\tset { activeFile = value; }\n\t}\n\n\tpublic Session()\n\t{\n\t\tfiles = new ArrayList();\n\t\tactiveFile = string.Empty;\n\t}\n\n\tpublic void AddFile(string name, long offset, long cursorOffset, int cursorDigit, string layout, int focusedArea)\n\t{\n\t\tstring path = Path.GetFullPath(name);\n\t\tSessionFileInfo sfi = new SessionFileInfo(path, offset, cursorOffset, cursorDigit, layout, focusedArea);\n\t\tfiles.Add(sfi);\n\t}\n\n\tpublic void Save(string path)\n\t{\n                using (XmlTextWriter xml = new XmlTextWriter(path, null)) {\n                        xml.Formatting = Formatting.Indented;\n                        xml.Indentation = 1;\n                        xml.IndentChar = '\\t';\n\n                        xml.WriteStartDocument();\n\n                        xml.WriteStartElement(null, \"session\", null);\n\n                        xml.WriteStartElement(null, \"windowheight\", null);\n                        xml.WriteString(windowHeight.ToString());\n                        xml.WriteEndElement();\n\n                        xml.WriteStartElement(null, \"windowwidth\", null);\n                        xml.WriteString(windowWidth.ToString());\n                        xml.WriteEndElement();\n\n                        xml.WriteStartElement(null, \"activefile\", null);\n                        xml.WriteString(activeFile);\n                        xml.WriteEndElement();\n\n                        foreach(SessionFileInfo sfi in files) {\n                                xml.WriteStartElement(null, \"file\", null);\n                                xml.WriteStartElement(null, \"path\", null);\n                                xml.WriteString(sfi.Path);\n                                xml.WriteEndElement();\n                                xml.WriteStartElement(null, \"offset\", null);\n                                xml.WriteString(sfi.Offset.ToString());\n                                xml.WriteEndElement();\n                                xml.WriteStartElement(null, \"cursoroffset\", null);\n                                xml.WriteString(sfi.CursorOffset.ToString());\n                                xml.WriteEndElement();\n                                xml.WriteStartElement(null, \"cursordigit\", null);\n                                xml.WriteString(sfi.CursorDigit.ToString());\n                                xml.WriteEndElement();\n                                xml.WriteStartElement(null, \"layout\", null);\n                                xml.WriteString(sfi.Layout);\n                                xml.WriteEndElement();\n                                xml.WriteStartElement(null, \"focusedarea\", null);\n                                xml.WriteString(sfi.FocusedArea.ToString());\n                                xml.WriteEndElement();\n                                xml.WriteEndElement();\n                        }\n\n                        xml.WriteEndElement();\n                        xml.WriteEndDocument();\n                }\n\t}\n\n\tpublic void Load(string path)\n\t{\n        using (XmlReader xmlReader = XmlReader.Create(path)) {\n            XmlDocument xmlDoc = new XmlDocument();\n            xmlDoc.Load(xmlReader);\n\n            XmlNodeList fileList = xmlDoc.GetElementsByTagName(\"file\");\n\n            foreach(XmlNode fileNode in fileList) {\n                XmlNodeList childNodes = fileNode.ChildNodes;\n                SessionFileInfo sfi = new SessionFileInfo();\n                foreach(XmlNode node in childNodes) {\n                    switch (node.Name) {\n                        case \"path\":\n                            sfi.Path = node.InnerText;\n                            break;\n                        case \"offset\":\n                            sfi.Offset = Convert.ToInt64(node.InnerText);\n                            break;\n                        case \"cursoroffset\":\n                            sfi.CursorOffset = Convert.ToInt64(node.InnerText);\n                            break;\n                        case \"cursordigit\":\n                            sfi.CursorDigit = Convert.ToInt32(node.InnerText);\n                            break;\n                        case \"layout\":\n                            sfi.Layout = node.InnerText;\n                            break;\n                        case \"focusedarea\":\n                            sfi.FocusedArea = Convert.ToInt32(node.InnerText);\n                            break;\n                        default:\n                            break;\n                    }\n                }\n                files.Add(sfi);\n            }\n\n            XmlNodeList heightList = xmlDoc.GetElementsByTagName(\"windowheight\");\n            foreach(XmlNode heightNode in heightList) {\n                windowHeight = Convert.ToInt32(heightNode.InnerText);\n            }\n\n            XmlNodeList widthList = xmlDoc.GetElementsByTagName(\"windowwidth\");\n            foreach(XmlNode widthNode in widthList) {\n                windowWidth = Convert.ToInt32(widthNode.InnerText);\n            }\n\n            XmlNodeList activeList = xmlDoc.GetElementsByTagName(\"activefile\");\n            foreach(XmlNode activeNode in activeList) {\n                activeFile = activeNode.InnerText;\n            }\n\t\t}\n\t}\n}\n\n///<summary>\n/// Holds information about a file as part of a session\n///</summary>\npublic class SessionFileInfo\n{\n\tpublic string Path;\n\tpublic long Offset;\n\tpublic long CursorOffset;\n\tpublic int CursorDigit;\n\tpublic string Layout;\n\tpublic int FocusedArea;\n\n\tpublic SessionFileInfo() { }\n\n\tpublic SessionFileInfo(string path, long offset, long cursorOffset, int cursorDigit, string layout, int focusedArea)\n\t{\n\t\tPath = path; Offset = offset; CursorOffset = cursorOffset; CursorDigit = cursorDigit; Layout = layout; FocusedArea = focusedArea;\n\t}\n}\n\n} // end namespace\n"
  },
  {
    "path": "src/tools/export/ExporterOperation.cs",
    "content": "// created on 12/4/2006 at 9:36 PM\n/*\n *   Copyright (c) 2006, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System;\nusing Bless.Util;\nusing Bless.Buffers;\n\nnamespace Bless.Tools.Export\n{\n\npublic class ExportOperation : ThreadedAsyncOperation\n{\n\tIExporter exporter;\n\n\tIBuffer buffer;\n\tlong rangeStart;\n\tlong rangeEnd;\n\n\n\tpublic IExporter Exporter {\n\t\tget { return exporter; }\n\t}\n\n\tpublic ExportOperation(IExporter ex, IBuffer buf, long start, long end, ProgressCallback progressCb, AsyncCallback endCb)\n\t\t\t: base(progressCb, endCb, true)\n\t{\n\t\texporter = ex;\n\t\tbuffer = buf;\n\t\trangeStart = start;\n\t\trangeEnd = end;\n\t}\n\n\tprivate double CalculatePercentDone()\n\t{\n\t\treturn ((double)(exporter.CurrentPosition - rangeStart)) / (rangeEnd - rangeStart);\n\t}\n\n\tprotected override bool StartProgress()\n\t{\n\t\treturn progressCallback(CalculatePercentDone(), ProgressAction.Show);\n\t}\n\n\tprotected override bool UpdateProgress()\n\t{\n\t\treturn progressCallback(CalculatePercentDone(), ProgressAction.Update);\n\t}\n\n\tprotected override bool EndProgress()\n\t{\n\t\treturn progressCallback(CalculatePercentDone(), ProgressAction.Hide);\n\t}\n\n\tprotected override void DoOperation()\n\t{\n\t\tSystem.Console.WriteLine(\"Starting export\");\n\t\texporter.Export(buffer, rangeStart, rangeEnd, ref cancelled);\n\t\tSystem.Console.WriteLine(\"Ending export\");\n\t}\n\n\n\tprotected override void EndOperation()\n\t{\n\n\t}\n\n}\n\n\n}\n"
  },
  {
    "path": "src/tools/export/IExportBuilder.cs",
    "content": "/*\n *   Copyright (c) 2006, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System.IO;\nusing System.Collections;\nusing Bless.Buffers;\n\nnamespace Bless.Tools.Export\n{\n\npublic struct BuildBytesInfo\n{\n\tpublic int Count;\n\tpublic char Type;\n\tpublic string Prefix;\n\tpublic string Suffix;\n\tpublic string Separator;\n\tpublic string Empty;\n\tpublic Hashtable Commands;\n}\n\n///<summary>\n/// A builder that is used to export bytes\n///</summary>\npublic interface IExportBuilder\n{\n\tvoid BuildPrologue();\n\tvoid BuildEpilogue();\n\tint BuildBytes(IBuffer buffer, long offset, BuildBytesInfo info);\n\tvoid BuildString(string str);\n\tvoid BuildCharacter(char c);\n\tvoid BuildAlignment(int align);\n\tvoid BuildOffset(long offset, int length, char type);\n\n\tStream OutputStream {\n\t\tget;\n\t\t}\n\t}\n\n\n\n}\n"
  },
  {
    "path": "src/tools/export/IExporter.cs",
    "content": "/*\n *   Copyright (c) 2006, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing Bless.Buffers;\nusing System.IO;\n\nnamespace Bless.Tools.Export\n{\n\n///<summary>\n/// Exports a range of data to various formats\n///</summary>\npublic interface IExporter\n{\n\tvoid Export(IBuffer buffer, long start, long end, ref bool cancelled);\n\n\tIExportBuilder Builder {\n\t\tget;\n\t\t}\n\n\t\tlong CurrentPosition {\n\t\t\tget;\n\t\t\t}\n\t\t}\n\n\n\n} // end namespace"
  },
  {
    "path": "src/tools/export/IPatternExporter.cs",
    "content": "/*\n *   Copyright (c) 2006, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing Bless.Buffers;\nusing System.IO;\n\nnamespace Bless.Tools.Export\n{\n\n///<summary>\n/// Exports a range of data to various formats\n/// using a specific pattern\n///</summary>\npublic interface IPatternExporter : IExporter\n{\n\tstring Pattern {\n\t\tget;\n\t\t\tset;\n\t\t\t}\n\t\t}\n\n\n\n} // end namespace"
  },
  {
    "path": "src/tools/export/InterpretedPatternExporter.cs",
    "content": "/*\n *   Copyright (c) 2006, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System;\nusing System.Text;\nusing System.Collections.Generic;\nusing System.Collections;\nusing Bless.Buffers;\nusing Bless.Util;\nusing Mono.Unix;\n\nnamespace Bless.Tools.Export\n{\n\n///<summary>\n/// Exports a range of data to various formats\n/// using a specific pattern which is constantly\n/// interpreted\n///</summary>\npublic class InterpretedPatternExporter : IPatternExporter\n{\n\tIExportBuilder builder;\n\n\tstring pattern;\n\tint patternIndex;\n\n\tchar characterData;\n\tstring stringData;\n\n\tStack<long> positionStack;\n\n\tlong rangeStart;\n\tlong rangeEnd;\n\tlong bufPos;\n\tIBuffer buffer;\n\n\tenum Token { LeftBracket, RightBracket, Percent, Character, String, Error, End }\n\n\tpublic InterpretedPatternExporter(IExportBuilder ieb)\n\t{\n\t\tbuilder = ieb;\n\t\tpositionStack = new Stack<long>();\n\t}\n\n\tpublic void Export(IBuffer buf, long start, long end, ref bool cancelled)\n\t{\n\t\tbuffer = buf;\n\t\trangeStart = start;\n\t\trangeEnd = end;\n\t\tbufPos = rangeStart;\n\n\t\tlong prevLoop = bufPos;\n\t\tbool finished = false;\n\t\tbuilder.BuildAlignment(1);\n\t\tHashtable cmds = new Hashtable();\n\n\t\tbuilder.BuildPrologue();\n\n\t\twhile (!finished && !cancelled) {\n\n\t\t\tToken tok = NextToken();\n\t\t\tswitch (tok) {\n\t\t\t\tcase Token.LeftBracket:\n\t\t\t\t\tSavePosition(bufPos);\n\t\t\t\t\tbreak;\n\t\t\t\tcase Token.RightBracket:\n\t\t\t\t\tbufPos = RestorePosition();\n\t\t\t\t\tbreak;\n\t\t\t\tcase Token.Percent:\n\t\t\t\t\tcmds.Clear();\n\t\t\t\t\t// try to parse a command\n\t\t\t\t\ttok = ParseCommand(cmds);\n\t\t\t\t\t// if we ended at another '%' parse was succesful\n\t\t\t\t\tif (tok == Token.Percent)\n\t\t\t\t\t\tbufPos += ExecuteCommand(cmds);\n\t\t\t\t\telse // otherwise mark an error\n\t\t\t\t\t\ttok = Token.Error;\n\t\t\t\t\tbreak;\n\t\t\t\tcase Token.Character:\n\t\t\t\t\tbuilder.BuildCharacter(characterData);\n\t\t\t\t\tbreak;\n\t\t\t\tcase Token.String:\n\t\t\t\t\tbuilder.BuildString(stringData);\n\t\t\t\t\tbreak;\n\t\t\t\tcase Token.End:\n\t\t\t\t\tif (bufPos <= rangeEnd && prevLoop < bufPos) {\n\t\t\t\t\t\tprevLoop = bufPos;\n\t\t\t\t\t\tRestartInterpreter();\n\t\t\t\t\t}\n\t\t\t\t\t// if we reached the end of the pattern and we haven't moved forwards\n\t\t\t\t\t// in the file, this is never going to end!\n\t\t\t\t\telse if (prevLoop >= bufPos && bufPos <= rangeEnd)\n\t\t\t\t\t\tthrow new FormatException(Catalog.GetString(\"Pattern causes infinite loop\"));\n\t\t\t\t\telse\n\t\t\t\t\t\tfinished = true;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (tok == Token.Error)\n\t\t\t\tthrow new FormatException(string.Format(Catalog.GetString(\"Error at format position {0}\"), patternIndex));\n\t\t}\n\n\t\tif (!cancelled)\n\t\t\tbuilder.BuildEpilogue();\n\t}\n\n\tpublic IExportBuilder Builder {\n\tget { return builder; }\n\t}\n\n\tpublic long CurrentPosition {\n\t\tget { return bufPos; }\n\t}\n\n\tpublic string Pattern {\n\t\tget { return pattern; }\n\t\tset { pattern = value; }\n\t}\n\n\n\n\t///<summary>\n\t/// Execute the command described by the cmds hashtable\n\t///</summary>\n\tprivate int ExecuteCommand(Hashtable cmds)\n\t{\n\n\t\t// Export command\n\t\tif (cmds.Contains('E')) {\n\t\t\tBuildBytesInfo bbi = new BuildBytesInfo();\n\n\t\t\tbbi.Count = 1;\n\t\t\tif ((cmds['E'] as string) != \"\")\n\t\t\t\tbbi.Count = Convert.ToInt32(cmds['E'] as string);\n\n\t\t\tif (cmds.Contains('p'))\n\t\t\t\tbbi.Prefix = cmds['p'] as string;\n\t\t\tif (cmds.Contains('s'))\n\t\t\t\tbbi.Suffix = cmds['s'] as string;\n\t\t\tif (cmds.Contains('x'))\n\t\t\t\tbbi.Separator = cmds['x'] as string;\n\t\t\tif (cmds.Contains('e'))\n\t\t\t\tbbi.Empty = cmds['e'] as string;\n\n\t\t\tif (cmds.Contains('t'))\n\t\t\t\tbbi.Type = Convert.ToChar(cmds['t'] as string);\n\t\t\telse\n\t\t\t\tbbi.Type = 'H';\n\n\t\t\tbbi.Commands = cmds;\n\t\t\treturn builder.BuildBytes(buffer, bufPos, bbi);\n\t\t}\n\n\t\t// Ignore command\n\t\tif (cmds.Contains('I')) {\n\t\t\tif ((cmds['I'] as string) == \"\")\n\t\t\t\treturn 1;\n\t\t\telse\n\t\t\t\treturn Convert.ToInt32(cmds['I'] as string);\n\t\t}\n\n\t\t// Offset command\n\t\tif (cmds.Contains('O')) {\n\t\t\tchar type = 'H';\n\t\t\tif (cmds.Contains('t'))\n\t\t\t\ttype = Convert.ToChar(cmds['t'] as string);\n\n\t\t\tint length = 8;\n\t\t\tif ((cmds['O'] as string) != \"\")\n\t\t\t\tlength = Convert.ToInt32(cmds['O'] as string);\n\n\t\t\tbuilder.BuildOffset(bufPos, length, type);\n\t\t\treturn 0;\n\t\t}\n\n\t\t// Alignment command\n\t\tif (cmds.Contains('A')) {\n\t\t\tbuilder.BuildAlignment(Convert.ToInt32(cmds['A'] as string));\n\t\t\treturn 0;\n\t\t}\n\n\n\t\treturn 0;\n\t}\n\n\tprivate void SavePosition(long cur)\n\t{\n\t\tpositionStack.Push(cur);\n\t}\n\n\tprivate long RestorePosition()\n\t{\n\t\treturn positionStack.Pop();\n\t}\n\n\n\tprivate void RestartInterpreter()\n\t{\n\t\tpatternIndex = 0;\n\t}\n\n\tprivate Token NextToken()\n\t{\n\t\tif (patternIndex >= pattern.Length)\n\t\t\treturn Token.End;\n\n\t\tToken tok = Token.Error;\n\n\t\tswitch (pattern[patternIndex]) {\n\t\t\tcase '[':\n\t\t\t\tpatternIndex++;\n\t\t\t\ttok = Token.LeftBracket;\n\t\t\t\tbreak;\n\t\t\tcase ']':\n\t\t\t\tpatternIndex++;\n\t\t\t\ttok = Token.RightBracket;\n\t\t\t\tbreak;\n\t\t\tcase '%':\n\t\t\t\tpatternIndex++;\n\t\t\t\ttok = Token.Percent;\n\t\t\t\tbreak;\n\t\t\tcase '\"':\n\t\t\t\ttok = ParseString();\n\t\t\t\tbreak;\n\t\t\tcase '\\\\':\n\t\t\t\ttok = ParseEscapedCharacter();\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tcharacterData = pattern[patternIndex];\n\t\t\t\tpatternIndex++;\n\t\t\t\ttok = Token.Character;\n\t\t\t\tbreak;\n\t\t}\n\n\t\treturn tok;\n\t}\n\n\tprivate Token ParseString()\n\t{\n\t\tStringBuilder sb = new StringBuilder();\n\n\t\tpatternIndex++;\n\t\tbool finished = false;\n\t\twhile (patternIndex < pattern.Length && !finished) {\n\n\t\t\tswitch (pattern[patternIndex]) {\n\t\t\t\tcase '\\\\':\n\t\t\t\t\tToken tok = ParseEscapedCharacter();\n\t\t\t\t\tif (tok == Token.Error)\n\t\t\t\t\t\treturn Token.Error;\n\t\t\t\t\telse\n\t\t\t\t\t\tsb.Append(characterData);\n\t\t\t\t\tbreak;\n\t\t\t\tcase '\"':\n\t\t\t\t\tfinished = true;\n\t\t\t\t\tpatternIndex++;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tsb.Append(pattern[patternIndex]);\n\t\t\t\t\tpatternIndex++;\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t}\n\n\t\tif (!finished)\n\t\t\treturn Token.Error;\n\n\t\tstringData = sb.ToString();\n\n\t\treturn Token.String;\n\t}\n\n\tprivate Token ParseEscapedCharacter()\n\t{\n\t\tToken ret = Token.Error;\n\n\t\tif (patternIndex + 1 < pattern.Length) {\n\t\t\tswitch (pattern[patternIndex + 1]) {\n\t\t\t\tcase 'n':\n\t\t\t\t\tcharacterData = '\\n';\n\t\t\t\t\tret = Token.Character;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 't':\n\t\t\t\t\tcharacterData = '\\t';\n\t\t\t\t\tret = Token.Character;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tcharacterData = pattern[patternIndex + 1];\n\t\t\t\t\tret = Token.Character;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\tret = Token.Error;\n\n\t\tpatternIndex += 2;\n\n\t\treturn ret;\n\t}\n\n\t///<summary>\n\t/// Parse a pattern command eg %E\"4\"p\"0x\"%\n\t///</summary>\n\tprivate Token ParseCommand(Hashtable cmds)\n\t{\n\t\tbool finished = false;\n\n\t\tToken tok = Token.Error;\n\t\tchar currentChar = ' ';\n\n\t\twhile (!finished) {\n\n\t\t\ttok = NextToken();\n\t\t\tswitch (tok) {\n\t\t\t\tcase Token.Percent:\n\t\t\t\t\tfinished = true;\n\t\t\t\t\tbreak;\n\t\t\t\tcase Token.Character:\n\t\t\t\t\tcurrentChar = characterData;\n\t\t\t\t\tcmds[currentChar] = string.Empty;\n\t\t\t\t\tbreak;\n\t\t\t\tcase Token.String:\n\t\t\t\t\tcmds[currentChar] = stringData;\n\t\t\t\t\tbreak;\n\t\t\t\tcase Token.End:\n\t\t\t\t\tfinished = true;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\ttok = Token.Error;\n\t\t\t\t\tfinished = true;\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t}\n\n\t\treturn tok;\n\t}\n\n}\n\n}\n"
  },
  {
    "path": "src/tools/export/plugins/HTMLExportBuilder.cs",
    "content": "// created on 12/5/2006 at 2:23 PM\n/*\n *   Copyright (c) 2006, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing System.IO;\nusing Bless.Buffers;\nusing Bless.Util;\nusing Bless.Tools.Export;\n\nnamespace Bless.Tools.Export.Plugins\n{\n\n///<summary>\n/// A builder that exports bytes to HTML\n///</summary>\npublic class HTMLExportBuilder : TextExportBuilder\n{\n\n\tpublic HTMLExportBuilder(Stream stream)\n\t\t\t: base(stream)\n\t{\n\t}\n\n\tpublic override void BuildPrologue()\n\t{\n\t\tSystem.Console.WriteLine(\"Writing prologue\");\n\t\tBuildString(\"<html><body><pre>\");\n\t}\n\n\tpublic override void BuildEpilogue()\n\t{\n\t\tSystem.Console.WriteLine(\"Writing epilogue\");\n\t\tBuildString(\"</pre></body></html>\");\n\t}\n\n\tprotected override int BuildByte(IBuffer buf, long offset, BuildBytesInfo info, bool dummy)\n\t{\n\t\tif (offset % 2 == 0)\n\t\t\tBuildString(\"<span style=\\\"color:blue\\\">\");\n\n\t\tint n = base.BuildByte(buf, offset, info, dummy);\n\n\t\tif (offset % 2 == 0)\n\t\t\tBuildString(\"</span>\");\n\t\treturn n;\n\t}\n}\n\n} //end namespace"
  },
  {
    "path": "src/tools/export/plugins/HTMLExportPlugin.cs",
    "content": "// created on 12/5/2006 at 2:23 PM\n// created on 12/3/2006 at 4:07 PM\n/*\n *   Copyright (c) 2006, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System.IO;\nusing Bless.Plugins;\nusing Bless.Tools.Export;\nusing Mono.Unix;\n\nnamespace Bless.Tools.Export.Plugins {\n\npublic class HTMLExportPlugin : ExportPlugin\n{\n\n\tpublic HTMLExportPlugin()\n\t{\n\t\tname = \"HTMLExport\";\n\t\tauthor = \"Alexandros Frantzis\";\n\t\tdescription = Catalog.GetString(\"Export as HTML\");\n\t\tdependencies.Add(\"TextExport\");\n\t}\n\n\tpublic override IExportBuilder CreateBuilder(Stream s)\n\t{\n\t\treturn new HTMLExportBuilder(s);\n\t}\n\n}\n\n}\n"
  },
  {
    "path": "src/tools/export/plugins/TextExportBuilder.cs",
    "content": "/*\n *   Copyright (c) 2006, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System;\nusing System.IO;\nusing Bless.Buffers;\nusing Bless.Util;\nusing Bless.Tools.Export;\n\nnamespace Bless.Tools.Export.Plugins\n{\n\n///<summary>\n/// A builder that exports bytes to text\n///</summary>\npublic class TextExportBuilder : IExportBuilder\n{\n\tprotected StreamWriter writer;\n\tprotected int alignment;\n\n\tpublic TextExportBuilder(Stream stream)\n\t{\n\t\twriter = new StreamWriter(stream);\n\t\talignment = 1;\n\t}\n\n\tpublic virtual void BuildPrologue()\n\t{\n\t}\n\n\tpublic virtual void BuildEpilogue()\n\t{\n\t}\n\n\tpublic virtual int BuildBytes(IBuffer buffer, long offset, BuildBytesInfo info)\n\t{\n\t\tint nwritten = 0;\n\t\tint count = info.Count;\n\n\t\tcount -= MatchAlignment(offset, info);\n\n\t\t// emit the bytes (eg \"__ __ 00 00\")\n\t\tfor (int i = 0; i < count; i++) {\n\t\t\tif (i != 0)\n\t\t\t\tBuildSeparator(info.Separator);\n\n\t\t\tnwritten += BuildByte(buffer, offset + i, info, false);\n\n\t\t}\n\n\t\twriter.Flush();\n\t\treturn nwritten;\n\t}\n\n\tpublic virtual void BuildString(string str)\n\t{\n\t\twriter.Write(str);\n\t\twriter.Flush();\n\t}\n\n\tpublic virtual void BuildCharacter(char c)\n\t{\n\t\twriter.Write(c);\n\t\twriter.Flush();\n\t}\n\n\tpublic virtual void BuildAlignment(int align)\n\t{\n\t\talignment = align;\n\t}\n\n\tpublic virtual void BuildOffset(long offset, int length, char type)\n\t{\n\t\tlong lowAlign = (offset / alignment) * alignment;\n\t\tbool lowercase;\n\t\tint numBase = GetBaseFromArgument(type, out lowercase);\n\t\tstring str = BaseConverter.ConvertToString(lowAlign, numBase, false, lowercase, length);\n\n\t\tBuildByteData(str);\n\t}\n\n\tpublic Stream OutputStream {\n\t\tget {\n\t\t\treturn writer.BaseStream;\n\t\t}\n\t}\n\n\n\tprotected virtual int MatchAlignment(long offset, BuildBytesInfo info)\n\t{\n\t\tint count = 0;\n\t\t// match alignment\n\t\t// find lower alignment offset\n\t\tlong lowAlign = (offset / alignment) * alignment;\n\n\t\t// fill with blanks (eg \"__ __\")\n\t\tfor (long i = lowAlign; i < offset; i++) {\n\t\t\tif (i != lowAlign)\n\t\t\t\tBuildSeparator(info.Separator);\n\n\t\t\tBuildByte(null, 0, info, true);\n\n\t\t\tcount++;\n\t\t}\n\n\t\t// if alignment adjustments had to be made\n\t\t// emit one more separator (eg \"__ __ \" <-- notice last space)\n\t\tif (lowAlign != offset)\n\t\t\twriter.Write(info.Separator);\n\n\t\treturn count;\n\t}\n\n\tprotected virtual int BuildByte(IBuffer buffer, long offset, BuildBytesInfo info, bool dummy)\n\t{\n\t\tstring str;\n\t\tint nwritten = 0;\n\t\tbyte b = 0;\n\n\t\tif (dummy == true || offset >= buffer.Size) {\n\t\t\tdummy = true;\n\t\t}\n\t\telse {\n\t\t\tnwritten++;\n\t\t\tb = buffer[offset];\n\t\t}\n\n\t\tif (info.Type == 'A') {\n\t\t\t// Replace unprintable characters with dots\n\t\t\tif (b < 32 || b >= 127) {\n\t\t\t\tstr = \".\";\n\t\t\t}\n\t\t\telse\n\t\t\t\tstr = System.Text.Encoding.ASCII.GetString(new byte[]{b});\n\t\t}\n\t\telse {\n\t\t\tbool lowercase;\n\t\t\tint numBase = GetBaseFromArgument(info.Type, out lowercase);\n\t\t\tstr = BaseConverter.ConvertToString(b, numBase, false, lowercase, 0);\n\t\t}\n\n\t\tif (!dummy && info.Prefix != null)\n\t\t\tBuildPrefix(info.Prefix);\n\t\telse\n\t\t\tBuildEmpty(info.Prefix, \" \");\n\n\t\tif (!dummy && str != null) {\n\t\t\tBuildByteData(str);\n\t\t}\n\t\telse if (info.Empty != null)\n\t\t\tBuildEmpty(str, info.Empty);\n\t\telse\n\t\t\tBuildEmpty(str, \" \");\n\n\t\tif (!dummy && info.Suffix != null)\n\t\t\tBuildSuffix(info.Suffix);\n\t\telse\n\t\t\tBuildEmpty(info.Suffix, \" \");\n\n\t\treturn nwritten;\n\t}\n\n\tprotected virtual void BuildSeparator(string separator)\n\t{\n\t\twriter.Write(separator);\n\t}\n\n\tprotected virtual void BuildEmpty(string str, string empty)\n\t{\n\t\tif (str == null)\n\t\t\treturn;\n\n\t\tfor (int i = str.Length; i > 0;) {\n\t\t\tif (empty.Length <= i) {\n\t\t\t\twriter.Write(empty);\n\t\t\t\ti -= empty.Length;\n\t\t\t}\n\t\t\telse {\n\t\t\t\twriter.Write(empty.Substring(0, i));\n\t\t\t\ti = 0;\n\t\t\t}\n\t\t}\n\t}\n\n\tprotected virtual void BuildPrefix(string str)\n\t{\n\t\twriter.Write(str);\n\t}\n\n\tprotected virtual void BuildSuffix(string str)\n\t{\n\t\twriter.Write(str);\n\t}\n\n\tprotected virtual void BuildByteData(string str)\n\t{\n\t\twriter.Write(str);\n\t}\n\n\tprivate int GetBaseFromArgument(char type, out bool lowercase)\n\t{\n\t\tint numBase = 0;\n\t\tlowercase = false;\n\n\t\tswitch (type) {\n\t\t\tcase 'H':\n\t\t\t\tnumBase = 16;\n\t\t\t\tbreak;\n\t\t\tcase 'h':\n\t\t\t\tnumBase = 16;\n\t\t\t\tlowercase = true;\n\t\t\t\tbreak;\n\t\t\tcase 'D':\n\t\t\t\tnumBase = 10;\n\t\t\t\tbreak;\n\t\t\tcase 'O':\n\t\t\t\tnumBase = 8;\n\t\t\t\tbreak;\n\t\t\tcase 'B':\n\t\t\t\tnumBase = 2;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\n\t\treturn numBase;\n\t}\n\n}\n\n} //end namespace\n"
  },
  {
    "path": "src/tools/export/plugins/TextExportPlugin.cs",
    "content": "// created on 12/3/2006 at 4:07 PM\n/*\n *   Copyright (c) 2006, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System.IO;\nusing Bless.Plugins;\nusing Bless.Tools.Export;\nusing Mono.Unix;\n\nnamespace Bless.Tools.Export.Plugins {\n\npublic class TextExportPlugin : ExportPlugin\n{\n\n\tpublic TextExportPlugin()\n\t{\n\t\tname = \"TextExport\";\n\t\tauthor = \"Alexandros Frantzis\";\n\t\tdescription = Catalog.GetString(\"Export as Text\");\n\t}\n\n\tpublic override IExportBuilder CreateBuilder(Stream s)\n\t{\n\t\treturn new TextExportBuilder(s);\n\t}\n\n}\n\n}\n"
  },
  {
    "path": "src/tools/find/BMFindStrategy.cs",
    "content": "// created on 2/15/2005 at 12:32 PM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing Bless.Util;\nusing Bless.Buffers;\n\nnamespace Bless.Tools.Find {\n\n/// <summary>A Boyer-Moore finder utilizing only skip-tables (bad-character shifts)</summary>\npublic class BMFindStrategy : IFindStrategy\n{\n\tbyte[] pattern;\n\tByteBuffer buffer;\n\tlong pos;\n\tbool cancelled;\n\n\tint[] skipTable;\n\tint[] skipTableReverse;\n\n\t///<summary>\n\t/// Create the forward and reverse skip tables\n\t/// for boyer-moore based searches\n\t///</summary>\n\tvoid UpdateSkipTables()\n\t{\n\t\tint len = skipTable.Length;\n\t\tint patLen = pattern.Length;\n\n\t\tfor (int i = 0; i < len; i++) {\n\t\t\tskipTable[i] = patLen;\n\t\t\tskipTableReverse[i] = patLen;\n\t\t}\n\n\t\tfor (int i = 0; i < patLen;i++)\n\t\t\tskipTable[pattern[i]] = patLen - i - 1;\n\n\t\tfor (int i = patLen - 1; i >= 0;i--)\n\t\t\tskipTableReverse[pattern[i]] = i;\n\t}\n\n\tpublic BMFindStrategy()\n\t{\n\t\tpattern = new byte[0];\n\t\tskipTable = new int[256];\n\t\tskipTableReverse = new int[256];\n\t}\n\n\tpublic byte[] Pattern {\n\t\tset {\n\t\t\tpattern = (byte[])value.Clone();\n\t\t\tUpdateSkipTables();\n\t\t}\n\n\t\tget { return pattern; }\n\t}\n\n\tpublic ByteBuffer Buffer {\n\t\tget { return buffer; }\n\t\tset { buffer = value; pos = 0; }\n\t}\n\n\tpublic long Position {\n\t\tget { return pos;}\n\t\tset { pos = value; }\n\t}\n\n\tpublic bool Cancelled { get { return cancelled; } set { cancelled = value;} }\n\n\t///<summary>Simple method to search forwards for a single byte</summary>\n\tRange FindNextSingle(long limit)\n\t{\n\t\tbyte b = pattern[0];\n\n\t\twhile ((pos < limit) && buffer[pos] != b && !cancelled) pos++;\n\n\t\tif (pos >= limit || cancelled)\n\t\t\treturn null;\n\t\telse {\n\t\t\tRange r = new Range(pos, pos);\n\t\t\tpos++; // next time start search from next byte\n\t\t\treturn r;\n\t\t}\n\t}\n\n\t///<summary>Simple method to search backwards for a single byte</summary>\n\tRange FindPreviousSingle(long limit)\n\t{\n\t\tbyte b = pattern[0];\n\n\t\t// start the search at the previous position\n\t\tpos--;\n\n\t\twhile ((pos >= limit) && buffer[pos] != b && !cancelled) pos--;\n\n\t\tif (pos < 0 || cancelled) {\n\t\t\t// make sure pos is not negative\n\t\t\tif (pos < 0) pos = 0;\n\t\t\treturn null;\n\t\t}\n\t\telse {\n\t\t\tRange r = new Range(pos, pos);\n\t\t\treturn r;\n\t\t}\n\t}\n\n\tpublic Range FindNext(long limit)\n\t{\n\t\tint patLen = pattern.Length;\n\t\tlong bufLen = buffer.Size;\n\t\tbyte curByte = 0;\n\t\tint i = 0;\n\n\t\t// adjustment: search up to and including limit...\n\t\tlimit++;\n\n\t\t// make sure limit is sane\n\t\tif (limit > bufLen)\n\t\t\tlimit = bufLen;\n\n\t\t// if pattern is empty don't bother searching...\n\t\tif (patLen == 0)\n\t\t\treturn null;\n\n\t\t// use simple method for 1 byte searches\n\t\tif (patLen == 1)\n\t\t\treturn FindNextSingle(limit);\n\n\t\t// while buffer has more bytes to search\n\t\twhile (pos <= limit - patLen && !cancelled) {\n\t\t\t// while bytes match and more bytes are left in the pattern, continue...\n\t\t\tfor (i = patLen - 1; i >= 0; --i) {\n\t\t\t\tcurByte = buffer[pos+i];\n\t\t\t\tif (curByte != pattern[i]) break;\n\t\t\t}\n\n\t\t\t// if we found a match\n\t\t\tif (i < 0) {\n\t\t\t\tRange r = new Range(pos, pos + patLen - 1);\n\t\t\t\tpos++; // next time start search from next byte\n\t\t\t\treturn r;\n\t\t\t}\n\t\t\telse {// shift\n\t\t\t\tint t = skipTable[curByte];\n\n\t\t\t\t// can we use the skip value?\n\t\t\t\tif (patLen - i > t) {\n\t\t\t\t\t// ...no, because the \"text\" byte that caused the mismatch\n\t\t\t\t\t// has already been matched in the pattern and the skipTable[]\n\t\t\t\t\t// holds info only for the rightmost occurence of a byte.\n\t\t\t\t\t// eg TEXT: abcdcg -> The c causes the mismatch\n\t\t\t\t\t//     PAT: aafdcg    but has already been matched\n\t\t\t\t\t// SAFE SOLUTION: move the pattern one position to the right and continue\n\t\t\t\t\t// BETTER: use the complete BM algorithm with good-suffix shift\n\t\t\t\t\tpos += patLen - i;\n\t\t\t\t}\n\t\t\t\telse // ...yes\n\t\t\t\t\tpos += t - patLen + 1 + i;\n\t\t\t} // end shift\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t// this is like FindNext(), only we are searching backwards\n\t// so everything is reversed\n\tpublic Range FindPrevious(long limit)\n\t{\n\t\tint patLen = pattern.Length;\n\t\tbyte curByte = 0;\n\t\tint i;\n\n\t\t// make sure limit is sane\n\t\tif (limit < 0)\n\t\t\tlimit = 0;\n\n\t\t// if pattern is empty don't bother searching...\n\t\tif (patLen == 0)\n\t\t\treturn null;\n\n\t\t// use simple method for 1 byte searches\n\t\tif (patLen == 1)\n\t\t\treturn FindPreviousSingle(limit);\n\n\t\t// start the search at the previous position\n\t\tpos--;\n\n\t\t// while buffer has more bytes to search\n\t\twhile (pos >= limit + patLen - 1 && !cancelled) {\n\t\t\t// while bytes match and more bytes are left in the pattern, continue...\n\t\t\tfor (i = 0; i < patLen; ++i) {\n\t\t\t\tcurByte = buffer[pos-patLen+1+i];\n\t\t\t\tif (curByte != pattern[i]) break;\n\t\t\t}\n\n\t\t\t// if we found a match\n\t\t\tif (i >= patLen) {\n\t\t\t\tRange r = new Range(pos - patLen + 1, pos);\n\t\t\t\treturn r;\n\t\t\t}\n\t\t\telse {// shift\n\t\t\t\tint t = skipTableReverse[curByte];\n\n\t\t\t\t// can we use the skip value?\n\t\t\t\tif (i > t) {\n\t\t\t\t\t// ...no, because the \"text\" byte that caused the mismatch\n\t\t\t\t\t// has already been matched in the pattern and the skipTableReverse[]\n\t\t\t\t\t// holds info only for the leftmost occurence of a byte.\n\t\t\t\t\t// eg TEXT: abcdcg -> The c causes the mismatch\n\t\t\t\t\t//     PAT: abcdfg    but has already been matched\n\t\t\t\t\t// SAFE SOLUTION: move the pattern one position to the left and continue\n\t\t\t\t\t// BETTER: use the complete BM algorithm with good-suffix shift\n\t\t\t\t\tpos--;\n\t\t\t\t}\n\t\t\t\telse // ...yes\n\t\t\t\t\tpos -= t - i;\n\t\t\t} // end shift\n\t\t}\n\n\t\t// make sure pos is not negative\n\t\tif (pos < 0) pos = 0;\n\n\t\treturn null;\n\t}\n\n\tpublic Range FindNext()\n\t{\n\t\treturn FindNext(long.MaxValue -1);\n\t}\n\n\tpublic Range FindPrevious()\n\t{\n\t\treturn FindPrevious(0);\n\t}\n}\n\n} //end namespace\n"
  },
  {
    "path": "src/tools/find/FindAsyncResult.cs",
    "content": "// created on 3/31/2005 at 1:41 PM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing Bless.Util;\nusing System;\nusing System.Threading;\n\n\nnamespace Bless.Tools.Find {\n\n///<summary>\n/// Class to hold information about an asynchronous find operation\n///</summary>\npublic class FindAsyncResult: IAsyncResult {\n\tobject asyncState;\n\tWaitHandle asyncWaitHandle;\n\tbool isCompleted;\n\n\tpublic FindAsyncResult(object state, WaitHandle handle, bool complete)\n\t{\n\t\tasyncState = state;\n\t\tasyncWaitHandle = handle;\n\t\tisCompleted = complete;\n\t}\n\tpublic object AsyncState {\n\t\tget { return asyncState;}\n\t}\n\tpublic WaitHandle AsyncWaitHandle {\n\t\tget { return asyncWaitHandle;}\n\t}\n\tpublic bool CompletedSynchronously {\n\t\tget { return false;}\n\t}\n\tpublic bool IsCompleted {\n\t\tget { return isCompleted;}\n\t}\n}\n\n} // end namespace"
  },
  {
    "path": "src/tools/find/FindOperations.cs",
    "content": "// created on 3/31/2005 at 2:23 PM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing System;\nusing System.IO;\nusing System.Threading;\nusing Bless.Util;\n\nnamespace Bless.Tools.Find {\n\n///<summary>\n/// Generic find operation using an asynchronous threaded model of operation.\n///</summary>\npublic abstract class GenericFindOperation: ThreadedAsyncOperation\n{\n\n\tprotected IFindStrategy strategy;\n\tprotected Bless.Util.Range match;\n\n\n\tpublic IFindStrategy Strategy {\n\t\tget {return strategy;}\n\t}\n\n\tpublic Bless.Util.Range Match {\n\t\tget { return match; }\n\t}\n\n\tpublic GenericFindOperation(IFindStrategy ifs, ProgressCallback pc,\n\t\t\t\t\t\t\t\tAsyncCallback ac): base(pc, ac, true)\n\t{\n\t\tstrategy = ifs;\n\n\t\tstrategy.Cancelled = false;\n\t\tmatch = null;\n\t}\n\n\tprotected override bool StartProgress()\n\t{\n\t\treturn progressCallback(((double)strategy.Position) / strategy.Buffer.Size, ProgressAction.Show);\n\t}\n\n\tprotected override bool UpdateProgress()\n\t{\n\t\tstrategy.Cancelled = progressCallback(((double)strategy.Position) / strategy.Buffer.Size, ProgressAction.Update);\n\t\treturn strategy.Cancelled;\n\t}\n\n\tprotected override bool EndProgress()\n\t{\n\t\treturn progressCallback(((double)strategy.Position) / strategy.Buffer.Size, ProgressAction.Hide);\n\t}\n\n\tprotected override void DoOperation()\n\t{\n\t\tmatch = strategy.FindNext();\n\t}\n\n\tprotected override void EndOperation()\n\t{\n\t\t// re-allow buffer usage\n\t\tstrategy.Buffer.ReadAllowed = true;\n\t\tstrategy.Buffer.ModifyAllowed = true;\n\t\tstrategy.Buffer.FileOperationsAllowed = true;\n\t}\n\n}\n\n///<summary>\n/// Find Next operation using an asynchronous threaded model of operation.\n///</summary>\npublic class FindNextOperation: GenericFindOperation\n{\n\tpublic FindNextOperation(IFindStrategy ifs, ProgressCallback pc,\n\t\t\t\t\t\t\t AsyncCallback ac): base(ifs, pc, ac)\n\t{\n\t}\n\n\tprotected override void DoOperation()\n\t{\n\t\tmatch = strategy.FindNext();\n\t}\n}\n\n///<summary>\n/// Find Previous operation using an asynchronous threaded model of operation.\n///</summary>\npublic class FindPreviousOperation: GenericFindOperation\n{\n\tpublic FindPreviousOperation(IFindStrategy ifs, ProgressCallback pc,\n\t\t\t\t\t\t\t\t AsyncCallback ac): base(ifs, pc, ac)\n\t{\n\t}\n\n\tprotected override void DoOperation()\n\t{\n\t\tmatch = strategy.FindPrevious();\n\t}\n}\n\n///<summary>\n/// Replace All operation using an asynchronous threaded model of operation.\n///</summary>\npublic class ReplaceAllOperation: GenericFindOperation\n{\n\tbyte[] replacePattern;\n\tBless.Util.Range firstMatch;\n\tlong numReplaced;\n\n\tpublic long NumReplaced {\n\t\tget { return numReplaced; }\n\t}\n\n\tpublic byte[] ReplacePattern {\n\t\tget { return replacePattern; }\n\t}\n\n\tpublic Bless.Util.Range FirstMatch {\n\t\tget { return firstMatch; }\n\t}\n\n\n\tpublic ReplaceAllOperation(IFindStrategy ifs, ProgressCallback pc,\n\t\t\t\t\t\t\t   AsyncCallback ac, byte[] repPat): base(ifs, pc, ac)\n\t{\n\t\treplacePattern = repPat;\n\t}\n\n\tprotected override void DoOperation()\n\t{\n\t\tUtil.Range m;\n\t\tmatch = new Util.Range();\n\t\tfirstMatch = null;\n\n\t\tnumReplaced = 0;\n\n\t\tstrategy.Buffer.BeginActionChaining();\n\t\tstrategy.Buffer.ModifyAllowed = false;\n\t\tstrategy.Buffer.FileOperationsAllowed = false;\n\t\tstrategy.Buffer.EmitEvents = false;\n\n\t\twhile ((m = strategy.FindNext()) != null) {\n\t\t\tif (firstMatch == null) {\n\t\t\t\tfirstMatch = new Util.Range(m);\n\t\t\t}\n\n\t\t\tmatch.Start = m.Start;\n\t\t\tmatch.End = m.End;\n\n\t\t\tlock (strategy.Buffer.LockObj) {\n\t\t\t\tstrategy.Buffer.ModifyAllowed = true;\n\t\t\t\tstrategy.Buffer.Replace(m.Start, m.End, replacePattern);\n\t\t\t\tstrategy.Buffer.ModifyAllowed = false;\n\t\t\t}\n\n\t\t\t// start next search after the replaced pattern\n\t\t\tstrategy.Position = m.Start + replacePattern.Length;\n\n\t\t\tnumReplaced++;\n\t\t}\n\n\t}\n\n\tprotected override void EndOperation()\n\t{\n\t\t// re-allow buffer usage\n\t\tstrategy.Buffer.ReadAllowed = true;\n\t\tstrategy.Buffer.ModifyAllowed = true;\n\t\tstrategy.Buffer.FileOperationsAllowed = true;\n\t\tstrategy.Buffer.EmitEvents = true;\n\n\t\tstrategy.Buffer.EmitPermissionsChanged();\n\t\tstrategy.Buffer.EmitChanged();\n\n\t\tstrategy.Buffer.EndActionChaining();\n\t}\n\n}\n\n} // end namespace\n"
  },
  {
    "path": "src/tools/find/IFindStrategy.cs",
    "content": "// created on 1/9/2005 at 1:14 PM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing System;\nusing Bless.Util;\nusing Bless.Buffers;\n\nnamespace Bless.Tools.Find {\n\npublic interface IFindStrategy\n{\n\tbyte[] Pattern { get; set; }\n\t\t\tByteBuffer Buffer {\tget; set; }\n\t\t\t\tlong Position { get; set; }\n\n\t\t\t\t\t\tUtil.Range FindNext();\n\tUtil.Range FindPrevious();\n\n\tUtil.Range FindNext(long limit);\n\tUtil.Range FindPrevious(long limit);\n\n\tbool Cancelled { get; set; }\n\t\t}\n\n} // end namespace\n"
  },
  {
    "path": "src/tools/find/IFinder.cs",
    "content": "// created on 1/17/2005 at 4:58 PM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing System;\nusing Bless.Util;\nusing Bless.Buffers;\n\nnamespace Bless.Tools.Find {\n\npublic delegate void FirstFindHandler();\n\npublic interface IFinder\n{\n\tIFindStrategy Strategy { get; set; }\n\t\t\tUtil.Range LastFound { get; set; }\n\n\n\t\t\t\t\tevent FirstFindHandler FirstFind;\n\n\tIAsyncResult FindNext(AsyncCallback ac);\n\tIAsyncResult FindPrevious(AsyncCallback ac);\n\tbool Replace(byte[] ba);\n\tIAsyncResult ReplaceAll(byte[] ba, AsyncCallback ac);\n}\n\n} // end namespace\n"
  },
  {
    "path": "src/tools/find/SimpleFindStrategy.cs",
    "content": "// created on 1/9/2005 at 1:18 PM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing Bless.Util;\nusing Bless.Buffers;\n\nnamespace Bless.Tools.Find {\n\n/// <summary>A simple, brute-force finder</summary>\nclass SimpleFindStrategy : IFindStrategy\n{\n\tbyte[] pattern;\n\tByteBuffer buffer;\n\tlong pos;\n\n\tpublic SimpleFindStrategy()\n\t{\n\t\tpattern = new byte[0];\n\t}\n\n\tpublic byte[] Pattern {\n\t\tset { pattern = (byte[])value.Clone(); }\n\t\tget { return pattern; }\n\t}\n\n\tpublic ByteBuffer Buffer {\n\t\tget { return buffer; }\n\t\tset { buffer = value; pos = 0; }\n\t}\n\n\tpublic long Position {\n\t\tget { return pos;}\n\t\tset { pos = value; }\n\t}\n\n\tpublic Range FindNext(long limit)\n\t{\n\t\tlong len = buffer.Size;\n\t\tint plen = pattern.Length;\n\t\tint i = 0;\n\n\t\tif (limit > len)\n\t\t\tlimit = len;\n\n\t\twhile (pos < limit && i < plen) {\n\t\t\tif (buffer[pos] == pattern[i]) {\n\t\t\t\ti++;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif (i > 0)\n\t\t\t\t\tpos = pos - i + 1;\n\t\t\t\ti = 0;\n\t\t\t}\n\t\t\tpos++;\n\t\t}\n\n\t\tif (i == plen && plen > 0)\n\t\t\treturn new Range(pos -plen, pos - 1);\n\t\telse\n\t\t\treturn null;\n\t}\n\n\tpublic Range FindPrevious(long limit)\n\t{\n\t\tint plen = pattern.Length;\n\t\tint i = plen - 1;\n\n\t\tif (limit < 0)\n\t\t\tlimit = 0;\n\n\t\tpos--;\n\n\t\twhile (pos >= limit && i >= 0 ) {\n\t\t\tif (buffer[pos] == pattern[i]) {\n\t\t\t\ti--;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif (i < plen - 1)\n\t\t\t\t\tpos = pos + (plen - 1 - i) - 1;\n\t\t\t\ti = plen - 1;\n\t\t\t}\n\t\t\tpos--;\n\t\t}\n\n\t\tif (i == -1 && plen > 0)\n\t\t\treturn new Range(pos + 1, pos + plen);\n\t\telse\n\t\t\treturn null;\n\t}\n\n\tpublic Range FindNext()\n\t{\n\t\treturn FindNext(long.MaxValue);\n\t}\n\n\tpublic Range FindPrevious()\n\t{\n\t\treturn FindPrevious(0);\n\t}\n}\n\n} //end namespace\n"
  },
  {
    "path": "src/util/BaseConverter.cs",
    "content": "// created on 2/19/2005 at 9:40 PM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System;\nusing System.Text;\nusing Mono.Unix;\n\nnamespace Bless.Util {\n\n///<summary>Convert strings to numbers and vice-versa using a specified base</summary>\npublic class BaseConverter\n{\n\tstatic public int[] DefaultMinDigits = new int[]{0, 0, 8, 6, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2};\n\n\t// Don't allow instantiation\n\tprivate BaseConverter() { }\n\n\t///<summary>Convinience method</summary>\n\tstatic public string ConvertToString(long num, int b)\n\t{\n\t\treturn ConvertToString(num, b, false, false, 0);\n\t}\n\n\t///<summary>Convert a number to string using the specified base</summary>\n\tstatic public string ConvertToString(long num, int b, bool prependPrefix, bool lowercase, int minDigits)\n\t{\n\t\t// make sure base is valid\n\t\tif (b < 2 || b > 16)\n\t\t\treturn null;\n\n\t\tStringBuilder sb = new StringBuilder(64);\n\n\t\tchar alpha = lowercase ? 'a' : 'A';\n\n\t\twhile (num > 0) {\n\t\t\tint rem = (int)(num % b);\n\t\t\tif (rem < 10)\n\t\t\t\tsb.Insert(0, (char)(rem + '0'));\n\t\t\telse\n\t\t\t\tsb.Insert(0, (char)(rem - 10 + alpha));\n\t\t\tnum = num / b;\n\t\t}\n\n\t\t// if minDigits == 0 use a minimum number of digits\n\t\t// which depends on the base used\n\t\tif (minDigits == 0)\n\t\t\tminDigits = DefaultMinDigits[b];\n\n\t\t// pad number with zeroes, until it reaches the minimum length\n\t\twhile (sb.Length < minDigits)\n\t\t\tsb.Insert(0, '0');\n\n\t\t// prepend a prefix to mark the number base\n\t\t// (for octal and hexadecimal bases)\n\t\tif (prependPrefix) {\n\t\t\tif (b == 16)\n\t\t\t\tsb.Insert(0, \"0x\");\n\t\t\telse if (b == 8 && sb[0] != '0')\n\t\t\t\tsb.Insert(0, '0');\n\t\t}\n\n\t\treturn sb.ToString();\n\t}\n\n\tstatic private int CharToInt(char c, int b)\n\t{\n\t\tint ret = -1;\n\n\t\tif (c >= '0' && c <= '9')\n\t\t\tret = c - '0';\n\t\telse {\n\t\t\tc = Char.ToLower(c);\n\t\t\tif (c >= 'a' && c <= 'f')\n\t\t\t\tret = c - 'a' + 10;\n\t\t}\n\n\t\t// if character is not valid or beyond base throw exception\n\t\tif (ret >= b || ret == -1)\n\t\t\tthrow new FormatException(String.Format(Catalog.GetString(\"Character '{0}' is not valid in a number of base {1}.\"), c, b));\n\n\t\treturn ret;\n\t}\n\n\t///<summary>Convert a string to a number using the specified base</summary>\n\tstatic public long ConvertToNum(string s, int startIndex, int endIndex, int b)\n\t{\n\t\tlong val = 0;\n\t\tint i = startIndex;\n\n\t\twhile (i <= endIndex) {\n\t\t\tval = b * val + CharToInt(s[i], b);\n\t\t\ti++;\n\t\t}\n\n\t\treturn val;\n\t}\n\n\tstatic public long ConvertToNum(string s, int b)\n\t{\n\t\treturn  ConvertToNum(s, 0, s.Length - 1, b);\n\t}\n\n\t///<summary>Convert a string to a number guessing the base from the string format</summary>\n\tstatic public long Parse(string s)\n\t{\n\t\t// trim the spaces from the string\n\t\tstring trimStr = s.Trim();\n\n\t\tint i = 0;\n\t\tint len = trimStr.Length;\n\n\t\tif (len == 0)\n\t\t\tthrow new FormatException(Catalog.GetString(\"The string to parse is empty.\"));\n\n\t\t//decide if it is hex, octal or decimal\n\n\t\t// if it starts with '0x' suppose it is hex\n\t\tif (i + 1 < len && trimStr[i] == '0' && trimStr[i+1] == 'x')\n\t\t\treturn ConvertToNum(trimStr, i + 2, trimStr.Length - 1, 16);\n\n\t\t// if it starts with just '0' suppose it is octal\n\t\tif (i < len && trimStr[i] == '0')\n\t\t\treturn ConvertToNum(trimStr, 8);\n\n\t\t// else suppose it is decimal\n\t\treturn ConvertToNum(trimStr, 10);\n\t}\n}\n\n} // end namespace\n"
  },
  {
    "path": "src/util/ByteArray.cs",
    "content": "// created on 1/13/2005 at 10:59 AM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing System;\nusing System.Text;\nusing ByteList = System.Collections.Generic.List<byte>;\n\nnamespace Bless.Util {\n\n///<summary>Create byte arrays from various kinds of strings</summary>\npublic class ByteArray\n{\n\t// Don't allow instantiation\n\tprivate ByteArray() { }\n\n\tstatic public byte[] FromString(string s, int baseNum)\n\t{\n\t\tint i = 0;\n\t\tint len = s.Length;\n\t\tByteList ba = new ByteList();\n\n\t\t// ignore leading whitespace\n\t\twhile (i < len && s[i] == ' ') i++;\n\n\t\twhile (i < len) {\n\t\t\tint k = 1;\n\t\t\twhile (i + k < len &&  s[i+k] != ' ' && k < BaseConverter.DefaultMinDigits[baseNum]) k++;\n\n\t\t\tba.Add((byte)BaseConverter.ConvertToNum(s, i, i + k - 1, baseNum));\n\n\t\t\t// skip spaces\n\t\t\ti = i + k;\n\t\t\twhile (i < len && s[i] == ' ') i++;\n\t\t}\n\n\t\treturn ba.ToArray();\n\t}\n\n\tstatic public string ToString(byte[] ba, int baseNum)\n\t{\n\t\tif (ba.Length == 0)\n\t\t\treturn string.Empty;\n\n\t\tStringBuilder sb = new StringBuilder(ba.Length*(BaseConverter.DefaultMinDigits[baseNum] + 1));\n\n\t\tforeach(byte b in ba) {\n\t\t\tsb.Append(BaseConverter.ConvertToString(b, baseNum));\n\t\t\tsb.Append(' ');\n\t\t}\n\n\t\treturn sb.ToString(0, sb.Length - 1);\n\t}\n\n} //end ByteArray\n\n} // end namespace\n"
  },
  {
    "path": "src/util/ConfigureDefines.cs.tmpl.in",
    "content": "/*\n *   Copyright (c) 2006, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nnamespace Bless.Util {\n\n///<summary>\n/// Useful constants defined by the configure script (taken from Banshee)\n///</summary>\npublic sealed class ConfigureDefines                                        \n{                                                                           \n\tpublic const string LOCALE_DIR = \"@datadir@/locale/\"; \n\tpublic const string PACKAGE = \"@PACKAGE@\";\n\tpublic const string VERSION = \"@VERSION@\";\n\tpublic const string GETTEXT_PACKAGE = \"@GETTEXT_PACKAGE@\";\n\tpublic const string DATADIR = \"@datadir@/@PACKAGE@/\";\n\tpublic const string HELPDIR = \"@datadir@/help\";\n}\n\n} // end namespace       \n"
  },
  {
    "path": "src/util/Deque.cs",
    "content": "// created on 7/4/2005 at 12:24 PM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\n\nnamespace Bless.Util {\n\n///<summary>\n/// Double-ended queue data structure\n///</summary>\npublic class Deque<T>: IEnumerable<T>\n{\n\tBless.Util.List<T> list;\n\n\tpublic Deque()\n\t{\n\t\tlist = new Bless.Util.List<T>();\n\t}\n\n\t///<summary>\n\t/// Add an object to the front of the queue\n\t///</summary>\n\tpublic void AddFront(T o)\n\t{\n\t\tlist.InsertBefore(list.First, o);\n\t}\n\n\tpublic void AddEnd(T o)\n\t{\n\t\tlist.InsertAfter(list.Last, o);\n\t}\n\n\t///<summary>\n\t/// Remove an object from the front of the queue (LIFO)\n\t///</summary>\n\tpublic T RemoveFront()\n\t{\n\t\tT o = default(T);\n\n\t\tif (list.First != null) {\n\t\t\to = list.First.data;\n\t\t\tlist.First.data = default(T);\n\t\t\tlist.Remove(list.First);\n\t\t}\n\n\t\treturn o;\n\t}\n\n\t///<summary>\n\t/// Remove an object from the end of the queue (FIFO)\n\t///</summary>\n\tpublic T RemoveEnd()\n\t{\n\t\tT o = default(T);\n\n\t\tif (list.Last != null) {\n\t\t\to = list.Last.data;\n\t\t\tlist.Last.data = default(T);\n\t\t\tlist.Remove(list.Last);\n\t\t}\n\n\t\treturn o;\n\t}\n\n\t///<summary>\n\t/// Peek the object at the front of the queue\n\t///</summary>\n\tpublic T PeekFront()\n\t{\n\t\tT o = default(T);\n\n\t\tif (list.First != null)\n\t\t\to = list.First.data;\n\n\t\treturn o;\n\t}\n\n\t///<summary>\n\t/// Peek the object at the end of the queue\n\t///</summary>\n\tpublic T PeekEnd()\n\t{\n\t\tT o = default(T);\n\n\t\tif (list.Last != null)\n\t\t\to = list.Last.data;\n\n\t\treturn o;\n\t}\n\n\tpublic void Clear()\n\t{\n\t\twhile (Count > 0)\n\t\t\tRemoveFront();\n\t}\n\n\tpublic int Count {\n\t\tget { return list.Count; }\n\t}\n\n\tpublic IEnumerator<T> GetEnumerator()\n\t{\n\t\treturn list.GetEnumerator();\n\t}\n\n\tIEnumerator IEnumerable.GetEnumerator()\n\t{\n\t\treturn GetEnumerator();\n\t}\n}\n\n\n} // end namespace"
  },
  {
    "path": "src/util/FileResourcePath.cs",
    "content": "// created on 3/11/2005 at 12:42 PM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing System.Reflection;\nusing System.IO;\nusing System;\n\nnamespace Bless.Util {\n\n///<summary>Path of a file resource</summary>\npublic class FileResourcePath\n{\n\tprivate FileResourcePath() { }\n\t\n\tprivate static string dataPath = null;\n\t\n\t///<summary>\n\t/// Gets the full path of a file resource\n\t/// which is given relatively to the\n\t/// assembly path\n\t///</summary>\n\tpublic static string GetBinPath(params string[] dirs)\n\t{\n\t\t// Get assembly path\n\t\tstring assemblyPath = Assembly.GetCallingAssembly().Location;\n\t\t// Get assembly dir\n\t\tstring assemblyDir = Path.GetDirectoryName(assemblyPath);\n\n\t\tstring resourcePath = assemblyDir;\n\n\t\tforeach (string s in dirs)\n\t\t\tresourcePath = Path.Combine(resourcePath, s);\n\n\t\treturn resourcePath;\n\t}\n\t\n\t///<summary>\n\t/// Gets the full path of a file resource\n\t/// located in the Bless data directory\n\t///</summary>\n\tpublic static string GetDataPath(params string[] dirs)\n\t{\n\t\tif (dataPath == null) {\n\t\t\t// get the local data path (eg when running bless from within the build directory)\n\t\t\tstring localDataDir = GetBinPath(\"..\", \"..\", \"data\");\n\t\t\t\n\t\t\t// if the local data path exists and is valid use it\n\t\t\t// else try to use the installation data path\n\t\t\tif (Directory.Exists(localDataDir) && File.Exists(Path.Combine(localDataDir, \"bless-default.layout\")))\n\t\t\t\tdataPath = localDataDir;\n\t\t\telse if (Directory.Exists(ConfigureDefines.DATADIR) && File.Exists(Path.Combine(ConfigureDefines.DATADIR, \"bless-default.layout\")))\n\t\t\t\tdataPath = ConfigureDefines.DATADIR;\n\t\t\telse\n\t\t\t\tthrow new DirectoryNotFoundException(localDataDir + \" or \" +  ConfigureDefines.DATADIR);\n\t\t}\n\t\t\n\t\tstring resourcePath = dataPath;\n\t\t\n\t\tforeach (string s in dirs)\n\t\t\tresourcePath = Path.Combine(resourcePath, s);\n\n\t\treturn resourcePath;\n\t}\n\t\n\tpublic static string GetUserPath(params string[] dirs)\n\t{\n\t\tstring resourcePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), \"bless\");\n\n\t\tforeach (string s in dirs)\n\t\t\tresourcePath = Path.Combine(resourcePath, s);\n\n\t\treturn resourcePath;\n\t}\n\n\tpublic static string GetHelpDir()\n\t{\n\t\tstring localHelpDir = GetDataPath(\"..\", \"doc\", \"user\", \"C\");\n\t\tstring helpDir = \"\";\n\t\tif (Directory.Exists(localHelpDir) &&\n\t\t\tFile.Exists(Path.Combine(localHelpDir, \"index.docbook\"))) {\n\t\t\thelpDir = localHelpDir;\n\t\t} else {\n\t\t\thelpDir = Path.Combine(ConfigureDefines.HELPDIR, \"C\", \"bless\");\n\t\t}\n\t\treturn helpDir;\n\t}\n\n}\n\n} // end namespace\n\n"
  },
  {
    "path": "src/util/IntervalTree.cs",
    "content": "// Created 1:14 PM 16/3/2008\n/*\n *   Copyright (c) 2008, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing System;\nusing System.Collections.Generic;\n\nnamespace Bless.Util\n{\n\npublic class IntervalTree<T> : RedBlackTree<long, T> where T : IRange\n{\n\tprotected class ITNode : INode\n\t{\n\t\tprivate long max;\n\t\tprivate long key;\n\t\tprivate IList<T> values;\t\n\t\tprivate INode left, right;\n\t\tprivate Color color;\n\t\t\n\t\tpublic long Max { \n\t\t\tget { return max; }\n\t\t\tset { max = value; }\n\t\t}\n\t\t\n\t\tpublic long Key {\n\t\t\tget { return key; }\n\t\t\tset { key = value; }\n\t\t}\n\t\t\n\t\tpublic IList<T> Values {\n\t\t\tget { return values; }\n\t\t\tset { values = value; UpdateMax();}\n\t\t}\n\t\t\n\t\tpublic INode Left {\n\t\t\tget { return left; }\n\t\t\tset { left = value; UpdateMax();}\n\t\t}\n\t\t\n\t\tpublic INode Right {\n\t\t\tget { return right; }\n\t\t\tset { right = value; UpdateMax();}\n\t\t}\n\t\t\n\t\tpublic Color Color {\n\t\t\tget { return color; }\n\t\t\tset { color = value; }\n\t\t}\n\t\t\n\t\tpublic ITNode(long key, T val, Color color)\n\t\t{\n\t\t\tthis.key = key;\n\t\t\tthis.values = new System.Collections.Generic.List<T>(); \n\t\t\tthis.values.Add(val);\n\t\t\tthis.color = color;\n\t\t\tmax = val.End; \n\t\t}\n\t\t\n\t\tprivate void UpdateMax()\n\t\t{\n\t\t\tlong tmpMax = -1;\n\t\t\t\n\t\t\tif (this.Left != null)\n\t\t\t\ttmpMax = Math.Max(tmpMax, (this.Left as ITNode).Max);\n\t\t\n\t\t\tif (this.Right != null)\n\t\t\t\ttmpMax = Math.Max(tmpMax, (this.Right as ITNode).Max);\n\t\t\t\n\t\t\tforeach(T r in this.Values) {\n\t\t\t\ttmpMax = Math.Max(tmpMax, r.End);\n\t\t\t}\n\t\t\n\t\t\tthis.max = tmpMax;\n\t\t}\n\t\t\n\t}\n\t\n\tprotected class ITNodeFactory : INodeFactory\n\t{\n\t\tpublic INode CreateNode(long key, T val, Color color) \n\t\t{\n\t\t\treturn new ITNode(key, val, color);\n\t\t}\n\t\t\n\t}\n\t\n\tprivate System.Collections.Generic.List<T> searchResults;\n\t\n\tpublic IntervalTree() : base(new ITNodeFactory())\n\t{\n\t\n\t}\n\t\t\n\tprivate bool RangesOverlap(IRange r1, IRange r2)\n\t{\n\t\tif (r1.Start >= r2.Start && r1.Start <= r2.End)\n\t\t\treturn true;\n\t\tif (r1.End >= r2.Start && r1.End <= r2.End)\n\t\t\treturn true;\n\t\tif (r1.Start <= r2.Start && r1.End >= r2.End)\n\t\t\treturn true;\n\t\t\n\t\treturn false;\n\t}\n\t\n\tprotected override void AddToValues(INode n, T val)\n\t{\n\t\tbase.AddToValues(n, val);\n\t\t\n\t\t(n as ITNode).Max = Math.Max((n as ITNode).Max, val.End);\n\t}\n\t\n\tpublic void Insert(T r)\n\t{\n\t\tInsert(r.Start, r);\n\t}\n\t\n\tpublic IList<T> SearchOverlap(IRange r)\n\t{\n\t\tlock(lockObj) {\n\t\t\tsearchResults = new System.Collections.Generic.List<T>();\n\t\t\tSearchOverlap(root as ITNode, r);\n\t\t\treturn searchResults;\n\t\t}\n\t}\n\t\n\tprivate void SearchOverlap(ITNode n, IRange r)\n\t{\n\t\t// search in left subtree first, so that results are sorted\n\t\tif (n != null) {\n\t\t\tif (n.Max >= r.Start) {\n\t\t\t\tif(n.Left != null)\n\t\t\t\t\tSearchOverlap(n.Left as ITNode, r);\n\t\t\t\t\t\n\t\t\t\tforeach(T q in n.Values) {\n\t\t\t\t\tif (RangesOverlap(q, r))\n\t\t\t\t\t\tsearchResults.Add(q);\n\t\t\t\t}\n\t\t\t\t\n\t\t\t}\n\t\t\t\n\t\t\tif (n.Key <= r.End && n.Right != null)\n\t\t\t\tSearchOverlap(n.Right as ITNode, r);\n\t\t}\n\t}\n\t\n\tpublic void Delete(T r)\n\t{\n\t\tITNode n = (this.SearchNode(r.Start) as ITNode);\n\t\t\n\t\tif (n == null)\n\t\t\treturn;\n\t\t\n\t\tn.Values.Remove(r);\n\t\t\n\t\tif (n.Values.Count == 0)\n\t\t\tthis.Delete(r.Start);\n\t}\n}\n\n} //end namespace\n"
  },
  {
    "path": "src/util/List.cs",
    "content": "/*\n *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\n\nnamespace Bless.Util {\n\n///<summary>A double-linked list</summary>\npublic class List<T> : IEnumerable<T>\n{\n\n\t///<summary>A node of the list</summary>\n\tpublic class Node\n\t{\n\t\tpublic T data;\n\t\tpublic Node next;\n\t\tpublic Node prev;\n\n\t\tpublic Node(T d, Node p, Node n) {\n\t\t\tdata = d;\n\t\t\tprev = p;\n\t\t\tnext = n;\n\t\t}\n\n\t}\n\n\n\tNode m_first;\n\tNode m_last;\n\n\tint m_count;\n\n\n\tpublic List()\n\t{\n\t\tm_first = null;\n\t\tm_last = null;\n\t}\n\n\n\tprivate Node AddFirst(T o)\n\t{\n\t\tm_first = new Node(o, null, null);\n\t\tm_last = m_first;\n\t\t++m_count;\n\t\treturn m_first;\n\t}\n\n\t///<summary>Append an object to the list</summary>\n\tpublic Node Append(T o)\n\t{\n\t\treturn InsertAfter(m_last, o);\n\t}\n\n\t///<summary>Insert an object before a node in the list</summary>\n\tpublic Node InsertBefore(Node n, T o)\n\t{\n\t\tif (m_last == null) { // first entry?\n\t\t\treturn AddFirst(o);\n\t\t}\n\t\telse {\n\t\t\tNode tmp = new Node(o, n.prev, n);\n\t\t\tif (n.prev != null)\n\t\t\t\tn.prev.next = tmp;\n\t\t\tn.prev = tmp;\n\t\t\tif (ReferenceEquals(n, m_first))\n\t\t\t\tm_first = tmp;\n\t\t\t++m_count;\n\t\t\treturn tmp;\n\t\t}\n\t}\n\n\t///<summary>Insert an object after a node in the list</summary>\n\tpublic Node InsertAfter(Node n, T o)\n\t{\n\t\tif (m_last == null) { // first entry?\n\t\t\treturn AddFirst(o);\n\t\t}\n\t\telse {\n\t\t\tNode tmp = new Node(o, n, n.next);\n\t\t\tif (n.next != null)\n\t\t\t\tn.next.prev = tmp;\n\t\t\tn.next = tmp;\n\t\t\tif (ReferenceEquals(n, m_last))\n\t\t\t\tm_last = tmp;\n\t\t\t++m_count;\n\t\t\treturn tmp;\n\t\t}\n\t}\n\n\t///<summary>Remove a node (unlink it)</summary>\n\tpublic void Remove(Node n)\n\t{\n\t\tif (n.prev != null)\n\t\t\tn.prev.next = n.next;\n\t\tif (n.next != null)\n\t\t\tn.next.prev = n.prev;\n\t\tif (ReferenceEquals(n, m_first))\n\t\t\tm_first = n.next;\n\t\tif (ReferenceEquals(n, m_last))\n\t\t\tm_last = n.prev;\n\t\tn.next = null;\n\t\tn.prev = null;\n\t\t--m_count;\n\t}\n\n\tpublic T this[int index] {\n\t\tget {\n\t\t\t//Console.WriteLine(\"Asking for index {0}\", index);\n\t\t\tif (index > m_count)\n\t\t\treturn default(T);\n\t\t\tNode n = m_first;\n\t\t\tfor (int i = 0; i < index; i++)\n\t\t\t\tn = n.next;\n\t\t\treturn n.data;\n\t\t}\n\t}\n\n\tpublic IEnumerator<T> GetEnumerator()\n\t{\n\t\tNode currentNode = First;\n\n\t\twhile (currentNode != null) {\n\t\t\tyield return currentNode.data;\n\t\t\tcurrentNode = currentNode.next;\n\t\t}\n\t}\n\n\tIEnumerator IEnumerable.GetEnumerator()\n\t{\n\t\treturn GetEnumerator();\n\t}\n\n\tpublic void Display()\n\t{\n\t\tNode n = m_first;\n\t\twhile (n != null) {\n\t\t\tConsole.Write(\"{0}<=>\", n.data);\n\t\t\tn = n.next;\n\t\t}\n\t\tConsole.WriteLine();\n\t}\n\n\tpublic Node First {\n\t\tget { return m_first; }\n\t}\n\n\tpublic Node Last {\n\t\tget { return m_last; }\n\t}\n\n\tpublic int Count {\n\t\tget { return m_count; }\n\t}\n\n\n}\n\n} // end namespace\n"
  },
  {
    "path": "src/util/Portable.cs",
    "content": "/*\n *   Copyright (c) 2008, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing Mono.Unix.Native;\nusing System;\nusing System.Runtime.InteropServices;\n\npublic class Portable\n{\n\tpublic static long GetAvailableMemory()\n\t{\n#if ENABLE_UNIX_SPECIFIC\n\t\tlong availPages = Syscall.sysconf(SysconfName._SC_AVPHYS_PAGES);\n\t\tlong pageSize = Syscall.sysconf(SysconfName._SC_PAGESIZE);\n\t\tlong freeMem = availPages * pageSize;\n\t\t\t\n\t\treturn freeMem;\n#else\n\t\tthrow new NotImplementedException();\n#endif\n\t}\n\n\tpublic static long GetAvailableDiskSpace(string path)\n\t{\n#if ENABLE_UNIX_SPECIFIC\n\t\t// get info about the device the file will be saved on\n\t\tMono.Unix.Native.Statvfs stat = new Mono.Unix.Native.Statvfs();\n\t\tMono.Unix.Native.Syscall.statvfs(path, out stat);\n\t\tlong freeSpace = (long)(stat.f_bavail * stat.f_bsize);\n\t\t\t\n\t\treturn freeSpace;\n#else\n\t\tthrow new NotImplementedException();\n#endif\n\t}\n\n\t[DllImport(\"libfontconfig.so.1\", CharSet = CharSet.Auto)]\n\tstatic extern IntPtr FcConfigAppFontAddFile(IntPtr fc, String path);\n\n\tpublic static void AddLocalFontFile(String path)\n\t{\n\t\tFcConfigAppFontAddFile(IntPtr.Zero, path);\n\t}\n}\n"
  },
  {
    "path": "src/util/ProgressCallback.cs",
    "content": "// created on 3/29/2005 at 5:49 PM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nnamespace Bless.Util {\n\npublic enum ProgressAction { Show, Hide, Update, Message, Details, Destroy}\n\npublic delegate bool ProgressCallback(object o, ProgressAction action);\n\n}\n"
  },
  {
    "path": "src/util/Range.cs",
    "content": "// created on 10/25/2004 at 9:32 AM\n/*\n *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing System;\n\nnamespace Bless.Util {\n\npublic interface IRange\n{\n\tlong Start { get; set; }\n\tlong End { get; set; }\n\tlong Size { get; }\n\tbool IsEmpty();\n\tvoid Clear();\n}\n\n///<summary>Represents a range of values</summary>\npublic class Range : IRange, IEquatable<Range>\n{\n\tprotected long start;\n\tprotected long end;\n\n\tpublic long Start {\n\t\tget { return start; }\n\t\tset { start = value; }\n\t}\n\n\tpublic long End {\n\t\tget { return end; }\n\t\tset { end = value; }\n\t}\n\n\tpublic long Size {\n\t\tget {\n\t\t\tif (IsEmpty())\n\t\t\t\treturn 0;\n\t\t\telse if (end >= start)\n\t\t\t\treturn end -start + 1;\n\t\t\telse\n\t\t\t\treturn start -end + 1;\n\t\t}\n\t}\n\n\tpublic Range()\n\t{\n\t\tClear();\n\t}\n\n\tpublic Range(long s, long e)\n\t{\n\t\tstart = s;\n\t\tend = e;\n\t}\n\n\t///<summary>copy constructor</summary>\n\tpublic Range(IRange r): this(r.Start, r.End)\n\t{\n\n\t}\n\n\t///<summary>value equality test</summary>\n\tpublic bool Equals(Range r)\n\t{\n\t\treturn ((start == r.Start) && (end == r.End) || (end == r.Start) && (start == r.End));\n\t}\n\t\n\t///<summary>value equality test (for general objects)</summary>\n\tpublic override bool Equals(object obj)\n\t{\n\t\tRange r = obj as Range;\n\t\tif (r != null)\n\t\t\treturn Equals(r);\n\t\telse\n\t\t\treturn false;\n\t}\n\n\t// we should override GetHashCode() because we\n\t// are overriding Equals()\n\tpublic override int GetHashCode()\n\t{\n\t\treturn (start.GetHashCode() ^ end.GetHashCode());\n\t}\n\n\tpublic void Clear()\n\t{\n\t\tstart = -1;\n\t\tend = -1;\n\t}\n\n\tpublic bool Contains(long n)\n\t{\n\t\tif (start < end)\n\t\t\treturn (n >= start && n <= end);\n\t\telse\n\t\t\treturn (n <= start && n >= end);\n\t}\n\n\t///<summary>Evaluates the intersection of two ranges</summary>\n\t// NOTE: expects both ranges to be sorted\n\tpublic void Intersect(Range sel)\n\t{\n\t\tif (sel.Start >= start && sel.Start <= end) {\n\t\t\tstart = sel.Start;\n\t\t\tif (sel.End < end)\n\t\t\t\tend = sel.End;\n\t\t}\n\t\telse if (sel.Start < start && sel.End >= start) {\n\t\t\tif (sel.End < end)\n\t\t\t\tend = sel.End;\n\t\t}\n\t\telse\n\t\t\tClear();\n\t}\n\n\t///<summary>Evaluates the difference of two ranges.</summary>\n\t// NOTE: expects both ranges to be sorted\n\tpublic void Difference(Range r, Range r1)\n\t{\n\n\t\tif (r.Start > start && r.Start <= end) {\n\t\t\tif (r.End >= end) {\n\t\t\t\tend = r.Start - 1;\n\t\t\t\tr1.Clear();\n\t\t\t}\n\t\t\telse {\n\t\t\t\tr1.Start = r.End + 1;\n\t\t\t\tr1.End = end;\n\t\t\t\tend = r.Start - 1;\n\t\t\t}\n\t\t}\n\t\telse if (r.Start <= start && r.End >= start) {\n\t\t\tr1.Clear();\n\t\t\tif (r.End < end)\n\t\t\t\tstart = r.End + 1;\n\t\t\telse\n\t\t\t\tClear();\n\t\t}\n\n\t}\n\n\tpublic bool IsEmpty()\n\t{\n\t\treturn ((start == -1) && (end == -1));\n\t}\n\t\n\tstatic public void SplitAtomic(Range[] results, Range r, Range s)\n\t{\n\t\t\n\t\tif (r.Contains(s.Start)) {\n\t\t\tresults[0].Start = r.Start;\n\t\t\tresults[0].End = s.Start - 1;\n\t\t\t\n\t\t\tresults[1].Start = s.Start;\n\t\t\tresults[1].End = s.End;\n\t\t\t\n\t\t\tif (r.Contains(s.End)) {\n\t\t\t\tresults[2].Start = s.End + 1;\n\t\t\t\tresults[2].End = r.End;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tresults[2].Clear();\n\t\t\t}\n\t\t}\n\t\telse if (r.Contains(s.End)) {\n\t\t\tresults[0].Clear();\n\t\t\t\n\t\t\tresults[1].Start = s.Start;\n\t\t\tresults[1].End = s.End;\n\t\t\t\n\t\t\tresults[2].Start = s.End + 1;\n\t\t\tresults[2].End = r.End;\n\t\t}\n\t\telse if (s.Start < r.Start && s.End > r.End) {\n\t\t\tresults[0].Clear();\n\t\t\t\n\t\t\tresults[1].Start = s.Start;\n\t\t\tresults[1].End = s.End;\n\t\t\t\n\t\t\tresults[2].Clear();\t\n\t\t}\n\t\telse {\n\t\t\tif (r.Start < s.Start) {\n\t\t\t\tresults[0].Start = r.Start;\n\t\t\t\tresults[0].End = r.End;\n\t\t\t\t\n\t\t\t\tresults[2].Clear();\n\t\t\t}\n\t\t\telse {\n\t\t\t\tresults[2].Start = r.Start;\n\t\t\t\tresults[2].End = r.End;\n\t\t\t\t\n\t\t\t\tresults[1].Clear();\n\t\t\t}\n\t\t\t\n\t\t\tresults[1].Start = s.Start;\n\t\t\tresults[1].End = s.End;\n\t\t}\n\t\t\n\t\tforeach(Range result in results) {\n\t\t\tif (result.Start > result.End)\n\t\t\t\tresult.Clear();\n\t\t}\t\n\t\t\n\t}\n\t\n\tpublic bool Overlaps(IRange r)\n\t{\n\t\tif (r.Start >= Start && r.Start <= End)\n\t\t\treturn true;\n\t\tif (r.End >= Start && r.End <= End)\n\t\t\treturn true;\n\t\tif (r.Start <= Start && r.End >= End)\n\t\t\treturn true;\n\t\t\n\t\treturn false;\n\t}\n\n\t///<summary>Make sure range start is less or equal to end</summary>\n\tpublic void Sort()\n\t{\n\t\tif (end < start) {\n\t\t\tlong t = start;\n\t\t\tstart = end;\n\t\t\tend = t;\n\t\t}\n\t}\n\t\n\tpublic override string ToString()\n\t{\n\t\treturn string.Format(\"{0} -> {1}\", start, end);\n\t}\n}\n\n} // end namespace\n"
  },
  {
    "path": "src/util/RangeCollection.cs",
    "content": "// created on 8/25/2005 at 11:21 AM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System.Collections;\n\nnamespace Bless.Util {\n\npublic class RangeCollection: ArrayList\n{\n\n\tpublic Range LastAdded {\n\t\tget { return (Range)this[Count-1]; }\n\t}\n\n\tpublic RangeCollection()\n\t{\n\t\tAdd(new Range());\n\t}\n\n\tpublic void UpdateRange(Range oldRange, Range newRange)\n\t{\n\t\tint index = IndexOf(oldRange);\n\t\tRemoveAt(index);\n\t\tInsert(index, newRange);\n\t}\n\n\tpublic new void Clear()\n\t{\n\t\tbase.Clear();\n\t\tAdd(new Range());\n\t}\n\n}\n\n\n} // end namespace\n"
  },
  {
    "path": "src/util/RedBlackTree.cs",
    "content": "/*\n *   Copyright (c) 2008, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Text;\n\nnamespace Bless.Util\n{\n/// <summary>\n/// A (left-leaning) red black tree (see [Sedgewick 2008]).\n/// Duplicates keys are all stored in the same node. \n/// </summary>\npublic class RedBlackTree<K, V> where K:IComparable<K>\n{\n\tprotected enum Color {Red, Black}\n\t\n\tprivate INodeFactory nodeFactory;\n\tprotected INode root;\n\tprotected object lockObj = new object();\n\tprivate IList<V> tmpValues;\n\t\n\tprotected interface INode\n\t{\n\t\tK Key { get; set; }\n\t\tIList<V> Values { get; set;}\t\n\t\tINode Left { get; set;}\n\t\tINode Right { get; set;}\n\t\tColor Color { get; set;}\n\t}\n\t\n\tprotected interface INodeFactory\n\t{\n\t\tINode CreateNode(K key, V val, Color color);\n\t}\n\t\n\tprotected class NodeFactory : INodeFactory\n\t{\n\t\tpublic INode CreateNode(K key, V val, Color color)\n\t\t{\n\t\t\treturn new Node(key, val, color);\n\t\t}\n\t}\n\t\n\tprotected class Node : INode\n\t{\n\t\tprivate K key;\n\t\tprivate IList<V> values;\t\n\t\tprivate INode left, right;\n\t\tprivate Color color;\n\t\t\n\t\tpublic K Key {\n\t\t\tget { return key; }\n\t\t\tset { key = value; }\n\t\t}\n\t\t\n\t\tpublic IList<V> Values {\n\t\t\tget { return values; }\n\t\t\tset { values = value; }\n\t\t}\n\t\t\n\t\tpublic INode Left {\n\t\t\tget { return left; }\n\t\t\tset { left = value; }\n\t\t}\n\t\t\n\t\tpublic INode Right {\n\t\t\tget { return right; }\n\t\t\tset { right = value; }\n\t\t}\n\t\t\n\t\tpublic Color Color {\n\t\t\tget { return color; }\n\t\t\tset { color = value; }\n\t\t}\n\t    \n\t\tpublic Node(K key, V val, Color color)\n\t\t{\n\t\t\tthis.key = key;\n\t\t\tthis.values = new System.Collections.Generic.List<V>(); \n\t\t\tthis.values.Add(val);\n\t\t\tthis.color = color;\n\t\t}\n\t}\n\n\tprivate bool IsRed(INode n)\n\t{\n\t\tif (n == null) return false;\n\t\treturn (n.Color == Color.Red);\n\t}\n\n\tprotected virtual INode RotL(INode h)\n\t{\n\t\tINode x = h.Right;\n\t\th.Right = x.Left;\n\t\tx.Left = h;\n\t\treturn x;\n\t}\n\n\tprotected virtual INode RotR(INode h)\n\t{\n\t\tINode x = h.Left;\n\t\th.Left = x.Right;\n\t\tx.Right = h;\n\t\treturn x;\n\t}\n\t\n\tprotected virtual INode SplitFourNode(INode h)\n\t{\n\t\tINode x = RotR(h);\n\t\tx.Left.Color = Color.Black;\n\t\treturn x;\n\t}\n\t\n\tprotected virtual INode LeanLeft(INode h)\n\t{\n\t\tINode x = RotL(h);\n\t\tx.Color = x.Left.Color;\n\t\tx.Left.Color = Color.Red;\n\t\treturn x;\n\t}\n\t\n\tprotected virtual INode LeanRight(INode h)\n\t{\n\t\tINode x = RotR(h);\n\t\tx.Color = x.Right.Color;\n\t\tx.Right.Color = Color.Red;\n\t\treturn x;\n\t}\n\t\n\tprotected INode MoveRedLeft(INode h)\n\t{\n\t\th.Color = Color.Black;\n\t\th.Left.Color = Color.Red;\n\t\t\n \t\tif (IsRed(h.Right.Left)) {\n \t\t\th.Right = RotR(h.Right);\n\t\t\th = RotL(h);\n\t\t}\n\t\telse\n\t\t\th.Right.Color = Color.Red;\n\t\t\t\n\t\treturn h;\n\t}\n\t\n\tprotected INode MoveRedRight(INode h)\n\t{\n\t\th.Color = Color.Black;\n\t\th.Right.Color = Color.Red;\n\t\t\n \t\tif (IsRed(h.Left.Left)) {\n \t\t\th = RotR(h);\n \t\t\th.Color = Color.Red;\n \t\t\th.Left.Color = Color.Black;\n\t\t}\n\t\telse\n\t\t\th.Left.Color = Color.Red;\n\t\t\t\n\t\treturn h;\n\t}\n\t\n\tprivate INode DeleteMin(INode h)\n\t{\n\t\t// remove node on bottom level (h must be RED by invariant)\n\t\tif (h.Left == null)\n\t\t\treturn null;\n\t\t\n\t\t// push red link down if necessary\n\t\tif (!IsRed(h.Left) && !IsRed(h.Left.Left))\n\t\t\th = MoveRedLeft(h);\n\t\t\t\n\t\t// move down one level\n\t\th.Left = DeleteMin(h.Left);\n\t\t\n\t\t// fix right-leaning red links on the way up the tree\n\t\tif (IsRed(h.Right))\n\t\t\th = LeanLeft(h);\n\t\t\n\t\treturn h;\n\t}\n\t\n\tprivate INode FindMinNode(INode h)\n\t{\n\t\twhile (h.Left != null)\n\t\t\th = h.Left;\n\t\t\n\t\treturn h;\n\t}\n\n\tprotected virtual void AddToValues(INode n, V val)\n\t{\n\t\tn.Values.Add(val);\n\t}\n\t\n\tpublic RedBlackTree()\n\t{\n\t\tnodeFactory = new NodeFactory();\n\t}\n\n\tprotected RedBlackTree(INodeFactory nf)\n\t{\n\t\tnodeFactory = nf;\n\t}\n\n\tprivate INode Insert(INode h, K key, V val)\n\t{\n\t\tif (h == null)\n\t\t\treturn nodeFactory.CreateNode(key, val, Color.Red);\n\t\t\n\t\t// split 4-nodes on the way down\n\t\tif (IsRed(h.Left) && IsRed(h.Left.Left))\n\t\t\th = SplitFourNode(h);\n\t\t\n\t\t// standard BST insert code\n\t\tint cmp = key.CompareTo(h.Key);\n\t\t\n\t\tif (cmp == 0)\n\t\t\tAddToValues(h, val);\n\t\telse if (cmp < 0)\n\t\t\th.Left = Insert(h.Left, key, val);\n\t\telse\n\t\t\th.Right = Insert(h.Right, key, val);\n\t\t\n\t\t// fix right-leaning reds on the way up\n\t\tif (IsRed(h.Right))\n\t\t\th = LeanLeft(h);\n\t\t\n\t\treturn h;\n\t}\n\n\t/// <summary>\n\t/// Insert a key and its associated value into the tree.\n\t/// </summary>\n\t/// <param name=\"key\">\n\t/// A <see cref=\"K\"/>\n\t/// </param>\n\t/// <param name=\"val\">\n\t/// A <see cref=\"V\"/>\n\t/// </param>\n\tpublic virtual void Insert(K key, V val)\n\t{\n\t\tlock(lockObj) {\n\t\t\troot = Insert(root, key, val);\n\t\t\troot.Color = Color.Black;\n\t\t}\n\t}\n\t\n\t/// <summary>\n\t/// Search for the tree node that contains a key. \n\t/// </summary>\n\t/// <param name=\"key\">\n\t/// A <see cref=\"K\"/>\n\t/// </param>\n\t/// <returns>\n\t/// A <see cref=\"INode\"/>\n\t/// </returns>\n\tprotected virtual INode SearchNode(K key)\n\t{\n\t\tINode x = root;\n\t\t\t\n\t\twhile (x != null) {\n\t\t\tint cmp = key.CompareTo(x.Key);\n\t\t\t\n\t\t\tif (cmp == 0) return x;\n\t\t\telse if (cmp < 0) x = x.Left;\n\t\t\telse if (cmp > 0) x = x.Right;\n\t\t}\n\t\t   \n\t\treturn null;\n\t}\n\t\n\t/// <summary>\n\t/// Search for all the values associated with a key.\n\t/// </summary>\n\t/// <param name=\"key\">\n\t/// A <see cref=\"K\"/>\n\t/// </param>\n\t/// <returns>\n\t/// A <see cref=\"IList`1\"/>\n\t/// </returns>\n\tpublic virtual IList<V> Search(K key)\n\t{\n\t\tlock(lockObj) {\n\t\t\tINode x = SearchNode(key);\n\t\t\t\n\t\t\tif (x != null)\n\t\t\t\treturn x.Values;\n\t\t\telse\n\t\t\t\treturn new System.Collections.Generic.List<V>(0);\n\t\t}\n\t}\n\t\n\tprivate INode Delete(INode h, K key)\n\t{\n\t\tif (h == null)\n\t\t\treturn null;\n\t\t\n\t\tint cmp = key.CompareTo(h.Key);\n\t\t\n\t\tif (cmp < 0) { // left\n\t\t\t\n\t\t\t// push red right if necessary\n\t\t\tif (!IsRed(h.Left) && h.Left != null && !IsRed(h.Left.Left))\n\t\t\t\th = MoveRedLeft(h);                           \n\t\t\t// move down (left)\n\t\t\th.Left = Delete(h.Left, key);\n\t\t}\n\t\telse { // right or equal\n\t\t\t// rotate to push red right\n\t\t\tif (IsRed(h.Left)) {\n\t\t\t\th = LeanRight(h);\n\t\t\t\t// LeanRight always rotates and brings (old) h to the right\n\t\t\t\tcmp = 1;\n\t\t\t}\n\t\t\t\n\t\t\t// equal (at bottom)...  delete node\n\t\t\t// or search reached bottom and we must go right (cmp == 1)\n\t\t\t// but we can't (h.Right == null) -> the key is not in the tree\n\t\t\tif ((cmp == 0 || cmp == 1) && (h.Right == null))\n\t\t\t\treturn null;\n\t\t\t\t\n\t\t\t// push red right if necessary\n\t\t\tif (!IsRed(h.Right) && !IsRed(h.Right.Left)) {\n\t\t\t\th = MoveRedRight(h);\n\t\t\t\t// MoveRedRight may or may not rotate so we must\n\t\t\t\t// check new node again\n\t\t\t\tcmp = key.CompareTo(h.Key);\n\t\t\t}\n\t\t\t\n\t\t\t// equal (not at bottom)\n\t\t\tif (cmp == 0) {\n\t\t\t\tINode minNode = FindMinNode(h.Right);\n\t\t\t\t// replace current node with successor key, value\n      \t\t\th.Key = minNode.Key;                               \n\t\t\t\th.Values = minNode.Values; \n\t\t\t\t// delete successor\n\t\t\t\th.Right = DeleteMin(h.Right);\n\t\t\t}\n\t\t\telse { // move down (right)\n\t\t\t\th.Right = Delete(h.Right, key);\n\t\t\t}\t\t\t\t\n\t\t}\n\t\t\n\t\t// Fix right-leaning red links on the way up the tree\n\t\tif (IsRed(h.Right)) h = LeanLeft(h);\n\t\t\n\t\treturn h;\n\t}\n\t\n\t/// <summary>\n\t/// Delete a key and all its associated values from the tree.\n\t/// </summary>\n\t/// <param name=\"key\">\n\t/// A <see cref=\"K\"/>\n\t/// </param>\n\tpublic virtual void Delete(K key)\n\t{\n\t\tlock(lockObj) {\n\t\t\troot = Delete(root, key);\n\t\t\tif (root != null)\n\t\t\t\troot.Color = Color.Black;\n\t\t}\n\t}\n\t\n\t/// <summary>\n\t/// Dump the contents of the tree as a graphviz/dot file\n\t/// </summary>\n\t/// <param name=\"filename\">\n\t/// A <see cref=\"System.String\"/>\n\t/// </param>\n\t/// <param name=\"title\">\n\t/// The title of the produced graph\n\t/// </param>\n\tpublic void DumpToDot(string filename, string title)\n\t{\n\t\tlock(lockObj) {\n\t\t\tStringBuilder sb = new StringBuilder(\"digraph {\\nlabel=\\\"\"+title+\"\\\"\\n\");\n\t\t\tDumpToDotInternal(root, sb);\n\t\t\tsb.Append(\"}\\n\");\n\t\t\t\n\t\t\tStreamWriter sw = new StreamWriter(filename);\n\t\t\tsw.Write(sb.ToString());\n\t\t\tsw.Close();\n\t\t}\n\t}\n\t\n\tpublic void Clear()\n\t{\n\t\tlock (lockObj) {\n\t\t\troot = null;\n\t\t}\n\t}\n\t\n\tpublic IList<V> GetValues()\n\t{\n\t\tlock (lockObj){\n\t\t\ttmpValues = new System.Collections.Generic.List<V>();\n\t\t\tGetValues(root);\n\t\t\t\n\t\t\t// clear private var\n\t\t\tIList<V> tv = tmpValues;\n\t\t\ttmpValues = null;\n\t\t\treturn tv;\n\t\t}\n\t}\n\t\n\tprivate void GetValues(INode x)\n\t{\n\t\tif (x == null)\n\t\t\treturn;\n\t\t\n\t\tGetValues(x.Left);\n\t\t\n\t\tforeach(V v in x.Values)\n\t\t\ttmpValues.Add(v);\n\t\t\n\t\tGetValues(x.Right);\n\t}\n\t\n\tprivate void DumpToDotInternal(INode h, StringBuilder sb)\n\t{\n\t\tif (h == null)\n\t\t\treturn;\n\t\t\n\t\tDumpToDotInternal(h.Left, sb);\n\t\t\n\t\tif (h.Left != null) {\n\t\t\tstring col = \" [label=L, color=\" + (h.Left.Color == Color.Red?\"red, style=bold]\\n\":\"black]\");\n\t\t\tsb.Append(h.Key + \" -> \" + h.Left.Key + col +\"\\n\");\n\t\t}\n\t\t\n\t\tif (h.Right != null) {\n\t\t\tstring col = \" [label=R, color=\" + (h.Right.Color == Color.Red?\"red, style=bold]\\n\":\"black]\");\n\t\t\tsb.Append(h.Key + \" -> \" + h.Right.Key + col + \"\\n\");\n\t\t}\n\t\t\n\t\tDumpToDotInternal(h.Right, sb);\n\t}\n\n}\n\n} // end namespace"
  },
  {
    "path": "src/util/TempFile.cs",
    "content": "// created on 10/27/2004 at 3:13 PM\n/*\n *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing System;\nusing System.IO;\n\nnamespace Bless.Util {\n\npublic class TempFile\n{\n\n\tprivate TempFile() { }\n\n\tstatic public string CreateName(string dir)\n\t{\n\t\tstring str;\n\t\tRandom rand = new Random();\n\n\t\tdo {\n\t\t\tstr = string.Empty;\n\t\t\tfor (int i = 0; i < 8; i++) {\n\t\t\t\tstr += Convert.ToChar(rand.Next() % 26 + Convert.ToInt32('a'));\n\t\t\t}\n\t\t} while (File.Exists(dir + Path.DirectorySeparatorChar + str + \".bless\") == true);\n\n\t\t//System.Console.WriteLine(\"Created random: {0}\",str);\n\t\treturn Path.Combine(dir, str + \".bless\");\n\t}\n}\n\n}//end namespace\n"
  },
  {
    "path": "src/util/ThreadedAsyncOperation.cs",
    "content": "// created on 4/4/2005 at 4:20 PM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing System;\nusing System.Threading;\n\nnamespace Bless.Util {\n\n///<summary>\n/// Abstract class modelling a threaded asynchronous operation\n///</summary>\npublic abstract class ThreadedAsyncOperation\n{\n\tprotected bool cancelled;\n\tprotected ProgressCallback progressCallback;\n\tprotected AsyncCallback opFinishedCallback;\n\tprotected bool activateProgress;\n\n\tException threadException;\n\tOperationResult opResult;\n\n\tbool useGLibIdle;\n\tTimer showProgressTimer;\n\tTimer progressTimer;\n\t\n\t// the kind of event that the save thread can emit to\n\t// the main thread\n\tprivate enum Event { ShowProgress, Finished, Exception}\n\n\t// the result of the operation\n\tpublic enum OperationResult { Finished, Cancelled, CaughtException }\n\n\tpublic OperationResult Result {\n\t\tget { return opResult; }\n\t\tset { opResult = value; }\n\t}\n\n\tpublic Exception ThreadException {\n\t\tget { return threadException; }\n\t\tset { threadException = value;}\n\t}\n\n\tpublic ThreadedAsyncOperation(ProgressCallback pc,\n\t\t\t\t\t\t\t\t  AsyncCallback ac, bool glibIdle)\n\t{\n\t\tprogressCallback = pc;\n\t\topFinishedCallback = ac;\n\t\tuseGLibIdle = glibIdle;\n\n\t\tcancelled = false;\n\t\tactivateProgress = true;\n\n\t\t// showProgressTimer fires once and makes progress reporting visible\n\t\tshowProgressTimer = new Timer(new TimerCallback(ShowProgressTimerExpired), null, Timeout.Infinite, Timeout.Infinite);\n\n\t\t// progressTimer fires periodically and updates progress reporting\n\t\tprogressTimer = new Timer(new TimerCallback(ProgressTimerExpired), null, Timeout.Infinite, Timeout.Infinite);\n\t}\n\n\tprotected abstract bool StartProgress();\n\tprotected abstract bool UpdateProgress();\n\tprotected abstract bool EndProgress();\n\tprotected abstract void DoOperation();\n\tprotected abstract void EndOperation();\n\n\t///<summary>\n\t/// Called when the operation has finished\n\t///</summary>\n\tvoid OperationFinished()\n\t{\n\t\t// destroy progress report\n\t\tif (progressCallback != null)\n\t\t\tEndProgress();\n\n\t\t// call callback\n\t\tif (opFinishedCallback != null)\n\t\t\topFinishedCallback(new ThreadedAsyncResult(this, null, true));\n\n\t}\n\n\t///<summary>\n\t/// Called once by a timer to make the progress report visible\n\t///</summary>\n\tvoid ShowProgressTimerExpired(object o)\n\t{\n\t\tif (progressCallback != null) {\n\t\t\tif (useGLibIdle)\n\t\t\t\tGLib.Idle.Add(StartProgress);\n\t\t\telse\n\t\t\t\tStartProgress();\n\t\t}\n\t}\n\n\t///<summary>\n\t/// Called periodically by a timer to update the progress report\n\t///</summary>\n\tvoid ProgressTimerExpired(object o)\n\t{\n\t\tif (progressCallback != null) {\n\t\t\tif (useGLibIdle)\n\t\t\t\tGLib.Idle.Add(delegate { cancelled = UpdateProgress(); return false; });\n\t\t\telse\n\t\t\t\tcancelled = UpdateProgress();\n\t\t}\n\t}\n\n\tprotected void ActivateProgressReport(bool activate)\n\t{\n\t\ttry {\n\t\t\tif (activate) {\n\t\t\t\tprogressTimer.Change(0, 50);\n\t\t\t\tshowProgressTimer.Change(500, 0);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tprogressTimer.Change(Timeout.Infinite, Timeout.Infinite);\n\t\t\t\tshowProgressTimer.Change(Timeout.Infinite, Timeout.Infinite);\n\t\t\t}\n\t\t}\n\t\tcatch(ObjectDisposedException) {}\n\t}\n\n\tpublic void OperationThread()\n\t{\n\t\tActivateProgressReport(activateProgress);\n\n\t\ttry {\n\t\t\tDoOperation();\n\n\t\t\tif (cancelled) \n\t\t\t\topResult = OperationResult.Cancelled;\n\t\t\telse\n\t\t\t\topResult = OperationResult.Finished;\t\n\t\t}\n\t\tcatch (Exception e) {\n\t\t\tthreadException = e;\n\t\t\topResult = OperationResult.CaughtException;\t\n\t\t}\n\t\tfinally {\n\t\t\tprogressTimer.Dispose();\n\t\t\tshowProgressTimer.Dispose();\n\t\t\tEndOperation();\n\n\t\t\tif (useGLibIdle)\n\t\t\t\tGLib.Idle.Add(delegate { OperationFinished(); return false; });\n\t\t\telse\n\t\t\t\tOperationFinished();\n\t\t}\n\n\t}\n}\n\n///<summary>\n/// Class to hold information about an asynchronous threaded operation\n///</summary>\npublic class ThreadedAsyncResult: IAsyncResult {\n\tobject asyncState;\n\tWaitHandle asyncWaitHandle;\n\tbool isCompleted;\n\n\tpublic ThreadedAsyncResult(object state, WaitHandle handle, bool complete)\n\t{\n\t\tasyncState = state;\n\t\tasyncWaitHandle = handle;\n\t\tisCompleted = complete;\n\t}\n\tpublic object AsyncState {\n\t\tget { return asyncState;}\n\t}\n\tpublic WaitHandle AsyncWaitHandle {\n\t\tget { return asyncWaitHandle;}\n\t}\n\tpublic bool CompletedSynchronously {\n\t\tget { return false;}\n\t}\n\tpublic bool IsCompleted {\n\t\tget { return isCompleted;}\n\t}\n}\n\n} // end namespace\n"
  },
  {
    "path": "tests/buffers/ByteBufferTests.cs",
    "content": "// created on 3/8/2005 at 5:02 PM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing NUnit.Framework;\nusing System;\nusing System.Threading;\n\nusing Bless.Buffers;\n\nnamespace BlessTests.Buffers {\n\n[TestFixture]\npublic class ByteBufferTests {\n\n\t[Test]\n\tpublic void AppendDoTest() {\n\t\tByteBuffer bb = new ByteBuffer();\n\t\tbyte[] ba = {1, 3, 5, 7, 13, 17};\n\t\tbb.Append(ba, 0, ba.LongLength);\n\n\t\tAssert.AreEqual(6, bb.Size);\n\t\tAssert.AreEqual(1, bb[0]);\n\t\tAssert.AreEqual(3, bb[1]);\n\t\tAssert.AreEqual(5, bb[2]);\n\t\tAssert.AreEqual(7, bb[3]);\n\t\tAssert.AreEqual(13, bb[4]);\n\t\tAssert.AreEqual(17, bb[5]);\n\t}\n\n\t[Test]\n\tpublic void AppendUndoTest() {\n\t\tByteBuffer bb = new ByteBuffer();\n\t\tbyte[] ba = {1, 3, 5, 7};\n\t\tbyte[] ba1 = {13, 17};\n\t\tbb.Append(ba, 0, ba.LongLength);\n\t\tbb.Append(ba1, 0, ba1.LongLength);\n\n\t\tAssert.AreEqual(6, bb.Size, \"#1\");\n\t\tAssert.AreEqual(3, bb[1], \"#2\");\n\t\tAssert.AreEqual(17, bb[5], \"#3\");\n\n\t\tbb.Undo();\n\n\t\tAssert.AreEqual(4, bb.Size, \"#4\");\n\t\tAssert.AreEqual(1, bb[0], \"#5\");\n\t\tAssert.AreEqual(3, bb[1], \"#6\");\n\t\tAssert.AreEqual(5, bb[2], \"#7\");\n\t\tAssert.AreEqual(7, bb[3], \"#8\");\n\t}\n\n\t[Test]\n\tpublic void InsertDoTest() {\n\t\tByteBuffer bb = new ByteBuffer();\n\t\tbyte[] ba = {1, 3, 17};\n\t\tbyte[] ba1 = {5, 7, 13};\n\t\tbb.Append(ba, 0, ba.LongLength);\n\t\t//bb.Display(\"D1\");\n\t\tbb.Insert(2, ba1, 0, ba1.LongLength);\n\t\t//bb.Display(\"D2\");\n\n\t\tAssert.AreEqual(6, bb.Size, \"#1\");\n\t\tAssert.AreEqual(1, bb[0], \"#2\");\n\t\tAssert.AreEqual(3, bb[1], \"#3\");\n\t\tAssert.AreEqual(5, bb[2], \"#4\");\n\t\tAssert.AreEqual(7, bb[3], \"#5\");\n\t\tAssert.AreEqual(13, bb[4], \"#6\");\n\t\tAssert.AreEqual(17, bb[5], \"#7\");\n\t}\n\n\t[Test]\n\tpublic void InsertUndoTest() {\n\t\tByteBuffer bb = new ByteBuffer();\n\t\tbyte[] ba = {1, 3, 17};\n\t\tbyte[] ba1 = {5, 7, 13};\n\t\tbb.Append(ba, 0, ba.LongLength);\n\t\t//bb.Display(\"D1\");\n\t\tbb.Insert(2, ba1, 0, ba1.LongLength);\n\t\t//bb.Display(\"D2\");\n\n\t\tAssert.AreEqual(6, bb.Size, \"#1\");\n\t\tAssert.AreEqual(3, bb[1], \"#2\");\n\t\tAssert.AreEqual(17, bb[5], \"#3\");\n\n\t\tbb.Undo();\n\t\t//bb.Display(\"D3\");\n\t\tAssert.AreEqual(3, bb.Size, \"#4\");\n\t\tAssert.AreEqual(1, bb[0], \"#5\");\n\t\tAssert.AreEqual(3, bb[1], \"#6\");\n\t\tAssert.AreEqual(17, bb[2], \"#7\");\n\t}\n\n\t[Test]\n\tpublic void DeleteDoTest() {\n\t\tByteBuffer bb = new ByteBuffer();\n\t\tbyte[] ba = {1, 3, 17};\n\t\tbyte[] ba1 = {5, 7, 13};\n\t\tbb.Append(ba, 0, ba.LongLength);\n\t\t//bb.Display(\"D1\");\n\t\tbb.Insert(2, ba1, 0, ba1.LongLength);\n\t\t//bb.Display(\"D2\");\n\t\tbb.Delete(1, 3);\n\n\t\tAssert.AreEqual(3, bb.Size, \"#1\");\n\t\tAssert.AreEqual(1, bb[0], \"#2\");\n\t\tAssert.AreEqual(13, bb[1], \"#3\");\n\t\tAssert.AreEqual(17, bb[2], \"#4\");\n\t}\n\n\t[Test]\n\tpublic void DeleteUndoTest() {\n\t\tByteBuffer bb = new ByteBuffer();\n\t\tbyte[] ba = {1, 3, 17};\n\t\tbyte[] ba1 = {5, 7, 13};\n\t\tbb.Append(ba, 0, ba.LongLength);\n\t\t//bb.Display(\"D1\");\n\t\tbb.Insert(2, ba1, 0, ba1.LongLength);\n\t\t//bb.Display(\"D2\");\n\t\tbb.Delete(1, 3);\n\n\t\tAssert.AreEqual(3, bb.Size, \"#1\");\n\t\tAssert.AreEqual(1, bb[0], \"#2\");\n\t\tAssert.AreEqual(13, bb[1], \"#3\");\n\t\tAssert.AreEqual(17, bb[2], \"#4\");\n\n\t\tbb.Undo();\n\n\t\tAssert.AreEqual(6, bb.Size, \"#5\");\n\t\tAssert.AreEqual(1, bb[0], \"#6\");\n\t\tAssert.AreEqual(3, bb[1], \"#7\");\n\t\tAssert.AreEqual(5, bb[2], \"#8\");\n\t\tAssert.AreEqual(7, bb[3], \"#9\");\n\t\tAssert.AreEqual(13, bb[4], \"#10\");\n\t\tAssert.AreEqual(17, bb[5], \"#11\");\n\t}\n\n\t[Test]\n\tpublic void FileLoadTest1() {\n\t\tByteBuffer bb = ByteBuffer.FromFile(\"test1.bin\");\n\n\t\tlong size = bb.Size;\n\t\tint sum = 0;\n\n\t\tfor (int i = 0; i < size; i++)\n\t\t\tsum ^= bb[i];\n\n\t\tAssert.AreEqual( 0x88, sum, \"XOR Result\");\n\t}\n\n\t[Test]\n\tpublic void FileLoadTest2() {\n\t\tByteBuffer bb = ByteBuffer.FromFile(\"test1.bin\");\n\t\tbyte[] ba = {0x41, 0x61};\n\t\tbb.Append(ba, 0, ba.LongLength);\n\n\t\tlong size = bb.Size;\n\t\tint sum = 0;\n\n\t\tfor (int i = 0; i < size; i++)\n\t\t\tsum ^= bb[i];\n\n\t\tAssert.AreEqual( 0x88 ^ 0x20, sum);\n\t}\n\n\t[Test]\n\tpublic void FileLoadTest3() {\n\t\tByteBuffer bb = ByteBuffer.FromFile(\"test1.bin\");\n\t\tbyte[] ba = {0x41, 0x61};\n\t\tbb.Insert(768, ba, 0, ba.LongLength);\n\n\t\tlong size = bb.Size;\n\t\tint sum = 0;\n\n\t\tfor (int i = 0; i < size; i++)\n\t\t\tsum ^= bb[i];\n\n\t\tAssert.AreEqual( 0x88 ^ 0x20, sum);\n\t}\n\n\t[Test]\n\t[Ignore(\"It fails, perhaps because it is run from nunit\")]\n\tpublic void FileSaveTest1() {\n\t\tByteBuffer bb = ByteBuffer.FromFile(\"test1.bin\");\n\t\tbyte[] ba = {0x41, 0x61};\n\t\tlong size1 = bb.Size;\n\n\t\tbb.Insert(768, ba, 0, ba.LongLength);\n\t\tAssert.AreEqual(size1 + 2, bb.Size, \"#1\");\n\n\t\tIAsyncResult ar = bb.BeginSaveAs(\"test2.bin\", null, null);\n\t\tar.AsyncWaitHandle.WaitOne();\n\t\tbb.CloseFile();\n\n\t\tByteBuffer bb1 = ByteBuffer.FromFile(\"test2.bin\");\n\n\t\tAssert.AreEqual(bb.Size, bb1.Size, \"#2\");\n\t\tlong size = bb1.Size;\n\n\t\tfor (int i = 0; i < size; i++) {\n\t\t\tif (bb1[i] != bb[i])\n\t\t\t\tAssert.Fail(string.Format(\"#3 Difference at {0} ({1}!={2})\", i, bb1[i], bb[i]));\n\t\t}\n\t}\n\n\t[Test]\n\tpublic void HasChangedTest()\n\t{\n\t\tByteBuffer bb = new ByteBuffer();\n\t\tbyte[] ba = {0x41, 0x61};\n\t\tAssert.AreEqual(false, bb.HasChanged, \"#0\");\n\t\tbb.Append(ba, 0, ba.LongLength);\n\t\tAssert.AreEqual(true, bb.HasChanged, \"#1\");\n\t\tbb.Undo();\n\t\tAssert.AreEqual(false, bb.HasChanged, \"#2\");\n\t}\n\n\t[Test]\n\tpublic void InsertEmptyUndoTest()\n\t{\n\t\tByteBuffer bb = new ByteBuffer();\n\t\tbyte[] ba = {0x01, 0x02, 0xfe, 0xff};\n\t\tbyte[] baEmpty = new byte[0];\n\n\t\tbb.Append(ba, 0, ba.LongLength);\n\t\tbb.Insert(2, baEmpty, 0, baEmpty.LongLength);\n\n\t\tAssert.AreEqual(4, bb.Size, \"#Size before undo\");\n\t\tAssert.AreEqual(0x01, bb[0], \"#bb[0] before undo\");\n\t\tAssert.AreEqual(0x02, bb[1], \"#bb[1] before undo\");\n\t\tAssert.AreEqual(0xfe, bb[2], \"#bb[2] before undo\");\n\t\tAssert.AreEqual(0xff, bb[3], \"#bb[3] before undo\");\n\n\t\tbb.Undo();\n\t\tAssert.AreEqual(4, bb.Size, \"#Size after undo\");\n\t\tAssert.AreEqual(0x01, bb[0], \"#bb[0] after undo\");\n\t\tAssert.AreEqual(0x02, bb[1], \"#bb[1] after undo\");\n\t\tAssert.AreEqual(0xfe, bb[2], \"#bb[2] after undo\");\n\t\tAssert.AreEqual(0xff, bb[3], \"#bb[3] after undo\");\n\t}\n\n\t[Test]\n\tpublic void AppendEmptyUndoTest()\n\t{\n\t\tByteBuffer bb = new ByteBuffer();\n\t\tbyte[] ba = {0x01, 0x02, 0xfe, 0xff};\n\t\tbyte[] baEmpty = new byte[0];\n\n\t\tbb.Append(ba, 0, ba.LongLength);\n\t\tbb.Append(baEmpty, 0, baEmpty.LongLength);\n\n\t\tAssert.AreEqual(4, bb.Size, \"#Size before undo\");\n\t\tAssert.AreEqual(0x01, bb[0], \"#bb[0] before undo\");\n\t\tAssert.AreEqual(0x02, bb[1], \"#bb[1] before undo\");\n\t\tAssert.AreEqual(0xfe, bb[2], \"#bb[2] before undo\");\n\t\tAssert.AreEqual(0xff, bb[3], \"#bb[3] before undo\");\n\n\t\tbb.Undo();\n\t\tAssert.AreEqual(4, bb.Size, \"#Size after undo\");\n\t\tAssert.AreEqual(0x01, bb[0], \"#bb[0] after undo\");\n\t\tAssert.AreEqual(0x02, bb[1], \"#bb[1] after undo\");\n\t\tAssert.AreEqual(0xfe, bb[2], \"#bb[2] after undo\");\n\t\tAssert.AreEqual(0xff, bb[3], \"#bb[3] after undo\");\n\t}\n\n\t[Test]\n\tpublic void ActionChainingTest()\n\t{\n\t\tByteBuffer bb = new ByteBuffer();\n\t\tbyte[] ba1 = {0x01, 0x04};\n\t\tbyte[] ba2 = {0x02, 0x03};\n\t\tbyte[] ba3 = {0x05, 0x06};\n\t\tbyte[] ba4 = {0x07, 0x08};\n\n\t\tbb.BeginActionChaining();\n\t\tbb.Append(ba1, 0, ba1.LongLength);\n\t\tbb.Insert(1, ba2, 0, ba2.LongLength);\n\t\tbb.EndActionChaining();\n\n\t\tAssert.AreEqual(4, bb.Size, \"#1\");\n\t\tAssert.IsTrue(bb.CanUndo, \"#2\");\n\t\tbb.Undo();\n\t\tAssert.AreEqual(0, bb.Size, \"#3\");\n\t\tAssert.IsFalse(bb.CanUndo, \"#4\");\n\n\t\tbb.Redo();\n\n\t\tbb.BeginActionChaining();\n\t\tbb.Append(ba4, 0, ba4.LongLength);\n\t\tbb.Insert(4, ba3, 0, ba3.LongLength);\n\t\tbb.EndActionChaining();\n\n\t\tAssert.AreEqual(8, bb.Size, \"#5\");\n\t\tAssert.IsTrue(bb.CanUndo, \"#6\");\n\n\t\tbb.Undo();\n\n\t\tAssert.AreEqual(4, bb.Size, \"#7\");\n\t\tAssert.IsTrue(bb.CanUndo, \"#8\");\n\t}\n\n\t[Test]\n\tpublic void LimitedUndoTest()\n\t{\n\t\tByteBuffer bb = new ByteBuffer();\n\t\tbb.MaxUndoActions = 3;\n\n\t\tbyte[] ba1 = {0x01, 0x04};\n\t\tbyte[] ba2 = {0x02, 0x03};\n\t\tbyte[] ba3 = {0x05, 0x06};\n\t\tbyte[] ba4 = {0x07, 0x08};\n\n\n\t\tbb.Append(ba1, 0, ba1.LongLength);\n\t\tbb.Insert(1, ba2, 0, ba2.LongLength);\n\t\tbb.Append(ba4, 0, ba4.LongLength);\n\t\tbb.Insert(4, ba3, 0, ba3.LongLength);\n\n\t\tAssert.AreEqual(true, bb.CanUndo, \"#1\");\n\t\tbb.Undo();\n\t\tAssert.AreEqual(true, bb.CanUndo, \"#2\");\n\t\tbb.Undo();\n\t\tAssert.AreEqual(true, bb.CanUndo, \"#3\");\n\t\tbb.Undo();\n\t\tAssert.AreEqual(false, bb.CanUndo, \"#4\");\n\t\tAssert.AreEqual(2, bb.Size, \"#5\");\n\t\tAssert.AreEqual(0x01, bb[0], \"#6\");\n\t\tAssert.AreEqual(0x04, bb[1], \"#7\");\n\n\t\tbb.Redo();\n\t\tbb.Redo();\n\t\tbb.Redo();\n\t\tAssert.AreEqual(8, bb.Size, \"#8\");\n\t\tbb.MaxUndoActions = 2;\n\n\t\tbb.Undo();\n\t\tAssert.AreEqual(6, bb.Size, \"#8.5\");\n\t\tAssert.AreEqual(true, bb.CanUndo, \"#9\");\n\t\tbb.Undo();\n\t\tAssert.AreEqual(false, bb.CanUndo, \"#10\");\n\t\tAssert.AreEqual(4, bb.Size, \"#11\");\n\t}\n}\n\n} // end namespace\n"
  },
  {
    "path": "tests/buffers/FileBufferTests.cs",
    "content": "// created on 3/8/2005 at 5:11 PM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing NUnit.Framework;\nusing System;\n\nusing Bless.Buffers;\n\nnamespace BlessTests.Buffers {\n\n[TestFixture]\npublic class FileBufferTests {\n\n\t[Test]\n\tpublic void LoadFile() {\n\t\tFileBuffer fb = new FileBuffer(\"test1.bin\");\n\t\tbyte[] baExpect = {0x3c, 0x13, 0xe3, 0x36, 0xcc, 0x66, 0x21, 0xda};\n\t\tbyte[] ba = new byte[baExpect.Length];\n\t\tfb.Read(ba, 0, 0x3f0, baExpect.Length);\n\n\t\tAssert.IsNotNull(ba, \"#1\");\n\t\tfor (int i = 0;i < baExpect.Length;i++)\n\t\t\tAssert.AreEqual(baExpect[i], ba[i]);\n\t}\n\n\t[Test]\n\tpublic void IndexerAccessTest() {\n\t\tFileBuffer fb = new FileBuffer(\"test1.bin\");\n\t\tAssert.IsNotNull(fb, \"#1\");\n\n\t\tlong size = fb.Size;\n\t\tint sum = 0;\n\n\t\tfor (int i = 0; i < size; i++)\n\t\t\tsum ^= fb[i];\n\n\t\tAssert.AreEqual( 0x88, sum);\n\n\t}\n\n}\n\n} // end namespace\n\n"
  },
  {
    "path": "tests/buffers/SegmentCollectionTests.cs",
    "content": "// created on 3/8/2005 at 5:15 PM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing NUnit.Framework;\nusing System;\n\nusing Bless.Util;\nusing Bless.Buffers;\n\nnamespace BlessTests.Buffers {\n\n[TestFixture]\npublic class SegmentCollectionTests {\n\n\tBless.Buffers.IBuffer buf1;\n\tBless.Buffers.IBuffer buf2;\n\n\n\t[SetUp]\n\tpublic void Init() {\n\t\tbuf1 = new BaseBuffer();\n\t\tbuf2 = new BaseBuffer();\n\t}\n\n\t[Test]\n\tpublic void AppendSegmentsTest1() {\n\t\tSegmentCollection segs = new SegmentCollection();\n\t\tSegment s1, s2;\n\t\ts1 = new Segment(buf1, 0, 5);\n\t\ts2 = new Segment(buf2, 6, 5);\n\t\tsegs.Append(s1);\n\t\tsegs.Append(s2);\n\t\tAssert.AreSame(s1, segs.List[0]);\n\t\tAssert.AreSame(s2, segs.List[1]);\n\t}\n\n\t[Test]\n\tpublic void AppendSegmentsTest2() {\n\t\tSegmentCollection segs = new SegmentCollection();\n\t\tSegment s1, s2;\n\t\ts1 = new Segment(buf1, 0, 5);\n\t\ts2 = new Segment(buf1, 6, 8);\n\t\tsegs.Append(s1);\n\t\tsegs.Append(s2);\n\t\tAssert.AreSame(s1, segs.List[0]);\n\t\tAssert.IsTrue(s1.Start == 0);\n\t\tAssert.IsTrue(s1.End == 8);\n\t\t//Assert.IsNull(segs[1]);\n\t}\n\n\t[Test]\n\tpublic void FindSegmentTest() {\n\t\tSegmentCollection segs1 = new SegmentCollection();\n\t\tSegment s1, s2, s3, s4;\n\t\ts1 = new Segment(buf1, 0, 5);\n\t\ts2 = new Segment(buf2, 6, 8);\n\t\ts3 = new Segment(buf2, 0, 5);\n\t\ts4 = new Segment(buf1, 6, 8);\n\t\tsegs1.Append(s1);\n\t\tsegs1.Append(s2);\n\t\tsegs1.Append(s3);\n\t\tsegs1.Append(s4);\n\n\t\tlong map;\n\t\tList<Segment>.Node n;\n\n\t\tAssert.AreSame(s1, segs1.FindSegment(4, out map, out n));\n\t\tAssert.AreEqual(0, map);\n\t\tAssert.AreSame(s3, segs1.FindSegment(10,  out map, out n));\n\t\tAssert.AreEqual(9, map);\n\t}\n\n\n\t[Test]\n\tpublic void InsertSegmentCollectionTest1() {\n\t\tSegmentCollection segs1 = new SegmentCollection();\n\t\tSegmentCollection segs2 = new SegmentCollection();\n\t\tSegment s1, s2, s3, s4;\n\t\ts1 = new Segment(buf1, 0, 5);\n\t\ts2 = new Segment(buf2, 6, 8);\n\t\ts3 = new Segment(buf2, 0, 5);\n\t\ts4 = new Segment(buf1, 6, 8);\n\n\t\tsegs1.Append(s1);\n\t\tsegs1.Append(s2);\n\t\tsegs2.Append(s3);\n\t\tsegs2.Append(s4);\n\n\t\tsegs1.Insert(segs2, 6);\n\n\t\tAssert.AreSame(s1, segs1.List[0]);\n\t\tAssert.AreSame(s3, segs1.List[1]);\n\t\tAssert.AreSame(s4, segs1.List[2]);\n\t\tAssert.AreSame(s2, segs1.List[3]);\n\t\t//Assert.IsNull(segs[1]);\n\t}\n\n\n\t[Test]\n\tpublic void InsertSegmentCollectionTest2() {\n\t\tSegmentCollection segs1 = new SegmentCollection();\n\t\tSegmentCollection segs2 = new SegmentCollection();\n\t\tSegment s1, s2, s3, s4;\n\t\ts1 = new Segment(buf1, 0, 5);\n\t\ts2 = new Segment(buf2, 6, 8);\n\t\ts3 = new Segment(buf2, 0, 5);\n\t\ts4 = new Segment(buf1, 6, 8);\n\n\t\tsegs1.Append(s1);\n\t\tsegs1.Append(s2);\n\t\tsegs2.Append(s3);\n\t\tsegs2.Append(s4);\n\n\t\tsegs1.Insert(segs2, 4);\n\n\t\tAssert.IsTrue(s1.End == 3);\n\t\tAssert.AreSame(s1, segs1.List[0]);\n\t\tAssert.AreSame(s3, segs1.List[1]);\n\t\tAssert.AreSame(s4, segs1.List[2]);\n\t\tAssert.AreSame(s2, segs1.List[4]);\n\t\tAssert.IsTrue(((Segment)segs1.List[3]).Start == 4);\n\t\tAssert.IsTrue(((Segment)segs1.List[3]).Buffer == buf1);\n\t\tAssert.IsTrue(((Segment)segs1.List[3]).End == 5);\n\t\t//Assert.IsNull(segs[1]);\n\t}\n\n\t[Test]\n\tpublic void InsertSegmentCollectionAtEndTest() {\n\t\tSegmentCollection segs1 = new SegmentCollection();\n\t\tSegmentCollection segs2 = new SegmentCollection();\n\t\tSegment s1, s2, s3, s4;\n\t\ts1 = new Segment(buf1, 0, 5);\n\t\ts2 = new Segment(buf2, 6, 8);\n\t\ts3 = new Segment(buf2, 0, 5);\n\t\ts4 = new Segment(buf1, 6, 8);\n\n\t\tsegs1.Append(s1);\n\t\tsegs1.Append(s2);\n\t\tsegs2.Append(s3);\n\t\tsegs2.Append(s4);\n\n\t\tsegs1.Insert(segs2, 9);\n\n\t\tAssert.AreSame(s1, segs1.List[0]);\n\t\tAssert.AreSame(s2, segs1.List[1]);\n\t\tAssert.AreSame(s3, segs1.List[2]);\n\t\tAssert.AreSame(s4, segs1.List[3]);\n\t\t//Assert.IsNull(segs[1]);\n\t}\n\n\t[Test]\n\tpublic void InsertSegmentCollectionThenFindTest() {\n\t\tSegmentCollection segs1 = new SegmentCollection();\n\t\tSegmentCollection segs2 = new SegmentCollection();\n\t\tSegment s1, s2, s3, s4;\n\t\ts1 = new Segment(buf1, 0, 5);\n\t\ts2 = new Segment(buf2, 6, 8);\n\t\ts3 = new Segment(buf2, 0, 5);\n\t\ts4 = new Segment(buf1, 6, 8);\n\n\t\tsegs1.Append(s1);\n\t\tsegs1.Append(s2);\n\t\tsegs2.Append(s3);\n\t\tsegs2.Append(s4);\n\n\t\tsegs1.Insert(segs2, 4);\n\n\t\tlong map;\n\t\tList<Segment>.Node n;\n\t\t//segs1.List.Display();\n\t\tAssert.AreSame(s1, segs1.FindSegment(3, out map, out n), \"s1\");\n\t\tAssert.AreEqual(0, map);\n\t\tAssert.AreSame(s3, segs1.FindSegment(7,  out map, out n), \"s3\");\n\t\tAssert.AreEqual(4, map);\n\t\tAssert.AreSame(s4, segs1.FindSegment(12,  out map, out n), \"s4\");\n\t\tAssert.AreEqual(10, map);\n\t\tSegment s5 = segs1.FindSegment(13,  out map, out n);\n\t\tAssert.AreEqual(13, map);\n\t\tAssert.IsTrue(s5.End == s5.Start + 1, \"s1'\");\n\t\tAssert.AreSame(s2, segs1.FindSegment(15,  out map, out n), \"s2\");\n\t\tAssert.AreEqual(15, map);\n\n\t}\n\n\n\t[Test]\n\tpublic void DeleteFromSegmentCollectionTest1() {\n\t\tSegmentCollection segs1 = new SegmentCollection();\n\t\tSegment s1, s2, s3, s4;\n\t\ts1 = new Segment(buf1, 0, 5);\n\t\ts2 = new Segment(buf2, 6, 8);\n\t\ts3 = new Segment(buf2, 0, 5);\n\t\ts4 = new Segment(buf1, 6, 8);\n\t\tsegs1.Append(s1);\n\t\tsegs1.Append(s2);\n\t\tsegs1.Append(s3);\n\t\tsegs1.Append(s4);\n\n\t\tsegs1.DeleteRange(7, 15);\n\t\tAssert.AreEqual(3, segs1.List.Count, \"#1\");\n\t\tAssert.AreEqual(6, ((Segment)segs1.List[0]).Size, \"#2\");\n\t\tAssert.AreEqual(6, ((Segment)segs1.List[1]).Start, \"#3\");\n\t\tAssert.AreEqual(6, ((Segment)segs1.List[1]).End, \"#4\");\n\t\tAssert.AreEqual(7, ((Segment)segs1.List[2]).Start, \"#5\");\n\t\tAssert.AreEqual(8, ((Segment)segs1.List[2]).End, \"#6\");\n\t}\n\n\t[Test]\n\tpublic void DeleteFromSegmentCollectionTest2() {\n\t\tSegmentCollection segs1 = new SegmentCollection();\n\t\tSegment s1;\n\t\ts1 = new Segment(buf1, 0, 8);\n\t\tsegs1.Append(s1);\n\t\tSegmentCollection del = segs1.DeleteRange(3, 6);\n\n\t\tAssert.AreEqual(2, segs1.List.Count, \"#0\");\n\t\tAssert.AreEqual(0, ((Segment)segs1.List[0]).Start, \"#1\");\n\t\tAssert.AreEqual(2, ((Segment)segs1.List[0]).End, \"#2\");\n\t\tAssert.AreEqual(7, ((Segment)segs1.List[1]).Start, \"#3\");\n\t\tAssert.AreEqual(8, ((Segment)segs1.List[1]).End, \"#4\");\n\n\t\tAssert.AreEqual(1, del.List.Count, \"#5\");\n\t\tAssert.AreEqual(3, ((Segment)del.List[0]).Start, \"#6\");\n\t\tAssert.AreEqual(6, ((Segment)del.List[0]).End, \"#7\");\n\n\t}\n\n\t[Test]\n\tpublic void DeleteFromSegmentCollectionTest3() {\n\t\tSegmentCollection segs1 = new SegmentCollection();\n\t\tSegment s1;\n\t\ts1 = new Segment(buf1, 0, 8);\n\t\tsegs1.Append(s1);\n\t\tSegmentCollection del = segs1.DeleteRange(0, 6);\n\n\t\tAssert.AreEqual(1, segs1.List.Count, \"#0\");\n\t\tAssert.AreEqual(7, ((Segment)segs1.List[0]).Start, \"#1\");\n\t\tAssert.AreEqual(8, ((Segment)segs1.List[0]).End, \"#2\");\n\n\t\tAssert.AreEqual(1, del.List.Count, \"#5\");\n\t\tAssert.AreEqual(0, ((Segment)del.List[0]).Start, \"#6\");\n\t\tAssert.AreEqual(6, ((Segment)del.List[0]).End, \"#7\");\n\n\t}\n\n\t[Test]\n\tpublic void DeleteFromSegmentCollectionTest4() {\n\t\tSegmentCollection segs1 = new SegmentCollection();\n\t\tSegment s1;\n\t\ts1 = new Segment(buf1, 0, 8);\n\t\tsegs1.Append(s1);\n\t\tSegmentCollection del = segs1.DeleteRange(0, 8);\n\n\t\tAssert.AreEqual(0, segs1.List.Count, \"#0\");\n\n\t\tAssert.AreEqual(1, del.List.Count, \"#5\");\n\t\tAssert.AreEqual(0, ((Segment)del.List[0]).Start, \"#6\");\n\t\tAssert.AreEqual(8, ((Segment)del.List[0]).End, \"#7\");\n\n\t}\n\n\t[Test]\n\tpublic void DeleteFromSegmentCollectionTest5() {\n\t\tSegmentCollection segs1 = new SegmentCollection();\n\t\tSegment s1;\n\t\ts1 = new Segment(buf1, 0, 8);\n\t\tsegs1.Append(s1);\n\t\tSegmentCollection del = segs1.DeleteRange(6, 8);\n\n\t\tAssert.AreEqual(1, segs1.List.Count, \"#0\");\n\t\tAssert.AreEqual(0, ((Segment)segs1.List[0]).Start, \"#1\");\n\t\tAssert.AreEqual(5, ((Segment)segs1.List[0]).End, \"#2\");\n\n\t\tAssert.AreEqual(1, del.List.Count, \"#5\");\n\t\tAssert.AreEqual(6, ((Segment)del.List[0]).Start, \"#6\");\n\t\tAssert.AreEqual(8, ((Segment)del.List[0]).End, \"#7\");\n\t}\n\n\t[Test]\n\tpublic void InsertToSegmentCollectionThenDeleteTest() {\n\t\tSegmentCollection segs1 = new SegmentCollection();\n\t\tSegment s1, s2;\n\t\ts1 = new Segment(buf1, 0, 2);\n\t\ts2 = new Segment(buf1, 3, 5);\n\t\tsegs1.Append(s1);\n\t\tSegmentCollection segs2 = new SegmentCollection();\n\t\tsegs2.Append(s2);\n\t\tsegs1.Insert(segs2, 2);\n\n\t\tsegs1.DeleteRange(2, 4);\n\n\t\tlong map;\n\t\tList<Segment>.Node n;\n\t\tSegment s = segs1.FindSegment(0, out map, out n);\n\t\tAssert.IsNotNull(s, \"#1\");\n\t\tAssert.AreEqual(0, map, \"#2\");\n\t\tAssert.AreEqual(0, s.Start, \"#3\");\n\n\n\n\t}\n\n\t[Test]\n\tpublic void ReplaceAtEnd() {\n\t\tSegmentCollection segs1 = new SegmentCollection();\n\t\tSegment s1, s2, s3;\n\t\ts1 = new Segment(buf1, 0, 4);\n\t\ts2 = new Segment(buf2, 7, 7);\n\t\ts3 = new Segment(buf2, 8, 8);\n\t\tsegs1.Append(s1);\n\t\t//segs1.List.Display();\n\t\tsegs1.DeleteRange(4, 4);\n\t\t//segs1.List.Display();\n\t\tsegs1.Append(s2);\n\t\t//segs1.List.Display();\n\t\tsegs1.DeleteRange(4, 4);\n\t\t//segs1.List.Display();\n\t\tsegs1.Append(s3);\n\t\t//segs1.List.Display();\n\n\t\tAssert.AreEqual(2, segs1.List.Count, \"#1\");\n\t\tAssert.AreEqual(3, (segs1.List[0] as Segment).End, \"#2\");\n\t\tAssert.AreEqual(8, (segs1.List[1] as Segment).Start, \"#3\");\n\t\tAssert.AreEqual(8, (segs1.List[1] as Segment).End, \"#4\");\n\n\t}\n\n\t[Test]\n\tpublic void InsertInEmptyCollection() {\n\t\tSegmentCollection segs1 = new SegmentCollection();\n\t\tSegmentCollection segs2 = new SegmentCollection();\n\t\tSegment s1 = new Segment(buf1, 0, 4);\n\t\tSegment s2 = new Segment(buf2, 7, 9);\n\n\t\tsegs2.Append(s1);\n\t\tsegs2.Append(s2);\n\n\t\tsegs1.Insert(segs2, 0);\n\n\t\tAssert.AreEqual(2, segs1.List.Count, \"#1\");\n\t\tAssert.AreEqual(4, (segs1.List[0] as Segment).End, \"#2\");\n\t\tAssert.AreEqual(7, (segs1.List[1] as Segment).Start, \"#3\");\n\t\tAssert.AreEqual(9, (segs1.List[1] as Segment).End, \"#4\");\n\t}\n}\n\n} // end namespace\n"
  },
  {
    "path": "tests/buffers/SegmentTests.cs",
    "content": "// created on 3/8/2005 at 5:14 PM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing NUnit.Framework;\nusing System;\n\nusing Bless.Buffers;\n\nnamespace BlessTests.Buffers {\n\n[TestFixture]\npublic class SegmentTests {\n\n\t[Test]\n\tpublic void SplitTest1() {\n\t\tSegment\ts = new Segment(null, 3, 8);\n\t\tSegment s1 = s.SplitAt(3);\n\t\tAssert.AreEqual(3, s.Start);\n\t\tAssert.AreEqual(5, s.End);\n\t\tAssert.AreEqual(6, s1.Start);\n\t\tAssert.AreEqual(8, s1.End);\n\t}\n\n\t[Test]\n\tpublic void SplitTest2() {\n\t\tSegment\ts = new Segment(null, 3, 8);\n\t\tSegment s1 = s.SplitAt(0);\n\t\tAssert.IsNull(s1);\n\t}\n\n\t[Test]\n\tpublic void ToStringTest() {\n\t\tSegment\ts = new Segment(null, 3, 8);\n\t\tAssert.AreEqual(\"(3->8)\", s.ToString());\n\t}\n\n\n}\n\n} // end namespace"
  },
  {
    "path": "tests/buffers/SimpleBufferTests.cs",
    "content": "// created on 3/8/2005 at 5:07 PM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing NUnit.Framework;\nusing System;\n\nusing Bless.Buffers;\n\nnamespace BlessTests.Buffers {\n\n[TestFixture]\npublic class SimpleBufferTests {\n\n\t[Test]\n\tpublic void AppendTest() {\n\t\tSimpleBuffer sb = new SimpleBuffer();\n\t\tbyte[] ba = {1, 2, 3};\n\t\tsb.Append(ba, 0, ba.Length);\n\t\tAssert.AreEqual(1, sb[0]);\n\t\tAssert.AreEqual(2, sb[1]);\n\t\tAssert.AreEqual(3, sb[2]);\n\t\tAssert.AreEqual(0, sb[3]);\n\t}\n\n\n\t[Test]\n\tpublic void ReadTest() {\n\t\tSimpleBuffer sb = new SimpleBuffer();\n\t\tbyte[] ba = {1, 2, 3, 4, 5};\n\n\t\tsb.Append(ba, 0, ba.Length);\n\n\t\tbyte[] ba1 = new byte[3];\n\t\tsb.Read(ba1, 0, 1, 3);\n\t\tAssert.AreEqual(3, ba1.Length);\n\t\tAssert.AreEqual(2, ba1[0]);\n\t\tAssert.AreEqual(3, ba1[1]);\n\t\tAssert.AreEqual(4, ba1[2]);\n\t}\n\n}\n\n} // end namespace\n"
  },
  {
    "path": "tests/copy_test_data.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport shutil\n\nshutil.copyfile(sys.argv[1], sys.argv[2])\nshutil.copymode(sys.argv[1], sys.argv[2])\n"
  },
  {
    "path": "tests/meson.build",
    "content": "nunit_console = find_program('nunit-console', required: false)\nnunit_dep = dependency('nunit', required: false)\n\nif not nunit_dep.found()\n    error('nunit not found, cannot build tests. You can disable with -Dtests=false')\nendif\n\ntest_env = environment()\ntest_env.append('MONO_PATH', src_build_dir)\n\ntests_buffers_lib = library(\n    'BlessTests.Buffers',\n    files(\n        'buffers/ByteBufferTests.cs',\n        'buffers/FileBufferTests.cs',\n        'buffers/SegmentCollectionTests.cs',\n        'buffers/SegmentTests.cs',\n        'buffers/SimpleBufferTests.cs',\n    ),\n    dependencies: nunit_dep,\n    link_with: [\n        buffers_lib,\n        util_lib,\n    ],\n)\n\n# The tests expect the test data files to be in the directory the runner runs in.\n# nunit-console changes directory to the module under test before running,\n# so copy the data files to that same build directory.\nmeson.add_postconf_script(\n    'copy_test_data.py',\n    join_paths(meson.current_source_dir(), 'buffers', 'test1.bin'),\n    join_paths(meson.current_build_dir(), 'test1.bin'))\n\nif get_option('run_tests')\n    if not nunit_console.found()\n        warning('nunit-console not found, cannot run tests. You can disable with -Drun_tests=false')\n        subdir_done()\n    endif\n\n    test(\n        'Buffers',\n        nunit_console,\n        args: tests_buffers_lib,\n        env: test_env,\n    )\n\n    tests_tools_export_lib = library(\n        'BlessTests.Tools.Export',\n        files(\n            'tools/export/ExporterTests.cs',\n        ),\n        dependencies: nunit_dep,\n        link_with: [\n            buffers_lib,\n            tools_export_lib,\n            tools_export_plugins_lib,\n        ],\n    )\n\n    test(\n        'Tools.Export',\n        nunit_console,\n        args: tests_tools_export_lib,\n        env: test_env,\n    )\n\n    tests_util_lib = library(\n        'BlessTests.Util',\n        files(\n            'util/ByteArrayTests.cs',\n            'util/DequeTests.cs',\n            'util/IntervalTreeTests.cs',\n            'util/ListTests.cs',\n            'util/RangeTests.cs',\n            'util/RedBlackTreeTests.cs',\n        ),\n        dependencies: nunit_dep,\n        link_with: [\n            util_lib,\n        ],\n    )\n\n    test(\n        'Util',\n        nunit_console,\n        args: tests_util_lib,\n        env: test_env,\n    )\nendif\n"
  },
  {
    "path": "tests/tools/export/ExporterTests.cs",
    "content": "/*\n *   Copyright (c) 2006, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing NUnit.Framework;\nusing System;\nusing System.IO;\nusing System.Text;\n\nusing Bless.Tools.Export;\nusing Bless.Tools.Export.Plugins;\nusing Bless.Buffers;\n\nnamespace BlessTests.Export {\n\n[TestFixture]\npublic class ExporterTests {\n\n\t[Test]\n\tpublic void AppendTest() {\n\t\tstring correct = \"0000:   __|  __|0x02|0x03 -       \\n\" +\n\t\t\t\t\t\t\"0004: 0x04|0x05|0x06|0x07 - 04*05*\\n\" +\n\t\t\t\t\t\t\"0008: 0x08|0x09|0x0A|0x0B - 08*09*\\n\" +\n\t\t\t\t\t\t\"000C: 0x0C|0x0D|0x0E|0x10 - 0C*0D*\\n\" +\n\t\t\t\t\t\t\"0010: 0x10|0x11|0x12|0x13 - 10*11*\\n\" +\n\t\t\t\t\t\t\"0014: 0x14|  __|  __|  __ - 14*   \\n\";\n\n\t\tMemoryStream ms = new MemoryStream();\n\t\tTextExportBuilder teb = new TextExportBuilder(ms);\n\n\t\tInterpretedPatternExporter ipe = new InterpretedPatternExporter(teb);\n\n\t\tIBuffer buffer = new SimpleBuffer();\n\t\tbuffer.Append(new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 16, 17, 18, 19, 20}, 0, 21);\n\n\t\tipe.Pattern = \"%A\\\"4\\\"%[%O\\\"4\\\"%: %E\\\"4\\\"e\\\"_\\\"p\\\"0x\\\"x\\\"|\\\"%] - %E\\\"2\\\"s\\\"*\\\"%%I\\\"2\\\"%\\n\";\n\t\tbool cancelled = false;\n\t\tipe.Export(buffer, 2, buffer.Size - 1, ref cancelled);\n\n\t\tAssert.AreEqual(correct, ASCIIEncoding.ASCII.GetString(ms.ToArray()), \"#1\"); \n\t}\n\n}\n\n} // end namespace\n"
  },
  {
    "path": "tests/util/BaseConverterTests.cs",
    "content": "// created on 3/8/2005 at 5:19 PM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing NUnit.Framework;\nusing System;\n\nusing Bless.Util;\n\nnamespace BlessTests.Util {\n\n[TestFixture]\npublic class BaseConverterTests\n{\n\t[Test]\n\tpublic void BaseConverterTest1()\n\t{\n\t\tstring s2 = BaseConverter.ConvertToString(15464, 2);\n\t\tstring s8 = BaseConverter.ConvertToString(15464, 8);\n\t\tstring s10 = BaseConverter.ConvertToString(15464, 10);\n\t\tstring s16 = BaseConverter.ConvertToString(15464, 16);\n\n\t\tAssert.AreEqual(\"11110001101000\", s2, \"#base2\");\n\t\tAssert.AreEqual(\"36150\", s8, \"#base8\");\n\t\tAssert.AreEqual(\"15464\", s10, \"#base10\");\n\t\tAssert.AreEqual(\"3C68\", s16, \"#base16\");\n\n\t}\n\n\t[Test]\n\tpublic void BaseConverterTest2()\n\t{\n\t\tlong l2 = BaseConverter.ConvertToNum(\"11110001101000\", 2);\n\t\tlong l8 = BaseConverter.ConvertToNum(\"36150\", 8);\n\t\tlong l10 = BaseConverter.ConvertToNum(\"15464\", 10);\n\t\tlong l16 = BaseConverter.ConvertToNum(\"3C68\", 16);\n\n\t\tAssert.AreEqual(15464, l2, \"#base2\");\n\t\tAssert.AreEqual(15464, l8, \"#base8\");\n\t\tAssert.AreEqual(15464, l10, \"#base10\");\n\t\tAssert.AreEqual(15464, l16, \"#base16\");\n\t}\n\n\t[Test]\n\t[ExpectedException(typeof(FormatException))]\n\tpublic void BaseConverterTest3()\n\t{\n\t\tBaseConverter.ConvertToNum(\"18032\", 8);\n\t}\n\n\t[Test]\n\t[ExpectedException(typeof(FormatException))]\n\tpublic void BaseConverterTest4()\n\t{\n\t\tBaseConverter.ConvertToNum(\"a04zd\", 16);\n\t}\n\n\t[Test]\n\tpublic void BaseConverterTest5()\n\t{\n\t\tlong l16 = BaseConverter.Parse(\"  0x66  \");\n\t\tlong l10 = BaseConverter.Parse(\"  66  \");\n\t\tlong l8 = BaseConverter.Parse(\"  066  \");\n\n\t\tAssert.AreEqual(0x66, l16, \"#base16\");\n\t\tAssert.AreEqual(66, l10, \"#base10\");\n\t\tAssert.AreEqual(54, l8, \"#base8\");\n\t}\n}\n\n} // end namespace\n"
  },
  {
    "path": "tests/util/ByteArrayTests.cs",
    "content": "// created on 3/8/2005 at 5:19 PM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing NUnit.Framework;\nusing System;\n\nusing Bless.Util;\n\nnamespace BlessTests.Util {\n\n[TestFixture]\npublic class ByteArrayTests\n{\n\t[Test]\n\tpublic void ByteArrayHexTest1()\n\t{\n\t\tbyte[] ba = ByteArray.FromString(\"0305ffFa66\", 16);\n\n\t\tAssert.AreEqual(5, ba.Length, \"#Length\");\n\t\tAssert.AreEqual(0x03, ba[0], \"#0\");\n\t\tAssert.AreEqual(0x05, ba[1], \"#1\");\n\t\tAssert.AreEqual(0xff, ba[2], \"#2\");\n\t\tAssert.AreEqual(0xfa, ba[3], \"#3\");\n\t\tAssert.AreEqual(0x66, ba[4], \"#4\");\n\n\t}\n\n\t[Test]\n\tpublic void ByteArrayHexTest2()\n\t{\n\t\tbyte[] ba = ByteArray.FromString(\" 63a5 fe DD Cb  \", 16);\n\n\t\tAssert.AreEqual(5, ba.Length, \"#Length\");\n\t\tAssert.AreEqual(0x63, ba[0], \"#0\");\n\t\tAssert.AreEqual(0xa5, ba[1], \"#1\");\n\t\tAssert.AreEqual(0xfe, ba[2], \"#2\");\n\t\tAssert.AreEqual(0xdd, ba[3], \"#3\");\n\t\tAssert.AreEqual(0xcb, ba[4], \"#4\");\n\n\t}\n\n\t[Test]\n\tpublic void ByteArrayHexTest3()\n\t{\n\t\tbyte[] ba = ByteArray.FromString(\" 63a fe DDCb  \", 16);\n\n\t\tAssert.AreEqual(5, ba.Length, \"#Length\");\n\t\tAssert.AreEqual(0x63, ba[0], \"#0\");\n\t\tAssert.AreEqual(0x0a, ba[1], \"#1\");\n\t\tAssert.AreEqual(0xfe, ba[2], \"#2\");\n\t\tAssert.AreEqual(0xdd, ba[3], \"#3\");\n\t\tAssert.AreEqual(0xcb, ba[4], \"#4\");\n\t}\n\n\t[Test]\n\t[ExpectedException(typeof(FormatException))]\n\tpublic void ByteArrayHexTest4()\n\t{\n\t\tByteArray.FromString(\" 63 a5 fg DD Cb  \", 16);\n\t}\n\n\t[Test]\n\tpublic void ByteArrayHexTest5()\n\t{\n\t\tstring s = ByteArray.ToString(new byte[]{0x63, 0xff, 0x12, 0x00, 0xca}, 16);\n\n\t\tAssert.AreEqual(14, s.Length, \"#Length\");\n\t\tAssert.AreEqual(s, \"63 FF 12 00 CA\", \"#0\");\n\t}\n\n\t[Test]\n\tpublic void ByteArrayStringWithShortNumbers()\n\t{\n\t\tbyte[] ba = ByteArray.FromString(\"0 0 2 0 0 0 209 1\", 10);\n\n\t\tAssert.AreEqual(new byte[]{0, 0, 2, 0, 0, 0, 209, 1}, ba, \"#Contents\");\n\t}\n\n}\n\n} // end namespace\n"
  },
  {
    "path": "tests/util/DequeTests.cs",
    "content": "// created on 7/4/2005 at 12:38 PM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing NUnit.Framework;\nusing System;\n\nusing Bless.Util;\n\nnamespace BlessTests.Util {\n\n[TestFixture]\npublic class DequeTests {\n\n\n\t[Test]\n\tpublic void CountTest()\n\t{\n\t\tDeque<int> d = new Deque<int>();\n\t\td.AddFront(4);\n\t\td.AddFront(5);\n\t\td.AddFront(6);\n\t\td.AddFront(7);\n\n\t\tAssert.AreEqual(4, d.Count);\n\t}\n\n\t[Test]\n\tpublic void RemoveEndTest()\n\t{\n\t\tDeque<int> d = new Deque<int>();\n\t\td.AddFront(4);\n\t\td.AddFront(5);\n\t\td.AddFront(6);\n\t\td.AddFront(7);\n\n\t\tAssert.AreEqual(4, (int)d.RemoveEnd());\n\t\tAssert.AreEqual(5, (int)d.RemoveEnd());\n\t\tAssert.AreEqual(6, (int)d.RemoveEnd());\n\t\tAssert.AreEqual(7, (int)d.RemoveEnd());\n\t}\n\n\t[Test]\n\tpublic void RemoveFrontTest()\n\t{\n\t\tDeque<int> d = new Deque<int>();\n\t\td.AddFront(4);\n\t\td.AddFront(5);\n\t\td.AddFront(6);\n\t\td.AddFront(7);\n\n\t\tAssert.AreEqual(7, (int)d.RemoveFront());\n\t\tAssert.AreEqual(6, (int)d.RemoveFront());\n\t\tAssert.AreEqual(5, (int)d.RemoveFront());\n\t\tAssert.AreEqual(4, (int)d.RemoveFront());\n\t}\n\n\n\n\n\t[Test]\n\tpublic void MixedTest()\n\t{\n\t\tDeque<int> d = new Deque<int>();\n\t\td.AddFront(5);\n\t\td.AddEnd(6);\n\t\td.AddFront(4);\n\t\td.AddEnd(7);\n\n\t\tAssert.AreEqual(7, (int)d.RemoveEnd());\n\t\tAssert.AreEqual(4, (int)d.RemoveFront());\n\t\tAssert.AreEqual(6, (int)d.RemoveEnd());\n\t\tAssert.AreEqual(5, (int)d.RemoveFront());\n\t}\n\n\t[Test]\n\tpublic void PeekTest()\n\t{\n\t\tDeque<int> d = new Deque<int>();\n\n\t\td.AddEnd(4);\n\t\td.AddEnd(5);\n\t\td.AddEnd(6);\n\t\td.AddEnd(7);\n\n\t\tAssert.AreEqual(7, (int)d.PeekEnd());\n\t\tAssert.AreEqual(7, (int)d.PeekEnd());\n\t\tAssert.AreEqual(4, (int)d.PeekFront());\n\t\tAssert.AreEqual(4, (int)d.PeekFront());\n\t\td.RemoveEnd();\n\t\tAssert.AreEqual(6, (int)d.PeekEnd());\n\t\td.RemoveFront();\n\t\tAssert.AreEqual(5, (int)d.PeekFront());\n\t}\n\n\t[Test]\n\tpublic void ClearTest()\n\t{\n\t\tDeque<int> d = new Deque<int>();\n\n\t\td.AddEnd(4);\n\t\td.AddEnd(5);\n\t\td.AddEnd(6);\n\t\td.AddEnd(7);\n\n\t\tAssert.AreEqual(7, (int)d.PeekEnd());\n\t\tAssert.AreEqual(4, (int)d.PeekFront());\n\n\t\td.Clear();\n\t\tAssert.AreEqual(0, d.Count);\n\t}\n\n\t[Test]\n\tpublic void NullTest()\n\t{\n\t\tDeque<object> d = new Deque<object>();\n\n\t\tAssert.IsNull(d.RemoveFront(), \"#1\");\n\t\t\n\t\tobject o = new object();\n\t\td.AddEnd(o);\n\t\tAssert.AreEqual(o, d.RemoveEnd(), \"#2\");\n\t\tAssert.IsNull(d.RemoveEnd(), \"#3\");\n\n\t\td.AddFront(o);\n\t\tAssert.AreEqual(o, d.RemoveFront(), \"#4\");\n\t\tAssert.IsNull(d.RemoveFront(), \"#5\");\n\n\t}\n\n}\n\n} // end namespace\n"
  },
  {
    "path": "tests/util/IntervalTreeTests.cs",
    "content": "/*\n *   Copyright (c) 2008, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing System;\nusing System.Collections.Generic;\nusing NUnit.Framework;\n\nusing Bless.Util;\nusing Range = Bless.Util.Range;\n\nnamespace BlessTests.Util\n{\n\t[TestFixture()]\n\tpublic class IntervalTreeTests\n\t{\n\t\t\n\t\t[Test()]\n\t\tpublic void ITInsertTest()\n\t\t{\n\t\t\tIntervalTree<Range> t = new IntervalTree<Range>();\n\t\t\t\n\t\t\tt.Insert(new Range(5,55));\n\t\t\t\n\t\t\tIList<Range> result = t.SearchOverlap(new Range(0, 4));\n\t\t\t\n\t\t\tAssert.AreEqual(0, result.Count, \"#1\");\n\t\t\t\n\t\t\tresult = t.SearchOverlap(new Range(4, 13));\n\t\t\tAssert.AreEqual(1, result.Count, \"#2\");\n\t\t\tAssert.AreEqual(55, result[0].End, \"#2.1\");\n\t\t\t\n\t\t\tresult = t.SearchOverlap(new Range(57, 68));\n\t\t\tAssert.AreEqual(0, result.Count, \"#3\");\n\t\t\t\n\t\t\tresult = t.SearchOverlap(new Range(3,100));\n\t\t\t\n\t\t\tAssert.AreEqual(1, result.Count, \"#4\");\n\t\t\tAssert.AreEqual(55, result[0].End, \"#2.1\");\n\t\t}\n\t\t\n\t\t[Test()]\n\t\tpublic void ITSearchTest()\n\t\t{\n\t\t\tIntervalTree<Range> t = new IntervalTree<Range>();\n\t\t\t\n\t\t\tfor (int i = 0; i < 1000; i += 4) {\n\t\t\t\tt.Insert(new Range(i, i + 2));\n\t\t\t}\n\t\t\t\n\t\t\tfor (int i = 0 ; i < 1000; i += 8) {\n\t\t\t\tIList<Range> result = t.SearchOverlap(new Range(i, i + 7));\n\t\t\t\tAssert.AreEqual(2, result.Count, \"#1.\"+i.ToString());\n\t\t\t}\n\t\t\t\n\t\t\tfor (int i = 2 ; i < 1000; i += 4) {\n\t\t\t\tIList<Range> result = t.SearchOverlap(new Range(i+1, i + 1));\n\t\t\t\tAssert.AreEqual(0, result.Count, \"#2.\"+i.ToString());\n\t\t\t}\n\t\t\t\n\t\t\t{\n\t\t\t\tIList<Range> result = t.SearchOverlap(new Range(0, 1050));\n\t\t\t\tAssert.AreEqual(250, result.Count, \"#3\");\n\t\t\t}\n\t\t}\n\t\t\n\t\t[Test()]\n\t\tpublic void ITDuplicateTest()\n\t\t{\n\t\t\tIntervalTree<Range> t = new IntervalTree<Range>();\n\t\t\t\n\t\t\tfor (int i = 0; i < 1000; i += 1) {\n\t\t\t\tt.Insert(new Range(0, i));\n\t\t\t}\n\t\t\t\n\t\t\tfor (int i = 0 ; i <= 1000; i++) {\n\t\t\t\tIList<Range> result = t.SearchOverlap(new Range(i, i));\n\t\t\t\tAssert.AreEqual(1000 - i, result.Count, \"#1.\"+i.ToString());\n\t\t\t}\n\t\t\t\n\t\t}\n\t\t\n\t\t[Test()]\n\t\tpublic void ITDeleteTest()\n\t\t{\n\t\t\tIntervalTree<Range> t = new IntervalTree<Range>();\n\t\t\t\n\t\t\tfor (int i = 0; i < 1000; i += 4) {\n\t\t\t\tt.Insert(new Range(i, i + 2));\n\t\t\t}\n\t\t\t\n\t\t\tfor (int i = 0 ; i < 1000; i += 8) {\n\t\t\t\tIList<Range> result = t.SearchOverlap(new Range(i, i + 7));\n\t\t\t\tAssert.AreEqual(2, result.Count, \"#1.\"+i.ToString());\n\t\t\t\t\n\t\t\t\tt.Delete(new Range(i, i+2));\n\t\t\t\t\n\t\t\t\tresult = t.SearchOverlap(new Range(i, i + 7));\n\t\t\t\tAssert.AreEqual(1, result.Count, \"#2.\"+i.ToString());\n\t\t\t\t\n\t\t\t\tt.Delete(new Range(i+2, i+4));\n\t\t\t\t\n\t\t\t\tresult = t.SearchOverlap(new Range(i, i + 7));\n\t\t\t\tAssert.AreEqual(1, result.Count, \"#3.\"+i.ToString());\n\t\t\t\t\n\t\t\t\tt.Delete(new Range(i+4, i+6));\n\t\t\t\t\n\t\t\t\tresult = t.SearchOverlap(new Range(i, i + 7));\n\t\t\t\tAssert.AreEqual(0, result.Count, \"#4.\"+i.ToString());\n\t\t\t\t\n\t\t\t\tt.Delete(new Range(i+6, i+8));\n\t\t\t\t\n\t\t\t\tresult = t.SearchOverlap(new Range(i, i + 7));\n\t\t\t\tAssert.AreEqual(0, result.Count, \"#5.\"+i.ToString());\n\t\t\t}\n\t\t\t\n\t\t}\n\t\t\n\t\t[Test()]\n\t\tpublic void ITDeleteDuplicateTest()\n\t\t{\n\t\t\tIntervalTree<Range> t = new IntervalTree<Range>();\n\t\t\t\n\t\t\tfor (int i = 0; i < 1000; i += 4) {\n\t\t\t\tt.Insert(new Range(i, i + 3));\n\t\t\t\tt.Insert(new Range(i, i + 3));\n\t\t\t\tt.Insert(new Range(i, i + 3));\n\t\t\t}\n\t\t\t\n\t\t\tfor (int i = 0; i < 1000; i += 8) {\n\t\t\t\tIList<Range> result = t.SearchOverlap(new Range(i, i + 7));\n\t\t\t\tAssert.AreEqual(6, result.Count, \"#5.\"+i.ToString());\n\t\t\t\n\t\t\t\tt.Delete(new Range(i, i+3));\n\t\t\t\tresult = t.SearchOverlap(new Range(i, i + 7));\n\t\t\t\tAssert.AreEqual(5, result.Count, \"#5.\"+i.ToString());\n\t\t\t\t\n\t\t\t\tt.Delete(new Range(i, i+3));\n\t\t\t\tresult = t.SearchOverlap(new Range(i, i + 7));\n\t\t\t\tAssert.AreEqual(4, result.Count, \"#5.\"+i.ToString());\n\t\t\t\t\n\t\t\t\tt.Delete(new Range(i, i+3));\n\t\t\t\tresult = t.SearchOverlap(new Range(i, i + 7));\n\t\t\t\tAssert.AreEqual(3, result.Count, \"#5.\"+i.ToString());\n\t\t\t\t\n\t\t\t\tt.Delete(new Range(i, i+3));\n\t\t\t\tresult = t.SearchOverlap(new Range(i, i + 7));\n\t\t\t\tAssert.AreEqual(3, result.Count, \"#5.\"+i.ToString());\n\t\t\t\t\n\t\t\t\tt.Delete(new Range(i+4, i+7));\n\t\t\t\tresult = t.SearchOverlap(new Range(i, i + 7));\n\t\t\t\tAssert.AreEqual(2, result.Count, \"#5.\"+i.ToString());\n\t\t\t\t\n\t\t\t\tt.Delete(new Range(i+4, i+7));\n\t\t\t\tresult = t.SearchOverlap(new Range(i, i + 7));\n\t\t\t\tAssert.AreEqual(1, result.Count, \"#5.\"+i.ToString());\n\t\t\t\t\n\t\t\t\tt.Delete(new Range(i+4, i+7));\n\t\t\t\tresult = t.SearchOverlap(new Range(i, i + 7));\n\t\t\t\tAssert.AreEqual(0, result.Count, \"#5.\"+i.ToString());\n\t\t\t}\n\t\t}\n\t\t\t\n\t}\n}\n"
  },
  {
    "path": "tests/util/ListTests.cs",
    "content": "// created on 3/8/2005 at 5:19 PM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing NUnit.Framework;\nusing System;\n\nusing Bless.Util;\n\nnamespace BlessTests.Util {\n\n[TestFixture]\npublic class ListTests {\n\n\t[Test]\n\tpublic void AppendTest() {\n\t\tList<int> list = new List<int>();\n\t\tlist.Append(4);\n\t\tlist.Append(7);\n\t\tList<int>.Node n = list.First;\n\t\tAssert.AreEqual(4, n.data);\n\t\tAssert.AreEqual(7, n.next.data);\n\t}\n\n\n\t[Test]\n\tpublic void CountTest() {\n\t\tList<int> list = new List<int>();\n\t\tlist.Append(1);\n\t\tlist.Append(2);\n\t\tlist.Append(3);\n\n\t\tAssert.AreEqual(3, list.Count);\n\t}\n\n\n\t[Test]\n\tpublic void InsertBeforeTest() {\n\t\tList<int> list = new List<int>();\n\t\tlist.InsertBefore(list.First, 3);\n\t\tlist.InsertBefore(list.First, 1);\n\t\tlist.InsertBefore(list.Last, 2);\n\n\n\t\tList<int>.Node n = list.First;\n\t\tAssert.AreEqual(1, n.data);\n\t\tAssert.AreEqual(2, n.next.data);\n\t\tAssert.AreEqual(3, n.next.next.data);\n\t}\n\n\t[Test]\n\tpublic void InsertAfterTest() {\n\t\tList<int> list = new List<int>();\n\t\tlist.InsertAfter(list.First, 1);\n\t\tlist.InsertAfter(list.Last, 3);\n\t\tlist.InsertAfter(list.First, 2);\n\n\n\t\tList<int>.Node n = list.First;\n\t\tAssert.AreEqual(1, n.data);\n\t\tAssert.AreEqual(2, n.next.data);\n\t\tAssert.AreEqual(3, n.next.next.data);\n\t}\n\n\n\t[Test]\n\tpublic void IndexerTest() {\n\t\tList<int> list = new List<int>();\n\t\tlist.Append(1);\n\t\tlist.Append(2);\n\t\tlist.Append(3);\n\n\t\tAssert.AreEqual(1, list[0]);\n\t\tAssert.AreEqual(2, list[1]);\n\t\tAssert.AreEqual(3, list[2]);\n\t\t//if (list[3]!=null)\n\t\t//Assert.Fail(\"Expected: null!\");\n\t}\n\n\t[Test]\n\tpublic void RemoveTest() {\n\t\tList<int> list = new List<int>();\n\t\tList<int>.Node n1 = list.Append(1);\n\t\tlist.Append(2);\n\t\tList<int>.Node n3 = list.Append(3);\n\t\tList<int>.Node n4 = list.Append(4);\n\n\t\tlist.Remove(n1);\n\t\tAssert.AreEqual(3, list.Count, \"#1\");\n\t\tAssert.AreEqual(2, list[0], \"#2\");\n\t\tAssert.AreEqual(3, list[1], \"#3\");\n\t\tAssert.AreEqual(4, list[2], \"#4\");\n\n\t\tlist.Remove(n3);\n\t\tAssert.AreEqual(2, list.Count, \"#5\");\n\t\tAssert.AreEqual(2, list[0], \"#6\");\n\t\tAssert.AreEqual(4, list[1], \"#7\");\n\n\t\tlist.Remove(n4);\n\t\tAssert.AreEqual(1, list.Count, \"#8\");\n\t\tAssert.AreEqual(2, list[0], \"#9\");\n\n\t\t//if (list[3]!=null)\n\t\t//Assert.Fail(\"Expected: null!\");\n\t}\n\n\t[Test]\n\tpublic void RemoveLastTest() {\n\t\tList<int> list = new List<int>();\n\t\tlist.Append(1);\n\t\tList<int>.Node n2 = list.Append(2);\n\n\t\tlist.Remove(n2);\n\t\tlist.Append(3);\n\n\t\tAssert.AreEqual(2, list.Count, \"#1\");\n\t\tAssert.AreEqual(1, list[0], \"#2\");\n\t\tAssert.AreEqual(3, list[1], \"#3\");\n\n\t}\n\n\n}\n\n} // end namespace\n"
  },
  {
    "path": "tests/util/RangeTests.cs",
    "content": "// created on 3/8/2005 at 5:20 PM\n/*\n *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\nusing NUnit.Framework;\nusing System;\n\nusing Bless.Util;\nusing Range = Bless.Util.Range;\n\nnamespace BlessTests.Util {\n\n[TestFixture]\npublic class RangeTests\n{\n\n\t[Test]\n\tpublic void IntersectTest()\n\t{\n\t\tRange r1 = new Range(5, 10);\n\t\tRange r2 = new Range(6, 9);\n\n\t\tr1.Intersect(r2);\n\t\tAssert.AreEqual(6, r1.Start);\n\t\tAssert.AreEqual(9, r1.End);\n\n\t\tRange r3 = new Range(5, 10);\n\t\tRange r4 = new Range(4, 8);\n\n\t\tr3.Intersect(r4);\n\t\tAssert.AreEqual(5, r3.Start);\n\t\tAssert.AreEqual(8, r4.End);\n\n\t\tRange r5 = new Range(5, 10);\n\t\tRange r6 = new Range(10, 14);\n\n\t\tr5.Intersect(r6);\n\t\tAssert.AreEqual(10, r5.Start);\n\t\tAssert.AreEqual(10, r5.End);\n\n\t}\n\n\t[Test]\n\tpublic void DifferenceTest()\n\t{\n\t\tRange r1 = new Range(5, 10);\n\t\tRange r2 = new Range(6, 9);\n\t\tRange r3 = new Range();\n\n\t\tr1.Difference(r2, r3);\n\t\tAssert.AreEqual(5, r1.Start, \"#1\");\n\t\tAssert.AreEqual(5, r1.End, \"#2\");\n\n\t\tAssert.AreEqual(10, r3.Start, \"#3\");\n\t\tAssert.AreEqual(10, r3.End, \"#4\");\n\n\t\tRange r4 = new Range(5, 10);\n\t\tRange r5 = new Range(5, 8);\n\n\t\tr4.Difference(r5, r3);\n\t\tAssert.AreEqual(9, r4.Start, \"#5\");\n\t\tAssert.AreEqual(10, r4.End, \"#6\");\n\t\tAssert.AreEqual(true, r3.IsEmpty(), \"#7\");\n\n\t}\n\t\n\t[Test]\n\tpublic void SplitAtomicTest()\n\t{\n\t\tRange r = new Range(0, 10);\n\t\tRange s = new Range(4, 6);\n\t\tRange[] ra = new Range[]{new Range(), new Range(), new Range()};\n\t\t\n\t\tAssert.IsTrue(r.Equals(new Range(0, 10)), \"#0\");\n\t\t\n\t\tRange.SplitAtomic(ra, r, s);\n\t\tAssert.AreEqual(new Range(0, 3), ra[0], \"#1.0\");\n\t\tAssert.AreEqual(new Range(4, 6), ra[1], \"#1.1\");\n\t\tAssert.AreEqual(new Range(7, 10), ra[2], \"#1.2\");\n\t\t\n\t\ts = new Range(0, 4);\n\t\tRange.SplitAtomic(ra, r, s);\n\t\tAssert.AreEqual(new Range(), ra[0], \"#2.0\");\n\t\tAssert.AreEqual(new Range(0, 4), ra[1], \"#2.1\");\n\t\tAssert.AreEqual(new Range(5, 10), ra[2], \"#2.2\");\n\t\t\n\t\ts = new Range(6, 10);\n\t\tRange.SplitAtomic(ra, r, s);\n\t\tAssert.AreEqual(new Range(0, 5), ra[0], \"#3.0\");\n\t\tAssert.AreEqual(new Range(6, 10), ra[1], \"#3.1\");\n\t\tAssert.AreEqual(new Range(), ra[2], \"#3.2\");\n\t\t\n\t\ts = new Range(0, 10);\n\t\tRange.SplitAtomic(ra, r, s);\n\t\tAssert.AreEqual(new Range(), ra[0], \"#4.0\");\n\t\tAssert.AreEqual(new Range(0, 10), ra[1], \"#4.1\");\n\t\tAssert.AreEqual(new Range(), ra[2], \"#4.2\");\n\t}\n\t\n\t[Test]\n\tpublic void SplitAtomic1Test()\n\t{\n\t\tRange r = new Range(10, 20);\n\t\tRange s = new Range(8, 13);\n\t\t\n\t\tRange[] ra = new Range[]{new Range(), new Range(), new Range()};\n\t\t\n\t\tRange.SplitAtomic(ra, r, s);\n\t\tAssert.AreEqual(new Range(), ra[0], \"#1.0\");\n\t\tAssert.AreEqual(new Range(8, 13), ra[1], \"#1.1\");\n\t\tAssert.AreEqual(new Range(14, 20), ra[2], \"#1.2\");\n\t\t\n\t\ts = new Range(16, 26);\n\t\tRange.SplitAtomic(ra, r, s);\n\t\tAssert.AreEqual(new Range(10, 15), ra[0], \"#2.0\");\n\t\tAssert.AreEqual(new Range(16, 26), ra[1], \"#2.1\");\n\t\tAssert.AreEqual(new Range(), ra[2], \"#2.2\");\n\t}\n\t\n}\n\n} // end namespace\n"
  },
  {
    "path": "tests/util/RedBlackTreeTests.cs",
    "content": "// Created 12:17 PM 16/3/2008\n/*\n *   Copyright (c) 2008, Alexandros Frantzis (alf82 [at] freemail [dot] gr)\n *\n *   This file is part of Bless.\n *\n *   Bless is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License as published by\n *   the Free Software Foundation; either version 2 of the License, or\n *   (at your option) any later version.\n *\n *   Bless is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *   GNU General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with Bless; if not, write to the Free Software\n *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\nusing System;\nusing NUnit.Framework;\nusing Bless.Util;\nusing System.Collections.Generic;\n\nnamespace BlessTests.Util\n{\n\t\n\t\n[TestFixture()]\npublic class RedBlackTreeTests\n{\n\t\n\t[Test()]\n\tpublic void RBInsertTest()\n\t{\n\t\tRedBlackTree<int, string> rb = new RedBlackTree<int, string>();\n\t\t\n\t\trb.Insert(5, \"5\");\n\t\tIList<string> result = rb.Search(5);\n\t\tAssert.AreEqual(\"5\", result[0], \"#1\");\n\t\t\n\t\tresult = rb.Search(8);\n\t\tAssert.AreEqual(0, result.Count, \"#1\");\n\t\t\n\t\trb.Insert(100, \"100\");\n\t\tresult = rb.Search(100);\n\t\tAssert.AreEqual(\"100\", result[0], \"#3\");\n\t\t\n\t\tresult = rb.Search(5);\n\t\tAssert.AreEqual(\"5\", result[0], \"#4\");\n\t}\n\t\n\t[Test()]\n\tpublic void RBSearchTest()\n\t{\n\t\tRedBlackTree<int, string> rb = new RedBlackTree<int, string>();\n\t\t\n\t\tfor (int i = 0; i < 10000; i += 2) {\n\t\t\trb.Insert(i, i.ToString());\n\t\t}\n\t\t\n\t\tfor (int i = 0; i < 10000; i++) {\n\t\t\tIList<string> result = rb.Search(i);\n\t\t\tif ( i % 2 == 0)\n\t\t\t\tAssert.AreEqual(i.ToString(), result[0], i.ToString());\n\t\t\telse\n\t\t\t\tAssert.AreEqual(0, result.Count, i.ToString());\n\t\t}\n\t\t\n\n\t}\n\t\n\t[Test()]\n\tpublic void RBDuplicateTest()\n\t{\n\t\tRedBlackTree<int, string> rb = new RedBlackTree<int, string>();\n\t\t\n\t\tfor (int i = 0; i < 1000; i++) {\n\t\t\trb.Insert(0, i.ToString());\n\t\t}\n\t\t\n\t\tIList<string> result = rb.Search(0);\n\t\t\n\t\tAssert.AreEqual(1000, result.Count, \"#1\");\n\t\t\n\t}\n\t\n\t[Test()]\n\tpublic void RBDeleteTest()\n\t{\n\t\tRedBlackTree<int, string> rb = new RedBlackTree<int, string>();\n\t\t\n\t\trb.Insert(0, \"0\");\n\t\tIList<string> result = rb.Search(0);\n\t\tAssert.AreEqual(1, result.Count, \"#1\");\n\t\tAssert.AreEqual(\"0\", result[0], \"#1.1\");\n\t\t\n\t\trb.Delete(0);\n\t\t\n\t\tresult = rb.Search(0);\n\t\tAssert.AreEqual(0, result.Count, \"#2\");\n\t\t\n\t\trb.Delete(0);\n\t}\n\t\n\t[Test()]\n\tpublic void RBDelete1Test()\n\t{\n\t\tRedBlackTree<int, string> rb = new RedBlackTree<int, string>();\n\t\t\n\t\tfor (int i = 0; i < 10; i++) {\n\t\t\trb.Insert(i, i.ToString());\n\t\t}\n\t\t\n\t\tfor (int i = 0; i < 10; i++) {\n\t\t\tIList<string> result = rb.Search(i);\n\t\t\tAssert.AreEqual(1, result.Count, \"#1.1:\" + i.ToString());\n\t\t\tAssert.AreEqual(i.ToString(), result[0], \"#1.2:\" + i.ToString());\n\t\t}\n\t\t\n\t\t\n\t\tfor (int i = 0; i < 10; i+=2) {\n\t\t\trb.Delete(i);\n\t\t}\n\t\t\n\t\tfor (int i = 0; i < 10; i++) {\n\t\t\tIList<string> result = rb.Search(i);\n\t\t\tif (i % 2 == 0)\n\t\t\t\tAssert.AreEqual(0, result.Count, \"#2.1:\" + i.ToString());\n\t\t\telse {\n\t\t\t\tAssert.AreEqual(1, result.Count, \"#2.2:\" + i.ToString());\n\t\t\t\tAssert.AreEqual(i.ToString(), result[0], \"#2.3:\" + i.ToString());\n\t\t\t}\n\t\t}\n\t\t\n\t}\n\t\n\tprivate void RBAssertPresent(RedBlackTree<int, string> rb, int s, int e)\n\t{\n\t\tfor (int i = s; i <= e; i++) {\n\t\t\tIList<string> result = rb.Search(i);\n\t\t\tAssert.AreEqual(1, result.Count, string.Format(\"#{0}->{1}@{2}\", s, e, i));\n\t\t\tAssert.AreEqual(i.ToString(), result[0], string.Format(\"#{0}->{1}@{2}\", s, e, i));\n\t\t}\n\t}\n\t\n\tprivate void RBAssertNotPresent(RedBlackTree<int, string> rb, int s, int e)\n\t{\n\t\tfor (int i = s; i <= e; i++) {\n\t\t\tIList<string> result = rb.Search(i);\n\t\t\tAssert.AreEqual(0, result.Count, string.Format(\"#!{0}->{1}@{2}\", s, e, i));\n\t\t}\n\t}\n\t\n\t[Test()]\n\tpublic void RBDelete2Test()\n\t{\n\t\tRedBlackTree<int, string> rb = new RedBlackTree<int,string>();\n\t\t\n\t\tfor (int i = 19; i >= 0; i--) {\n\t\t\trb.Insert(i, i.ToString());\n\t\t}\n\t\t\t\t\n\t\tfor (int i = 0; i < 10; i++) {\n\t\t\trb.Delete(9 - i);\n\t\t\t\n\t\t\tRBAssertPresent(rb, 0, 9 - i - 1);\n\t\t\tRBAssertPresent(rb, 10 + i, 19);\n\t\t\tRBAssertNotPresent(rb, 9 - i, 10 + i - 1);\n\t\t\t\n\t\t\trb.Delete(10 + i);\n\t\t\t\n\t\t\tRBAssertPresent(rb, 0, 9 - i - 1);\n\t\t\tRBAssertPresent(rb, 10 + i + 1, 19);\n\t\t\tRBAssertNotPresent(rb, 9 - i, 10 + i );\n\t\t}\n\t}\n\t\n\t[Test()]\n\tpublic void RBDelete3Test()\n\t{\n\t\tRedBlackTree<int, string> rb = new RedBlackTree<int,string>();\n\t\t\n\t\tfor (int i = 99; i >= 0; i--) {\n\t\t\trb.Insert(i, i.ToString());\n\t\t}\n\t\t\n\t\tfor (int i = 0; i < 50; i++) {\n\t\t\trb.Delete(49 - i);\n\t\t\t\n\t\t\tRBAssertPresent(rb, 0, 49 - i - 1);\n\t\t\tRBAssertPresent(rb, 50 + i, 99);\n\t\t\tRBAssertNotPresent(rb, 49 - i, 50 + i - 1);\n\t\t\t\n\t\t\trb.Delete(50 + i);\n\t\t\t\n\t\t\tRBAssertPresent(rb, 0, 49 - i - 1);\n\t\t\tRBAssertPresent(rb, 50 + i + 1, 99);\n\t\t\tRBAssertNotPresent(rb, 49 - i, 50 + i );\n\t\t}\n\t}\n\t\n\t[Test()]\n\tpublic void RBDeleteNotPresentTest()\n\t{\n\t\tRedBlackTree<int, string> rb = new RedBlackTree<int,string>();\n\t\t\n\t\tfor (int i = 0; i < 5; i++) {\n\t\t\trb.Insert(i, i.ToString());\n\t\t}\n\t\t\n\t\tfor (int i = 0; i < 5; i++) {\n\t\t\trb.Delete(i);\n\t\t\trb.Delete(i);\n\t\t}\n\t\t\n\t}\n\t\n\t[Test()]\n\tpublic void RBDeleteRandomTest()\n\t{\n\t\tRedBlackTree<int, string> rb = new RedBlackTree<int,string>();\n\t\t\n\t\tfor (int i = 99; i >= 0; i--) {\n\t\t\trb.Insert(i, i.ToString());\n\t\t}\n\t\tRandom r = new Random();\n\t\t\n\t\tfor (int i = 0; i < 1000; i++) {\n\t\t\tint j = r.Next(0, 99);\n\t\t\trb.Delete(j);\n\t\t}\n\t}\n}\n\n} // end namespace\n\n"
  }
]