<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://mediawiki.gnustep.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Quineska</id>
	<title>GNUstepWiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://mediawiki.gnustep.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Quineska"/>
	<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php/Special:Contributions/Quineska"/>
	<updated>2026-04-23T04:00:50Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.35.7</generator>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Talk:Installation_on_Windows&amp;diff=4421</id>
		<title>Talk:Installation on Windows</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Talk:Installation_on_Windows&amp;diff=4421"/>
		<updated>2007-02-28T02:05:31Z</updated>

		<summary type="html">&lt;p&gt;Quineska: /* Installation quirks */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Are the *-bin.zip files needed? Are not the *-lib files sufficient?&lt;br /&gt;
&lt;br /&gt;
[[User:Stefan Urbanek|Stefan Urbanek]] 16:06, 10 Mar 2005 (CET)&lt;br /&gt;
&lt;br /&gt;
=== Installation quirks ===&lt;br /&gt;
&lt;br /&gt;
I had to do:&lt;br /&gt;
&lt;br /&gt;
configure CPPFLAGS=-I/C/GNUstep/msys/1.0/include LDFLAGS=-I/C/GNUstep/msys/1.0/lib&lt;br /&gt;
&lt;br /&gt;
to get the gui build going.&lt;br /&gt;
&lt;br /&gt;
Also, ffcall wouldn't compile, so it was necessary to copy one from an older GNUstep installation on windows.  I will make a zip of this and put in on the GNUstep ftp site so that others don't run into the same issue.&lt;br /&gt;
&lt;br /&gt;
Later, GJC&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
I don't think that the libiconv stuff is necessary anymore, at least not with modern source distributions of libxml2. Also, there should be a warning NOT to install libxslt, as it gets compiled as a static library and its symbols clobber *everything* inside a DLL (hence messing up gnustep-base). It needs to be fixed for mingw (I'm sure the authors would have if they ever used the configure script in MSYS).&lt;br /&gt;
&lt;br /&gt;
== TODO ==&lt;br /&gt;
&lt;br /&gt;
* outdated, pull in http://www.gnustep.org/resources/documentation/User/GNUstep/README.MinGW&lt;br /&gt;
OR&lt;br /&gt;
* delete or convince everyone of putting these kind of things on the wiki and not in some external file.&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Installation_on_Windows&amp;diff=4396</id>
		<title>Installation on Windows</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Installation_on_Windows&amp;diff=4396"/>
		<updated>2007-02-08T05:39:22Z</updated>

		<summary type="html">&lt;p&gt;Quineska: /* Download gnustep using SVN */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Install Windows GNUstep Manually =&lt;br /&gt;
&lt;br /&gt;
== Install MinGW ==&lt;br /&gt;
Download MinGW-3.2.0-rc-3 or later from http://sourceforge.net/projects/mingw Install it into&lt;br /&gt;
&lt;br /&gt;
 C:/xxx/msys/1.0/mingw&lt;br /&gt;
&lt;br /&gt;
(where /xxx/ is the top-level path you want to use, I use Nicola/GNUstep so I install it into C:/Nicola/GNUstep/msys/1.0/mingw) (earlier versions of MinGW won't work)&lt;br /&gt;
&lt;br /&gt;
== Install msys ==&lt;br /&gt;
&lt;br /&gt;
Download MSYS-1.0.10 or later from the same site.  Install it into C:/xxx/msys/1.0&lt;br /&gt;
The postinstall script should ask you for the mingw location, then detect it and be happy that it's there and all is setup properly.&lt;br /&gt;
&lt;br /&gt;
== Install msys developer toolkit ==&lt;br /&gt;
&lt;br /&gt;
Download msysDTK-1.0.1 or later from the same site.  Install it into&lt;br /&gt;
&lt;br /&gt;
 C:/xxx/msys/1.0&lt;br /&gt;
&lt;br /&gt;
Now your MSYS/MinGW system should be setup!  Go around and make sure you know how to use the Unix-like shell.  Log into it and work in it.&lt;br /&gt;
&lt;br /&gt;
== Download gnustep using SVN ==&lt;br /&gt;
&lt;br /&gt;
In windows, go to &lt;br /&gt;
 Start -&amp;gt; All Programs -&amp;gt; mingw -&amp;gt; MSYS -&amp;gt;Msys&lt;br /&gt;
The MINGW32 window appears.&lt;br /&gt;
&lt;br /&gt;
Type the following:&lt;br /&gt;
 mkdir install&lt;br /&gt;
 cd install&lt;br /&gt;
 svn co svn://svn.gna.org/svn/gnustep/modules/core&lt;br /&gt;
&lt;br /&gt;
This will download the core GNUstep libraries (make, base, gui and back). You will need to have a copy of SVN installed somewhere on your system.&lt;br /&gt;
&lt;br /&gt;
Alternatively, you could download the GNUstep Startup package the main site http://www.gnustep.org. It contains a copy of the core libraries as well (and can be used to automate the installation of an SVN copy as well).&lt;br /&gt;
&lt;br /&gt;
== Install GNUstep make ==&lt;br /&gt;
&lt;br /&gt;
 cd gnustep/core/make&lt;br /&gt;
 ./configure --prefix=/C/xxx/GNUstep&lt;br /&gt;
 make&lt;br /&gt;
 make install&lt;br /&gt;
&lt;br /&gt;
== Setup your GNUstep environment ==&lt;br /&gt;
&lt;br /&gt;
(you will need to do the same every time you start up your MSYS shell to do development)&lt;br /&gt;
&lt;br /&gt;
 . /C/xxx/GNUstep/System/Library/Makefiles/GNUstep.sh&lt;br /&gt;
&lt;br /&gt;
Also, set HOMEPATH, HOMEDRIVE and HOME ... add the following lines to your ~/.profile:&lt;br /&gt;
&lt;br /&gt;
 export HOMEDRIVE=C:&lt;br /&gt;
 export HOMEPATH=/home/Nicola&lt;br /&gt;
 export HOME=/C/xxx/msys/1.0/home/Nicola&lt;br /&gt;
 . /C/xxx/GNUstep/System/Library/Makefiles/GNUstep.sh&lt;br /&gt;
&lt;br /&gt;
(obviously replacing 'Nicola' with your Login name) (not sure if this setting of HOMEDRIVE etc is really required, will investigate)&lt;br /&gt;
&lt;br /&gt;
== Install the ObjC runtime  ==&lt;br /&gt;
&lt;br /&gt;
Actually, recent versions of gcc (3.2+) have a working libobjc on Windows. Nevertheless this step is necessary (at least on Windows 2000) unless you want some strange errors concerning NSAutoreleasePool etc.&lt;br /&gt;
&lt;br /&gt;
First make sure to delete the old libobjc files&lt;br /&gt;
&lt;br /&gt;
 find /C/xxx/GNUstep/ -iname &amp;quot;libobjc*&amp;quot; -exec rm -i {} \;&lt;br /&gt;
&lt;br /&gt;
Then cd to dev-libs/libobjc in your cvs checkout directory and install it. &lt;br /&gt;
 cd ~/install/gnustep/dev-libs/libobjc &lt;br /&gt;
 make&lt;br /&gt;
 make install&lt;br /&gt;
&lt;br /&gt;
== Reinstall GNUstep make (with ObjC this time) ==&lt;br /&gt;
&lt;br /&gt;
go in core/make and reconfigure/recompile again so that gnustep-objc is detected:&lt;br /&gt;
 cd ~/install/gnustep/core/make&lt;br /&gt;
 make distclean&lt;br /&gt;
 ./configure&lt;br /&gt;
 make &lt;br /&gt;
 make install&lt;br /&gt;
&lt;br /&gt;
gnustep-make should have detected your custom libobjc.&lt;br /&gt;
&lt;br /&gt;
== Install ffcall ==&lt;br /&gt;
&lt;br /&gt;
Download ffcall from the GNUstep website into c:/xxx/msys/1.0/home/Nicola/install&lt;br /&gt;
or from here: ftp://ftp.santafe.edu/pub/gnu/ffcall-1.10.tar.gz,&lt;br /&gt;
and type:&lt;br /&gt;
&lt;br /&gt;
 cd ~/install&lt;br /&gt;
 tar -zxvf ffcall-1.10.tar.gz&lt;br /&gt;
 cd ffcall-1.10&lt;br /&gt;
 ./configure --prefix=$GNUSTEP_SYSTEM_ROOT&lt;br /&gt;
    A windows prompt will appear stating that conftest.exe has encountered a problem and needs to close.&lt;br /&gt;
&lt;br /&gt;
Click the [Don't Send] button.&lt;br /&gt;
&lt;br /&gt;
    A second windows prompt will appear stating that conftest.exe has encountered a problem and needs to close.&lt;br /&gt;
&lt;br /&gt;
Click the [Don't Send] button.&lt;br /&gt;
&lt;br /&gt;
    A third windows prompt will appear stating that conftest.exe has encountered a problem and needs to close.&lt;br /&gt;
&lt;br /&gt;
Click the [Don't Send] button.&lt;br /&gt;
    &lt;br /&gt;
    After much output,  the following will be displayed:&lt;br /&gt;
    &lt;br /&gt;
    configure: creating ./config.status&lt;br /&gt;
    config.status: creating Makefile&lt;br /&gt;
    config.status: creating config.h&lt;br /&gt;
&lt;br /&gt;
Type the following:&lt;br /&gt;
&lt;br /&gt;
 make&lt;br /&gt;
 make install&lt;br /&gt;
&lt;br /&gt;
Note: The configure script of ffcall-1.10 is broken for Windows 2000. You have to apply a patch: http://lists.gnu.org/archive/html/discuss-gnustep/2005-03/msg00258.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Alternatively, a zip containing a precompiled copy of ffcall-1.9 is availabe here: ftp://ftp.gnustep.org/pub/gnustep/binaries/windows/mingw-libs/ffcall-1.9-gnustep.zip&lt;br /&gt;
&lt;br /&gt;
Unzip it into $GNUSTEP_SYSTEM_ROOT/Library.&lt;br /&gt;
&lt;br /&gt;
== Install additional libs ==&lt;br /&gt;
&lt;br /&gt;
Download the following packages:&lt;br /&gt;
&lt;br /&gt;
[http://sourceforge.net/project/showfiles.php?group_id=23617&amp;amp;package_id=73290 Download libintl]&lt;br /&gt;
&lt;br /&gt;
 libintl-0.11.5-2-bin.zip&lt;br /&gt;
 libintl-0.11.5-2-lib.zip&lt;br /&gt;
&lt;br /&gt;
[http://sourceforge.net/project/showfiles.php?group_id=23617&amp;amp;package_id=17090 Download libiconv]&lt;br /&gt;
&lt;br /&gt;
 libiconv-1.8.1-bin.zip &lt;br /&gt;
 libiconv-1.8.1-lib.zip &lt;br /&gt;
&lt;br /&gt;
[http://sourceforge.net/project/showfiles.php?group_id=23617&amp;amp;package_id=16861 Download zlib]&lt;br /&gt;
&lt;br /&gt;
 zlib-1.2.2-bin.zip&lt;br /&gt;
 zlib-1.2.2-lib.zip&lt;br /&gt;
&lt;br /&gt;
from http://gnuwin32.sourceforge.net, and install them.  To install them, simply unzip them into&lt;br /&gt;
&lt;br /&gt;
 /C/xxx/msys/1.0/mingw.&lt;br /&gt;
&lt;br /&gt;
== Install XML support ==&lt;br /&gt;
&lt;br /&gt;
You will have to make some changes to libiconv for libxml to work properly.&lt;br /&gt;
&lt;br /&gt;
 cd /mingw/lib&lt;br /&gt;
 mkdir backup-libiconv&lt;br /&gt;
 mv libiconv.la backup-libiconv&lt;br /&gt;
 mv libiconv.lib backup-libiconv&lt;br /&gt;
 dlltool -D libiconv-2.dll -C -l libiconvlib --export-all-symbols -A ../bin/libiconv-2.dll&lt;br /&gt;
&lt;br /&gt;
If there are no errors:&lt;br /&gt;
&lt;br /&gt;
 rm -r backup-libiconv&lt;br /&gt;
&lt;br /&gt;
I had to compile libiconv from source for this to work (the binaries didn't work with my computer for some reason, and I'm not sure if it normally works.)&lt;br /&gt;
&lt;br /&gt;
Download the latest version of libxml from [[ftp://xmlsoft.org/libxml2/]].&lt;br /&gt;
&lt;br /&gt;
 cd libxml2-...&lt;br /&gt;
 vim include/libxml/xmlexports.h&lt;br /&gt;
&lt;br /&gt;
There is a chunk of code in this file you will have to change.&lt;br /&gt;
&lt;br /&gt;
Search for:&lt;br /&gt;
&lt;br /&gt;
 Windows platform with GNU compiler&lt;br /&gt;
&lt;br /&gt;
in the code. Replace the code below it up to the comment about Cygwin:&lt;br /&gt;
&lt;br /&gt;
 #if defined(_WIN32) &amp;amp;&amp;amp; defined(__MINGW32__)&lt;br /&gt;
   #undef XMLPUBFUN&lt;br /&gt;
   #undef XMLPUBVAR&lt;br /&gt;
   #undef XMLCALL&lt;br /&gt;
   #if !defined(LIBXML_STATIC)&lt;br /&gt;
     #define XMLPUBFUN __declspec(dllexport)&lt;br /&gt;
     #define XMLPUBVAR __declspec(dllexport) extern&lt;br /&gt;
   #else&lt;br /&gt;
     #define XMLPUBFUN&lt;br /&gt;
     #if !defined(LIBXML_STATIC)&lt;br /&gt;
       #define XMLPUBVAR __declspec(dllimport) extern&lt;br /&gt;
     #else&lt;br /&gt;
       #define XMLPUBVAR extern&lt;br /&gt;
     #endif&lt;br /&gt;
   #endif&lt;br /&gt;
   #define XMLCALL __cdecl&lt;br /&gt;
   #if !defined _REENTRANT&lt;br /&gt;
     #define _REENTRANT&lt;br /&gt;
   #endif&lt;br /&gt;
 #endif&lt;br /&gt;
&lt;br /&gt;
Save the file, then quit. Then compile normally.&lt;br /&gt;
&lt;br /&gt;
 ./configure&lt;br /&gt;
 make&lt;br /&gt;
 make install&lt;br /&gt;
&lt;br /&gt;
I never installed to the end with this method (halfway through I just decided to use the installer) but it worked well for me.&lt;br /&gt;
&lt;br /&gt;
== Install GNUstep base ==&lt;br /&gt;
&lt;br /&gt;
go in gnustep-base, and type &lt;br /&gt;
&lt;br /&gt;
 cd ~/install/gnustep/core/base&lt;br /&gt;
 ./configure&lt;br /&gt;
 make&lt;br /&gt;
 make install&lt;br /&gt;
&lt;br /&gt;
If you didn't install libxml,&lt;br /&gt;
&lt;br /&gt;
 ./configure --disable-xml&lt;br /&gt;
 make&lt;br /&gt;
 make install&lt;br /&gt;
&lt;br /&gt;
== Install additional GUI libs ==&lt;br /&gt;
&lt;br /&gt;
for the gui, download and install the following packages:&lt;br /&gt;
&lt;br /&gt;
[http://sourceforge.net/project/showfiles.php?group_id=23617&amp;amp;package_id=16348&amp;amp;release_id=218220 Download jpeg]&lt;br /&gt;
&lt;br /&gt;
  jpeg-6b-3-bin.zip&lt;br /&gt;
  jpeg-6b-3-dep.zip&lt;br /&gt;
  jpeg-6b-3-lib.zip&lt;br /&gt;
&lt;br /&gt;
[http://sourceforge.net/project/showfiles.php?group_id=23617&amp;amp;package_id=16351 Download tiff]&lt;br /&gt;
&lt;br /&gt;
  tiff-3.7.1-bin.zip&lt;br /&gt;
  tiff-3.7.1-dep.zip&lt;br /&gt;
  tiff-3.7.1-lib.zip&lt;br /&gt;
&lt;br /&gt;
[http://sourceforge.net/project/showfiles.php?group_id=23617&amp;amp;package_id=16183 Download libpng]&lt;br /&gt;
&lt;br /&gt;
  libpng-1.2.8-bin.zip&lt;br /&gt;
  libpng-1.2.8-dep.zip&lt;br /&gt;
  libpng-1.2.8-lib.zip&lt;br /&gt;
&lt;br /&gt;
The process is always the same: download the zip file from the gnuwin32 website, then unzip them into&lt;br /&gt;
&lt;br /&gt;
 /C/xxx/msys/1.0/mingw.&lt;br /&gt;
&lt;br /&gt;
== Install GNUstep gui ==&lt;br /&gt;
&lt;br /&gt;
Type the following:&lt;br /&gt;
  cd ~/install/gnustep/core/gui&lt;br /&gt;
  ./configure&lt;br /&gt;
  make&lt;br /&gt;
  make install&lt;br /&gt;
&lt;br /&gt;
== Install GNUstep back ==&lt;br /&gt;
&lt;br /&gt;
go in back, and type:&lt;br /&gt;
&lt;br /&gt;
  ./configure&lt;br /&gt;
  make&lt;br /&gt;
  make install&lt;br /&gt;
&lt;br /&gt;
== Check the installation ==&lt;br /&gt;
&lt;br /&gt;
go in a simple gui application (examples/gui a very good starting point), compile and run it. :-)&lt;br /&gt;
&lt;br /&gt;
''based on a mail from Nicola Pero''&lt;br /&gt;
&lt;br /&gt;
= GNUstep .exe installer using Nullsoft's [http://nsis.sourceforge.net/Main_Page NSIS] =&lt;br /&gt;
&lt;br /&gt;
== install instruction ==&lt;br /&gt;
There are three versions of exe installer for gnustep.&lt;br /&gt;
&lt;br /&gt;
* Download [ftp://ftp.gnustep.org/pub/gnustep/binaries/windows gnustep NSIS installer ].&lt;br /&gt;
** select copy the binaries.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Download and compile gnustep examples tar ball.&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;openapp GSTest.app&amp;quot; will bring up a screen with GNUstep interface.&lt;br /&gt;
&lt;br /&gt;
= GNUstep MSI installer created  by [http://wix.sourceforge.net/ WiX]  =&lt;br /&gt;
&lt;br /&gt;
There are three sub packages &lt;br /&gt;
* user : To minimize the footprint of gnustep system on Windows machines.&lt;br /&gt;
* developer : include WiX,gcc and package sources.&lt;br /&gt;
* gnustep applications : include a broad suite of GNUstep applications.&lt;br /&gt;
== Install GNUstep MSI installer ==&lt;br /&gt;
* Download the msi from here.&lt;br /&gt;
* answer following questions.&lt;br /&gt;
* Test the installation.&lt;br /&gt;
== Prepare your gnustep win32 development environment ==&lt;br /&gt;
=== List of depended software ===&lt;br /&gt;
* WiX Win32 MSI package creation tool.&lt;br /&gt;
** candle.exe &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
C:\tmp&amp;gt;candle&lt;br /&gt;
Microsoft (R) Windows Installer Xml Compiler version 2.0.4221.0&lt;br /&gt;
Copyright (C) Microsoft Corporation 2003. All rights reserved.&lt;br /&gt;
&lt;br /&gt;
 usage:  candle.exe [-?] [-nologo] [-out outputFile] sourceFile [sourceFile ...]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   -d&amp;lt;name&amp;gt;=&amp;lt;value&amp;gt;  define a parameter for the preprocessor&lt;br /&gt;
   -p&amp;lt;file&amp;gt;  preprocess to a file (or stdout if no file supplied)&lt;br /&gt;
   -I&amp;lt;dir&amp;gt;  add to include search path&lt;br /&gt;
   -nologo  skip printing candle logo information&lt;br /&gt;
   -out     specify output file (default: write to current directory)&lt;br /&gt;
   -pedantic:&amp;lt;level&amp;gt;  pedantic checks (levels: easy, heroic, legendary)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;snip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For more information see: http://wix.sourceforge.net&lt;br /&gt;
&lt;br /&gt;
C:\tmp&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
** light.exe&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
C:\tmp&amp;gt;light&lt;br /&gt;
Microsoft (R) Windows Installer Xml Linker version 2.0.4221.0&lt;br /&gt;
Copyright (C) Microsoft Corporation 2003. All rights reserved.&lt;br /&gt;
&lt;br /&gt;
 usage:  light.exe [-?] [-b basePath] [-nologo] [-out outputFile] objectFile [o&lt;br /&gt;
jectFile ...]&lt;br /&gt;
&lt;br /&gt;
   -ai        allow identical rows, identical rows will be treated as a warning&lt;br /&gt;
   -au        (experimental) allow unresolved references, will not create a val&lt;br /&gt;
d output&lt;br /&gt;
   -b         base path to locate all files (default: current directory)&lt;br /&gt;
   -cc        path to cache built cabinets (will not be deleted after linking)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;snip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For more information see: http://wix.sourceforge.net&lt;br /&gt;
&lt;br /&gt;
C:\tmp&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* makefile for nmake.&lt;br /&gt;
* gcc win32 compiler from MingW.&lt;br /&gt;
&lt;br /&gt;
=== Checkout gnustep.wxs ===&lt;br /&gt;
=== overview of gnustep.wxs ===&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Installation_on_Windows&amp;diff=4395</id>
		<title>Installation on Windows</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Installation_on_Windows&amp;diff=4395"/>
		<updated>2007-02-08T05:08:37Z</updated>

		<summary type="html">&lt;p&gt;Quineska: Changed to downloading GNUstep with SVN&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Install Windows GNUstep Manually =&lt;br /&gt;
&lt;br /&gt;
== Install MinGW ==&lt;br /&gt;
Download MinGW-3.2.0-rc-3 or later from http://sourceforge.net/projects/mingw Install it into&lt;br /&gt;
&lt;br /&gt;
 C:/xxx/msys/1.0/mingw&lt;br /&gt;
&lt;br /&gt;
(where /xxx/ is the top-level path you want to use, I use Nicola/GNUstep so I install it into C:/Nicola/GNUstep/msys/1.0/mingw) (earlier versions of MinGW won't work)&lt;br /&gt;
&lt;br /&gt;
== Install msys ==&lt;br /&gt;
&lt;br /&gt;
Download MSYS-1.0.10 or later from the same site.  Install it into C:/xxx/msys/1.0&lt;br /&gt;
The postinstall script should ask you for the mingw location, then detect it and be happy that it's there and all is setup properly.&lt;br /&gt;
&lt;br /&gt;
== Install msys developer toolkit ==&lt;br /&gt;
&lt;br /&gt;
Download msysDTK-1.0.1 or later from the same site.  Install it into&lt;br /&gt;
&lt;br /&gt;
 C:/xxx/msys/1.0&lt;br /&gt;
&lt;br /&gt;
Now your MSYS/MinGW system should be setup!  Go around and make sure you know how to use the Unix-like shell.  Log into it and work in it.&lt;br /&gt;
&lt;br /&gt;
== Download gnustep using SVN ==&lt;br /&gt;
&lt;br /&gt;
In windows, go to &lt;br /&gt;
 Start -&amp;gt; All Programs -&amp;gt; mingw -&amp;gt; MSYS -&amp;gt;Msys&lt;br /&gt;
The MINGW32 window appears.&lt;br /&gt;
&lt;br /&gt;
Type the following:&lt;br /&gt;
 mkdir install&lt;br /&gt;
 cd install&lt;br /&gt;
 svn co svn://svn.gna.org/svn/gnustep/devmodules/core&lt;br /&gt;
&lt;br /&gt;
This will download the core GNUstep libraries (make, base, gui and back). You will need to have a copy of SVN installed somewhere on your system.&lt;br /&gt;
&lt;br /&gt;
Alternatively, you could download the GNUstep Startup package the main site http://www.gnustep.org. It contains a copy of the core libraries as well (and can be used to automate the installation of an SVN copy as well).&lt;br /&gt;
&lt;br /&gt;
== Install GNUstep make ==&lt;br /&gt;
&lt;br /&gt;
 cd gnustep/core/make&lt;br /&gt;
 ./configure --prefix=/C/xxx/GNUstep&lt;br /&gt;
 make&lt;br /&gt;
 make install&lt;br /&gt;
&lt;br /&gt;
== Setup your GNUstep environment ==&lt;br /&gt;
&lt;br /&gt;
(you will need to do the same every time you start up your MSYS shell to do development)&lt;br /&gt;
&lt;br /&gt;
 . /C/xxx/GNUstep/System/Library/Makefiles/GNUstep.sh&lt;br /&gt;
&lt;br /&gt;
Also, set HOMEPATH, HOMEDRIVE and HOME ... add the following lines to your ~/.profile:&lt;br /&gt;
&lt;br /&gt;
 export HOMEDRIVE=C:&lt;br /&gt;
 export HOMEPATH=/home/Nicola&lt;br /&gt;
 export HOME=/C/xxx/msys/1.0/home/Nicola&lt;br /&gt;
 . /C/xxx/GNUstep/System/Library/Makefiles/GNUstep.sh&lt;br /&gt;
&lt;br /&gt;
(obviously replacing 'Nicola' with your Login name) (not sure if this setting of HOMEDRIVE etc is really required, will investigate)&lt;br /&gt;
&lt;br /&gt;
== Install the ObjC runtime  ==&lt;br /&gt;
&lt;br /&gt;
Actually, recent versions of gcc (3.2+) have a working libobjc on Windows. Nevertheless this step is necessary (at least on Windows 2000) unless you want some strange errors concerning NSAutoreleasePool etc.&lt;br /&gt;
&lt;br /&gt;
First make sure to delete the old libobjc files&lt;br /&gt;
&lt;br /&gt;
 find /C/xxx/GNUstep/ -iname &amp;quot;libobjc*&amp;quot; -exec rm -i {} \;&lt;br /&gt;
&lt;br /&gt;
Then cd to dev-libs/libobjc in your cvs checkout directory and install it. &lt;br /&gt;
 cd ~/install/gnustep/dev-libs/libobjc &lt;br /&gt;
 make&lt;br /&gt;
 make install&lt;br /&gt;
&lt;br /&gt;
== Reinstall GNUstep make (with ObjC this time) ==&lt;br /&gt;
&lt;br /&gt;
go in core/make and reconfigure/recompile again so that gnustep-objc is detected:&lt;br /&gt;
 cd ~/install/gnustep/core/make&lt;br /&gt;
 make distclean&lt;br /&gt;
 ./configure&lt;br /&gt;
 make &lt;br /&gt;
 make install&lt;br /&gt;
&lt;br /&gt;
gnustep-make should have detected your custom libobjc.&lt;br /&gt;
&lt;br /&gt;
== Install ffcall ==&lt;br /&gt;
&lt;br /&gt;
Download ffcall from the GNUstep website into c:/xxx/msys/1.0/home/Nicola/install&lt;br /&gt;
or from here: ftp://ftp.santafe.edu/pub/gnu/ffcall-1.10.tar.gz,&lt;br /&gt;
and type:&lt;br /&gt;
&lt;br /&gt;
 cd ~/install&lt;br /&gt;
 tar -zxvf ffcall-1.10.tar.gz&lt;br /&gt;
 cd ffcall-1.10&lt;br /&gt;
 ./configure --prefix=$GNUSTEP_SYSTEM_ROOT&lt;br /&gt;
    A windows prompt will appear stating that conftest.exe has encountered a problem and needs to close.&lt;br /&gt;
&lt;br /&gt;
Click the [Don't Send] button.&lt;br /&gt;
&lt;br /&gt;
    A second windows prompt will appear stating that conftest.exe has encountered a problem and needs to close.&lt;br /&gt;
&lt;br /&gt;
Click the [Don't Send] button.&lt;br /&gt;
&lt;br /&gt;
    A third windows prompt will appear stating that conftest.exe has encountered a problem and needs to close.&lt;br /&gt;
&lt;br /&gt;
Click the [Don't Send] button.&lt;br /&gt;
    &lt;br /&gt;
    After much output,  the following will be displayed:&lt;br /&gt;
    &lt;br /&gt;
    configure: creating ./config.status&lt;br /&gt;
    config.status: creating Makefile&lt;br /&gt;
    config.status: creating config.h&lt;br /&gt;
&lt;br /&gt;
Type the following:&lt;br /&gt;
&lt;br /&gt;
 make&lt;br /&gt;
 make install&lt;br /&gt;
&lt;br /&gt;
Note: The configure script of ffcall-1.10 is broken for Windows 2000. You have to apply a patch: http://lists.gnu.org/archive/html/discuss-gnustep/2005-03/msg00258.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Alternatively, a zip containing a precompiled copy of ffcall-1.9 is availabe here: ftp://ftp.gnustep.org/pub/gnustep/binaries/windows/mingw-libs/ffcall-1.9-gnustep.zip&lt;br /&gt;
&lt;br /&gt;
Unzip it into $GNUSTEP_SYSTEM_ROOT/Library.&lt;br /&gt;
&lt;br /&gt;
== Install additional libs ==&lt;br /&gt;
&lt;br /&gt;
Download the following packages:&lt;br /&gt;
&lt;br /&gt;
[http://sourceforge.net/project/showfiles.php?group_id=23617&amp;amp;package_id=73290 Download libintl]&lt;br /&gt;
&lt;br /&gt;
 libintl-0.11.5-2-bin.zip&lt;br /&gt;
 libintl-0.11.5-2-lib.zip&lt;br /&gt;
&lt;br /&gt;
[http://sourceforge.net/project/showfiles.php?group_id=23617&amp;amp;package_id=17090 Download libiconv]&lt;br /&gt;
&lt;br /&gt;
 libiconv-1.8.1-bin.zip &lt;br /&gt;
 libiconv-1.8.1-lib.zip &lt;br /&gt;
&lt;br /&gt;
[http://sourceforge.net/project/showfiles.php?group_id=23617&amp;amp;package_id=16861 Download zlib]&lt;br /&gt;
&lt;br /&gt;
 zlib-1.2.2-bin.zip&lt;br /&gt;
 zlib-1.2.2-lib.zip&lt;br /&gt;
&lt;br /&gt;
from http://gnuwin32.sourceforge.net, and install them.  To install them, simply unzip them into&lt;br /&gt;
&lt;br /&gt;
 /C/xxx/msys/1.0/mingw.&lt;br /&gt;
&lt;br /&gt;
== Install XML support ==&lt;br /&gt;
&lt;br /&gt;
You will have to make some changes to libiconv for libxml to work properly.&lt;br /&gt;
&lt;br /&gt;
 cd /mingw/lib&lt;br /&gt;
 mkdir backup-libiconv&lt;br /&gt;
 mv libiconv.la backup-libiconv&lt;br /&gt;
 mv libiconv.lib backup-libiconv&lt;br /&gt;
 dlltool -D libiconv-2.dll -C -l libiconvlib --export-all-symbols -A ../bin/libiconv-2.dll&lt;br /&gt;
&lt;br /&gt;
If there are no errors:&lt;br /&gt;
&lt;br /&gt;
 rm -r backup-libiconv&lt;br /&gt;
&lt;br /&gt;
I had to compile libiconv from source for this to work (the binaries didn't work with my computer for some reason, and I'm not sure if it normally works.)&lt;br /&gt;
&lt;br /&gt;
Download the latest version of libxml from [[ftp://xmlsoft.org/libxml2/]].&lt;br /&gt;
&lt;br /&gt;
 cd libxml2-...&lt;br /&gt;
 vim include/libxml/xmlexports.h&lt;br /&gt;
&lt;br /&gt;
There is a chunk of code in this file you will have to change.&lt;br /&gt;
&lt;br /&gt;
Search for:&lt;br /&gt;
&lt;br /&gt;
 Windows platform with GNU compiler&lt;br /&gt;
&lt;br /&gt;
in the code. Replace the code below it up to the comment about Cygwin:&lt;br /&gt;
&lt;br /&gt;
 #if defined(_WIN32) &amp;amp;&amp;amp; defined(__MINGW32__)&lt;br /&gt;
   #undef XMLPUBFUN&lt;br /&gt;
   #undef XMLPUBVAR&lt;br /&gt;
   #undef XMLCALL&lt;br /&gt;
   #if !defined(LIBXML_STATIC)&lt;br /&gt;
     #define XMLPUBFUN __declspec(dllexport)&lt;br /&gt;
     #define XMLPUBVAR __declspec(dllexport) extern&lt;br /&gt;
   #else&lt;br /&gt;
     #define XMLPUBFUN&lt;br /&gt;
     #if !defined(LIBXML_STATIC)&lt;br /&gt;
       #define XMLPUBVAR __declspec(dllimport) extern&lt;br /&gt;
     #else&lt;br /&gt;
       #define XMLPUBVAR extern&lt;br /&gt;
     #endif&lt;br /&gt;
   #endif&lt;br /&gt;
   #define XMLCALL __cdecl&lt;br /&gt;
   #if !defined _REENTRANT&lt;br /&gt;
     #define _REENTRANT&lt;br /&gt;
   #endif&lt;br /&gt;
 #endif&lt;br /&gt;
&lt;br /&gt;
Save the file, then quit. Then compile normally.&lt;br /&gt;
&lt;br /&gt;
 ./configure&lt;br /&gt;
 make&lt;br /&gt;
 make install&lt;br /&gt;
&lt;br /&gt;
I never installed to the end with this method (halfway through I just decided to use the installer) but it worked well for me.&lt;br /&gt;
&lt;br /&gt;
== Install GNUstep base ==&lt;br /&gt;
&lt;br /&gt;
go in gnustep-base, and type &lt;br /&gt;
&lt;br /&gt;
 cd ~/install/gnustep/core/base&lt;br /&gt;
 ./configure&lt;br /&gt;
 make&lt;br /&gt;
 make install&lt;br /&gt;
&lt;br /&gt;
If you didn't install libxml,&lt;br /&gt;
&lt;br /&gt;
 ./configure --disable-xml&lt;br /&gt;
 make&lt;br /&gt;
 make install&lt;br /&gt;
&lt;br /&gt;
== Install additional GUI libs ==&lt;br /&gt;
&lt;br /&gt;
for the gui, download and install the following packages:&lt;br /&gt;
&lt;br /&gt;
[http://sourceforge.net/project/showfiles.php?group_id=23617&amp;amp;package_id=16348&amp;amp;release_id=218220 Download jpeg]&lt;br /&gt;
&lt;br /&gt;
  jpeg-6b-3-bin.zip&lt;br /&gt;
  jpeg-6b-3-dep.zip&lt;br /&gt;
  jpeg-6b-3-lib.zip&lt;br /&gt;
&lt;br /&gt;
[http://sourceforge.net/project/showfiles.php?group_id=23617&amp;amp;package_id=16351 Download tiff]&lt;br /&gt;
&lt;br /&gt;
  tiff-3.7.1-bin.zip&lt;br /&gt;
  tiff-3.7.1-dep.zip&lt;br /&gt;
  tiff-3.7.1-lib.zip&lt;br /&gt;
&lt;br /&gt;
[http://sourceforge.net/project/showfiles.php?group_id=23617&amp;amp;package_id=16183 Download libpng]&lt;br /&gt;
&lt;br /&gt;
  libpng-1.2.8-bin.zip&lt;br /&gt;
  libpng-1.2.8-dep.zip&lt;br /&gt;
  libpng-1.2.8-lib.zip&lt;br /&gt;
&lt;br /&gt;
The process is always the same: download the zip file from the gnuwin32 website, then unzip them into&lt;br /&gt;
&lt;br /&gt;
 /C/xxx/msys/1.0/mingw.&lt;br /&gt;
&lt;br /&gt;
== Install GNUstep gui ==&lt;br /&gt;
&lt;br /&gt;
Type the following:&lt;br /&gt;
  cd ~/install/gnustep/core/gui&lt;br /&gt;
  ./configure&lt;br /&gt;
  make&lt;br /&gt;
  make install&lt;br /&gt;
&lt;br /&gt;
== Install GNUstep back ==&lt;br /&gt;
&lt;br /&gt;
go in back, and type:&lt;br /&gt;
&lt;br /&gt;
  ./configure&lt;br /&gt;
  make&lt;br /&gt;
  make install&lt;br /&gt;
&lt;br /&gt;
== Check the installation ==&lt;br /&gt;
&lt;br /&gt;
go in a simple gui application (examples/gui a very good starting point), compile and run it. :-)&lt;br /&gt;
&lt;br /&gt;
''based on a mail from Nicola Pero''&lt;br /&gt;
&lt;br /&gt;
= GNUstep .exe installer using Nullsoft's [http://nsis.sourceforge.net/Main_Page NSIS] =&lt;br /&gt;
&lt;br /&gt;
== install instruction ==&lt;br /&gt;
There are three versions of exe installer for gnustep.&lt;br /&gt;
&lt;br /&gt;
* Download [ftp://ftp.gnustep.org/pub/gnustep/binaries/windows gnustep NSIS installer ].&lt;br /&gt;
** select copy the binaries.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Download and compile gnustep examples tar ball.&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;openapp GSTest.app&amp;quot; will bring up a screen with GNUstep interface.&lt;br /&gt;
&lt;br /&gt;
= GNUstep MSI installer created  by [http://wix.sourceforge.net/ WiX]  =&lt;br /&gt;
&lt;br /&gt;
There are three sub packages &lt;br /&gt;
* user : To minimize the footprint of gnustep system on Windows machines.&lt;br /&gt;
* developer : include WiX,gcc and package sources.&lt;br /&gt;
* gnustep applications : include a broad suite of GNUstep applications.&lt;br /&gt;
== Install GNUstep MSI installer ==&lt;br /&gt;
* Download the msi from here.&lt;br /&gt;
* answer following questions.&lt;br /&gt;
* Test the installation.&lt;br /&gt;
== Prepare your gnustep win32 development environment ==&lt;br /&gt;
=== List of depended software ===&lt;br /&gt;
* WiX Win32 MSI package creation tool.&lt;br /&gt;
** candle.exe &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
C:\tmp&amp;gt;candle&lt;br /&gt;
Microsoft (R) Windows Installer Xml Compiler version 2.0.4221.0&lt;br /&gt;
Copyright (C) Microsoft Corporation 2003. All rights reserved.&lt;br /&gt;
&lt;br /&gt;
 usage:  candle.exe [-?] [-nologo] [-out outputFile] sourceFile [sourceFile ...]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   -d&amp;lt;name&amp;gt;=&amp;lt;value&amp;gt;  define a parameter for the preprocessor&lt;br /&gt;
   -p&amp;lt;file&amp;gt;  preprocess to a file (or stdout if no file supplied)&lt;br /&gt;
   -I&amp;lt;dir&amp;gt;  add to include search path&lt;br /&gt;
   -nologo  skip printing candle logo information&lt;br /&gt;
   -out     specify output file (default: write to current directory)&lt;br /&gt;
   -pedantic:&amp;lt;level&amp;gt;  pedantic checks (levels: easy, heroic, legendary)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;snip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For more information see: http://wix.sourceforge.net&lt;br /&gt;
&lt;br /&gt;
C:\tmp&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
** light.exe&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
C:\tmp&amp;gt;light&lt;br /&gt;
Microsoft (R) Windows Installer Xml Linker version 2.0.4221.0&lt;br /&gt;
Copyright (C) Microsoft Corporation 2003. All rights reserved.&lt;br /&gt;
&lt;br /&gt;
 usage:  light.exe [-?] [-b basePath] [-nologo] [-out outputFile] objectFile [o&lt;br /&gt;
jectFile ...]&lt;br /&gt;
&lt;br /&gt;
   -ai        allow identical rows, identical rows will be treated as a warning&lt;br /&gt;
   -au        (experimental) allow unresolved references, will not create a val&lt;br /&gt;
d output&lt;br /&gt;
   -b         base path to locate all files (default: current directory)&lt;br /&gt;
   -cc        path to cache built cabinets (will not be deleted after linking)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;snip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For more information see: http://wix.sourceforge.net&lt;br /&gt;
&lt;br /&gt;
C:\tmp&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* makefile for nmake.&lt;br /&gt;
* gcc win32 compiler from MingW.&lt;br /&gt;
&lt;br /&gt;
=== Checkout gnustep.wxs ===&lt;br /&gt;
=== overview of gnustep.wxs ===&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Creating_document_based_applications&amp;diff=2892</id>
		<title>Creating document based applications</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Creating_document_based_applications&amp;diff=2892"/>
		<updated>2005-11-28T00:39:16Z</updated>

		<summary type="html">&lt;p&gt;Quineska: /* Application Interface File */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Note: First version; subject to further revisions and changes.&lt;br /&gt;
--[[User:Quineska|ChrisArmstrong]] 07:09, 7 Jul 2005 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
[[OpenStep]] can provide your application a document-based model. It helps to simplify the process of creating such applications. [[GNUstep]] implements this as well; this document aims to provide an overview of what is required in the creation and design of such an application.&lt;br /&gt;
&lt;br /&gt;
It is assumed you are familiar with GNUstep, and have some understanding as how to create [[Gorm]]'s interface files (often referred to as nib's), as well as some understanding of how they work.&lt;br /&gt;
&lt;br /&gt;
Importantly, such applications have certain components that are required, and should be considered as part of their design. When programming, classes that will be used as part of the [[AppKit]] are:&lt;br /&gt;
&lt;br /&gt;
==== NSDocument ====&lt;br /&gt;
&lt;br /&gt;
This class is central to the OpenStep document based model. These application's declare a new instance of a subclass of NSDocument for each “document” that is opened. You will subclass NSDocument to implement this.&lt;br /&gt;
&lt;br /&gt;
Each instance of your NSDocument subclass may have one or more windows associated with it. These are used as an interface for loading and saving a representation of your document type. Each window will have an “NSWindowController” instance associated with it, where NSDocument maintains a list of these.&lt;br /&gt;
&lt;br /&gt;
==== NSDocumentController ====&lt;br /&gt;
&lt;br /&gt;
This class acts a controller. It maintains a list of documents (instances of your NSDocument subclass) and is responsible for loading and instantiating new documents. It is usually not necessary to implement a subclass of this, but often it may be useful to implement special functionality (especially related to opening and creating documents at an application level).&lt;br /&gt;
&lt;br /&gt;
==== NSWindowController ====&lt;br /&gt;
&lt;br /&gt;
As mentioned above, NSWindowController instances are individually associated with one NSWindow instance, in such a way that a document maintains a list of window controllers that are reponsible for rendering the views associated with a document.&lt;br /&gt;
&lt;br /&gt;
You will most likely not have to subclass NSWindowController. Instead, you associate a nib file (the Gorm output) with the subclass of NSDocument, and NSDocumentController will load this nib file for each document that is created or loaded.&lt;br /&gt;
&lt;br /&gt;
For example, a text based application that is used for the editing of plain text files, may subclass NSDocument with a TextDocument class. Each instance of this class would have an NSWindowController instance associated with it, which in turn manages a window instance that is instantiated from a nib file. The NSDocumentController instance, as managed and instantiated by GNUstep, would be responsible for loading and saving documents in your application. It even prompts the user to save their documents when they try to quit the application.&lt;br /&gt;
&lt;br /&gt;
== File Components ==&lt;br /&gt;
&lt;br /&gt;
In building your application you will need to create a number of special files. From scratch, the following should be a rough guide to getting it working. These include the Makefile, your application's property list and the interface files.&lt;br /&gt;
&lt;br /&gt;
=== The Makefile ===&lt;br /&gt;
&lt;br /&gt;
For this type of application, no special makefile is needed: it just has to be a normal application. Project Builder should be able to spit out the required makefile and Gorm files that are needed for a generic application. I believe it is also capable of providing support for document-based applications. Otherwise use the following as a template:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''GNUmakefile'''&lt;br /&gt;
&lt;br /&gt;
 include $(GNUSTEP_MAKEFILES)/common.make&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 APP_NAME = DocumentApp&amp;lt;br&amp;gt;&lt;br /&gt;
 DocumentApp_OBJC_FILES =&amp;lt;br&amp;gt;&lt;br /&gt;
  MyDocument.m &amp;lt;br&amp;gt;&lt;br /&gt;
  main.m&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 DocumentApp_RESOURCES = \ &amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/Info-gnustep.plist \&amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/DocumentApp.gorm \&amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/MyDocument.gorm&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 -include GNUmakefile.preamble&amp;lt;br&amp;gt;&lt;br /&gt;
 include $(GNUSTEP_MAKEFILES)/application.make&amp;lt;br&amp;gt;&lt;br /&gt;
 -include GNUmakefile.postamble&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For more information as to customising this file, as well as setting up compiler options for third party libraries and includes, see the GNUstep makefile manual.&lt;br /&gt;
&lt;br /&gt;
===The application dictionary===&lt;br /&gt;
&lt;br /&gt;
For those that have edited this file in their project before, it is a dictionary with various values entered. For our purposes, we need an array within the main dictionary, called &amp;quot;NSTypes&amp;quot;. This is a array of unnamed dictionaries, with one dictionary for each type. &lt;br /&gt;
&lt;br /&gt;
I have provided an example for this file below. ProjectBuilder creates one as well. Please note that &amp;quot;TextEdit&amp;quot; does exist as an example application from NEXT I think, and again on MacOS X but I have constructed a much simpler version, used only for plain text files.&lt;br /&gt;
&lt;br /&gt;
Taking a look at the single dictionary entry in the NSTypes array, the following key-value pairs are needed:&lt;br /&gt;
* '''NSDocumentClass:''' This is (string) the subclass name you use in your code, the &amp;quot;objective-c name&amp;quot; of your document subclass. This is used by NSDocumentController's default implementation to create instances of your document type.&lt;br /&gt;
* '''NSName:''' The generic file type (string). This is completely arbitrary, and can be anything you like. For the purpose of conventions, it may be more appropriate not to use the &amp;quot;NS&amp;quot; or &amp;quot;GS&amp;quot; prefix (the latter of which I not sure), and instead use either your own, or no prefix at all.&lt;br /&gt;
* '''NSHumanReadableName:''' The human readable name of your document type (string)? TODO: explain where this is used.&lt;br /&gt;
* '''NSUnixExtensions:''' An array of strings, each containing a file extension connected to this document type on &amp;quot;unix&amp;quot; platforms. TODO: explain how &amp;quot;unix&amp;quot; is interpreted by GNUstep.&lt;br /&gt;
* '''NSDOSExtensions:''' An array of strings, each containing a file extenstion connected to this document type on &amp;quot;DOS&amp;quot; platforms (could be loosely interpreted as any MS platforms GNUstep runs on, i.e. Windows 2000/XP).&lt;br /&gt;
* '''NSRole:''' A string, either &amp;quot;Viewer&amp;quot; or &amp;quot;Editor&amp;quot;, depending on how your document operates on this file type.&lt;br /&gt;
* '''NSIcon:''' A icon name associated with this document type. TODO: Investigate how this works.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Info-gnustep.plist'''&lt;br /&gt;
 {&lt;br /&gt;
     ApplicationDescription = &amp;quot;A simple text editor for GNUstep.&amp;quot;;&lt;br /&gt;
     ApplicationName = TextEdit;&lt;br /&gt;
     ApplicationRelease = 0.10;&lt;br /&gt;
     Authors = ( &amp;quot;Christopher Armstrong&amp;quot; );&lt;br /&gt;
     Copyright = &amp;quot;Copyright (C) 2005 Christopher Armstrong&amp;quot;;&lt;br /&gt;
     CopyrightDescription = &amp;quot;Released under GPL.&amp;quot;;&lt;br /&gt;
     FullVersionID = 0.10;&lt;br /&gt;
     NSExecutable = TextEdit;&lt;br /&gt;
     NSMainNibFile = TextEdit.gorm;&lt;br /&gt;
     NSPrincipalClass = NSApplication;&lt;br /&gt;
     NSRole = Application;&lt;br /&gt;
     NSTypes = (&lt;br /&gt;
         {&lt;br /&gt;
                 NSDocumentClass = &amp;quot;TextDocument&amp;quot;;&lt;br /&gt;
                 NSName = &amp;quot;GSTextDocumentType&amp;quot;;&lt;br /&gt;
                 NSHumanReadableName = &amp;quot;Text Document&amp;quot;;&lt;br /&gt;
                 NSUnixExtensions = ( &amp;quot;txt&amp;quot;, &amp;quot;&amp;quot; );&lt;br /&gt;
                 NSDOSExtensions = ( &amp;quot;txt&amp;quot; );&lt;br /&gt;
                 NSRole = Editor;&lt;br /&gt;
         }&lt;br /&gt;
     );&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For more information on property list files, consult [[Property Lists]].&lt;br /&gt;
&lt;br /&gt;
=== Interface files ===&lt;br /&gt;
&lt;br /&gt;
Two interface files are needed: one for your main application, and another that will be instantiated with each instance of your document subclass. These both should be listed as resources in your makefile, (as shown the GNUmakefile example above). It may be helpful to name the document nib file after your class.&lt;br /&gt;
&lt;br /&gt;
==== Application Interface File ====&lt;br /&gt;
&lt;br /&gt;
The application one should just be a menu (though it could be more if necessary). When constructing it, take the following into account:&lt;br /&gt;
&lt;br /&gt;
* '''Use an &amp;quot;Application&amp;quot; template''': Use a standard Gorm template for an Application.&lt;br /&gt;
* '''Delete the NSWindow instance''': In the &amp;quot;Objects&amp;quot; pane, remove the NSWindow instance by going File-&amp;gt;Delete (unless you need a main window, which is beyond the scope of this document).&lt;br /&gt;
* '''Set NSOwner's class to &amp;quot;NSDocumentController&amp;quot;''': This is the custom class option of NSOwner in the property inspector. This ensures that the openDocument:, newDocument: messages, as sent to NSFirst, get picked up by NSDocumentController. Do not instantiate it (I believe you can't anyway).&lt;br /&gt;
* '''[Optional] Subclass NSDocumentController''':If you intend to subclass NSDocumentController, subclass it in the Classes pane. To make sure that this class is instantiated and used, make sure you instantiate it in Gorm or in your main.m file, and then set NSOwner to be of your custom subclass type.&lt;br /&gt;
* '''Add a &amp;quot;Document&amp;quot; menu''': Drag a Document menu from the palette onto your main menu. This already has the proper outlet and action linkage for each relevant message to be directed to NSFirst. Generic messages (such as openDocument:, not associated with any document instance) are forwarded to the shared instance of NSDocumentController (see it's reference documentation). When a document is active, more specific messages (such as close: or saveDocument:) are forwarded to the relevant document instance of your NSDocument subclass.&lt;br /&gt;
* '''[Optional] Add other menus''': Add any appropriate menus such as &amp;quot;Info&amp;quot; and &amp;quot;Format&amp;quot; which may be relevant to your application.&lt;br /&gt;
&lt;br /&gt;
==== Document Interface File(s) ====&lt;br /&gt;
&lt;br /&gt;
The document interface file is a window containing the view(s) required for the implementation of one instance of your document type. For example, in the case of a TextDocument type, a window instance with a NSTextView drawn on it is used for each document window. This interface file is instantiated every time a person creates a new document (the newDocument: message is sent to NSDocumentController) or opens an existing document (openDocument:).&lt;br /&gt;
&lt;br /&gt;
You will need to:&lt;br /&gt;
* '''Subclass NSDocument''' with your document type in Gorm. This is done in a couple of ways, see [[Gorm_Manual#Custom_classes|custom classes]]. It is up to you whether or not you let Gorm generate the class files, but make sure you add the appropriate outlets to your class in the source files (otherwise, I think your your program may segfault).&lt;br /&gt;
* '''Set NSOwner:''' Set your subclass as NSOwner's Custom class using the Property Inspector. ''DO NOT INSTANTIATE IT.''&lt;br /&gt;
&lt;br /&gt;
Another thing that you may want to consider is custom outlets. If you place certain views or controls on your window (including the window itself), you may want to refer to them directly in your code, e.g. the NSTextView in our TextEdit example is accessed directly, so that we can save it's contents to a file. To enable this, we add outlets to our class (see [[Gorm_Manual#Custom_classes|custom classes]]). We then connect NSOwner to the appropriate controls/views, and select the outlets in the Connections Property Inspector (see [[Gorm_Manual#Editing_the_interface|editing the interface]]).&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
Various things need to be done at a code level, to ensure that your NSDocument subclass is properly instantiated. This section aims to tell you what is necessary.&lt;br /&gt;
&lt;br /&gt;
=== NSDocument subclass ===&lt;br /&gt;
&lt;br /&gt;
When creating your subclass, you may have chosen to have Gorm create the class files. If not, you should create two files for your subclass: a header (.h) file and an implementation file (.m). The header file should take the following layout (we're using the TextEdit example again):&lt;br /&gt;
&lt;br /&gt;
 #ifndef TEXTDOCUMENT_H&lt;br /&gt;
 #define TEXTDOCUMENT_H &amp;lt;br&amp;gt;&lt;br /&gt;
 #include &amp;lt;AppKit/AppKit.h&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
 @class NSDocument; &amp;lt;br&amp;gt;&lt;br /&gt;
 /* The document type string, as specified in the property list [[#The_application_dictionary|NSTypes array]] */ &amp;lt;br&amp;gt;&lt;br /&gt;
 NSString * GSTextDocumentType = &amp;quot;GSTextDocumentType&amp;quot;;&lt;br /&gt;
 @interface TextDocument : NSDocument&lt;br /&gt;
 {&lt;br /&gt;
 @protected&lt;br /&gt;
     /* Outlets we added in our Gorm nib file */&lt;br /&gt;
     id * textView;&lt;br /&gt;
 }&lt;br /&gt;
 /* Basic methods used for loading and saving document data (respectively). */&lt;br /&gt;
 - (BOOL) loadDataRepresentation:(NSData*)representation ofType:(NSString*)type;&lt;br /&gt;
 - (NSData*) dataRepresentationOfType: (NSString*)type; &amp;lt;br&amp;gt;&lt;br /&gt;
 /* Information and events handling of GUI related changes */&lt;br /&gt;
 - (NSString*) windowNibName;&lt;br /&gt;
 - (void) windowControllerDidLoadNib:(NSWindowController*)windowController; &amp;lt;br&amp;gt;&lt;br /&gt;
 @end&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Firstly, take note that we inherit from NSDocument. As a result, we need to override some methods for a basic (but working) implementation. &lt;br /&gt;
&lt;br /&gt;
==== loadDataRepresentation:ofType: and dataRepresentationOfType: ====&lt;br /&gt;
&lt;br /&gt;
The methods, loadDataRepresent:ofType: and dataRepresentationOfType: are used by NSDocumentController to load and save our files. The first method is called when the user trys to open a document (NSDocumentController gets the file name and copies it's data using an open panel). The method is passed the raw data in this file, as well as a string representing its type. It is important to note that this type string is the same one used in your property list. It is used by NSDocumentController to tell you what type it thinks you should open the data with. If this is not possible, or if there is an error trying to parse the data, your method returns FALSE/NO. Otherwise, you should store a local, meaningful representation of the data, which you can insert into your document window a little later (and return TRUE/YES).&lt;br /&gt;
&lt;br /&gt;
For example, in terms of the TextEdit example:&lt;br /&gt;
 - (BOOL) loadDataRepresentation:(NSData*) representation ofType:(NSString*)type&lt;br /&gt;
 {&lt;br /&gt;
    /*Check type information */&lt;br /&gt;
    if ([representation equalTo:GSTextDocumentType]==NO)&lt;br /&gt;
        return NO;&lt;br /&gt;
    /* Clean out our old representation if it still exists */&lt;br /&gt;
    if (fileContents) RELEASE(fileContents); &amp;lt;br&amp;gt;&lt;br /&gt;
    /* Allocate room for the new data, and try to initialise a string with it. */&lt;br /&gt;
    self-&amp;gt;fileContents = [NSString alloc];&lt;br /&gt;
    fileContents = [fileContents initWithBytes: [representation bytes]&lt;br /&gt;
                         length: [representation length]&lt;br /&gt;
                       encoding: NSASCIIStringEncoding]; &amp;lt;br&amp;gt;&lt;br /&gt;
    /* If this can't be done, return NO */&lt;br /&gt;
    if (!fileContents)&lt;br /&gt;
        return NO; &amp;lt;br&amp;gt;&lt;br /&gt;
    /* Otherwise, set our TextView to the string data. */&lt;br /&gt;
    [self-&amp;gt;textView setString: fileContents];&lt;br /&gt;
    return YES;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
If this is not sufficient, or if your program can open the data in a more efficient manner, it may be worth looking into overriding -initWithContentsOfFile:ofType: and -initWithContentsOfURL:ofType:. Again, see the GUI manual for more details.&lt;br /&gt;
&lt;br /&gt;
dataRepresentationOfType: is used to save the data. Your method is expected to return an instance of NSData that contains what should be saved to a file, for the type specified. Again, the ''type'' variable should be checked to ensure that you can write data of that type. Return nil if the file cannot be saved as that type.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
 - (NSData*) dataRepresentationOfType:(NSString*)type&lt;br /&gt;
 {&lt;br /&gt;
     if ([type equalTo:GSTextDocumentType]==NO)&lt;br /&gt;
         return nil; &amp;lt;br&amp;gt;&lt;br /&gt;
     NSData stringData =  [[textView string] dataUsingEncoding:NSASCIIStringEncoding];  &lt;br /&gt;
     return stringData; &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
If a more sophisticated save implementation is needed, consult the documentation for information on the writeTo* methods.&lt;br /&gt;
&lt;br /&gt;
==== windowNibName ====&lt;br /&gt;
&lt;br /&gt;
This method must be overriden to return the a string of the name of your nib file (without the file extension). More complex implementations will use other methods to load the interface files. TODO: information on what methods need to be overriden.&lt;br /&gt;
&lt;br /&gt;
==== windowControllerDidLoadNib: ====&lt;br /&gt;
&lt;br /&gt;
Use this method to add code that should be run as soon as ''windowController'' has been initialised. Your document may have many window controllers; each window controller taking possession of one window.&lt;br /&gt;
&lt;br /&gt;
In the TextEdit example, this method is used to copy the ''fileContents'' variable to the text view. It otherwise initialises the document window. &lt;br /&gt;
&lt;br /&gt;
Also note that you can override windowControllerWillLoadNib: to perform pre-interface loading initialisation.&lt;br /&gt;
&lt;br /&gt;
==== makeWindowControllers ====&lt;br /&gt;
&lt;br /&gt;
This is an optional method to override, which must be used if you have multiple window controllers per document. It is responsible for creating each window controller from it's interface file and then adding it to the document. Use the addWindowController: method.&lt;br /&gt;
&lt;br /&gt;
==== Other considerations ====&lt;br /&gt;
&lt;br /&gt;
* You need a way to notify NSDocument that your document has changed, so that NSDocumentController can enable the menu item to allow saving. This is done by a call to the updateChangeCount: method. For example, the TextDocument class adds itself as a delegate to the textView, for any notification of changes. It then calls updateChangeCount: in the delegate's method.&lt;br /&gt;
&lt;br /&gt;
* You may also wish to add a close: method (not the close method already in NSDocument, see below) to respond to the menu item permitting your document to close. This could perform cleanup operations before a call to [self close] is made e.g.&lt;br /&gt;
&lt;br /&gt;
 - (void) close:(id)sender /* Note this is not the method found in NSDocument (they differ by a parameter) */&lt;br /&gt;
 {&lt;br /&gt;
     [self close];&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== NSDocumentController ===&lt;br /&gt;
&lt;br /&gt;
This class can optionally be subclassed, to implement some specific functionality. For example, programs handling multiple document types may override newDocument: to create a window so that the user can select which document type to create.&lt;br /&gt;
&lt;br /&gt;
You should use separate implementation files and add the .m file to GNUmakefile.&lt;br /&gt;
&lt;br /&gt;
=== NSWindowController ===&lt;br /&gt;
&lt;br /&gt;
This class can also be optionally subclassed, to implement functionality specific to a window controller for a document type. You may need to override makeWindowControllers: in the NSDocument subclass in order to make sure your specific window controller is instantiated.&lt;br /&gt;
&lt;br /&gt;
You should use separate implemenation files and add the .m file to GNUmakefile.&lt;br /&gt;
&lt;br /&gt;
== Optional Additions ==&lt;br /&gt;
&lt;br /&gt;
=== Custom NSDocumentController and NSWindowController implementations ===&lt;br /&gt;
&lt;br /&gt;
See [[#NSWindowController|NSWindowController]] and [[#NSDocumentController|NSDocumentController]].&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Platform_compatibility&amp;diff=2878</id>
		<title>Platform compatibility</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Platform_compatibility&amp;diff=2878"/>
		<updated>2005-11-22T07:47:42Z</updated>

		<summary type="html">&lt;p&gt;Quineska: /* MingW */  Added &amp;quot;Installation on Windows&amp;quot; Link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Note''': Anyone know how to convert [http://www.gnustep.org/resources/documentation/User/GNUstep/gnustep-howto_toc.html Platform Compatibility HowTO] source into wiki language, so we can work on others' effort?&lt;br /&gt;
&lt;br /&gt;
Following are procedures for installing GNUstep on different Operating Systems.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== AIX ===&lt;br /&gt;
''To be provided.''&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== BSD ===&lt;br /&gt;
&lt;br /&gt;
==== Darwin-based Systems ====&lt;br /&gt;
''To be provided.''&lt;br /&gt;
&lt;br /&gt;
===== Intel =====&lt;br /&gt;
''To be provided.''&lt;br /&gt;
&lt;br /&gt;
===== PowerPC =====&lt;br /&gt;
''To be provided.''&lt;br /&gt;
&lt;br /&gt;
==== FreeBSD-based Systems ==== &lt;br /&gt;
&lt;br /&gt;
===== DesktopBSD =====&lt;br /&gt;
[http://desktopbsd.sourceforge.net/ DesktopBSD] joins the ranks of PC-BSD and FreeSBIE as a desktop-ready version of FreeBSD. However, their desktop is based on [http://www.kde.org KDE].&lt;br /&gt;
&lt;br /&gt;
===== DragonFly =====&lt;br /&gt;
[http://www.dragonflybsd.org/main/ DragonFly] is an operating system and environment designed to be the logical continuation of the [[Platform_compatibility#FreeBSD|FreeBSD]]-4.x OS series.&lt;br /&gt;
&lt;br /&gt;
I have mostly ported GNUstep to DragonFly, I just need to submit patches now for both GNUstep and DragonFly. To know more, you can contact me. ''[[user:Qmathe | Quentin Mathé]]''&lt;br /&gt;
&lt;br /&gt;
===== FreeBSD =====&lt;br /&gt;
You can install GNUstep via ''/usr/ports/devel/gnustep''. However, not all required dependencies are installed.&lt;br /&gt;
&lt;br /&gt;
If you install the following in advance, you should be fine: ''[http://www.freshports.org/x11-wm/windowmaker/ wmaker], [http://www.freshports.org/textproc/libxml2/ libxml2], [http://www.freshports.org/textproc/libxslt/ libxslt], [http://www.freshports.org/math/libgmp4/ libgmp4], [http://www.freshports.org/graphics/libart_lgpl2/ libart_lgpl2], [http://www.freshports.org/audio/libaudiofile/ libaudiofile], [http://www.freshports.org/audio/portaudio/ portaudio], [http://www.freshports.org/devel/ffcall ffcall], [http://www.freshports.org/graphics/glitz/ glitz]''&lt;br /&gt;
&lt;br /&gt;
''[http://www.freshports.org/print/cups/ CUPS]'' is used for printing functionality. OTOH, it is a good idea to go for [http://www.freshports.org/net/samba/ Samba] directly, which also includes CUPS.&lt;br /&gt;
Additionally, you may also want to install ''[http://www.freshports.org/net/mDNSResponder/ mDNSResponder]''.&lt;br /&gt;
&lt;br /&gt;
'''Note''':&lt;br /&gt;
There is a bug in libkvm that '''requires''' a mounted ''/proc''. Until this bug is fixed, make sure you have an entry for ''/proc'' in your ''/etc/fstab'':&lt;br /&gt;
&lt;br /&gt;
 proc                    /proc           procfs  rw              0       0&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
[http://www.freebsd.org/cgi/ports.cgi?query=gnustep&amp;amp;stype=all FreeBSD GNUstep ports], &lt;br /&gt;
[http://www.freshports.org/search.php?query=gnustep&amp;amp;search=go&amp;amp;num=10&amp;amp;stype=name&amp;amp;method=match&amp;amp;deleted=excludedeleted&amp;amp;start=1&amp;amp;casesensitivity=caseinsensitive Freshports GNUstep]&lt;br /&gt;
&lt;br /&gt;
===== FreeBSD-Kernel w/ GNU userland =====&lt;br /&gt;
It was reported that this runs GNUstep as well. For more details see the topic of&lt;br /&gt;
the IRC channel #gnu-kbsd on irc.gnu.org&lt;br /&gt;
&lt;br /&gt;
===== FreeSBIE =====&lt;br /&gt;
[http://www.freesbie.org/ FreeSBIE] is a Live-CD Version of FreeBSD.&lt;br /&gt;
&lt;br /&gt;
===== PicoBSD =====&lt;br /&gt;
[http://people.freebsd.org/~picobsd/picobsd.html PicoBSD] is a one floppy version of [[Platform_compatibility#FreeBSD|FreeBSD]] 3.0-current. You won't be able to use it as a platform for GNUstep.&lt;br /&gt;
&lt;br /&gt;
===== PC-BSD =====&lt;br /&gt;
[http://www.pcbsd.org/ PC-BSD] has as its goals to be an easy to install and use desktop OS, which is built on the [[Platform_compatibility#FreeBSD|FreeBSD]] operating system.&lt;br /&gt;
&lt;br /&gt;
==== Mac OS X ====&lt;br /&gt;
''To be provided.''&lt;br /&gt;
&lt;br /&gt;
==== NetBSD ====&lt;br /&gt;
Installing GNUstep from pkgsrc is really straight-forward for NetBSD if you're using a recent pkgsrc distribution. NetBSD/i386 has no known problems right now, however there are reports of crashout problems for gdomap on NetBSD/sparc which may be related to ffi/ffcall issues.&lt;br /&gt;
&lt;br /&gt;
In terms of pre-requisites, ensure you've got a working X11 environment on your system and preferrably are using WindowMaker as your window manager. &lt;br /&gt;
&lt;br /&gt;
'''Build instructions'''&lt;br /&gt;
&lt;br /&gt;
To install GNUstep, you need to cd to your pkgsrc tree and then cd to the right package directory, on my system:&lt;br /&gt;
&lt;br /&gt;
  cd /usr/pkgsrc&lt;br /&gt;
&lt;br /&gt;
then go to the package you wish to install, for example:&lt;br /&gt;
&lt;br /&gt;
  cd meta-pkgs/gnustep&lt;br /&gt;
&lt;br /&gt;
and issue the command:&lt;br /&gt;
&lt;br /&gt;
  make install&lt;br /&gt;
&lt;br /&gt;
This command will download source code and whatever dependencies and compile and install them. The version of the meta-packages I used (released with NetBSD 2.0 and called gnustep-1.10.0nb2) installs the following GNUstep components as parts of the meta-package:&lt;br /&gt;
&lt;br /&gt;
* gnustep-make-1.10.0&lt;br /&gt;
* gnustep-base-1.10.1&lt;br /&gt;
* gnustep-ssl-1.10.1&lt;br /&gt;
* gnustep-gui-0.9.4&lt;br /&gt;
* gnustep-back-0.9.4&lt;br /&gt;
* gnustep-examples-1.0.0&lt;br /&gt;
* ImageViewer-0.6.3&lt;br /&gt;
* Pantomime-1.1.2&lt;br /&gt;
* Addresses-0.4.6&lt;br /&gt;
* GNUMail-1.1.2&lt;br /&gt;
* Gorm-0.8.0&lt;br /&gt;
* ProjectCenter-0.4.0&lt;br /&gt;
* GWLib-0.6.5&lt;br /&gt;
* Renaissance-0.8.0&lt;br /&gt;
* gworkspace-0.6.5&lt;br /&gt;
&lt;br /&gt;
A number of dependency packages are also installed.&lt;br /&gt;
&lt;br /&gt;
This may be overkill - if you don't need all the applications etc, you can install the packages individually.&lt;br /&gt;
&lt;br /&gt;
==== OpenBSD ====&lt;br /&gt;
''To be provided.''&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== GNU/Hurd ===&lt;br /&gt;
GNUstep also runs on GNU/Hurd on the GNUMach kernel.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== HP/UX  ===&lt;br /&gt;
* GNUstep-core-1.0, please see http://en.wikibooks.org/wiki/CPAM_with_TWW/References_Manual#GNUstep_and_CPAM. look for the gnustep-core-1.0.sb and gnustep-core-1.0.pb file for building and packaging information.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Irix ===&lt;br /&gt;
''To be provided.''&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Linux ===&lt;br /&gt;
&lt;br /&gt;
==== Debian ====&lt;br /&gt;
Since Debian &amp;quot;Sarge&amp;quot; you can just say&lt;br /&gt;
&lt;br /&gt;
 apt-get install x-window-system-core wmaker gnustep gnustep-devel gnustep-games&lt;br /&gt;
&lt;br /&gt;
to get GNUstep, X11 and Window Maker installed.&lt;br /&gt;
&lt;br /&gt;
But what happen if you are on Debian stable (3.0) release ?&lt;br /&gt;
&lt;br /&gt;
Here is an answer from gnustep irc channel:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 &amp;lt;fsmunoz&amp;gt; change every occurence of &amp;quot;stable&amp;quot; for &amp;quot;testing&amp;quot;&lt;br /&gt;
 &amp;lt;fsmunoz&amp;gt; remove the security.debian.org line&lt;br /&gt;
 &amp;lt;fsmunoz&amp;gt; do apt-get update&lt;br /&gt;
 &amp;lt;fsmunoz&amp;gt; apt-get dist-upgrade&lt;br /&gt;
 &amp;lt;fsmunoz&amp;gt; repeat  this last one until nothing gets installed or removed.&lt;br /&gt;
 &amp;lt;fsmunoz&amp;gt; the, replace &amp;quot;testing&amp;quot; with &amp;quot;unstable&amp;quot;&lt;br /&gt;
 &amp;lt;fsmunoz&amp;gt; then, apt-get update&lt;br /&gt;
 &amp;lt;fsmunoz&amp;gt; apt-get dist-upgrade&lt;br /&gt;
 &amp;lt;fsmunoz&amp;gt; repeat, repeat.&lt;br /&gt;
 &amp;lt;fsmunoz&amp;gt; done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above was a general guide to upgrade from Debian stable to unstable, not exactly the best way to install GNUstep packages. If one doesn't want to upgrade it is possible to simply add the unstable apt lines to the sources.list and specify the distribution when installing the packages, e.g.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# apt-get install -t unstable gnumail.app&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will probably upgrade some other packages to satisfy dependencies, but will have a much small impact on the system since only the packages on which GNUstep depends will be upgraded.&lt;br /&gt;
&lt;br /&gt;
Yet another way is to add tarzeau's repository (powerpc and source); he packages a huge ammount of GNUstep packages. Just add this to your sources.list:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
deb http://www.linuks.mine.nu/debian/ ./   &lt;br /&gt;
deb-src http://www.linuks.mine.nu/debian/ ./&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This repository contains packages made in unstable, so it's possible that the dependencies only are satisfied in unstable systems.&lt;br /&gt;
&lt;br /&gt;
==== RedHat ====&lt;br /&gt;
''To be provided.''&lt;br /&gt;
&lt;br /&gt;
===== Advance Server 3.0 =====&lt;br /&gt;
* GNUstep-core-1.0, please see http://en.wikibooks.org/wiki/CPAM_with_TWW#GNUstep_and_TWW_HPMS. look for the gnustep-core-1.0.sb and gnustep-core-1.0.pb file for building and packaging information.&lt;br /&gt;
&lt;br /&gt;
===== FC 3 =====&lt;br /&gt;
''To be provided.''&lt;br /&gt;
&lt;br /&gt;
==== Slackware ====&lt;br /&gt;
''To be provided.''&lt;br /&gt;
&lt;br /&gt;
==== SuSE ====&lt;br /&gt;
''To be provided.''&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Solaris ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Intel ====&lt;br /&gt;
''To be provided.''&lt;br /&gt;
&lt;br /&gt;
==== Sparc ====&lt;br /&gt;
&lt;br /&gt;
* http://www.linuks.mine.nu/gnustep/solaris is one of package sources to create solaris packages for GNUstep.&lt;br /&gt;
* GNUstep-core-1.0, please see http://en.wikibooks.org/wiki/CPAM_with_TWW#GNUstep_and_TWW_HPMS. look for the gnustep-core-1.0.sb and gnustep-core-1.0.pb file for building and packaging information.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Windows ===&lt;br /&gt;
&lt;br /&gt;
==== Cygwin ====&lt;br /&gt;
''To be provided.''&lt;br /&gt;
&lt;br /&gt;
==== MingW ====&lt;br /&gt;
&lt;br /&gt;
See [[Installation on Windows]] for details on MingW setup. Also look at precompiled binary installer, available from GNUstep's ftp site.&lt;br /&gt;
&lt;br /&gt;
==== SFU ====&lt;br /&gt;
Microsfot's Service For Unix.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Others ===&lt;br /&gt;
&lt;br /&gt;
==== LiveCD for Intel ====&lt;br /&gt;
Current version is 0.9.4.2&lt;br /&gt;
&lt;br /&gt;
Find the instructions to install and the CD itself [http://livecd.gnustep.org/ here]&lt;br /&gt;
&lt;br /&gt;
==== Linksys NSLU2 ====&lt;br /&gt;
* First thing need to happen is to gnerate a gcc cross compiler with objc enabled.&lt;br /&gt;
 Current nslu2 supported gcc only has c and c++ enabled when building the crosstool-native package.&lt;br /&gt;
&lt;br /&gt;
* check out unslung source using follow command.&lt;br /&gt;
&lt;br /&gt;
 cvs -z3 -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/nslu co unslung&lt;br /&gt;
&lt;br /&gt;
* add in objc as language need to be enabled.&lt;br /&gt;
 &amp;lt;pre&amp;gt;&lt;br /&gt;
 perl -pi -e 's!^GCC_LANGUAGES=.*!GCC_LANGUAGES=&amp;quot;c,c++,objc&amp;quot;!' toolchain/crosstool/nslu2-cross335.sh&lt;br /&gt;
 perl -pi -e 's!^GCC_LANGUAGES=.*!GCC_LANGUAGES=&amp;quot;c,c++,objc&amp;quot;!' sources/crosstool-native/nslu2-native335.sh&lt;br /&gt;
 &amp;lt;/pre&amp;gt;&lt;br /&gt;
** Compile cross-compiler for arm cpu using gcc compiler on debian 3.1 linux.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;pre&amp;gt;&lt;br /&gt;
tjyang@debian:~/unslung$ pwd&lt;br /&gt;
/home/tjyang/unslung&lt;br /&gt;
tjyang@debian:~/unslung$ rm toolchain/crosstool/.configured&lt;br /&gt;
tjyang@debian:~/unslung$ rm toolchain/crosstool/.built&lt;br /&gt;
tjyang@debian:~/unslung$ unset LD_LIBRARY_PATH&lt;br /&gt;
tjyang@debian:~/unslung$make toolchain&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* A arm gcc with objective-C enabled.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/export/home/tjyang/slug/unslung/toolchain/armv5b-softfloat-linux/gcc-3.3.5-glibc-2.2.5/bin/armv5b-softfloat-linux-gcc -v&lt;br /&gt;
&lt;br /&gt;
Reading specs from /export/home/tjyang/slug/unslung/toolchain/armv5b-softfloat-linux/gcc-3.3.5-glibc-2.2.5/lib/gcc-lib/armv5b-softfloat-linux/3.3.5/specs&lt;br /&gt;
Configured with: /export/home/tjyang/slug/unslung/toolchain/crosstool/build/armv5b-softfloat-linux/gcc-3.3.5-glibc-2.2.5/gcc-3.3.5/configure --target=armv5b-softfloat-linux --host=i686-host_pc-linux-gnu --prefix=/export/home/tjyang/slug/unslung/toolchain/armv5b-softfloat-linux/gcc-3.3.5-glibc-2.2.5 --with-float=soft --with-cpu=xscale --enable-cxx-flags=-mcpu=xscale --with-headers=/export/home/tjyang/slug/unslung/toolchain/armv5b-softfloat-linux/gcc-3.3.5-glibc-2.2.5/armv5b-softfloat-linux/include --with-local-prefix=/export/home/tjyang/slug/unslung/toolchain/armv5b-softfloat-linux/gcc-3.3.5-glibc-2.2.5/armv5b-softfloat-linux --disable-nls --enable-threads=posix --enable-symvers=gnu --enable-__cxa_atexit --enable-languages=c,c++,objc --enable-shared --enable-c99 --enable-long-long&lt;br /&gt;
Thread model: posix&lt;br /&gt;
gcc version 3.3.5&lt;br /&gt;
[tjyang@dual unslung]$&lt;br /&gt;
   &amp;lt;/pre&amp;gt; &lt;br /&gt;
** A simple test of objc on host linux machine.&lt;br /&gt;
  &amp;lt;pre&amp;gt;&lt;br /&gt;
  [tjyang@dual bin]$ pwd&lt;br /&gt;
  /home/tjyang/slug/unslung/toolchain/armv5b-softfloat-linux/gcc-3.3.5-glibc-2.2.5/armv5b-softfloat-linux/bin&lt;br /&gt;
  [tjyang@dual bin]$&lt;br /&gt;
  [tjyang@dual bin]$ cat helloworld.m&lt;br /&gt;
  #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  int main(void)&lt;br /&gt;
  {&lt;br /&gt;
     printf(&amp;quot;Hello World\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  [tjyang@dual bin]$ ./gcc helloworld.m -lobjc -o helloworld&lt;br /&gt;
  [tjyang@dual bin]$ file helloworld&lt;br /&gt;
  hellow: ELF 32-bit MSB executable, ARM, version 1 (ARM), for GNU/Linux 2.4.3, dynamically linked (uses shared libs), not stripped&lt;br /&gt;
  [tjyang@dual bin]$ uname -a&lt;br /&gt;
  Linux dual 2.4.21-9.ELsmp #1 SMP Thu Jan 8 17:08:56 EST 2004 i686 i686 i386 GNU/Linux&lt;br /&gt;
  [tjyang@dual bin]$&lt;br /&gt;
  &amp;lt;/pre&amp;gt;&lt;br /&gt;
** Second step is to use this cross-compiler which generate binaries code for armb cpu to compile a native compiler. This complier can only be run on native machine nslu2 not on Intel linux.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[tjyang@dual unslung]$ make crosstool-native;make crosstool-native-ipk&lt;br /&gt;
[tjyang@dual unslung]$ ls -lrt builds/*.ipk&lt;br /&gt;
-rw-rw-r--    1 tjyang   tjyang    5569523 Feb 17 13:32 builds/crosstool-native-bin_0.28-rc37-3_armeb.ipk&lt;br /&gt;
-rw-rw-r--    1 tjyang   tjyang   12677163 Feb 17 13:33 builds/crosstool-native-lib_0.28-rc37-3_armeb.ipk&lt;br /&gt;
-rw-rw-r--    1 tjyang   tjyang    1722660 Feb 17 13:33 builds/crosstool-native-inc_0.28-rc37-3_armeb.ipk&lt;br /&gt;
-rw-rw-r--    1 tjyang   tjyang    7049858 Feb 17 13:34 builds/crosstool-native-arch-bin_0.28-rc37-3_armeb.ipk&lt;br /&gt;
-rw-rw-r--    1 tjyang   tjyang    9032668 Feb 17 13:34 builds/crosstool-native-arch-lib_0.28-rc37-3_armeb.ipk&lt;br /&gt;
-rw-rw-r--    1 tjyang   tjyang    7483945 Feb 17 13:35 builds/crosstool-native-arch-inc_0.28-rc37-3_armeb.ipk&lt;br /&gt;
-rw-rw-r--    1 tjyang   tjyang       1058 Feb 17 13:35 builds/crosstool-native_0.28-rc37-3_armeb.ipk&lt;br /&gt;
&lt;br /&gt;
[tjyang@dual unslung]$ cp  /export/home/tjyang/slug/unslung/builds/*.ipk  /disk76/nslu2/tmp/&lt;br /&gt;
[tjyang@dual unslung]$&lt;br /&gt;
&lt;br /&gt;
login into your nslu2, cd to where the ipk packages are.&lt;br /&gt;
run following commands.&lt;br /&gt;
bash-2.05b# for i in *.ipk&lt;br /&gt;
&amp;gt; do&lt;br /&gt;
&amp;gt; ipkg -force-overwrite install $i&lt;br /&gt;
&amp;gt; done&lt;br /&gt;
Upgrading crosstool-native-arch-bin on root from 0.28-rc37-3 to 0.28-rc37-5...&lt;br /&gt;
Configuring crosstool-native-arch-bin&lt;br /&gt;
Upgrading crosstool-native-arch-inc on root from 0.28-rc37-3 to 0.28-rc37-5...&lt;br /&gt;
Configuring crosstool-native-arch-inc&lt;br /&gt;
Upgrading crosstool-native-arch-lib on root from 0.28-rc37-3 to 0.28-rc37-5...&lt;br /&gt;
Configuring crosstool-native-arch-lib&lt;br /&gt;
Upgrading crosstool-native-bin on root from 0.28-rc37-3 to 0.28-rc37-5...&lt;br /&gt;
Configuring crosstool-native-bin&lt;br /&gt;
Upgrading crosstool-native-inc on root from 0.28-rc37-3 to 0.28-rc37-5...&lt;br /&gt;
Configuring crosstool-native-inc&lt;br /&gt;
Upgrading crosstool-native-lib on root from 0.28-rc37-3 to 0.28-rc37-5...&lt;br /&gt;
Configuring crosstool-native-lib&lt;br /&gt;
Upgrading crosstool-native on root from 0.28-rc37-3 to 0.28-rc37-5...&lt;br /&gt;
Configuring crosstool-native&lt;br /&gt;
bash-2.05b# date&lt;br /&gt;
Sat Feb 19 01:04:07 CST 2005&lt;br /&gt;
bash-2.05b#&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
** try to compile helloworld.m objective-C file and run the helloworld binary on nslu2.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
bash-2.05b# gcc helloworld.m -lobjc -o helloworld&lt;br /&gt;
bash-2.05b# file helloworld&lt;br /&gt;
helloworld: ELF 32-bit MSB executable, ARM, version 1 (ARM), for GNU/Linux 2.4.3, dynamically linked (uses shared libs), not stripped&lt;br /&gt;
bash-2.05b# ./helloworld&lt;br /&gt;
./helloworld: error while loading shared libraries: libobjc.so.1: cannot open shared object file: No such file or directory&lt;br /&gt;
bash-2.05b#&lt;br /&gt;
&lt;br /&gt;
libobjc.so.1 is in /opt/armeb/armv5b-softfloat-linux/lib, this path need to be in LD_LIBRARY_PATH.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
bash-2.05b# ./helloworld&lt;br /&gt;
Hello World&lt;br /&gt;
bash-2.05b# uname -a&lt;br /&gt;
Linux LKG7BFA96 2.4.22-xfs #1 Sat Jan 1 21:34:54 HST 2005 armv5b unknown unknown GNU/Linux&lt;br /&gt;
bash-2.05b# date&lt;br /&gt;
Thu Feb 17 11:35:19 CST 2005&lt;br /&gt;
bash-2.05b# cat compile.sh&lt;br /&gt;
/opt/armeb/armv5b-softfloat-linux/bin/gcc  helloworld.m -o helloworld -lobjc&lt;br /&gt;
bash-2.05b# cat /etc/profile&lt;br /&gt;
PATH=/opt/bin:/share/hdd/data/public/nslu2/tjyang/unslung/staging/bin:${PATH}&lt;br /&gt;
TERM=xterm&lt;br /&gt;
export LD_LIBRARY_PATH=/opt/lib:/lib:/opt/armeb/armv5b-softfloat-linux/lib&lt;br /&gt;
export PATH TERM&lt;br /&gt;
bash-2.05b#&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Using Objective-C enalbed gcc to compile gnustep-core,gnustep-* software.&lt;br /&gt;
** more strong testing is needed. please add instructon below if you know how to run objective-c's testsuite in crosstool.&lt;br /&gt;
&lt;br /&gt;
References: http://lists.gnu.org/archive/html/discuss-gnustep/2005-02/msg00124.html&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Protocol&amp;diff=2877</id>
		<title>Protocol</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Protocol&amp;diff=2877"/>
		<updated>2005-11-22T07:43:08Z</updated>

		<summary type="html">&lt;p&gt;Quineska: formatting error&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A protocol is a  declaration of a group of methods not associated with any particular class.&lt;br /&gt;
&lt;br /&gt;
== Formal Protocol ==&lt;br /&gt;
&lt;br /&gt;
Formal Protocols are used to define the [[Interface]] for a set of methods, but not the implementation or any data members.&lt;br /&gt;
&lt;br /&gt;
This is useful for defining an interface which objects will need to conform to in order to take advantage of some service or other.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
    @protocol MyFormalProtocol&lt;br /&gt;
    &lt;br /&gt;
    -(void) someMethod;&lt;br /&gt;
    -(id) someOtherMethod;&lt;br /&gt;
    &lt;br /&gt;
    @end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Informal Protocol ==&lt;br /&gt;
&lt;br /&gt;
Informal Protocols are constructs that allow you to share a common [[Interface]] between two classes without them having to inherit from any specific object (the notable exception being NSObject).&lt;br /&gt;
&lt;br /&gt;
They are generally made with a category on NSObject that has no implementation associated with it.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
    @interface NSObject (MyInformalProtocol)&lt;br /&gt;
    &lt;br /&gt;
    - (id) someMethod;&lt;br /&gt;
    - (void) anotherMethod;&lt;br /&gt;
    &lt;br /&gt;
    @end&lt;br /&gt;
&lt;br /&gt;
== Implementing Protocols ==&lt;br /&gt;
&lt;br /&gt;
Formal and informal protocols take slightly different implementation paths. For formal protocols, you enclose the protocol name in less than/greater than signs e.g.:&lt;br /&gt;
&lt;br /&gt;
    @interface MyClass &amp;lt;MyFormalProtocol&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    /* Methods in protocol */&lt;br /&gt;
    &lt;br /&gt;
    -(void) someMethod;&lt;br /&gt;
    -(id) someOtherMethod;&lt;br /&gt;
    &lt;br /&gt;
    /* Your methods */&lt;br /&gt;
    &lt;br /&gt;
    @end    &lt;br /&gt;
&lt;br /&gt;
With informal protocols, you place the protocol name in brackets after your class name, both in the interface and implemenation i.e.:&lt;br /&gt;
&lt;br /&gt;
    @interface MyClass (MyInformalProtocol)&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
    @implementation MyClass (MyInformalProtocol)&lt;br /&gt;
&lt;br /&gt;
Although the interface declaration is optional.&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Protocol&amp;diff=2876</id>
		<title>Protocol</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Protocol&amp;diff=2876"/>
		<updated>2005-11-22T07:41:38Z</updated>

		<summary type="html">&lt;p&gt;Quineska: Added implementation examples&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A protocol is a  declaration of a group of methods not associated with any particular class.&lt;br /&gt;
&lt;br /&gt;
== Formal Protocol ==&lt;br /&gt;
&lt;br /&gt;
Formal Protocols are used to define the [[Interface]] for a set of methods, but not the implementation or any data members.&lt;br /&gt;
&lt;br /&gt;
This is useful for defining an interface which objects will need to conform to in order to take advantage of some service or other.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
    @protocol MyFormalProtocol&lt;br /&gt;
    &lt;br /&gt;
    -(void) someMethod;&lt;br /&gt;
    -(id) someOtherMethod;&lt;br /&gt;
    &lt;br /&gt;
    @end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Informal Protocol ==&lt;br /&gt;
&lt;br /&gt;
Informal Protocols are constructs that allow you to share a common [[Interface]] between two classes without them having to inherit from any specific object (the notable exception being NSObject).&lt;br /&gt;
&lt;br /&gt;
They are generally made with a category on NSObject that has no implementation associated with it.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
    @interface NSObject (MyInformalProtocol)&lt;br /&gt;
    &lt;br /&gt;
    - (id) someMethod;&lt;br /&gt;
    - (void) anotherMethod;&lt;br /&gt;
    &lt;br /&gt;
    @end&lt;br /&gt;
&lt;br /&gt;
== Implementing Protocols ==&lt;br /&gt;
&lt;br /&gt;
Formal and informal protocols take slightly different implementation paths. For formal protocols, you enclose the protocol name in less than/greater than signs e.g.:&lt;br /&gt;
&lt;br /&gt;
    @interface MyClass &amp;lt;MyFormalProtocol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    /* Methods in protocol */&lt;br /&gt;
    -(void) someMethod;&lt;br /&gt;
    -(id) someOtherMethod;&lt;br /&gt;
    &lt;br /&gt;
    /* Your methods */&lt;br /&gt;
&lt;br /&gt;
    @end    &lt;br /&gt;
&lt;br /&gt;
With informal protocols, you place the protocol name in brackets after your class name, both in the interface and implemenation i.e.:&lt;br /&gt;
&lt;br /&gt;
    @interface MyClass (MyInformalProtocol)&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
    @implementation MyClass(MyInformalProtocol)&lt;br /&gt;
&lt;br /&gt;
Although the interface declaration is optional.&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Archiving&amp;diff=2875</id>
		<title>Archiving</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Archiving&amp;diff=2875"/>
		<updated>2005-11-22T06:40:39Z</updated>

		<summary type="html">&lt;p&gt;Quineska: Added page with NSCoding details&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Allowing objects to be archived ==&lt;br /&gt;
&lt;br /&gt;
To permit an object be archived (also known as serialised) it's class needs to implement the NSCoding protocol. This protocol exposes two methods: -encoderWithCoder and -initWithCoder:. By implementing these methods, your object can be serialised/deserialised as well as sent over GNUstep's Distributed objects mechanism.&lt;br /&gt;
&lt;br /&gt;
See the reference manual for more details.&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Foundation&amp;diff=2874</id>
		<title>Foundation</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Foundation&amp;diff=2874"/>
		<updated>2005-11-22T06:35:33Z</updated>

		<summary type="html">&lt;p&gt;Quineska: Added gnustep-base reference&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The GNUstep base library (aka gnustep-base) contains a powerful set of non-graphical [[Objective-C]] classes that can readily be used in your programs. At present there are approximately 70 different classes available, including classes to handle [[NSStrng|strings]] and [[NSArray|arrays]], [[NSDate|dates]] and times, [[NSConnection|distributed objects]], URLs and file systems (to name but a few).&lt;br /&gt;
&lt;br /&gt;
Features:&lt;br /&gt;
&lt;br /&gt;
* [[Strings]]&lt;br /&gt;
* [[Collections]] (arrays, sets, dictionaries) and enumerators&lt;br /&gt;
* [[File management]]&lt;br /&gt;
* [[Archiving|object archiving]]&lt;br /&gt;
* advanced calendar [[Date|date]] manipulation&lt;br /&gt;
* [[Distributed Objects]] and inter-process communication&lt;br /&gt;
* [[URL]] handling&lt;br /&gt;
* [[Notifications]] (and distributed notifications)&lt;br /&gt;
* easy [[Threading|multi-threading]]&lt;br /&gt;
* [[Timer]]s&lt;br /&gt;
* [[Lock]]s&lt;br /&gt;
* [[Exception handling]]&lt;br /&gt;
&lt;br /&gt;
== Classes ==&lt;br /&gt;
&lt;br /&gt;
[[NSArray]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Frameworks]]&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=NSString&amp;diff=2873</id>
		<title>NSString</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=NSString&amp;diff=2873"/>
		<updated>2005-11-22T06:34:58Z</updated>

		<summary type="html">&lt;p&gt;Quineska: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Strings in GNUstep use the NSString class in gnustep-base. See the reference manual for gnustep-base for more details about NSString.&lt;br /&gt;
&lt;br /&gt;
== Constant Strings ==&lt;br /&gt;
&lt;br /&gt;
As you can create static instances of char* plain C, you can create strings in GNUstep that automatically flatten out to be static instances of NSString. This is done by preceding the quoted string by an &amp;quot;at&amp;quot; symbol ('@'). For example:&lt;br /&gt;
&lt;br /&gt;
  NSString * myString = @&amp;quot;This is an example of a string.&amp;quot;;&lt;br /&gt;
  NSLog(myString);&lt;br /&gt;
&lt;br /&gt;
myString is now an NSString object, and can have methods called on it like any other string.&lt;br /&gt;
&lt;br /&gt;
== Getting a C String ==&lt;br /&gt;
&lt;br /&gt;
You can convert an NSString object to a plain C string using the cString method. For example:&lt;br /&gt;
&lt;br /&gt;
  NSString* newString = @&amp;quot;This is a test string.&amp;quot;;&lt;br /&gt;
  char* theString = [newString cString];&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=NSString&amp;diff=2872</id>
		<title>NSString</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=NSString&amp;diff=2872"/>
		<updated>2005-11-22T06:31:48Z</updated>

		<summary type="html">&lt;p&gt;Quineska: Added some details to encourage additions&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Strings in GNUstep use the NSString class in gnustep-base. See the reference manual for gnustep-base for more details about NSString.&lt;br /&gt;
&lt;br /&gt;
== Constant Strings ==&lt;br /&gt;
&lt;br /&gt;
As in plain C, you can create strings in GNUstep that automatically flatten out to be static instances of NSString. This is done by preceding the quoted string by an &amp;quot;at&amp;quot; symbol ('@'). For example:&lt;br /&gt;
&lt;br /&gt;
  NSString * myString = @&amp;quot;This is an example of a string.&amp;quot;;&lt;br /&gt;
  NSLog(myString);&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Document_based_applications&amp;diff=2871</id>
		<title>Document based applications</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Document_based_applications&amp;diff=2871"/>
		<updated>2005-11-22T06:27:44Z</updated>

		<summary type="html">&lt;p&gt;Quineska: Filled out page a bit more with some better details&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Document based applications are those that are primarily concerned with user documents, allowing multiple (context-sensitive) document windows and a consistent mechanism for file loading and saving. GNUstep provides a model and associated services, for the rapid development of applications following this paradigm. &lt;br /&gt;
&lt;br /&gt;
Document based applications in GNUstep use NSDocument and NSDocumentController to support and coordinate this behaviour. Below are some articles describing how you can add this functionality to your program, and the role these classes in play in gnustep-gui.&lt;br /&gt;
&lt;br /&gt;
[[NSDocument]]&lt;br /&gt;
&lt;br /&gt;
[[Creating document based applications]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Talk:Window_Maker&amp;diff=2870</id>
		<title>Talk:Window Maker</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Talk:Window_Maker&amp;diff=2870"/>
		<updated>2005-11-22T06:21:19Z</updated>

		<summary type="html">&lt;p&gt;Quineska: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I was going to add:&lt;br /&gt;
&lt;br /&gt;
&amp;quot;This said, questions specifically regarding Window Maker should be directed towards the developers of Window Maker (GNUstep and Window Maker collaborate, but they are separate projects). &amp;quot;&lt;br /&gt;
&lt;br /&gt;
so we don't keep getting Window Maker specific questions. What do people think?&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Class_variable&amp;diff=2869</id>
		<title>Class variable</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Class_variable&amp;diff=2869"/>
		<updated>2005-11-22T03:33:13Z</updated>

		<summary type="html">&lt;p&gt;Quineska: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Objective-C dialect which is implemented by the GNU Compiler Collection (gcc) does not explicitly support the concept, widely used in some other object-oriented languages, of class variables.&lt;br /&gt;
&lt;br /&gt;
Class variables are shared values or properties of a specific class. This is useful when encapsulating more complex class and instance behaviour which requires the class to keep track, say of numbers of instances created or other more complex behaviours.&lt;br /&gt;
&lt;br /&gt;
A way of implementing class variables is to declare static variables in the class's [[Implementation]] section, and define class accessor methods if the values need to be changed externally. Note that these statics are not true class variables and will not be inherited by subclasses, and will not be visible outside of the source file's scope.&lt;br /&gt;
&lt;br /&gt;
One can make use of the +initialize method to have class variables initialised when their class is loaded into the runtime.&lt;br /&gt;
&lt;br /&gt;
Compare with the concept of an [[Instance variable]].&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Objective-C&amp;diff=2055</id>
		<title>Objective-C</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Objective-C&amp;diff=2055"/>
		<updated>2005-09-22T02:59:40Z</updated>

		<summary type="html">&lt;p&gt;Quineska: Linked language to use in GNUstep&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Objective-C consists of a set of object-oriented extensions to the C language, featuring things like dynamic binding and a powerful runtime system. That makes Objective-C a superset of C. It is the main  programming language used to program with GNUstep.&lt;br /&gt;
&lt;br /&gt;
Objective-C was created by [http://virtualschool.edu/cox/ Brad Cox].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Some resources:&lt;br /&gt;
# [http://www.objc.info Objective-C portal]&lt;br /&gt;
# Apple Site: [http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/ The Objective-C Programming Language]&lt;br /&gt;
# [http://www.toodarkpark.org/computers/objc/ Object-Oriented Programming and the Objective-C Language]&lt;br /&gt;
# [http://www.faqs.org/faqs/computer-lang/Objective-C/faq/ Objective-C FAQ]&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Property_Lists&amp;diff=2030</id>
		<title>Property Lists</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Property_Lists&amp;diff=2030"/>
		<updated>2005-09-18T08:50:15Z</updated>

		<summary type="html">&lt;p&gt;Quineska: Spelling errors, grammatical errors, removed TODO's&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;NOTE: this document is still a work in progress. No responsibility is accepted for any problems arising from inaccuracies.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
Property lists are used throughout GNUstep to store defaults, program settings, application meta information, and so on. MacOS X has begun to use XML based property lists, but GNUstep uses the classic property list format. Support in GNUstep for XML property lists is still limited on some platforms (namely Windows); this situation should improve in the future as libxml platform build issues are resolved within GNUstep.&lt;br /&gt;
&lt;br /&gt;
A property list is a logical tree of arrays, dictionaries, strings and numbers. The arrays and dictionaries may contain other arrays and dictionaries as data elements, and structures may become quite rich and expressive when representing complex data relationships. &lt;br /&gt;
&lt;br /&gt;
== Dictionary ==&lt;br /&gt;
&lt;br /&gt;
A dictionary is a list of key-value pairs, where each item in the list has a name associated with it (key) and another type (value), which could be another dictionary, an array or often a string. It programmatically corresponds to NSDictionary/NSMutableDictionary. They take the following syntax:&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
    KeyName1 = Value1;&lt;br /&gt;
    AnotherKeyName = &amp;quot;Value2&amp;quot;;&lt;br /&gt;
    Something = ( &amp;quot;ArrayItem1&amp;quot;, &amp;quot;ArrayItem2&amp;quot;, &amp;quot;ArrayItem3&amp;quot; );&lt;br /&gt;
    Key4 = 0.10;&lt;br /&gt;
    KeyFive = { Dictionary2Key1 = &amp;quot;Something&amp;quot;; AnotherKey = &amp;quot;Somethingelse&amp;quot;; };&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
As can be seen, each key-value pair is separated by a semi-colon. Within the pair, the key is seperated from the value with an &amp;quot;equals&amp;quot; (=) sign. The key name is arbitrary, and not put in inverted commas (&amp;quot;&amp;quot;). Shown above are:  an unknown type (could be some sort of string - TODO), a string, an array, a number and another dictionary  (respectively).&lt;br /&gt;
&lt;br /&gt;
== Array ==&lt;br /&gt;
&lt;br /&gt;
An array is a list of values, each of the same type (often arrays or dictionaries). Programmatically, it uses NSArray/NSMutableArray. It takes a syntax similar to the following:&lt;br /&gt;
&lt;br /&gt;
 ( Value1, Value2, Value3, Value4 )&amp;lt;br&amp;gt;&lt;br /&gt;
 or&amp;lt;br&amp;gt;&lt;br /&gt;
 (&lt;br /&gt;
    Value1,&lt;br /&gt;
    Value2,&lt;br /&gt;
    Value3,&lt;br /&gt;
    Value4&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Each value is seperated by commas. By the technical definition of an array, each value is of the same &amp;quot;type&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Programming ==&lt;br /&gt;
&lt;br /&gt;
GNUstep permits such property list files (normally having a .plist extension) to be loaded and subsequently used in your applications or tools. FoundationKit - in GNUstep's case gnustep-base - classes NSDictionary and NSArray are used as representations of the property list data structures. Check the base API documentation for more information on working with these types programmatically.&lt;br /&gt;
&lt;br /&gt;
NSString can be used to turn property lists in string form (either read from a file or constructed programmatically) into an equivalent data structure in memory. Again, see the API documentation for NSString (particularly the -propertyList method).&lt;br /&gt;
&lt;br /&gt;
== Other tips ==&lt;br /&gt;
&lt;br /&gt;
* Property lists are much like C programming, where newlines and spaces and tabs are not so important to parsing, but syntax elements like braces, semilcolons and operators are.&lt;br /&gt;
* Some examples of property lists may include:&lt;br /&gt;
** ~/GNUstep/System/Defaults/.GNUstepDefaults (this is your defaults file for all installed GNUstep software; be careful when editing this file manually)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=NSView&amp;diff=1927</id>
		<title>NSView</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=NSView&amp;diff=1927"/>
		<updated>2005-08-31T22:10:09Z</updated>

		<summary type="html">&lt;p&gt;Quineska: Fixed link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;NSView is an [[AppKit]] class. It's role as a superclass is to provide most of the core functionality and services that specific GUI classes (such as NSButton or NSMenuView) use to display/render and handle events.&lt;br /&gt;
&lt;br /&gt;
== Code chunks ==&lt;br /&gt;
&lt;br /&gt;
=== Dragging objects ===&lt;br /&gt;
&lt;br /&gt;
''Note: following code can be somehow optimised by adding small 0.01s delay or something like that. If someone knows how to, please write it here.''&lt;br /&gt;
&lt;br /&gt;
Implement the '''mouseDown:''' method:&lt;br /&gt;
&lt;br /&gt;
 - (void)mouseDown:(NSEvent *)event&lt;br /&gt;
 {&lt;br /&gt;
    NSPoint        oldPoint;&lt;br /&gt;
    NSEvent       *presentEvent;&lt;br /&gt;
    NSEventType    eventType = [event type];&lt;br /&gt;
    unsigned int   eventMask = NSLeftMouseDownMask | NSLeftMouseUpMask&lt;br /&gt;
                                                 | NSLeftMouseDraggedMask;&lt;br /&gt;
    NSPoint        point;&lt;br /&gt;
    float          dx,dy;&lt;br /&gt;
    NSPoint        location;&lt;br /&gt;
 &lt;br /&gt;
    point = [self convertPoint:[event locationInWindow] fromView:nil];&lt;br /&gt;
 &lt;br /&gt;
    oldPoint = point;&lt;br /&gt;
 &lt;br /&gt;
    do&lt;br /&gt;
    {&lt;br /&gt;
        while (event &amp;amp;&amp;amp; eventType != NSLeftMouseUp)&lt;br /&gt;
        {&lt;br /&gt;
            presentEvent = event;&lt;br /&gt;
            event = [NSApp nextEventMatchingMask: eventMask&lt;br /&gt;
                         untilDate: [NSDate distantPast]&lt;br /&gt;
                            inMode: NSEventTrackingRunLoopMode&lt;br /&gt;
                           dequeue: YES];&lt;br /&gt;
            eventType = [event type];&lt;br /&gt;
        }&lt;br /&gt;
                           &lt;br /&gt;
        point = [self convertPoint: [presentEvent locationInWindow]&lt;br /&gt;
                          fromView: nil];&lt;br /&gt;
    &lt;br /&gt;
        dx = point.x - oldPoint.x;&lt;br /&gt;
        dy = point.y - oldPoint.y;&lt;br /&gt;
 &lt;br /&gt;
        [self scrollRectToVisible:frame];&lt;br /&gt;
&lt;br /&gt;
Add code here:&lt;br /&gt;
&lt;br /&gt;
        //&lt;br /&gt;
        // here move the dragged thing by: dx, dy&lt;br /&gt;
        // ....&lt;br /&gt;
        &lt;br /&gt;
Then finish the loop:&lt;br /&gt;
&lt;br /&gt;
        [self setNeedsDisplay:YES];&lt;br /&gt;
 &lt;br /&gt;
        oldPoint = point;&lt;br /&gt;
 &lt;br /&gt;
        if (eventType == NSLeftMouseUp)&lt;br /&gt;
        {&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
 &lt;br /&gt;
        event = [NSApp nextEventMatchingMask: eventMask&lt;br /&gt;
                      untilDate: nil&lt;br /&gt;
                         inMode: NSEventTrackingRunLoopMode&lt;br /&gt;
                        dequeue: YES];&lt;br /&gt;
       eventType = [event type];&lt;br /&gt;
 &lt;br /&gt;
    } while (eventType != NSLeftMouseUp);&lt;br /&gt;
 &lt;br /&gt;
    [self setNeedsDisplay:YES];&lt;br /&gt;
 }&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=NSView&amp;diff=974</id>
		<title>NSView</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=NSView&amp;diff=974"/>
		<updated>2005-08-31T22:07:14Z</updated>

		<summary type="html">&lt;p&gt;Quineska: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;NSView is an [AppKit] class. It's role as a superclass is to provide most of the core functionality and services that specific GUI classes (such as NSButton or NSMenuView) use to display/render and handle events.&lt;br /&gt;
&lt;br /&gt;
== Code chunks ==&lt;br /&gt;
&lt;br /&gt;
=== Dragging objects ===&lt;br /&gt;
&lt;br /&gt;
''Note: following code can be somehow optimised by adding small 0.01s delay or something like that. If someone knows how to, please write it here.''&lt;br /&gt;
&lt;br /&gt;
Implement the '''mouseDown:''' method:&lt;br /&gt;
&lt;br /&gt;
 - (void)mouseDown:(NSEvent *)event&lt;br /&gt;
 {&lt;br /&gt;
    NSPoint        oldPoint;&lt;br /&gt;
    NSEvent       *presentEvent;&lt;br /&gt;
    NSEventType    eventType = [event type];&lt;br /&gt;
    unsigned int   eventMask = NSLeftMouseDownMask | NSLeftMouseUpMask&lt;br /&gt;
                                                 | NSLeftMouseDraggedMask;&lt;br /&gt;
    NSPoint        point;&lt;br /&gt;
    float          dx,dy;&lt;br /&gt;
    NSPoint        location;&lt;br /&gt;
 &lt;br /&gt;
    point = [self convertPoint:[event locationInWindow] fromView:nil];&lt;br /&gt;
 &lt;br /&gt;
    oldPoint = point;&lt;br /&gt;
 &lt;br /&gt;
    do&lt;br /&gt;
    {&lt;br /&gt;
        while (event &amp;amp;&amp;amp; eventType != NSLeftMouseUp)&lt;br /&gt;
        {&lt;br /&gt;
            presentEvent = event;&lt;br /&gt;
            event = [NSApp nextEventMatchingMask: eventMask&lt;br /&gt;
                         untilDate: [NSDate distantPast]&lt;br /&gt;
                            inMode: NSEventTrackingRunLoopMode&lt;br /&gt;
                           dequeue: YES];&lt;br /&gt;
            eventType = [event type];&lt;br /&gt;
        }&lt;br /&gt;
                           &lt;br /&gt;
        point = [self convertPoint: [presentEvent locationInWindow]&lt;br /&gt;
                          fromView: nil];&lt;br /&gt;
    &lt;br /&gt;
        dx = point.x - oldPoint.x;&lt;br /&gt;
        dy = point.y - oldPoint.y;&lt;br /&gt;
 &lt;br /&gt;
        [self scrollRectToVisible:frame];&lt;br /&gt;
&lt;br /&gt;
Add code here:&lt;br /&gt;
&lt;br /&gt;
        //&lt;br /&gt;
        // here move the dragged thing by: dx, dy&lt;br /&gt;
        // ....&lt;br /&gt;
        &lt;br /&gt;
Then finish the loop:&lt;br /&gt;
&lt;br /&gt;
        [self setNeedsDisplay:YES];&lt;br /&gt;
 &lt;br /&gt;
        oldPoint = point;&lt;br /&gt;
 &lt;br /&gt;
        if (eventType == NSLeftMouseUp)&lt;br /&gt;
        {&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
 &lt;br /&gt;
        event = [NSApp nextEventMatchingMask: eventMask&lt;br /&gt;
                      untilDate: nil&lt;br /&gt;
                         inMode: NSEventTrackingRunLoopMode&lt;br /&gt;
                        dequeue: YES];&lt;br /&gt;
       eventType = [event type];&lt;br /&gt;
 &lt;br /&gt;
    } while (eventType != NSLeftMouseUp);&lt;br /&gt;
 &lt;br /&gt;
    [self setNeedsDisplay:YES];&lt;br /&gt;
 }&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Talk:Main_Page&amp;diff=1069</id>
		<title>Talk:Main Page</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Talk:Main_Page&amp;diff=1069"/>
		<updated>2005-08-21T02:30:23Z</updated>

		<summary type="html">&lt;p&gt;Quineska: DESPAM&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Can example be provided about &amp;quot;production environment in serveral organization&amp;quot; ? this will clear the doubt of people on GNUstep stability.&lt;br /&gt;
&lt;br /&gt;
added ([[User:Stefan Urbanek|Stefan Urbanek]] 10:08, 17 Feb 2005 (CET))&lt;br /&gt;
&lt;br /&gt;
Thank you ([[User:TJ Yang ]])&lt;br /&gt;
&lt;br /&gt;
Internationalisation in the Users section is probably misnamed and misspelled for this site. &lt;br /&gt;
&lt;br /&gt;
For the user their issue is normally Localisation, but even this isn't necessarily clear. I would argue for terminology like &amp;quot;Configuring language, script and input methods&amp;quot; or even something as formal as &amp;quot;National language configuration&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Internationalisation is a word most often used to describe the process of modifying ''code'' to ''support'' varied text encodings, number formats, currencies and so on and is a developer topic. Localisation is a word used most consistently for ''translation or conversion'' of an application interface and documentation into ''specific'' human languages, date and number formats etc and is probably a developer or volunteer topic.&lt;br /&gt;
&lt;br /&gt;
Even though my personally-preferred spelling in English is the Commonwealth variant, the most wide-spread spelling for Internationalization and Localization are the American-style 'z' spellings. Let's make it easier for people to find what they are looking for in search engines. When a user is trying to find out how to localise their script input and national language preferences, what terms are they going to search for? The link and page should be somehow connected to that.&lt;br /&gt;
&lt;br /&gt;
([[User:Comrade]])&lt;br /&gt;
&lt;br /&gt;
== A question concerning non-ASCII input in GNUstep applications ==&lt;br /&gt;
&lt;br /&gt;
Hello folks!&lt;br /&gt;
I tried to use GNUstep applications for my day-to-day tasks but I couldn't make them accept any text input except ASCII characters. When I switch to Russian, all applications refuse input. Is this the right way they should work now? As I know, there isn't any problems with Russian input in the original OpenStep environment. I use XKB and ru_RU.KOI8-R locale. Maybe it's necessary to use ru_RU.UTF8 or you know any other workarounds? All non-GNUstep applications work perfectly.&lt;br /&gt;
&lt;br /&gt;
likely the important thing is to set the GNUSTEP_STRING_ENCODING environment variable to NSKOI8RStringEncoding. There is an [[http://www.gnustep.org/resources/documentation/User/Gui/LanguageSetup.html Asian language support]] page on the gnustep website, that also contains information that could be useful for other languages.&lt;br /&gt;
&lt;br /&gt;
--[[User:Serge RU|Serge RU]] 04:48, 11 May 2005 (CEST)&lt;br /&gt;
Thank you, it works :) I also had to make some font assignments not covered in &amp;quot;Asian language support&amp;quot; document (Preferences.app let me find out about them and fix menu font, etc.), but the direction was right.&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Creating_document_based_applications&amp;diff=934</id>
		<title>Creating document based applications</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Creating_document_based_applications&amp;diff=934"/>
		<updated>2005-07-29T02:53:39Z</updated>

		<summary type="html">&lt;p&gt;Quineska: /* Document Interface File(s) */  - Added better subclassing information/Fixed typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Note: First version; subject to further revisions and changes.&lt;br /&gt;
--[[User:Quineska|ChrisArmstrong]] 07:09, 7 Jul 2005 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
OpenStep can provide your application a document-based model. It helps to simplify the process of creating such applications. GNUstep implements this as well; this document aims to provide an overview of what is required in the creation and design of such an application.&lt;br /&gt;
&lt;br /&gt;
It is assumed you are familiar with GNUstep, and have some understanding as how to create Gorm's interface files (often referred to as nib's), as well as some understanding of how they work.&lt;br /&gt;
&lt;br /&gt;
Importantly, such applications have certain components that are required, and should be considered as part of their design. When programming, classes that will be used as part of the AppKit are:&lt;br /&gt;
&lt;br /&gt;
==== NSDocument ====&lt;br /&gt;
&lt;br /&gt;
This class is central to the OpenStep document based model. These application's declare a new instance of a subclass of NSDocument for each “document” that is opened. You will subclass NSDocument to implement this.&lt;br /&gt;
&lt;br /&gt;
Each instance of your NSDocument subclass may have one or more windows associated with it. These are used as an interface for loading and saving a representation of your document type. Each window will have an “NSWindowController” instance associated with it, where NSDocument maintains a list of these.&lt;br /&gt;
&lt;br /&gt;
==== NSDocumentController ====&lt;br /&gt;
&lt;br /&gt;
This class acts a controller. It maintains a list of documents (instances of your NSDocument subclass) and is responsible for loading and instantiating new documents. It is usually not necessary to implement a subclass of this, but often it may be useful to implement special functionality (especially related to opening and creating documents at an application level).&lt;br /&gt;
&lt;br /&gt;
==== NSWindowController ====&lt;br /&gt;
&lt;br /&gt;
As mentioned above, NSWindowController instances are individually associated with one NSWindow instance, in such a way that a document maintains a list of window controllers that are reponsible for rendering the views associated with a document.&lt;br /&gt;
&lt;br /&gt;
You will most likely not have to subclass NSWindowController. Instead, you associate a nib file (the Gorm output) with the subclass of NSDocument, and NSDocumentController will load this nib file for each document that is created or loaded.&lt;br /&gt;
&lt;br /&gt;
For example, a text based application that is used for the editing of plain text files, may subclass NSDocument with a TextDocument class. Each instance of this class would have an NSWindowController instance associated with it, which in turn manages a window instance that is instantiated from a nib file. The NSDocumentController instance, as managed and instantiated by GNUstep, would be responsible for loading and saving documents in your application. It even prompts the user to save their documents when they try to quit the application.&lt;br /&gt;
&lt;br /&gt;
== File Components ==&lt;br /&gt;
&lt;br /&gt;
In building your application you will need to create a number of special files. From scratch, the following should be a rough guide to getting it working. These include the Makefile, your application's property list and the interface files.&lt;br /&gt;
&lt;br /&gt;
=== The Makefile ===&lt;br /&gt;
&lt;br /&gt;
For this type of application, no special makefile is needed: it just has to be a normal application. Project Builder should be able to spit out the required makefile and Gorm files that are needed for a generic application. I believe it is also capable of providing support for document-based applications. Otherwise use the following as a template:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''GNUmakefile'''&lt;br /&gt;
&lt;br /&gt;
 include $(GNUSTEP_MAKEFILES)/common.make&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 APP_NAME = DocumentApp&amp;lt;br&amp;gt;&lt;br /&gt;
 DocumentApp_OBJC_FILES =&amp;lt;br&amp;gt;&lt;br /&gt;
  MyDocument.m &amp;lt;br&amp;gt;&lt;br /&gt;
  main.m&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 DocumentApp_RESOURCES = \ &amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/Info-gnustep.plist \&amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/DocumentApp.gorm \&amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/MyDocument.gorm&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 -include GNUmakefile.preamble&amp;lt;br&amp;gt;&lt;br /&gt;
 include $(GNUSTEP_MAKEFILES)/application.make&amp;lt;br&amp;gt;&lt;br /&gt;
 -include GNUmakefile.postamble&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For more information as to customising this file, as well as setting up compiler options for third party libraries and includes, see the GNUstep makefile manual.&lt;br /&gt;
&lt;br /&gt;
===The application dictionary===&lt;br /&gt;
&lt;br /&gt;
For those that have edited this file in their project before, it is a dictionary with various values entered. For our purposes, we need an array within the main dictionary, called &amp;quot;NSTypes&amp;quot;. This is a array of unnamed dictionaries, with one dictionary for each type. &lt;br /&gt;
&lt;br /&gt;
I have provided an example for this file below. ProjectBuilder creates one as well. Please note that &amp;quot;TextEdit&amp;quot; does exist as an example application from NEXT I think, and again on MacOS X but I have constructed a much simpler version, used only for plain text files.&lt;br /&gt;
&lt;br /&gt;
Taking a look at the single dictionary entry in the NSTypes array, the following key-value pairs are needed:&lt;br /&gt;
* '''NSDocumentClass:''' This is (string) the subclass name you use in your code, the &amp;quot;objective-c name&amp;quot; of your document subclass. This is used by NSDocumentController's default implementation to create instances of your document type.&lt;br /&gt;
* '''NSName:''' The generic file type (string). This is completely arbitrary, and can be anything you like. For the purpose of conventions, it may be more appropriate not to use the &amp;quot;NS&amp;quot; or &amp;quot;GS&amp;quot; prefix (the latter of which I not sure), and instead use either your own, or no prefix at all.&lt;br /&gt;
* '''NSHumanReadableName:''' The human readable name of your document type (string)? TODO: explain where this is used.&lt;br /&gt;
* '''NSUnixExtensions:''' An array of strings, each containing a file extension connected to this document type on &amp;quot;unix&amp;quot; platforms. TODO: explain how &amp;quot;unix&amp;quot; is interpreted by GNUstep.&lt;br /&gt;
* '''NSDOSExtensions:''' An array of strings, each containing a file extenstion connected to this document type on &amp;quot;DOS&amp;quot; platforms (could be loosely interpreted as any MS platforms GNUstep runs on, i.e. Windows 2000/XP).&lt;br /&gt;
* '''NSRole:''' A string, either &amp;quot;Viewer&amp;quot; or &amp;quot;Editor&amp;quot;, depending on how your document operates on this file type.&lt;br /&gt;
* '''NSIcon:''' A icon name associated with this document type. TODO: Investigate how this works.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Info-gnustep.plist'''&lt;br /&gt;
 {&lt;br /&gt;
     ApplicationDescription = &amp;quot;A simple text editor for GNUstep.&amp;quot;;&lt;br /&gt;
     ApplicationName = TextEdit;&lt;br /&gt;
     ApplicationRelease = 0.10;&lt;br /&gt;
     Authors = ( &amp;quot;Christopher Armstrong&amp;quot; );&lt;br /&gt;
     Copyright = &amp;quot;Copyright (C) 2005 Christopher Armstrong&amp;quot;;&lt;br /&gt;
     CopyrightDescription = &amp;quot;Released under GPL.&amp;quot;;&lt;br /&gt;
     FullVersionID = 0.10;&lt;br /&gt;
     NSExecutable = TextEdit;&lt;br /&gt;
     NSMainNibFile = TextEdit.gorm;&lt;br /&gt;
     NSPrincipalClass = NSApplication;&lt;br /&gt;
     NSRole = Application;&lt;br /&gt;
     NSTypes = (&lt;br /&gt;
         {&lt;br /&gt;
                 NSDocumentClass = &amp;quot;TextDocument&amp;quot;;&lt;br /&gt;
                 NSName = &amp;quot;GSTextDocumentType&amp;quot;;&lt;br /&gt;
                 NSHumanReadableName = &amp;quot;Text Document&amp;quot;;&lt;br /&gt;
                 NSUnixExtensions = ( &amp;quot;txt&amp;quot;, &amp;quot;&amp;quot; );&lt;br /&gt;
                 NSDOSExtensions = ( &amp;quot;txt&amp;quot; );&lt;br /&gt;
                 NSRole = Editor;&lt;br /&gt;
         }&lt;br /&gt;
     );&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For more information on property list files, consult [[Property Lists]].&lt;br /&gt;
&lt;br /&gt;
=== Interface files ===&lt;br /&gt;
&lt;br /&gt;
Two interface files are needed: one for your main application, and another that will be instantiated with each instance of your document subclass. These both should be listed as resources in your makefile, (as shown the GNUmakefile example above). It may be helpful to name the document nib file after your class.&lt;br /&gt;
&lt;br /&gt;
==== Application Interface File ====&lt;br /&gt;
&lt;br /&gt;
The application one should just be a menu (though it could be more if necessary). When constructing it, take the following into account:&lt;br /&gt;
&lt;br /&gt;
* Use a standard Gorm template for an Application.&lt;br /&gt;
* Delete the window instance in the &amp;quot;Objects&amp;quot; pane (unless you need a main window, which is beyond the scope of this document).&lt;br /&gt;
* Set NSOwner's class to &amp;quot;NSDocumentController&amp;quot;. This is the custom class option of NSOwner in the property inspector. This ensures that the openDocument:, newDocument: messages, as sent to NSFirst, get picked up by NSDocumentController. Do not instantiate it (I believe you can't anyway).&lt;br /&gt;
* If you intend to subclass NSDocumentController, subclass it in the Classes pane. To make sure that this class is instantiated and used, make sure you instantiate it in Gorm or in your main.m file, and set NSOwner to be your subclass.&lt;br /&gt;
* Drag a Document menu from the palette onto your main menu. This already has the proper outlet and action linkage for each relevant message to be directed to NSFirst. Generic messages (such as openDocument:, not associated with any document instance) are forwarded to the shared instance of NSDocumentController (see it's reference documentation). When a document is active, more specific messages (such as close: or saveDocument:) are forwarded to the relevant document instance of your NSDocument subclass.&lt;br /&gt;
* Add any appropriate menus such as &amp;quot;Info&amp;quot; and &amp;quot;Format&amp;quot; which may be relevant to your application.&lt;br /&gt;
&lt;br /&gt;
==== Document Interface File(s) ====&lt;br /&gt;
&lt;br /&gt;
The document interface file is a window containing the view(s) required for the implementation of one instance of your document type. For example, in the case of a TextDocument type, a window instance with a NSTextView drawn on it is used for each document window. This interface file is instantiated every time a person creates a new document (the newDocument: message is sent to NSDocumentController) or opens an existing document (openDocument:).&lt;br /&gt;
&lt;br /&gt;
You will need to:&lt;br /&gt;
* '''Subclass NSDocument''' with your document type in Gorm. This is done in a couple of ways, see [[Gorm_Manual#Custom_classes|custom classes]]. It is up to you whether or not you let Gorm generate the class files, but make sure you add the appropriate outlets to your class in the source files (otherwise, I think your your program may segfault).&lt;br /&gt;
* '''Set NSOwner:''' Set your subclass as NSOwner's Custom class using the Property Inspector. ''DO NOT INSTANTIATE IT.''&lt;br /&gt;
&lt;br /&gt;
Another thing that you may want to consider is custom outlets. If you place certain views or controls on your window (including the window itself), you may want to refer to them directly in your code, e.g. the NSTextView in our TextEdit example is accessed directly, so that we can save it's contents to a file. To enable this, we add outlets to our class (see [[Gorm_Manual#Custom_classes|custom classes]]). We then connect NSOwner to the appropriate controls/views, and select the outlets in the Connections Property Inspector (see [[Gorm_Manual#Editing_the_interface|editing the interface]]).&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
Various things need to be done at a code level, to ensure that your NSDocument subclass is properly instantiated. This section aims to tell you what is necessary.&lt;br /&gt;
&lt;br /&gt;
=== NSDocument subclass ===&lt;br /&gt;
&lt;br /&gt;
When creating your subclass, you may have chosen to have Gorm create the class files. If not, you should create two files for your subclass: a header (.h) file and an implementation file (.m). The header file should take the following layout (we're using the TextEdit example again):&lt;br /&gt;
&lt;br /&gt;
 #ifndef TEXTDOCUMENT_H&lt;br /&gt;
 #define TEXTDOCUMENT_H &amp;lt;br&amp;gt;&lt;br /&gt;
 #include &amp;lt;AppKit/AppKit.h&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
 @class NSDocument; &amp;lt;br&amp;gt;&lt;br /&gt;
 /* The document type string, as specified in the property list [[#The_application_dictionary|NSTypes array]] */ &amp;lt;br&amp;gt;&lt;br /&gt;
 NSString * GSTextDocumentType = &amp;quot;GSTextDocumentType&amp;quot;;&lt;br /&gt;
 @interface TextDocument : NSDocument&lt;br /&gt;
 {&lt;br /&gt;
 @protected&lt;br /&gt;
     /* Outlets we added in our Gorm nib file */&lt;br /&gt;
     id * textView;&lt;br /&gt;
 }&lt;br /&gt;
 /* Basic methods used for loading and saving document data (respectively). */&lt;br /&gt;
 - (BOOL) loadDataRepresentation:(NSData*)representation ofType:(NSString*)type;&lt;br /&gt;
 - (NSData*) dataRepresentationOfType: (NSString*)type; &amp;lt;br&amp;gt;&lt;br /&gt;
 /* Information and events handling of GUI related changes */&lt;br /&gt;
 - (NSString*) windowNibName;&lt;br /&gt;
 - (void) windowControllerDidLoadNib:(NSWindowController*)windowController; &amp;lt;br&amp;gt;&lt;br /&gt;
 @end&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Firstly, take note that we inherit from NSDocument. As a result, we need to override some methods for a basic (but working) implementation. &lt;br /&gt;
&lt;br /&gt;
==== loadDataRepresentation:ofType: and dataRepresentationOfType: ====&lt;br /&gt;
&lt;br /&gt;
The methods, loadDataRepresent:ofType: and dataRepresentationOfType: are used by NSDocumentController to load and save our files. The first method is called when the user trys to open a document (NSDocumentController gets the file name and copies it's data using an open panel). The method is passed the raw data in this file, as well as a string representing its type. It is important to note that this type string is the same one used in your property list. It is used by NSDocumentController to tell you what type it thinks you should open the data with. If this is not possible, or if there is an error trying to parse the data, your method returns FALSE/NO. Otherwise, you should store a local, meaningful representation of the data, which you can insert into your document window a little later (and return TRUE/YES).&lt;br /&gt;
&lt;br /&gt;
For example, in terms of the TextEdit example:&lt;br /&gt;
 - (BOOL) loadDataRepresentation:(NSData*) representation ofType:(NSString*)type&lt;br /&gt;
 {&lt;br /&gt;
    /*Check type information */&lt;br /&gt;
    if ([representation equalTo:GSTextDocumentType]==NO)&lt;br /&gt;
        return NO;&lt;br /&gt;
    /* Clean out our old representation if it still exists */&lt;br /&gt;
    if (fileContents) RELEASE(fileContents); &amp;lt;br&amp;gt;&lt;br /&gt;
    /* Allocate room for the new data, and try to initialise a string with it. */&lt;br /&gt;
    self-&amp;gt;fileContents = [NSString alloc];&lt;br /&gt;
    fileContents = [fileContents initWithBytes: [representation bytes]&lt;br /&gt;
                         length: [representation length]&lt;br /&gt;
                       encoding: NSASCIIStringEncoding]; &amp;lt;br&amp;gt;&lt;br /&gt;
    /* If this can't be done, return NO */&lt;br /&gt;
    if (!fileContents)&lt;br /&gt;
        return NO; &amp;lt;br&amp;gt;&lt;br /&gt;
    /* Otherwise, set our TextView to the string data. */&lt;br /&gt;
    [self-&amp;gt;textView setString: fileContents];&lt;br /&gt;
    return YES;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
If this is not sufficient, or if your program can open the data in a more efficient manner, it may be worth looking into overriding -initWithContentsOfFile:ofType: and -initWithContentsOfURL:ofType:. Again, see the GUI manual for more details.&lt;br /&gt;
&lt;br /&gt;
dataRepresentationOfType: is used to save the data. Your method is expected to return an instance of NSData that contains what should be saved to a file, for the type specified. Again, the ''type'' variable should be checked to ensure that you can write data of that type. Return nil if the file cannot be saved as that type.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
 - (NSData*) dataRepresentationOfType:(NSString*)type&lt;br /&gt;
 {&lt;br /&gt;
     if ([type equalTo:GSTextDocumentType]==NO)&lt;br /&gt;
         return nil; &amp;lt;br&amp;gt;&lt;br /&gt;
     NSData stringData =  [[textView string] dataUsingEncoding:NSASCIIStringEncoding];  &lt;br /&gt;
     return stringData; &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
If a more sophisticated save implementation is needed, consult the documentation for information on the writeTo* methods.&lt;br /&gt;
&lt;br /&gt;
==== windowNibName ====&lt;br /&gt;
&lt;br /&gt;
This method must be overriden to return the a string of the name of your nib file (without the file extension). More complex implementations will use other methods to load the interface files. TODO: information on what methods need to be overriden.&lt;br /&gt;
&lt;br /&gt;
==== windowControllerDidLoadNib: ====&lt;br /&gt;
&lt;br /&gt;
Use this method to add code that should be run as soon as ''windowController'' has been initialised. Your document may have many window controllers; each window controller taking possession of one window.&lt;br /&gt;
&lt;br /&gt;
In the TextEdit example, this method is used to copy the ''fileContents'' variable to the text view. It otherwise initialises the document window. &lt;br /&gt;
&lt;br /&gt;
Also note that you can override windowControllerWillLoadNib: to perform pre-interface loading initialisation.&lt;br /&gt;
&lt;br /&gt;
==== makeWindowControllers ====&lt;br /&gt;
&lt;br /&gt;
This is an optional method to override, which must be used if you have multiple window controllers per document. It is responsible for creating each window controller from it's interface file and then adding it to the document. Use the addWindowController: method.&lt;br /&gt;
&lt;br /&gt;
==== Other considerations ====&lt;br /&gt;
&lt;br /&gt;
* You need a way to notify NSDocument that your document has changed, so that NSDocumentController can enable the menu item to allow saving. This is done by a call to the updateChangeCount: method. For example, the TextDocument class adds itself as a delegate to the textView, for any notification of changes. It then calls updateChangeCount: in the delegate's method.&lt;br /&gt;
&lt;br /&gt;
* You may also wish to add a close: method (not the close method already in NSDocument, see below) to respond to the menu item permitting your document to close. This could perform cleanup operations before a call to [self close] is made e.g.&lt;br /&gt;
&lt;br /&gt;
 - (void) close:(id)sender /* Note this is not the method found in NSDocument (they differ by a parameter) */&lt;br /&gt;
 {&lt;br /&gt;
     [self close];&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== NSDocumentController ===&lt;br /&gt;
&lt;br /&gt;
This class can optionally be subclassed, to implement some specific functionality. For example, programs handling multiple document types may override newDocument: to create a window so that the user can select which document type to create.&lt;br /&gt;
&lt;br /&gt;
You should use separate implementation files and add the .m file to GNUmakefile.&lt;br /&gt;
&lt;br /&gt;
=== NSWindowController ===&lt;br /&gt;
&lt;br /&gt;
This class can also be optionally subclassed, to implement functionality specific to a window controller for a document type. You may need to override makeWindowControllers: in the NSDocument subclass in order to make sure your specific window controller is instantiated.&lt;br /&gt;
&lt;br /&gt;
You should use separate implemenation files and add the .m file to GNUmakefile.&lt;br /&gt;
&lt;br /&gt;
== Optional Additions ==&lt;br /&gt;
&lt;br /&gt;
=== Custom NSDocumentController and NSWindowController implementations ===&lt;br /&gt;
&lt;br /&gt;
See [[#NSWindowController|NSWindowController]] and [[#NSDocumentController|NSDocumentController]].&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Creating_document_based_applications&amp;diff=875</id>
		<title>Creating document based applications</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Creating_document_based_applications&amp;diff=875"/>
		<updated>2005-07-29T02:50:12Z</updated>

		<summary type="html">&lt;p&gt;Quineska: /* Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Note: First version; subject to further revisions and changes.&lt;br /&gt;
--[[User:Quineska|ChrisArmstrong]] 07:09, 7 Jul 2005 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
OpenStep can provide your application a document-based model. It helps to simplify the process of creating such applications. GNUstep implements this as well; this document aims to provide an overview of what is required in the creation and design of such an application.&lt;br /&gt;
&lt;br /&gt;
It is assumed you are familiar with GNUstep, and have some understanding as how to create Gorm's interface files (often referred to as nib's), as well as some understanding of how they work.&lt;br /&gt;
&lt;br /&gt;
Importantly, such applications have certain components that are required, and should be considered as part of their design. When programming, classes that will be used as part of the AppKit are:&lt;br /&gt;
&lt;br /&gt;
==== NSDocument ====&lt;br /&gt;
&lt;br /&gt;
This class is central to the OpenStep document based model. These application's declare a new instance of a subclass of NSDocument for each “document” that is opened. You will subclass NSDocument to implement this.&lt;br /&gt;
&lt;br /&gt;
Each instance of your NSDocument subclass may have one or more windows associated with it. These are used as an interface for loading and saving a representation of your document type. Each window will have an “NSWindowController” instance associated with it, where NSDocument maintains a list of these.&lt;br /&gt;
&lt;br /&gt;
==== NSDocumentController ====&lt;br /&gt;
&lt;br /&gt;
This class acts a controller. It maintains a list of documents (instances of your NSDocument subclass) and is responsible for loading and instantiating new documents. It is usually not necessary to implement a subclass of this, but often it may be useful to implement special functionality (especially related to opening and creating documents at an application level).&lt;br /&gt;
&lt;br /&gt;
==== NSWindowController ====&lt;br /&gt;
&lt;br /&gt;
As mentioned above, NSWindowController instances are individually associated with one NSWindow instance, in such a way that a document maintains a list of window controllers that are reponsible for rendering the views associated with a document.&lt;br /&gt;
&lt;br /&gt;
You will most likely not have to subclass NSWindowController. Instead, you associate a nib file (the Gorm output) with the subclass of NSDocument, and NSDocumentController will load this nib file for each document that is created or loaded.&lt;br /&gt;
&lt;br /&gt;
For example, a text based application that is used for the editing of plain text files, may subclass NSDocument with a TextDocument class. Each instance of this class would have an NSWindowController instance associated with it, which in turn manages a window instance that is instantiated from a nib file. The NSDocumentController instance, as managed and instantiated by GNUstep, would be responsible for loading and saving documents in your application. It even prompts the user to save their documents when they try to quit the application.&lt;br /&gt;
&lt;br /&gt;
== File Components ==&lt;br /&gt;
&lt;br /&gt;
In building your application you will need to create a number of special files. From scratch, the following should be a rough guide to getting it working. These include the Makefile, your application's property list and the interface files.&lt;br /&gt;
&lt;br /&gt;
=== The Makefile ===&lt;br /&gt;
&lt;br /&gt;
For this type of application, no special makefile is needed: it just has to be a normal application. Project Builder should be able to spit out the required makefile and Gorm files that are needed for a generic application. I believe it is also capable of providing support for document-based applications. Otherwise use the following as a template:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''GNUmakefile'''&lt;br /&gt;
&lt;br /&gt;
 include $(GNUSTEP_MAKEFILES)/common.make&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 APP_NAME = DocumentApp&amp;lt;br&amp;gt;&lt;br /&gt;
 DocumentApp_OBJC_FILES =&amp;lt;br&amp;gt;&lt;br /&gt;
  MyDocument.m &amp;lt;br&amp;gt;&lt;br /&gt;
  main.m&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 DocumentApp_RESOURCES = \ &amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/Info-gnustep.plist \&amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/DocumentApp.gorm \&amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/MyDocument.gorm&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 -include GNUmakefile.preamble&amp;lt;br&amp;gt;&lt;br /&gt;
 include $(GNUSTEP_MAKEFILES)/application.make&amp;lt;br&amp;gt;&lt;br /&gt;
 -include GNUmakefile.postamble&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For more information as to customising this file, as well as setting up compiler options for third party libraries and includes, see the GNUstep makefile manual.&lt;br /&gt;
&lt;br /&gt;
===The application dictionary===&lt;br /&gt;
&lt;br /&gt;
For those that have edited this file in their project before, it is a dictionary with various values entered. For our purposes, we need an array within the main dictionary, called &amp;quot;NSTypes&amp;quot;. This is a array of unnamed dictionaries, with one dictionary for each type. &lt;br /&gt;
&lt;br /&gt;
I have provided an example for this file below. ProjectBuilder creates one as well. Please note that &amp;quot;TextEdit&amp;quot; does exist as an example application from NEXT I think, and again on MacOS X but I have constructed a much simpler version, used only for plain text files.&lt;br /&gt;
&lt;br /&gt;
Taking a look at the single dictionary entry in the NSTypes array, the following key-value pairs are needed:&lt;br /&gt;
* '''NSDocumentClass:''' This is (string) the subclass name you use in your code, the &amp;quot;objective-c name&amp;quot; of your document subclass. This is used by NSDocumentController's default implementation to create instances of your document type.&lt;br /&gt;
* '''NSName:''' The generic file type (string). This is completely arbitrary, and can be anything you like. For the purpose of conventions, it may be more appropriate not to use the &amp;quot;NS&amp;quot; or &amp;quot;GS&amp;quot; prefix (the latter of which I not sure), and instead use either your own, or no prefix at all.&lt;br /&gt;
* '''NSHumanReadableName:''' The human readable name of your document type (string)? TODO: explain where this is used.&lt;br /&gt;
* '''NSUnixExtensions:''' An array of strings, each containing a file extension connected to this document type on &amp;quot;unix&amp;quot; platforms. TODO: explain how &amp;quot;unix&amp;quot; is interpreted by GNUstep.&lt;br /&gt;
* '''NSDOSExtensions:''' An array of strings, each containing a file extenstion connected to this document type on &amp;quot;DOS&amp;quot; platforms (could be loosely interpreted as any MS platforms GNUstep runs on, i.e. Windows 2000/XP).&lt;br /&gt;
* '''NSRole:''' A string, either &amp;quot;Viewer&amp;quot; or &amp;quot;Editor&amp;quot;, depending on how your document operates on this file type.&lt;br /&gt;
* '''NSIcon:''' A icon name associated with this document type. TODO: Investigate how this works.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Info-gnustep.plist'''&lt;br /&gt;
 {&lt;br /&gt;
     ApplicationDescription = &amp;quot;A simple text editor for GNUstep.&amp;quot;;&lt;br /&gt;
     ApplicationName = TextEdit;&lt;br /&gt;
     ApplicationRelease = 0.10;&lt;br /&gt;
     Authors = ( &amp;quot;Christopher Armstrong&amp;quot; );&lt;br /&gt;
     Copyright = &amp;quot;Copyright (C) 2005 Christopher Armstrong&amp;quot;;&lt;br /&gt;
     CopyrightDescription = &amp;quot;Released under GPL.&amp;quot;;&lt;br /&gt;
     FullVersionID = 0.10;&lt;br /&gt;
     NSExecutable = TextEdit;&lt;br /&gt;
     NSMainNibFile = TextEdit.gorm;&lt;br /&gt;
     NSPrincipalClass = NSApplication;&lt;br /&gt;
     NSRole = Application;&lt;br /&gt;
     NSTypes = (&lt;br /&gt;
         {&lt;br /&gt;
                 NSDocumentClass = &amp;quot;TextDocument&amp;quot;;&lt;br /&gt;
                 NSName = &amp;quot;GSTextDocumentType&amp;quot;;&lt;br /&gt;
                 NSHumanReadableName = &amp;quot;Text Document&amp;quot;;&lt;br /&gt;
                 NSUnixExtensions = ( &amp;quot;txt&amp;quot;, &amp;quot;&amp;quot; );&lt;br /&gt;
                 NSDOSExtensions = ( &amp;quot;txt&amp;quot; );&lt;br /&gt;
                 NSRole = Editor;&lt;br /&gt;
         }&lt;br /&gt;
     );&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For more information on property list files, consult [[Property Lists]].&lt;br /&gt;
&lt;br /&gt;
=== Interface files ===&lt;br /&gt;
&lt;br /&gt;
Two interface files are needed: one for your main application, and another that will be instantiated with each instance of your document subclass. These both should be listed as resources in your makefile, (as shown the GNUmakefile example above). It may be helpful to name the document nib file after your class.&lt;br /&gt;
&lt;br /&gt;
==== Application Interface File ====&lt;br /&gt;
&lt;br /&gt;
The application one should just be a menu (though it could be more if necessary). When constructing it, take the following into account:&lt;br /&gt;
&lt;br /&gt;
* Use a standard Gorm template for an Application.&lt;br /&gt;
* Delete the window instance in the &amp;quot;Objects&amp;quot; pane (unless you need a main window, which is beyond the scope of this document).&lt;br /&gt;
* Set NSOwner's class to &amp;quot;NSDocumentController&amp;quot;. This is the custom class option of NSOwner in the property inspector. This ensures that the openDocument:, newDocument: messages, as sent to NSFirst, get picked up by NSDocumentController. Do not instantiate it (I believe you can't anyway).&lt;br /&gt;
* If you intend to subclass NSDocumentController, subclass it in the Classes pane. To make sure that this class is instantiated and used, make sure you instantiate it in Gorm or in your main.m file, and set NSOwner to be your subclass.&lt;br /&gt;
* Drag a Document menu from the palette onto your main menu. This already has the proper outlet and action linkage for each relevant message to be directed to NSFirst. Generic messages (such as openDocument:, not associated with any document instance) are forwarded to the shared instance of NSDocumentController (see it's reference documentation). When a document is active, more specific messages (such as close: or saveDocument:) are forwarded to the relevant document instance of your NSDocument subclass.&lt;br /&gt;
* Add any appropriate menus such as &amp;quot;Info&amp;quot; and &amp;quot;Format&amp;quot; which may be relevant to your application.&lt;br /&gt;
&lt;br /&gt;
==== Document Interface File(s) ====&lt;br /&gt;
&lt;br /&gt;
The document interface file is a window containing the view(s) required for the implementation of one instance of your document type. For example, in the case of a TextDocument type, a window instance with a NSTextView drawn on it is used for each document window. This interface file is instantiated every time a person creates a new document (the newDocument: message goes to NSDocumentController) or opens an existing document (openDocument:).&lt;br /&gt;
&lt;br /&gt;
You will need to:&lt;br /&gt;
* '''Subclass NSDocument''' with your document type in Gorm. This is done in a couple of ways, see [[Gorm_Manual#Custom_classes|custom classes]].&lt;br /&gt;
* '''Set NSOwner:''' Set your subclass as NSOwner's Custom class using the Property Inspector). DO NOT INSTANTIATE IT.&lt;br /&gt;
&lt;br /&gt;
Another thing that you may want to consider is custom outlets. If you place certain views or controls on your window (including the window itself), you may want to refer to them directly in your code, e.g. the NSTextView in our TextEdit example is accessed directly, so that we can save it's contents to a file. To enable this, we add outlets to our class (see [[Gorm_Manual#Custom_classes|custom classes]]). We then connect NSOwner to the appropriate controls/views, and select the outlets in the Connections Property Inspector (see [[Gorm_Manual#Editing_the_interface|editing the interface]]).&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
Various things need to be done at a code level, to ensure that your NSDocument subclass is properly instantiated. This section aims to tell you what is necessary.&lt;br /&gt;
&lt;br /&gt;
=== NSDocument subclass ===&lt;br /&gt;
&lt;br /&gt;
When creating your subclass, you may have chosen to have Gorm create the class files. If not, you should create two files for your subclass: a header (.h) file and an implementation file (.m). The header file should take the following layout (we're using the TextEdit example again):&lt;br /&gt;
&lt;br /&gt;
 #ifndef TEXTDOCUMENT_H&lt;br /&gt;
 #define TEXTDOCUMENT_H &amp;lt;br&amp;gt;&lt;br /&gt;
 #include &amp;lt;AppKit/AppKit.h&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
 @class NSDocument; &amp;lt;br&amp;gt;&lt;br /&gt;
 /* The document type string, as specified in the property list [[#The_application_dictionary|NSTypes array]] */ &amp;lt;br&amp;gt;&lt;br /&gt;
 NSString * GSTextDocumentType = &amp;quot;GSTextDocumentType&amp;quot;;&lt;br /&gt;
 @interface TextDocument : NSDocument&lt;br /&gt;
 {&lt;br /&gt;
 @protected&lt;br /&gt;
     /* Outlets we added in our Gorm nib file */&lt;br /&gt;
     id * textView;&lt;br /&gt;
 }&lt;br /&gt;
 /* Basic methods used for loading and saving document data (respectively). */&lt;br /&gt;
 - (BOOL) loadDataRepresentation:(NSData*)representation ofType:(NSString*)type;&lt;br /&gt;
 - (NSData*) dataRepresentationOfType: (NSString*)type; &amp;lt;br&amp;gt;&lt;br /&gt;
 /* Information and events handling of GUI related changes */&lt;br /&gt;
 - (NSString*) windowNibName;&lt;br /&gt;
 - (void) windowControllerDidLoadNib:(NSWindowController*)windowController; &amp;lt;br&amp;gt;&lt;br /&gt;
 @end&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Firstly, take note that we inherit from NSDocument. As a result, we need to override some methods for a basic (but working) implementation. &lt;br /&gt;
&lt;br /&gt;
==== loadDataRepresentation:ofType: and dataRepresentationOfType: ====&lt;br /&gt;
&lt;br /&gt;
The methods, loadDataRepresent:ofType: and dataRepresentationOfType: are used by NSDocumentController to load and save our files. The first method is called when the user trys to open a document (NSDocumentController gets the file name and copies it's data using an open panel). The method is passed the raw data in this file, as well as a string representing its type. It is important to note that this type string is the same one used in your property list. It is used by NSDocumentController to tell you what type it thinks you should open the data with. If this is not possible, or if there is an error trying to parse the data, your method returns FALSE/NO. Otherwise, you should store a local, meaningful representation of the data, which you can insert into your document window a little later (and return TRUE/YES).&lt;br /&gt;
&lt;br /&gt;
For example, in terms of the TextEdit example:&lt;br /&gt;
 - (BOOL) loadDataRepresentation:(NSData*) representation ofType:(NSString*)type&lt;br /&gt;
 {&lt;br /&gt;
    /*Check type information */&lt;br /&gt;
    if ([representation equalTo:GSTextDocumentType]==NO)&lt;br /&gt;
        return NO;&lt;br /&gt;
    /* Clean out our old representation if it still exists */&lt;br /&gt;
    if (fileContents) RELEASE(fileContents); &amp;lt;br&amp;gt;&lt;br /&gt;
    /* Allocate room for the new data, and try to initialise a string with it. */&lt;br /&gt;
    self-&amp;gt;fileContents = [NSString alloc];&lt;br /&gt;
    fileContents = [fileContents initWithBytes: [representation bytes]&lt;br /&gt;
                         length: [representation length]&lt;br /&gt;
                       encoding: NSASCIIStringEncoding]; &amp;lt;br&amp;gt;&lt;br /&gt;
    /* If this can't be done, return NO */&lt;br /&gt;
    if (!fileContents)&lt;br /&gt;
        return NO; &amp;lt;br&amp;gt;&lt;br /&gt;
    /* Otherwise, set our TextView to the string data. */&lt;br /&gt;
    [self-&amp;gt;textView setString: fileContents];&lt;br /&gt;
    return YES;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
If this is not sufficient, or if your program can open the data in a more efficient manner, it may be worth looking into overriding -initWithContentsOfFile:ofType: and -initWithContentsOfURL:ofType:. Again, see the GUI manual for more details.&lt;br /&gt;
&lt;br /&gt;
dataRepresentationOfType: is used to save the data. Your method is expected to return an instance of NSData that contains what should be saved to a file, for the type specified. Again, the ''type'' variable should be checked to ensure that you can write data of that type. Return nil if the file cannot be saved as that type.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
 - (NSData*) dataRepresentationOfType:(NSString*)type&lt;br /&gt;
 {&lt;br /&gt;
     if ([type equalTo:GSTextDocumentType]==NO)&lt;br /&gt;
         return nil; &amp;lt;br&amp;gt;&lt;br /&gt;
     NSData stringData =  [[textView string] dataUsingEncoding:NSASCIIStringEncoding];  &lt;br /&gt;
     return stringData; &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
If a more sophisticated save implementation is needed, consult the documentation for information on the writeTo* methods.&lt;br /&gt;
&lt;br /&gt;
==== windowNibName ====&lt;br /&gt;
&lt;br /&gt;
This method must be overriden to return the a string of the name of your nib file (without the file extension). More complex implementations will use other methods to load the interface files. TODO: information on what methods need to be overriden.&lt;br /&gt;
&lt;br /&gt;
==== windowControllerDidLoadNib: ====&lt;br /&gt;
&lt;br /&gt;
Use this method to add code that should be run as soon as ''windowController'' has been initialised. Your document may have many window controllers; each window controller taking possession of one window.&lt;br /&gt;
&lt;br /&gt;
In the TextEdit example, this method is used to copy the ''fileContents'' variable to the text view. It otherwise initialises the document window. &lt;br /&gt;
&lt;br /&gt;
Also note that you can override windowControllerWillLoadNib: to perform pre-interface loading initialisation.&lt;br /&gt;
&lt;br /&gt;
==== makeWindowControllers ====&lt;br /&gt;
&lt;br /&gt;
This is an optional method to override, which must be used if you have multiple window controllers per document. It is responsible for creating each window controller from it's interface file and then adding it to the document. Use the addWindowController: method.&lt;br /&gt;
&lt;br /&gt;
==== Other considerations ====&lt;br /&gt;
&lt;br /&gt;
* You need a way to notify NSDocument that your document has changed, so that NSDocumentController can enable the menu item to allow saving. This is done by a call to the updateChangeCount: method. For example, the TextDocument class adds itself as a delegate to the textView, for any notification of changes. It then calls updateChangeCount: in the delegate's method.&lt;br /&gt;
&lt;br /&gt;
* You may also wish to add a close: method (not the close method already in NSDocument, see below) to respond to the menu item permitting your document to close. This could perform cleanup operations before a call to [self close] is made e.g.&lt;br /&gt;
&lt;br /&gt;
 - (void) close:(id)sender /* Note this is not the method found in NSDocument (they differ by a parameter) */&lt;br /&gt;
 {&lt;br /&gt;
     [self close];&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== NSDocumentController ===&lt;br /&gt;
&lt;br /&gt;
This class can optionally be subclassed, to implement some specific functionality. For example, programs handling multiple document types may override newDocument: to create a window so that the user can select which document type to create.&lt;br /&gt;
&lt;br /&gt;
You should use separate implementation files and add the .m file to GNUmakefile.&lt;br /&gt;
&lt;br /&gt;
=== NSWindowController ===&lt;br /&gt;
&lt;br /&gt;
This class can also be optionally subclassed, to implement functionality specific to a window controller for a document type. You may need to override makeWindowControllers: in the NSDocument subclass in order to make sure your specific window controller is instantiated.&lt;br /&gt;
&lt;br /&gt;
You should use separate implemenation files and add the .m file to GNUmakefile.&lt;br /&gt;
&lt;br /&gt;
== Optional Additions ==&lt;br /&gt;
&lt;br /&gt;
=== Custom NSDocumentController and NSWindowController implementations ===&lt;br /&gt;
&lt;br /&gt;
See [[#NSWindowController|NSWindowController]] and [[#NSDocumentController|NSDocumentController]].&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Application_wish_list&amp;diff=1992</id>
		<title>Application wish list</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Application_wish_list&amp;diff=1992"/>
		<updated>2005-07-27T03:08:54Z</updated>

		<summary type="html">&lt;p&gt;Quineska: /* Printer.app */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;What applications do you want for GNUstep? Add below:&lt;br /&gt;
(Please check [All GNUstep Applications] before adding)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Old NeXTSTEP/OPENSTEP apps: http://www.levenez.com/NeXTSTEP/meApps.html&lt;br /&gt;
&lt;br /&gt;
__Frontend for different platform to www.granddictionnaire.com__&lt;br /&gt;
&lt;br /&gt;
-------------------------------&lt;br /&gt;
&lt;br /&gt;
== Keyboard switcher application ==&lt;br /&gt;
&lt;br /&gt;
== Web browser ==&lt;br /&gt;
&lt;br /&gt;
Seems to be a popular request :).&lt;br /&gt;
&lt;br /&gt;
* Could [http://www.mozilla.org/projects/camino/ Camino] (formerly known as Chimera) be the one (after backporting)?&lt;br /&gt;
* [http://www.apple.com/safari/ Apple's Safari] web browser uses KHTML and KJS software from the KDE open source project, updated and re-released [http://developer.apple.com/darwin/projects/webcore/index.html here], but needs Objective-C++ support in GCC.&lt;br /&gt;
-- Hasan --&lt;br /&gt;
&lt;br /&gt;
* I could port [http://ibn.com/~hdiwan/orchidWeb.html OrchidWeb] to GNUStep. I'd just need enough examples on developing the views from code to {do it.&lt;br /&gt;
Apparently, camino is written in Objective-C++, which GCC can't compile (although Apple is supposed to have contibuted the patch). Until gcc can compile mixed obj-c and c++, it can't be ported. There is a thread about this at [http://linuxfr.org/2003/03/10/11647.html] (it's in french).&lt;br /&gt;
* This seems very close... Stefan has began porting [http://mac.wms-network.de/gnustep/WebCore/blog/ Webcore to GNUstep]. Still some way to go, but a great breaktrough. This seems to be the most probable answer to the web browser request.&lt;br /&gt;
&lt;br /&gt;
== Project Management app ==&lt;br /&gt;
&lt;br /&gt;
Something like [http://mrproject.codefactory.se/screenshots.php MrProject]. It has to be simple, not overbloated as MS Project.&lt;br /&gt;
&lt;br /&gt;
== Google.app ==&lt;br /&gt;
&lt;br /&gt;
* Complete with ApplicationServices&lt;br /&gt;
* WebBrowser integration&lt;br /&gt;
* Using proper NS* classes for HTML retrieval&lt;br /&gt;
* Ability to select which Google server (www.google.ca, www.google.co.jp)&lt;br /&gt;
* Google News, Google Groups, Google Images too.&lt;br /&gt;
&lt;br /&gt;
== DMG.app? ==&lt;br /&gt;
&lt;br /&gt;
* Installer/extractor/viewer for DMG images.&lt;br /&gt;
* Create DMG packages&lt;br /&gt;
* Useful for OSX source packages&lt;br /&gt;
&lt;br /&gt;
''Note:'' The DMG format is Apple proprietary and undocumented. Basically, DMG support is only available under OSX and its unlikely to change.&lt;br /&gt;
&lt;br /&gt;
== Blender ==&lt;br /&gt;
&lt;br /&gt;
Blender has recently (since October 2002) gone GPL. Consisting of porting the Blender GUI/WM abstract library GHOST, using NSOpenGLContext, or a CoreGraphics implementation one day. Objective-C++ might be needed for implementing GHOST, but probably can be worked around easily enough. There is an OSX port, probably using CoreGraphics.&lt;br /&gt;
&lt;br /&gt;
[http://www.blender.org/ Blender Foundation Homepage]&lt;br /&gt;
&lt;br /&gt;
Most of Blender is written in C++ doesn't seem to use CoreGraphics but Apple's GL.&lt;br /&gt;
&lt;br /&gt;
== CSS/html editor ==&lt;br /&gt;
&lt;br /&gt;
A cool html/css editor - emphasis on the css structural side.&lt;br /&gt;
&lt;br /&gt;
Object oriented properties application to CSS element definitions, and insert those properties into HTML in web pages. Don't worry about WYSIWIG - that's what web browsers are for, displaying web pages. Just make a object-oriented CSS/HTML editor.&lt;br /&gt;
&lt;br /&gt;
Maybe port [http://www.w3.org/People/Berners-Lee/WorldWideWeb.html Nexus] for that?&lt;br /&gt;
&lt;br /&gt;
== OmniGraffle clone ==&lt;br /&gt;
&lt;br /&gt;
(I don't really know what this is, but people have said they want one. Someone please add a description! :)&lt;br /&gt;
&lt;br /&gt;
This is for diagram, UML ....&lt;br /&gt;
I 'm thinking to write it. But not *right now*.&lt;br /&gt;
It will have probably a Gorm-feel&lt;br /&gt;
&lt;br /&gt;
[http://www.omnigroup.com/applications/omnigraffle/ OmniGraffle] was a clone of Lighthouse Design's Diagram.app, which was a re-working of the NeXT Developer Example Sketch.app, adding rubber-banding / angular connection lines.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== OmniOutliner clone ==&lt;br /&gt;
&lt;br /&gt;
This is a really cool app which can be used for anything. Mostly i think it is used to organise your minds while being creative (some kind of knowledge manager).&lt;br /&gt;
&lt;br /&gt;
The inspiration for this was Jayson Adams' Millennium Software's NoteBook.app, which lives again as the (commercial) program [http://www.aquaminds.com/ NoteTaker].&lt;br /&gt;
&lt;br /&gt;
== A text editor ==&lt;br /&gt;
&lt;br /&gt;
A simple text editor that can read and write plain or rich text, including both simple word processing functionality (nothing too splashy, like frames) and optional programming features (like syntax highlighting -- not just coloring; controllable tabs; tab v. space indentation, multiple language support). Programming features could be provided by a bundle, but it would be good to for the app to be designed with that bundle in mind.&lt;br /&gt;
&lt;br /&gt;
This editor which is to guarantee me world domination includes a split view where the other pane locates and displays the corresponding end-tag/start-tag when programming.&lt;br /&gt;
&lt;br /&gt;
Ink is not that editor. :)&lt;br /&gt;
&lt;br /&gt;
[http://www.softpanorama.org/Editors/index.shtml Softpanorama] seems to give a good overview of editors&lt;br /&gt;
&lt;br /&gt;
''We have to distinguish between a text editor as programming tool (CodeEditor.app) and a text editor as a word processor (WordProcessor.app?). '' They are two different approaches to text editing and text processing.&lt;br /&gt;
&lt;br /&gt;
Source code editing view and associated inspector panels and preferences should be provided as a framework, so the SourceView should be reused in other apps. CodeEditor should be only some default wrapper for that framework.&lt;br /&gt;
&lt;br /&gt;
WordProcessor.app sould be an application that extends NSText system. (With easy-to-use paragraph style editing)&lt;br /&gt;
&lt;br /&gt;
How about interfacing with [http://www.scintilla.org Scintilla]?&lt;br /&gt;
-- Hasan --&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== A simple DTP application ==&lt;br /&gt;
&lt;br /&gt;
A simple frame-based application for desktop publishing. Something like [http://www.calamus.net/ Calamus] ([http://www.calamus.net/man/index_us.htm here] is the documentation of tools and modules). Nothing fancy, just application that can lay out frames, control text flow, use paragraph styles and master pages.&lt;br /&gt;
&lt;br /&gt;
I'd rather see TeXView.app come back myself.... I think it's far more feasible (doing a decent page layout app is _hard_ just as Donald E. Knuth). Perhaps better still would be to take advantage of LyX's ``GUI-independence'' and provide a GNUstep front-end for it, http://www.lyx.org .&lt;br /&gt;
&lt;br /&gt;
No, nothing like LyX or TeX. I have in mind a ''visual'' page layout editing tool with features as described above (similar to PageMaker). LyX and TeX are a bit different approaches and should be alternatives to Frame based DTP application.&lt;br /&gt;
&lt;br /&gt;
 - Stefan&lt;br /&gt;
&lt;br /&gt;
I think a heavy-weight drawing package w/ page layout features would be a better solution here (this is the workflow I'm using on my NeXT Cube now), then it could be tied into an XML-based workflow in a fashion like to Apple's new Keynote, perhaps in a fashion like to Pages-by-Pages. To describe my workflow a bit---I now use Altsys Virtuoso on my NeXT Cube w/ Omega (Unicode-aware TeX variant) for most of my page layout. IME, if a document gets too large to manage w/ Altsys Virtuoso, it might as well go into TeX... Not that I'd mind seeing a replacement for PasteUp.app, I just think that a drawing program is more immediately important / useful.&lt;br /&gt;
&lt;br /&gt;
For simple DTP utility, I'd dearly love to see a re-creation of [http://members.aol.com/willadams/gnustep/apps/type/touchtype.html TouchType.app]&lt;br /&gt;
&lt;br /&gt;
 - William&lt;br /&gt;
&lt;br /&gt;
Maybe you should take a look at [http://www.texmacs.org/ TeXmacs]. Looks promising and is in great need of a GNUstep frontend.&lt;br /&gt;
&lt;br /&gt;
 - david.&lt;br /&gt;
&lt;br /&gt;
Interesting. I'd seen TeXMacs mentioned on comp.text.tex quite often, but hadn't realized it had gotten as far as it had. Interesting counterpoint to LyX.&lt;br /&gt;
 - William&lt;br /&gt;
&lt;br /&gt;
One really interesting thing would be to have a fame class which would useful enough so it could be used to put together a simple DTP Application but which would be flexible enough that it could be available to any application - the text control is a standard control for windows managers like MS Windows or Gnome. If there were an equivalent &amp;quot;flowing graphic control&amp;quot;, you'd have a powerful building block indeed (note that in MS windows, the text control is actually poor enough that no credible application can built around besides notepad).&lt;br /&gt;
Also, for a programming text editor, scintilla is great. One thing to consider is that for DTP/HTML editor, what you would want would be a *superset* of the scintilla interface. It would be great to add all the different features in such a way that you didn't have interfaces duplicating each other's functionalities.&lt;br /&gt;
&lt;br /&gt;
-- JosephSolbrig&lt;br /&gt;
&lt;br /&gt;
== Painting app (photoshop) ==&lt;br /&gt;
&lt;br /&gt;
Bitmap drawing app.&lt;br /&gt;
&lt;br /&gt;
Think Photoshop, not [http://www.gimp.org/ The Gimp].&lt;br /&gt;
&lt;br /&gt;
In fact, forget that. Something new.&lt;br /&gt;
&lt;br /&gt;
Something usable - can do Photoshop, but easy to learn. The Gimp can nearly do photoshop, but who can use it?&lt;br /&gt;
&lt;br /&gt;
It would be great if it consisted of two parts - a very small very useful image viewer/manager (eg gqview) and the actual editor plugin (the big part). So installing image-core would give a very small useful app, then adding image-edit would make it into photoshop.&lt;br /&gt;
&lt;br /&gt;
When opening an image file eg by clicking on it or running image-core thefile.jpg then only the core apps should start, so it starts real quick. If i right-click and choose edit or something .. THEN the other stuff is pulled in.&lt;br /&gt;
&lt;br /&gt;
Or whatever. Just an idea. But makes development path cool. Could also have a vector plugin, or whatever.&lt;br /&gt;
&lt;br /&gt;
Maybe we should wait, when (if?) Gimp gets '[http://gegl.org/ gegl]'ed.&lt;br /&gt;
then having a decent photoshop like app would be as simple as writing a gui for the gegl foundation.&lt;br /&gt;
+ gives us a nice featureset + plugins!&lt;br /&gt;
&lt;br /&gt;
Maliwan project is aiming to achieve the same goal of GEGL. Right now GEGL isn't even half complete but we can still reimplement it base on GEGL's design. lastlife is waiting for you in irc if you want to discuss the idea. Maliwan is planned to be the heart of the BluTulip which is the actual application.&lt;br /&gt;
&lt;br /&gt;
== Calendar ==&lt;br /&gt;
&lt;br /&gt;
check  SKYRIX libs (Opengroupware).&lt;br /&gt;
 http://www.opengroupware.org/cvsweb/cvsweb.cgi/OpenGroupware.org/SOPE/skyrix-core/NGiCal/&lt;br /&gt;
&lt;br /&gt;
== CVS app ==&lt;br /&gt;
&lt;br /&gt;
Port CVL&lt;br /&gt;
&lt;br /&gt;
== Task management app ==&lt;br /&gt;
&lt;br /&gt;
Chronographer (lobbying by ludovic) + libical&lt;br /&gt;
or&lt;br /&gt;
~TaskManager (lobbying by Fabien) + libical&lt;br /&gt;
&lt;br /&gt;
Check SKYRIX libs (Opengroupware)&lt;br /&gt;
&lt;br /&gt;
== ICQ ==&lt;br /&gt;
&lt;br /&gt;
and other instant messengers.&lt;br /&gt;
check http://freshmeat.net/projects/fireapp/&lt;br /&gt;
&lt;br /&gt;
== DatabaseModeller.app ==&lt;br /&gt;
&lt;br /&gt;
See [[DBModeler]], currently a work in progress.&lt;br /&gt;
&lt;br /&gt;
== Database management ==&lt;br /&gt;
&lt;br /&gt;
A desktop software (Like [http://www.flex.ro/pgaccess/ PgAccess] for example) to manage database. This program could use the GDL2 (Gnustep Database Library). It could be a good exercice and demonstration of this very good library.&lt;br /&gt;
&lt;br /&gt;
== Video conferencing software ==&lt;br /&gt;
&lt;br /&gt;
There's [http://www.gnomemeeting.org/ Gnomemeeting] (excellent piece of software), but I don't like Gnome too much (all those dependencies).&lt;br /&gt;
&lt;br /&gt;
Update: Gnomemeeting 0.9.6 is supposed to work without Gnome libs (limited functionality).&lt;br /&gt;
&lt;br /&gt;
== CronniX - A cron front end ==&lt;br /&gt;
&lt;br /&gt;
http://www.koch-schmidt.de/cronnix/&lt;br /&gt;
&lt;br /&gt;
That won't be easily portable, as different OSs use a different cron setup. Eg. BSD has (and uses) both, /etc/crontab __and__ /var/cron/tabs/&amp;lt;username&amp;gt; ...&lt;br /&gt;
&lt;br /&gt;
== PfaEdit - A font editor ==&lt;br /&gt;
&lt;br /&gt;
(This is now called FontForge)&lt;br /&gt;
&lt;br /&gt;
http://pfaedit.sourceforge.net&lt;br /&gt;
&lt;br /&gt;
Actually, Cenon (see above) is able to do some limited font editing. Not to knock pfaedit, I use it a lot and think it's a way cool program. Wonder if the two could be merged somehow.&lt;br /&gt;
&lt;br /&gt;
== GuileServices / StepTalk Services ==&lt;br /&gt;
&lt;br /&gt;
On NeXTSTEP there was an application (service?) called [TickleServices|http://www.doubleu.com/TickleServices.html] that allowed you to write your own services in the Tcl language. Something along these lines, but using guile/steptalk would be a nice addition to gnustep.&lt;br /&gt;
&lt;br /&gt;
== Printer.app ==&lt;br /&gt;
&lt;br /&gt;
An application/framework for managing printers, printer properties and print queues. (CUPS frontend?) (NOTE: To an extent, GNUstep already has CUPS support, and has number of builtin classes and panels for managing printers and printer settings. They may just need to be extended a little for different uses and environments.)&lt;br /&gt;
&lt;br /&gt;
== DivX/XViD/DVD/VCD Player ==&lt;br /&gt;
&lt;br /&gt;
I see that there was at least an attempt to port mplayer at one point but it seems to be dead. Maybe VLC (http://www.videolan.org/) which does have an OSX version, could be ported.&lt;br /&gt;
&lt;br /&gt;
== Abiword (Word Processor) ==&lt;br /&gt;
&lt;br /&gt;
A port of the Cocoa version of [AbiWord|http://www.abisource.com] would be great, considering a word processor is a pretty vital application, and that Abiword is a pretty good one.&lt;br /&gt;
&lt;br /&gt;
== Spreadsheet ==&lt;br /&gt;
&lt;br /&gt;
A spreadsheet application would be great for GNUstep.  A clone of Lotus Improv or Lighthouse Design's Parasheet would be a nice thing for GNUstep to have.&lt;br /&gt;
&lt;br /&gt;
== Pixen (Pixel Art Tool) ==&lt;br /&gt;
&lt;br /&gt;
[Pixen|http://www.opensword.org] is a decent, open source pixel art tool and there aren't alot of free or professional programs like it. There is also a compliment tool by the same guys for mapping called Reptile.&lt;br /&gt;
&lt;br /&gt;
We're working on a GNUstep port now, in fact.&lt;br /&gt;
&lt;br /&gt;
== Growl! (Global notification system) ==&lt;br /&gt;
&lt;br /&gt;
[http://growl.info/ Growl!] uses distributed notification center to display a graphic message on screen. Every application can send messages to it, for example, when new emails arrive, buddies sign in the instant messager, a task end, etc. It is very easy to implement.&lt;br /&gt;
&lt;br /&gt;
== Digital Librarian-like ==&lt;br /&gt;
&lt;br /&gt;
I would really, really like a Digital Librarian for GNUstep. Basically, imagine an application that manage your documents the same way iTunes manage your music or iPhoto your photos... (to take well-known OSX apps as example ;-)&lt;br /&gt;
&lt;br /&gt;
It would provide 1) automatic management of the documents by projects/ideas/whatever metadata 2) index your documents to let you search quickly in it 3) handles bibliography&lt;br /&gt;
As a postgrad student I have a LOT of articles in PDF/PS/DVI/html on my hard drive, and such an application would be really nice to help managing that.&lt;br /&gt;
&lt;br /&gt;
A Digital Librarian screenshot: http://www.levenez.com/NeXTSTEP/Librarian.jpg&lt;br /&gt;
A screenshot of Vertex Librarian, a similar program for NeXTSTEP: http://www.levenez.com/NeXTSTEP/VertexLibrarian.jpg&lt;br /&gt;
&lt;br /&gt;
== nib2gmodel/nib2gorm without OPENSTEP/MacOSX ==&lt;br /&gt;
&lt;br /&gt;
I want;but I heard it is so hard to implementation. :-(&lt;br /&gt;
&lt;br /&gt;
== iTunes/Rhythmbox clone ==&lt;br /&gt;
&lt;br /&gt;
It would be nice to see a music or video player with real music/media management like [http://www.gnome.org/projects/rhythmbox/ Rhythmbox] or [http://www.apple.com/itunes/ iTunes]. iTunes has started to support management of movies and videoclips, so maybe media management is the way to go?&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Creating_document_based_applications&amp;diff=874</id>
		<title>Creating document based applications</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Creating_document_based_applications&amp;diff=874"/>
		<updated>2005-07-09T02:18:37Z</updated>

		<summary type="html">&lt;p&gt;Quineska: Spelling errors, grammatical fixes&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Note: First version; subject to further revisions and changes.&lt;br /&gt;
--[[User:Quineska|ChrisArmstrong]] 07:09, 7 Jul 2005 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
OpenStep can provide your application a document-based model. It helps to simplify the process of creating such applications. GNUstep implements this as well; this document aims to provide an overview of what is required in the creation and design of such an application.&lt;br /&gt;
&lt;br /&gt;
It is assumed you are familiar with GNUstep, and have some understanding as how to create Gorm's interface files (often referred to as nib's), as well as some understanding of how they work.&lt;br /&gt;
&lt;br /&gt;
Importantly, such applications have certain components that are required, and should be considered as part of their design. When programming, classes that will be used as part of the AppKit are:&lt;br /&gt;
&lt;br /&gt;
==== NSDocument ====&lt;br /&gt;
&lt;br /&gt;
This class is central to the OpenStep document based model. These application's declare a new instance of a subclass of NSDocument for each “document” that is opened. You will subclass NSDocument to implement this.&lt;br /&gt;
&lt;br /&gt;
Each instance of your NSDocument subclass may have one or more windows associated with it. These are used as an interface for loading and saving a representation of your document type. Each window will have an “NSWindowController” instance associated with it, where NSDocument maintains a list of these.&lt;br /&gt;
&lt;br /&gt;
==== NSDocumentController ====&lt;br /&gt;
&lt;br /&gt;
This class acts a controller. It maintains a list of documents (instances of your NSDocument subclass) and is responsible for loading and instantiating new documents. It is usually not necessary to implement a subclass of this, but often it may be useful to implement special functionality (especially related to opening and creating documents at an application level).&lt;br /&gt;
&lt;br /&gt;
==== NSWindowController ====&lt;br /&gt;
&lt;br /&gt;
As mentioned above, NSWindowController instances are individually associated with one NSWindow instance, in such a way that a document maintains a list of window controllers that are reponsible for rendering the views associated with a document.&lt;br /&gt;
&lt;br /&gt;
You will most likely not have to subclass NSWindowController. Instead, you associate a nib file (the Gorm output) with the subclass of NSDocument, and NSDocumentController will load this nib file for each document that is created or loaded.&lt;br /&gt;
&lt;br /&gt;
For example, a text based application that is used for the editing of plain text files, may subclass NSDocument with a TextDocument class. Each instance of this class would have an NSWindowController instance associated with it, which in turn manages a window instance that is instantiated from a nib file. The NSDocumentController instance, as managed and instantiated by GNUstep, would be responsible for loading and saving documents in your application. It even prompts the user to save their documents when they try to quit the application.&lt;br /&gt;
&lt;br /&gt;
== File Components ==&lt;br /&gt;
&lt;br /&gt;
In building your application you will need to create a number of special files. From scratch, the following should be a rough guide to getting it working. These include the Makefile, your application's property list and the interface files.&lt;br /&gt;
&lt;br /&gt;
=== The Makefile ===&lt;br /&gt;
&lt;br /&gt;
For this type of application, no special makefile is needed: it just has to be a normal application. Project Builder should be able to spit out the required makefile and Gorm files that are needed for a generic application. I believe it is also capable of providing support for document-based applications. Otherwise use the following as a template:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''GNUmakefile'''&lt;br /&gt;
&lt;br /&gt;
 include $(GNUSTEP_MAKEFILES)/common.make&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 APP_NAME = DocumentApp&amp;lt;br&amp;gt;&lt;br /&gt;
 DocumentApp_OBJC_FILES =&amp;lt;br&amp;gt;&lt;br /&gt;
  MyDocument.m &amp;lt;br&amp;gt;&lt;br /&gt;
  main.m&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 DocumentApp_RESOURCES = \ &amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/Info-gnustep.plist \&amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/DocumentApp.gorm \&amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/MyDocument.gorm&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 -include GNUmakefile.preamble&amp;lt;br&amp;gt;&lt;br /&gt;
 include $(GNUSTEP_MAKEFILES)/application.make&amp;lt;br&amp;gt;&lt;br /&gt;
 -include GNUmakefile.postamble&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For more information as to customising this file, as well as setting up compiler options for third party libraries and includes, see the GNUstep makefile manual.&lt;br /&gt;
&lt;br /&gt;
===The application dictionary===&lt;br /&gt;
&lt;br /&gt;
For those that have edited this file in their project before, it is a dictionary with various values entered. For our purposes, we need an array within the main dictionary, called &amp;quot;NSTypes&amp;quot;. This is a array of unnamed dictionaries, with one dictionary for each type. &lt;br /&gt;
&lt;br /&gt;
I have provided an example for this file below. ProjectBuilder creates one as well. Please note that &amp;quot;TextEdit&amp;quot; does exist as an example application from NEXT I think, and again on MacOS X but I have constructed a much simpler version, used only for plain text files.&lt;br /&gt;
&lt;br /&gt;
Taking a look at the single dictionary entry in the NSTypes array, the following key-value pairs are needed:&lt;br /&gt;
* '''NSDocumentClass:''' This is (string) the subclass name you use in your code, the &amp;quot;objective-c name&amp;quot; of your document subclass. This is used by NSDocumentController's default implementation to create instances of your document type.&lt;br /&gt;
* '''NSName:''' The generic file type (string). This is completely arbitrary, and can be anything you like. For the purpose of conventions, it may be more appropriate not to use the &amp;quot;NS&amp;quot; or &amp;quot;GS&amp;quot; prefix (the latter of which I not sure), and instead use either your own, or no prefix at all.&lt;br /&gt;
* '''NSHumanReadableName:''' The human readable name of your document type (string)? TODO: explain where this is used.&lt;br /&gt;
* '''NSUnixExtensions:''' An array of strings, each containing a file extension connected to this document type on &amp;quot;unix&amp;quot; platforms. TODO: explain how &amp;quot;unix&amp;quot; is interpreted by GNUstep.&lt;br /&gt;
* '''NSDOSExtensions:''' An array of strings, each containing a file extenstion connected to this document type on &amp;quot;DOS&amp;quot; platforms (could be loosely interpreted as any MS platforms GNUstep runs on, i.e. Windows 2000/XP).&lt;br /&gt;
* '''NSRole:''' A string, either &amp;quot;Viewer&amp;quot; or &amp;quot;Editor&amp;quot;, depending on how your document operates on this file type.&lt;br /&gt;
* '''NSIcon:''' A icon name associated with this document type. TODO: Investigate how this works.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Info-gnustep.plist'''&lt;br /&gt;
 {&lt;br /&gt;
     ApplicationDescription = &amp;quot;A simple text editor for GNUstep.&amp;quot;;&lt;br /&gt;
     ApplicationName = TextEdit;&lt;br /&gt;
     ApplicationRelease = 0.10;&lt;br /&gt;
     Authors = ( &amp;quot;Christopher Armstrong&amp;quot; );&lt;br /&gt;
     Copyright = &amp;quot;Copyright (C) 2005 Christopher Armstrong&amp;quot;;&lt;br /&gt;
     CopyrightDescription = &amp;quot;Released under GPL.&amp;quot;;&lt;br /&gt;
     FullVersionID = 0.10;&lt;br /&gt;
     NSExecutable = TextEdit;&lt;br /&gt;
     NSMainNibFile = TextEdit.gorm;&lt;br /&gt;
     NSPrincipalClass = NSApplication;&lt;br /&gt;
     NSRole = Application;&lt;br /&gt;
     NSTypes = (&lt;br /&gt;
         {&lt;br /&gt;
                 NSDocumentClass = &amp;quot;TextDocument&amp;quot;;&lt;br /&gt;
                 NSName = &amp;quot;GSTextDocumentType&amp;quot;;&lt;br /&gt;
                 NSHumanReadableName = &amp;quot;Text Document&amp;quot;;&lt;br /&gt;
                 NSUnixExtensions = ( &amp;quot;txt&amp;quot;, &amp;quot;&amp;quot; );&lt;br /&gt;
                 NSDOSExtensions = ( &amp;quot;txt&amp;quot; );&lt;br /&gt;
                 NSRole = Editor;&lt;br /&gt;
         }&lt;br /&gt;
     );&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For more information on property list files, consult [[Property Lists]].&lt;br /&gt;
&lt;br /&gt;
=== Interface files ===&lt;br /&gt;
&lt;br /&gt;
Two interface files are needed: one for your main application, and another that will be instantiated with each instance of your document subclass. These both should be listed as resources in your makefile, (as shown the GNUmakefile example above). It may be helpful to name the document nib file after your class.&lt;br /&gt;
&lt;br /&gt;
==== Application Interface File ====&lt;br /&gt;
&lt;br /&gt;
The application one should just be a menu (though it could be more if necessary). When constructing it, take the following into account:&lt;br /&gt;
&lt;br /&gt;
* Use a standard Gorm template for an Application.&lt;br /&gt;
* Delete the window instance in the &amp;quot;Objects&amp;quot; pane (unless you need a main window, which is beyond the scope of this document).&lt;br /&gt;
* Set NSOwner's class to &amp;quot;NSDocumentController&amp;quot;. This is the custom class option of NSOwner in the property inspector. This ensures that the openDocument:, newDocument: messages, as sent to NSFirst, get picked up by NSDocumentController. Do not instantiate it (I believe you can't anyway).&lt;br /&gt;
* If you intend to subclass NSDocumentController, subclass it in the Classes pane. To make sure that this class is instantiated and used, make sure you instantiate it in Gorm or in your main.m file, and set NSOwner to be your subclass.&lt;br /&gt;
* Drag a Document menu from the palette onto your main menu. This already has the proper outlet and action linkage for each relevant message to be directed to NSFirst. Generic messages (such as openDocument:, not associated with any document instance) are forwarded to the shared instance of NSDocumentController (see it's reference documentation). When a document is active, more specific messages (such as close: or saveDocument:) are forwarded to the relevant document instance of your NSDocument subclass.&lt;br /&gt;
* Add any appropriate menus such as &amp;quot;Info&amp;quot; and &amp;quot;Format&amp;quot; which may be relevant to your application.&lt;br /&gt;
&lt;br /&gt;
==== Document Interface File(s) ====&lt;br /&gt;
&lt;br /&gt;
The document interface file is a window containing the view(s) required for the implementation of one instance of your document type. For example, in the case of a TextDocument type, a window instance with a NSTextView drawn on it is used for each document window. This interface file is instantiated every time a person creates a new document (the newDocument: message goes to NSDocumentController) or opens an existing document (openDocument:).&lt;br /&gt;
&lt;br /&gt;
You will need to:&lt;br /&gt;
* '''Subclass NSDocument''' with your document type in Gorm. This is done in a couple of ways, see [[Gorm_Manual#Custom_classes|custom classes]].&lt;br /&gt;
* '''Set NSOwner:''' Set your subclass as NSOwner's Custom class using the Property Inspector). DO NOT INSTANTIATE IT.&lt;br /&gt;
&lt;br /&gt;
Another thing that you may want to consider is custom outlets. If you place certain views or controls on your window (including the window itself), you may want to refer to them directly in your code, e.g. the NSTextView in our TextEdit example is accessed directly, so that we can save it's contents to a file. To enable this, we add outlets to our class (see [[Gorm_Manual#Custom_classes|custom classes]]). We then connect NSOwner to the appropriate controls/views, and select the outlets in the Connections Property Inspector (see [[Gorm_Manual#Editing_the_interface|editing the interface]]).&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
Various things need to be done at a code level, to ensure that your NSDocument subclass is properly instantiated. This section aims to tell you what is necessary.&lt;br /&gt;
&lt;br /&gt;
=== NSDocument subclass ===&lt;br /&gt;
&lt;br /&gt;
When creating your subclass, you may have chosen to have Gorm create the class files. If not, you should create two files for your subclass: a header (.h) file and an implementation file (.m). The header file should take the following layout (we're using the TextEdit example again):&lt;br /&gt;
&lt;br /&gt;
 #ifndef TEXTDOCUMENT_H&lt;br /&gt;
 #define TEXTDOCUMENT_H &amp;lt;br&amp;gt;&lt;br /&gt;
 #include &amp;lt;AppKit/AppKit.h&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
 @class NSDocument; &amp;lt;br&amp;gt;&lt;br /&gt;
 /* The document type string, as specified in the property list [[#The_application_dictionary|NSTypes array]] */ &amp;lt;br&amp;gt;&lt;br /&gt;
 NSString * GSTextDocumentType = &amp;quot;GSTextDocumentType&amp;quot;;&lt;br /&gt;
 @interface TextDocument : NSDocument&lt;br /&gt;
 {&lt;br /&gt;
 @protected&lt;br /&gt;
     /* Outlets we added in our Gorm nib file */&lt;br /&gt;
     id * textView;&lt;br /&gt;
 }&lt;br /&gt;
 /* Basic methods used for loading and saving document data (respectively). */&lt;br /&gt;
 - (BOOL) loadDataRepresentation:(NSData*)representation ofType:(NSString*)type;&lt;br /&gt;
 - (NSData*) dataRepresentationOfType: (NSString*)type; &amp;lt;br&amp;gt;&lt;br /&gt;
 /* Information and events handling of GUI related changes */&lt;br /&gt;
 - (NSString*) windowNibName;&lt;br /&gt;
 - (void) windowControllerDidLoadNib:(NSWindowController*)windowController; &amp;lt;br&amp;gt;&lt;br /&gt;
 @end&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Firstly, take note that we inherit from NSDocument. As a result, we need to override some methods for a basic (but working) implementation. &lt;br /&gt;
&lt;br /&gt;
==== loadDataRepresentation:ofType: and dataRepresentationOfType: ====&lt;br /&gt;
&lt;br /&gt;
The methods, loadDataRepresent:ofType: and dataRepresentationOfType: are used by NSDocumentController to load and save our files. The first method is called when the user trys to open a document (NSDocumentController gets the file name and copies it's data using an open panel). The method is passed the raw data in this file, as well as a string representing its type. It is important to note that this type string is the same one used in your property list. It is used by NSDocumentController to tell you what type it thinks you should open the data with. If this is not possible, or if there is an error trying to parse the data, your method returns FALSE/NO. Otherwise, you should store a local, meaningful representation of the data, which you can insert into your document window a little later (and return TRUE/YES).&lt;br /&gt;
&lt;br /&gt;
For example, in terms of the TextEdit example:&lt;br /&gt;
 - (BOOL) loadDataRepresentation:(NSData*) representation ofType:(NSString*)type&lt;br /&gt;
 {&lt;br /&gt;
    /*Check type information */&lt;br /&gt;
    if ([representation equalTo:GSTextDocumentType]==NO)&lt;br /&gt;
        return NO;&lt;br /&gt;
    /* Clean out our old representation if it still exists */&lt;br /&gt;
    if (fileContents) RELEASE(fileContents); &amp;lt;br&amp;gt;&lt;br /&gt;
    /* Allocate room for the new data, and try to initialise a string with it. */&lt;br /&gt;
    self-&amp;gt;fileContents = [NSString alloc];&lt;br /&gt;
    fileContents = [fileContents initWithBytes: [representation bytes]&lt;br /&gt;
                         length: [representation length]&lt;br /&gt;
                       encoding: NSASCIIStringEncoding]; &amp;lt;br&amp;gt;&lt;br /&gt;
    /* If this can't be done, return NO */&lt;br /&gt;
    if (!fileContents)&lt;br /&gt;
        return NO; &amp;lt;br&amp;gt;&lt;br /&gt;
    /* Otherwise, set our TextView to the string data. */&lt;br /&gt;
    [self-&amp;gt;textView setString: fileContents];&lt;br /&gt;
    return YES;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
If this is not sufficient, or if your program can open the data in a more efficient manner, it may be worth looking into overriding -initWithContentsOfFile:ofType: and -initWithContentsOfURL:ofType:. Again, see the GUI manual for more details.&lt;br /&gt;
&lt;br /&gt;
dataRepresentationOfType: is used to save the data. Your method is expected to return an instance of NSData that contains what should be saved to a file, for the type specified. Again, the ''type'' variable should be checked to ensure that you can write data of that type. Return nil if the file cannot be saved as that type.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
 - (NSData*) dataRepresentationOfType:(NSString*)type&lt;br /&gt;
 {&lt;br /&gt;
     if ([type equalTo:GSTextDocumentType]==NO)&lt;br /&gt;
         return nil; &amp;lt;br&amp;gt;&lt;br /&gt;
     NSData stringData =  [[textView string] dataUsingEncoding:NSASCIIStringEncoding];  &lt;br /&gt;
     return stringData; &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
If a more sophisticated save implementation is needed, consult the documentation for information on the writeTo* methods.&lt;br /&gt;
&lt;br /&gt;
==== windowNibName ====&lt;br /&gt;
&lt;br /&gt;
This method must be overriden to return the a string of the name of your nib file (without the file extension). More complex implementations will use other methods to load the interface files. TODO: information on what methods need to be overriden.&lt;br /&gt;
&lt;br /&gt;
==== windowControllerDidLoadNib: ====&lt;br /&gt;
&lt;br /&gt;
Use this method to add code that should be run as soon as ''windowController'' has been initialised. Your document may have many window controllers; each window controller taking possession of one window.&lt;br /&gt;
&lt;br /&gt;
In the TextEdit example, this method is used to copy the ''fileContents'' variable to the text view. It otherwise initialises the document window. &lt;br /&gt;
&lt;br /&gt;
Also note that you can override windowControllerWillLoadNib: to perform pre-interface loading initialisation.&lt;br /&gt;
&lt;br /&gt;
==== makeWindowControllers ====&lt;br /&gt;
&lt;br /&gt;
This is an optional method override, which must be used if you have multiple window controllers per document. It is responsible for creating each window controller from it's interface file and then adding it to the document. Use the addWindowController: method.&lt;br /&gt;
&lt;br /&gt;
==== Other considerations ====&lt;br /&gt;
&lt;br /&gt;
* You need a way to notify NSDocument that your document has changed, so that NSDocumentController can enable the menu item to allow saving. This is done by a call to the updateChangeCount: method. For example, the TextDocument class adds itself as a delegate to the textView, for any notification of changes. It then calls updateChangeCount: in the delegate's method.&lt;br /&gt;
&lt;br /&gt;
* You may also wish to add a close: method (not the close method already in NSDocument, see below) to respond to the menu item permitting your document to close. This could perform cleanup operations before a call to [self close] is made e.g.&lt;br /&gt;
&lt;br /&gt;
 - (void) close:(id)sender /* Note this is not the method found in NSDocument (they differ by a parameter) */&lt;br /&gt;
 {&lt;br /&gt;
     [self close];&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== NSDocumentController ===&lt;br /&gt;
&lt;br /&gt;
This class can optionally be subclassed, to implement some specific functionality. For example, programs handling multiple document types may override newDocument: to create a window so that the user can select which document type to create.&lt;br /&gt;
&lt;br /&gt;
You should use separate implementation files and add the .m file to GNUmakefile.&lt;br /&gt;
&lt;br /&gt;
=== NSWindowController ===&lt;br /&gt;
&lt;br /&gt;
This class can also be optionally subclassed, to implement functionality specific to a window controller for a document type. You may need to override makeWindowControllers: in the NSDocument subclass in order to make sure your specific window controller is instantiated.&lt;br /&gt;
&lt;br /&gt;
You should use separate implemenation files and add the .m file to GNUmakefile.&lt;br /&gt;
&lt;br /&gt;
== Optional Additions ==&lt;br /&gt;
&lt;br /&gt;
=== Custom NSDocumentController and NSWindowController implementations ===&lt;br /&gt;
&lt;br /&gt;
See [[#NSWindowController|NSWindowController]] and [[#NSDocumentController|NSDocumentController]].&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Creating_document_based_applications&amp;diff=846</id>
		<title>Creating document based applications</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Creating_document_based_applications&amp;diff=846"/>
		<updated>2005-07-09T02:08:00Z</updated>

		<summary type="html">&lt;p&gt;Quineska: Spelling errors, grammatical fixes&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Note: First version; subject to further revisions and changes.&lt;br /&gt;
--[[User:Quineska|ChrisArmstrong]] 07:09, 7 Jul 2005 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
OpenStep can provide your application a document-based model. It helps to simplify the process of creating such applications. GNUstep implements this as well; this document aims to provide an overview of what is required in the creation and design of such an application.&lt;br /&gt;
&lt;br /&gt;
It is assumed you are familiar with GNUstep, and have some understanding as how to create Gorm's interface files (often referred to as nib's), as well as some understanding of how they work.&lt;br /&gt;
&lt;br /&gt;
Importantly, such applications have certain components that are required, and should be considered as part of their design. When programming, classes that will be used as part of the AppKit are:&lt;br /&gt;
&lt;br /&gt;
==== NSDocument ====&lt;br /&gt;
&lt;br /&gt;
This class is central to the OpenStep document based model. These application's declare a new instance of a subclass of NSDocument for each “document” that is opened. You will subclass NSDocument to implement this.&lt;br /&gt;
&lt;br /&gt;
Each instance of your NSDocument subclass may have one or more windows associated with it. These are used as an interface for loading and saving a representation of your document type. Each window will have an “NSWindowController” instance associated with it, where NSDocument maintains a list of these.&lt;br /&gt;
&lt;br /&gt;
==== NSDocumentController ====&lt;br /&gt;
&lt;br /&gt;
This class acts a controller. It maintains a list of documents (instances of your NSDocument subclass) and is responsible for loading and instantiating new documents. It is usually not necessary to implement a subclass of this, but often it may be useful to implement special functionality (especially related to opening and creating documents at an application level).&lt;br /&gt;
&lt;br /&gt;
==== NSWindowController ====&lt;br /&gt;
&lt;br /&gt;
As mentioned above, NSWindowController instances are individually associated with one NSWindow instance, in such a way that a document maintains a list of window controllers that are reponsible for rendering the views associated with a document.&lt;br /&gt;
&lt;br /&gt;
You will most likely not have to subclass NSWindowController. Instead, you associate a nib file (the Gorm output) with the subclass of NSDocument, and NSDocumentController will load this nib file for each document that is created or loaded.&lt;br /&gt;
&lt;br /&gt;
For example, a text based application that is used for the editing of plain text files, may subclass NSDocument with a TextDocument class. Each instance of this class would have an NSWindowController instance associated with it, which in turn manages a window instance that is instantiated from a nib file. The NSDocumentController instance, as managed and instantiated by GNUstep, would be responsible for loading and saving documents in your application. It even prompts the user to save their documents when they try to quit the application.&lt;br /&gt;
&lt;br /&gt;
== File Components ==&lt;br /&gt;
&lt;br /&gt;
In building your application you will need to create a number of special files. From scratch, the following should be a rough guide to getting it working. These include the Makefile, your application's property list and the interface files.&lt;br /&gt;
&lt;br /&gt;
=== The Makefile ===&lt;br /&gt;
&lt;br /&gt;
For this type of application, no special makefile is needed: it just has to be a normal application. Project Builder should be able to spit out the required makefile and Gorm files that are needed for a generic application. I believe it is also capable of providing support for document-based applications. Otherwise use the following as a template:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''GNUmakefile'''&lt;br /&gt;
&lt;br /&gt;
 include $(GNUSTEP_MAKEFILES)/common.make&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 APP_NAME = DocumentApp&amp;lt;br&amp;gt;&lt;br /&gt;
 DocumentApp_OBJC_FILES =&amp;lt;br&amp;gt;&lt;br /&gt;
  MyDocument.m &amp;lt;br&amp;gt;&lt;br /&gt;
  main.m&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 DocumentApp_RESOURCES = \ &amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/Info-gnustep.plist \&amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/DocumentApp.gorm \&amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/MyDocument.gorm&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 -include GNUmakefile.preamble&amp;lt;br&amp;gt;&lt;br /&gt;
 include $(GNUSTEP_MAKEFILES)/application.make&amp;lt;br&amp;gt;&lt;br /&gt;
 -include GNUmakefile.postamble&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For more information as to customising this file, as well as setting up compiler options for third party libraries and includes, see the GNUstep makefile manual.&lt;br /&gt;
&lt;br /&gt;
===The application dictionary===&lt;br /&gt;
&lt;br /&gt;
For those that have edited this file in their project before, it is a dictionary with various values entered. For our purposes, we need an array within the main dictionary, called &amp;quot;NSTypes&amp;quot;. This is a array of unnamed dictionaries, with one dictionary for each type. &lt;br /&gt;
&lt;br /&gt;
I have provided an example for this file below. ProjectBuilder creates one as well. Please note that &amp;quot;TextEdit&amp;quot; does exist as an example application from NEXT I think, and again on MacOS X but I have constructed a much simpler version, used only for plain text files.&lt;br /&gt;
&lt;br /&gt;
Taking a look at the single dictionary entry in the NSTypes array, the following key-value pairs are needed:&lt;br /&gt;
* '''NSDocumentClass:''' This is (string) the subclass name you use in your code, the &amp;quot;objective-c name&amp;quot; of your document subclass. This is used by NSDocumentController's default implementation to create instances of your document type.&lt;br /&gt;
* '''NSName:''' The generic file type (string). This is completely arbitrary, and can be anything you like. For the purpose of conventions, it may be more appropriate not to use the &amp;quot;NS&amp;quot; or &amp;quot;GS&amp;quot; prefix (the latter of which I not sure), and instead use either your own, or no prefix at all.&lt;br /&gt;
* '''NSHumanReadableName:''' The human readable name of your document type (string)? TODO: explain where this is used.&lt;br /&gt;
* '''NSUnixExtensions:''' An array of strings, each containing a file extension connected to this document type on &amp;quot;unix&amp;quot; platforms. TODO: explain how &amp;quot;unix&amp;quot; is interpreted by GNUstep.&lt;br /&gt;
* '''NSDOSExtensions:''' An array of strings, each containing a file extenstion connected to this document type on &amp;quot;DOS&amp;quot; platforms (could be loosely interpreted as any MS platforms GNUstep runs on, i.e. Windows 2000/XP).&lt;br /&gt;
* '''NSRole:''' A string, either &amp;quot;Viewer&amp;quot; or &amp;quot;Editor&amp;quot;, depending on how your document operates on this file type.&lt;br /&gt;
* '''NSIcon:''' A icon name associated with this document type. TODO: Investigate how this works.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Info-gnustep.plist'''&lt;br /&gt;
 {&lt;br /&gt;
     ApplicationDescription = &amp;quot;A simple text editor for GNUstep.&amp;quot;;&lt;br /&gt;
     ApplicationName = TextEdit;&lt;br /&gt;
     ApplicationRelease = 0.10;&lt;br /&gt;
     Authors = ( &amp;quot;Christopher Armstrong&amp;quot; );&lt;br /&gt;
     Copyright = &amp;quot;Copyright (C) 2005 Christopher Armstrong&amp;quot;;&lt;br /&gt;
     CopyrightDescription = &amp;quot;Released under GPL.&amp;quot;;&lt;br /&gt;
     FullVersionID = 0.10;&lt;br /&gt;
     NSExecutable = TextEdit;&lt;br /&gt;
     NSMainNibFile = TextEdit.gorm;&lt;br /&gt;
     NSPrincipalClass = NSApplication;&lt;br /&gt;
     NSRole = Application;&lt;br /&gt;
     NSTypes = (&lt;br /&gt;
         {&lt;br /&gt;
                 NSDocumentClass = &amp;quot;TextDocument&amp;quot;;&lt;br /&gt;
                 NSName = &amp;quot;GSTextDocumentType&amp;quot;;&lt;br /&gt;
                 NSHumanReadableName = &amp;quot;Text Document&amp;quot;;&lt;br /&gt;
                 NSUnixExtensions = ( &amp;quot;txt&amp;quot;, &amp;quot;&amp;quot; );&lt;br /&gt;
                 NSDOSExtensions = ( &amp;quot;txt&amp;quot; );&lt;br /&gt;
                 NSRole = Editor;&lt;br /&gt;
         }&lt;br /&gt;
     );&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For more information on property list files, consult [[Property Lists]].&lt;br /&gt;
&lt;br /&gt;
=== Interface files ===&lt;br /&gt;
&lt;br /&gt;
Two interface files are needed: one for your main application, and another that will be instantiated with each instance of your document subclass. These both should be listed as resources in your makefile, (as shown the GNUmakefile example above). It may be helpful to name the document nib file after your class.&lt;br /&gt;
&lt;br /&gt;
==== Application Interface File ====&lt;br /&gt;
&lt;br /&gt;
The application one should just be a menu (though it could be more if necessary). When constructing it, take the following into account:&lt;br /&gt;
&lt;br /&gt;
* Use a standard Gorm template for an Application.&lt;br /&gt;
* Delete the window instance in the &amp;quot;Objects&amp;quot; pane (unless you need a main window, in which case I don't know how to operate).&lt;br /&gt;
* Set NSOwner's class to &amp;quot;NSDocumentController&amp;quot; (this is the custom class option of NSOwner in the property inspector). This ensures openDocument, newDocument, etc. messages, as sent to NSFirst, get picked up by NSDocumentController. Do not instantiate it (I believe you can't anyway).&lt;br /&gt;
* If you intend to subclass NSDocumentController, subclass it in the Classes pane. To make sure that this class is instantiated and used, make sure you instantiate it in Gorm or in your main.m file, and set NSOwner to be your subclass.&lt;br /&gt;
* Drag a Document menu from the palette onto your main menu. This already has the proper linkage for each relevant message for a document setup to be directed to NSFirst. In the case of generic messages (such as openDocument:, not associated with any document instance), these are forwarded to the shared instance of NSDocumentController (see it's reference documentation). When a document is active, more specific messages (such as close: or saveDocument:) are forwarded to the relevant document instance of your NSDocument subclass.&lt;br /&gt;
* Add any appropriate menus such as &amp;quot;Info&amp;quot; and &amp;quot;Format&amp;quot; which may be relevant to your application.&lt;br /&gt;
&lt;br /&gt;
==== Document Interface File(s) ====&lt;br /&gt;
&lt;br /&gt;
The document interface file is (generically) a window containing the view(s) required for the implementation of one instance of your document type. For example, in the case of a TextDocument type, a window instance with a NSTextView drawn on it is used for each open window. This nib file is instantiated every time a person creates a new document (the newDocument: message goes to NSDocumentController) or opens an existing document (openDocument:).&lt;br /&gt;
&lt;br /&gt;
You will need to:&lt;br /&gt;
* '''Subclass NSDocument''' with your document type in Gorm (this is done in a couple of ways, see [[Gorm_Manual#Custom_classes|custom classes]]).&lt;br /&gt;
* '''Set NSOwner:''' Set your subclass as NSOwner's Custom class (done using the Property inspector). DO NOT INSTANTIATE IT.&lt;br /&gt;
&lt;br /&gt;
Another thing that you may want to consider is custom outlets. If you place certain views or controls on your window (including the window itself), you may want to refer to them directly in yout code, e.g. the NSTextView in our TextEdit example is accessed directly, so that we can save it's contents to a file. To enable this, we add outlets to our class (see [[Gorm_Manual#Custom_classes|custom classes]]). We then connected NSOwner to the appropriate controls/views, and selected the outlets in the Connections property inspector (see [[Gorm_Manual#Editing_the_interface|editing the interface]]).&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
Various things need to be done at a code level, to ensure that your NSDocument subclass is properly instantiated. This section aims to tell you what is necessary.&lt;br /&gt;
&lt;br /&gt;
=== NSDocument subclass ===&lt;br /&gt;
&lt;br /&gt;
When creating your subclass, you may have chosen to have Gorm create the class files. If not, you should create two files for your subclass: a header (.h) file and an implementation file (.m). The header file should take the following layout (we're using the TextEdit example again):&lt;br /&gt;
&lt;br /&gt;
 #ifndef TEXTDOCUMENT_H&lt;br /&gt;
 #define TEXTDOCUMENT_H &amp;lt;br&amp;gt;&lt;br /&gt;
 #include &amp;lt;AppKit/AppKit.h&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
 @class NSDocument; &amp;lt;br&amp;gt;&lt;br /&gt;
 /* The document type string, as specified in the property list [[#The_application_dictionary|NSTypes array]] */ &amp;lt;br&amp;gt;&lt;br /&gt;
 NSString * GSTextDocumentType = &amp;quot;GSTextDocumentType&amp;quot;;&lt;br /&gt;
 @interface TextDocument : NSDocument&lt;br /&gt;
 {&lt;br /&gt;
 @protected&lt;br /&gt;
     /* Outlets we added in our Gorm nib file */&lt;br /&gt;
     id * textView;&lt;br /&gt;
 }&lt;br /&gt;
 /* Basic methods used for loading and saving document data (respectively). */&lt;br /&gt;
 - (BOOL) loadDataRepresentation:(NSData*)representation ofType:(NSString*)type;&lt;br /&gt;
 - (NSData*) dataRepresentationOfType: (NSString*)type; &amp;lt;br&amp;gt;&lt;br /&gt;
 /* Information and events handling of GUI related changes */&lt;br /&gt;
 - (NSString*) windowNibName;&lt;br /&gt;
 - (void) windowControllerDidLoadNib:(NSWindowController*)windowController; &amp;lt;br&amp;gt;&lt;br /&gt;
 @end&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Firstly, take note that we inherit from NSDocument. As a result, we need to override some methods for a basic (but working) implementation. &lt;br /&gt;
&lt;br /&gt;
==== loadDataRepresentation:ofType: and dataRepresentationOfType: ====&lt;br /&gt;
&lt;br /&gt;
The methods, loadDataRepresent:ofType: and dataRepresentationOfType: are used by NSDocumentController to load and save our files. The first method is called when the user trys to open a document (NSDocumentController gets the file name and copies it's data using an open panel). The method is passed the raw data in this file, as well as a string representing its type. It is important to note that this type string is the same one used in your property list. It is used by NSDocumentController to tell you what type it thinks you should open the data with. If this is not possible, or if there is an error trying to parse the data, your method returns FALSE/NO. Otherwise, you should store a local, meaningful representation of the data, which you can insert into your document window a little later (and return YES).&lt;br /&gt;
&lt;br /&gt;
For example, in terms of the TextEdit example:&lt;br /&gt;
 - (BOOL) loadDataRepresentation:(NSData*) representation ofType:(NSString*)type&lt;br /&gt;
 {&lt;br /&gt;
    /*Check type information */&lt;br /&gt;
    if ([representation equalTo:GSTextDocumentType]==NO)&lt;br /&gt;
        return NO;&lt;br /&gt;
    /* Clean out our old representation if it still exists */&lt;br /&gt;
    if (fileContents) RELEASE(fileContents); &amp;lt;br&amp;gt;&lt;br /&gt;
    /* Allocate room for the new data, and try to initialise a string with it. */&lt;br /&gt;
    self-&amp;gt;fileContents = [NSString alloc];&lt;br /&gt;
    fileContents = [fileContents initWithBytes: [representation bytes]&lt;br /&gt;
                         length: [representation length]&lt;br /&gt;
                       encoding: NSASCIIStringEncoding]; &amp;lt;br&amp;gt;&lt;br /&gt;
    /* If this can't be done, return NO */&lt;br /&gt;
    if (!fileContents)&lt;br /&gt;
        return NO; &amp;lt;br&amp;gt;&lt;br /&gt;
    /* Otherwise, set our TextView to the string data. */&lt;br /&gt;
    [self-&amp;gt;textView setString: fileContents];&lt;br /&gt;
    return YES;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
If this is not suffice, or if your program can open the data in a more efficient manner, it may be worth looking into overriding -initWithContentsOfFile:ofType: and -initWithContentsOfURL:ofType: (see the GUI manual for more details).&lt;br /&gt;
&lt;br /&gt;
dataRepresentationOfType: is used to save the data. Your method is expected to return an instance of NSData that contains what should be saved to a file, for the type specified. Again, the ''type'' variable should be checked to ensure that you can write data of that type. Return nil if the file cannot be saved as that type.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
 - (NSData*) dataRepresentationOfType:(NSString*)type&lt;br /&gt;
 {&lt;br /&gt;
     if ([type equalTo:GSTextDocumentType]==NO)&lt;br /&gt;
         return nil; &amp;lt;br&amp;gt;&lt;br /&gt;
     NSData stringData =  [[textView string] dataUsingEncoding:NSASCIIStringEncoding];  &lt;br /&gt;
     return stringData; &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
If a more sophisticated save implementation is needed, consult the documentation for information on the writeTo methods.&lt;br /&gt;
&lt;br /&gt;
==== windowNibName ====&lt;br /&gt;
&lt;br /&gt;
This method must be overriden to return the a string of the name of your nib file (without the file extention). More complex implementations will use other methods to load the interface files. TODO: information on what methods need to be overriden.&lt;br /&gt;
&lt;br /&gt;
==== windowControllerDidLoadNib: ====&lt;br /&gt;
&lt;br /&gt;
Use this method to add code that should be run as soon as ''windowController'' has been initialised. Your document may have many window controllers; each window controller taking possession of one window.&lt;br /&gt;
&lt;br /&gt;
In the TextEdit example, this method is used to copy the fileContents object ivar to the text view. It otherwise initialises the document window. &lt;br /&gt;
&lt;br /&gt;
Also note that you can override windowControllerWillLoadNib: to perform pre-nib loading initialisation.&lt;br /&gt;
&lt;br /&gt;
==== makeWindowControllers ====&lt;br /&gt;
&lt;br /&gt;
This is an optional method override, which must be used if you have multiple window controllers per document. It is responsible for creating each window controller from it's nib and then adding it to the document. Use the addWindowController: method.&lt;br /&gt;
&lt;br /&gt;
==== Other considerations ====&lt;br /&gt;
&lt;br /&gt;
* You need a way to notify NSDocument that your document has changed, so that NSDocumentController can enable the menu item to allow saving. This is done by a call to the updateChangeCount: method. For example, the TextDocument class adds itself as a delegate to the textView, for any notification of changes. It then calls updateChangeCount: in the delegate's method.&lt;br /&gt;
&lt;br /&gt;
* You may also wish to add a close: method (not the close method already in NSDocument, see below) to respond to the menu item permitting your document to close. This could perform cleanup operations before a call to [super close] is called e.g.&lt;br /&gt;
&lt;br /&gt;
 - (void) close:(id)sender /* Note this is not the method found in NSDocument (they differ by a parameter) */&lt;br /&gt;
 {&lt;br /&gt;
     [self close];&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== NSDocumentController ===&lt;br /&gt;
&lt;br /&gt;
This class can optionally be subclassed, to implement some specific functionality. For example, programs handling multiple document types may override newDocument: to create a window so that the user can select which document type to create.&lt;br /&gt;
&lt;br /&gt;
You should use separate implementation files and add the .m file to GNUmakefile.&lt;br /&gt;
&lt;br /&gt;
=== NSWindowController ===&lt;br /&gt;
&lt;br /&gt;
This class can also be optionally subclassed, to implement functionality specific to a window controller for a document type. You may need to override makeWindowControllers: in the NSDocument subclass in order to make sure your specific window controller is instantiated.&lt;br /&gt;
&lt;br /&gt;
You should use separate implemenatino files and add the .m file to GNUmakefile.&lt;br /&gt;
&lt;br /&gt;
== Optional Additions ==&lt;br /&gt;
&lt;br /&gt;
=== Custom NSDocumentController and NSWindowController implementations ===&lt;br /&gt;
&lt;br /&gt;
See [[#NSWindowController|NSWindowController]] and [[#NSDocumentController|NSDocumentController]].&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Creating_document_based_applications&amp;diff=845</id>
		<title>Creating document based applications</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Creating_document_based_applications&amp;diff=845"/>
		<updated>2005-07-09T02:03:41Z</updated>

		<summary type="html">&lt;p&gt;Quineska: Spelling errors, grammatical fixes&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Note: First version; subject to further revisions and changes.&lt;br /&gt;
--[[User:Quineska|ChrisArmstrong]] 07:09, 7 Jul 2005 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
OpenStep can provide your application a document-based model. It helps to simplify the process of creating such applications. GNUstep implements this as well; this document aims to provide an overview of what is required in the creation and design of such an application.&lt;br /&gt;
&lt;br /&gt;
It is assumed you are familiar with GNUstep, and have some understanding as how to create Gorm's interface files (often referred to as nib's), as well as some understanding of how they work.&lt;br /&gt;
&lt;br /&gt;
Importantly, such applications have certain components that are required, and should be considered as part of their design. When programming, classes that will be used as part of the AppKit are:&lt;br /&gt;
&lt;br /&gt;
==== NSDocument ====&lt;br /&gt;
&lt;br /&gt;
This class is central to the OpenStep document based model. These application's declare a new instance of a subclass of NSDocument for each “document” that is opened. You will subclass NSDocument to implement this.&lt;br /&gt;
&lt;br /&gt;
Each instance of your NSDocument subclass may have one or more windows associated with it. These are used as an interface for loading and saving a representation of your document type. Each window will have an “NSWindowController” instance associated with it, where NSDocument maintains a list of these.&lt;br /&gt;
&lt;br /&gt;
==== NSDocumentController ====&lt;br /&gt;
&lt;br /&gt;
This class acts a controller. It maintains a list of documents (instances of your NSDocument subclass) and is responsible for loading and instantiating new documents. It is usually not necessary to implement a subclass of this, but often it may be useful to implement special functionality (especially related to opening and creating documents at an application level).&lt;br /&gt;
&lt;br /&gt;
==== NSWindowController ====&lt;br /&gt;
&lt;br /&gt;
As mentioned above, NSWindowController instances are individually associated with one NSWindow instance, in such a way that a document maintains a list of window controllers that are reponsible for rendering the views associated with a document.&lt;br /&gt;
&lt;br /&gt;
You will most likely not have to subclass NSWindowController. Instead, you associate a nib file (the Gorm output) with the subclass of NSDocument, and NSDocumentController will load this nib file for each document that is created or loaded.&lt;br /&gt;
&lt;br /&gt;
For example, a text based application that is used for the editing of plain text files, may subclass NSDocument with a TextDocument class. Each instance of this class would have an NSWindowController instance associated with it, which in turn manages a window instance that is instantiated from a nib file. The NSDocumentController instance, as managed and instantiated by GNUstep, would be responsible for loading and saving documents in your application. It even prompts the user to save their documents when they try to quit the application.&lt;br /&gt;
&lt;br /&gt;
== File Components ==&lt;br /&gt;
&lt;br /&gt;
In building your application you will need to create a number of special files. From scratch, the following should be a rough guide to getting it working. These include the Makefile, your application's property list and the interface files.&lt;br /&gt;
&lt;br /&gt;
=== The Makefile ===&lt;br /&gt;
&lt;br /&gt;
For this type of application, no special makefile is needed: it just has to be a normal application. Project Builder should be able to spit out the required makefile and Gorm files that are needed for a generic application. I believe it is also capable of providing support for document-based applications. Otherwise use the following as a template:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''GNUmakefile'''&lt;br /&gt;
&lt;br /&gt;
 include $(GNUSTEP_MAKEFILES)/common.make&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 APP_NAME = DocumentApp&amp;lt;br&amp;gt;&lt;br /&gt;
 DocumentApp_OBJC_FILES =&amp;lt;br&amp;gt;&lt;br /&gt;
  MyDocument.m &amp;lt;br&amp;gt;&lt;br /&gt;
  main.m&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 DocumentApp_RESOURCES = \ &amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/Info-gnustep.plist \&amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/DocumentApp.gorm \&amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/MyDocument.gorm&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 -include GNUmakefile.preamble&amp;lt;br&amp;gt;&lt;br /&gt;
 include $(GNUSTEP_MAKEFILES)/application.make&amp;lt;br&amp;gt;&lt;br /&gt;
 -include GNUmakefile.postamble&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For more information as to customising this file, as well as setting up compiler options for third party libraries and includes, see the GNUstep makefile manual.&lt;br /&gt;
&lt;br /&gt;
===The application dictionary===&lt;br /&gt;
&lt;br /&gt;
For those that have edited this file in their project before, it is a dictionary with various values entered. For our purposes, we need an array within the main dictionary, called &amp;quot;NSTypes&amp;quot;. This is a array of unnamed dictionaries, with one dictionary for each type. &lt;br /&gt;
&lt;br /&gt;
An entire example of this file, for a &amp;quot;theoretical&amp;quot; TextEdit application (please note that such an application does exist as an example application from Next I think, and again on MacOS X but I have constructed a much simpler version, used only for plain text files).&lt;br /&gt;
&lt;br /&gt;
Taking a look at the single dictionary entry in the NSTypes array, the following key-value pairs are needed:&lt;br /&gt;
* '''NSDocumentClass:''' This is (string) the subclass name you use in your code, the &amp;quot;objective-c name&amp;quot; of your document subclass. This is used by NSDocumentController's default implementation to create instances of your document type.&lt;br /&gt;
* '''NSName:''' The generic file type (string). This is completely arbitrary, and can be anything you like. For the purpose of conventions, it may be more appropriate not to use the &amp;quot;NS&amp;quot; or &amp;quot;GS&amp;quot; prefix (the latter of which I not sure), and instead use either your own, or no prefix at all.&lt;br /&gt;
* '''NSHumanReadableName:''' The human readable name of your document type (string)? TODO: explain where this is used.&lt;br /&gt;
* '''NSUnixExtensions:''' An array of strings, each containing a file extension connected to this document type on &amp;quot;unix&amp;quot; platforms. TODO: explain how &amp;quot;unix&amp;quot; is interpreted by GNUstep.&lt;br /&gt;
* '''NSDOSExtensions:''' An array of strings, each containing a file extenstion connected to this document type on &amp;quot;DOS&amp;quot; platforms (could be loosely interpreted as any MS platforms GNUstep runs on, i.e. Windows 2000/XP).&lt;br /&gt;
* '''NSRole:''' A string, either &amp;quot;Viewer&amp;quot; or &amp;quot;Editor&amp;quot;, depending on how your document operates on this file type.&lt;br /&gt;
* '''NSIcon:''' A icon name associated with this document type. TODO: Investigate how this works.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Info-gnustep.plist'''&lt;br /&gt;
 {&lt;br /&gt;
     ApplicationDescription = &amp;quot;A simple text editor for GNUstep.&amp;quot;;&lt;br /&gt;
     ApplicationName = TextEdit;&lt;br /&gt;
     ApplicationRelease = 0.10;&lt;br /&gt;
     Authors = ( &amp;quot;Christopher Armstrong&amp;quot; );&lt;br /&gt;
     Copyright = &amp;quot;Copyright (C) 2005 Christopher Armstrong&amp;quot;;&lt;br /&gt;
     CopyrightDescription = &amp;quot;Released under GPL.&amp;quot;;&lt;br /&gt;
     FullVersionID = 0.10;&lt;br /&gt;
     NSExecutable = TextEdit;&lt;br /&gt;
     NSMainNibFile = TextEdit.gorm;&lt;br /&gt;
     NSPrincipalClass = NSApplication;&lt;br /&gt;
     NSRole = Application;&lt;br /&gt;
     NSTypes = (&lt;br /&gt;
         {&lt;br /&gt;
                 NSDocumentClass = &amp;quot;TextDocument&amp;quot;;&lt;br /&gt;
                 NSName = &amp;quot;GSTextDocumentType&amp;quot;;&lt;br /&gt;
                 NSHumanReadableName = &amp;quot;Text Document&amp;quot;;&lt;br /&gt;
                 NSUnixExtensions = ( &amp;quot;txt&amp;quot;, &amp;quot;&amp;quot; );&lt;br /&gt;
                 NSDOSExtensions = ( &amp;quot;txt&amp;quot; );&lt;br /&gt;
                 NSRole = Editor;&lt;br /&gt;
         }&lt;br /&gt;
     );&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For more information on property list files, consult [[Property Lists]].&lt;br /&gt;
&lt;br /&gt;
=== Interface files ===&lt;br /&gt;
&lt;br /&gt;
Two interface files are needed: one for your main application, and another that will be instantiated with each instance of your document subclass. These both should be listed as resources in your makefile, (as shown the GNUmakefile example above). It may be helpful to name the document nib file after your class.&lt;br /&gt;
&lt;br /&gt;
==== Application Interface File ====&lt;br /&gt;
&lt;br /&gt;
The application one should just be a menu (though it could be more if necessary). When constructing it, take the following into account:&lt;br /&gt;
&lt;br /&gt;
* Use a standard Gorm template for an Application.&lt;br /&gt;
* Delete the window instance in the &amp;quot;Objects&amp;quot; pane (unless you need a main window, in which case I don't know how to operate).&lt;br /&gt;
* Set NSOwner's class to &amp;quot;NSDocumentController&amp;quot; (this is the custom class option of NSOwner in the property inspector). This ensures openDocument, newDocument, etc. messages, as sent to NSFirst, get picked up by NSDocumentController. Do not instantiate it (I believe you can't anyway).&lt;br /&gt;
* If you intend to subclass NSDocumentController, subclass it in the Classes pane. To make sure that this class is instantiated and used, make sure you instantiate it in Gorm or in your main.m file, and set NSOwner to be your subclass.&lt;br /&gt;
* Drag a Document menu from the palette onto your main menu. This already has the proper linkage for each relevant message for a document setup to be directed to NSFirst. In the case of generic messages (such as openDocument:, not associated with any document instance), these are forwarded to the shared instance of NSDocumentController (see it's reference documentation). When a document is active, more specific messages (such as close: or saveDocument:) are forwarded to the relevant document instance of your NSDocument subclass.&lt;br /&gt;
* Add any appropriate menus such as &amp;quot;Info&amp;quot; and &amp;quot;Format&amp;quot; which may be relevant to your application.&lt;br /&gt;
&lt;br /&gt;
==== Document Interface File(s) ====&lt;br /&gt;
&lt;br /&gt;
The document interface file is (generically) a window containing the view(s) required for the implementation of one instance of your document type. For example, in the case of a TextDocument type, a window instance with a NSTextView drawn on it is used for each open window. This nib file is instantiated every time a person creates a new document (the newDocument: message goes to NSDocumentController) or opens an existing document (openDocument:).&lt;br /&gt;
&lt;br /&gt;
You will need to:&lt;br /&gt;
* '''Subclass NSDocument''' with your document type in Gorm (this is done in a couple of ways, see [[Gorm_Manual#Custom_classes|custom classes]]).&lt;br /&gt;
* '''Set NSOwner:''' Set your subclass as NSOwner's Custom class (done using the Property inspector). DO NOT INSTANTIATE IT.&lt;br /&gt;
&lt;br /&gt;
Another thing that you may want to consider is custom outlets. If you place certain views or controls on your window (including the window itself), you may want to refer to them directly in yout code, e.g. the NSTextView in our TextEdit example is accessed directly, so that we can save it's contents to a file. To enable this, we add outlets to our class (see [[Gorm_Manual#Custom_classes|custom classes]]). We then connected NSOwner to the appropriate controls/views, and selected the outlets in the Connections property inspector (see [[Gorm_Manual#Editing_the_interface|editing the interface]]).&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
Various things need to be done at a code level, to ensure that your NSDocument subclass is properly instantiated. This section aims to tell you what is necessary.&lt;br /&gt;
&lt;br /&gt;
=== NSDocument subclass ===&lt;br /&gt;
&lt;br /&gt;
When creating your subclass, you may have chosen to have Gorm create the class files. If not, you should create two files for your subclass: a header (.h) file and an implementation file (.m). The header file should take the following layout (we're using the TextEdit example again):&lt;br /&gt;
&lt;br /&gt;
 #ifndef TEXTDOCUMENT_H&lt;br /&gt;
 #define TEXTDOCUMENT_H &amp;lt;br&amp;gt;&lt;br /&gt;
 #include &amp;lt;AppKit/AppKit.h&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
 @class NSDocument; &amp;lt;br&amp;gt;&lt;br /&gt;
 /* The document type string, as specified in the property list [[#The_application_dictionary|NSTypes array]] */ &amp;lt;br&amp;gt;&lt;br /&gt;
 NSString * GSTextDocumentType = &amp;quot;GSTextDocumentType&amp;quot;;&lt;br /&gt;
 @interface TextDocument : NSDocument&lt;br /&gt;
 {&lt;br /&gt;
 @protected&lt;br /&gt;
     /* Outlets we added in our Gorm nib file */&lt;br /&gt;
     id * textView;&lt;br /&gt;
 }&lt;br /&gt;
 /* Basic methods used for loading and saving document data (respectively). */&lt;br /&gt;
 - (BOOL) loadDataRepresentation:(NSData*)representation ofType:(NSString*)type;&lt;br /&gt;
 - (NSData*) dataRepresentationOfType: (NSString*)type; &amp;lt;br&amp;gt;&lt;br /&gt;
 /* Information and events handling of GUI related changes */&lt;br /&gt;
 - (NSString*) windowNibName;&lt;br /&gt;
 - (void) windowControllerDidLoadNib:(NSWindowController*)windowController; &amp;lt;br&amp;gt;&lt;br /&gt;
 @end&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Firstly, take note that we inherit from NSDocument. As a result, we need to override some methods for a basic (but working) implementation. &lt;br /&gt;
&lt;br /&gt;
==== loadDataRepresentation:ofType: and dataRepresentationOfType: ====&lt;br /&gt;
&lt;br /&gt;
The methods, loadDataRepresent:ofType: and dataRepresentationOfType: are used by NSDocumentController to load and save our files. The first method is called when the user trys to open a document (NSDocumentController gets the file name and copies it's data using an open panel). The method is passed the raw data in this file, as well as a string representing its type. It is important to note that this type string is the same one used in your property list. It is used by NSDocumentController to tell you what type it thinks you should open the data with. If this is not possible, or if there is an error trying to parse the data, your method returns FALSE/NO. Otherwise, you should store a local, meaningful representation of the data, which you can insert into your document window a little later (and return YES).&lt;br /&gt;
&lt;br /&gt;
For example, in terms of the TextEdit example:&lt;br /&gt;
 - (BOOL) loadDataRepresentation:(NSData*) representation ofType:(NSString*)type&lt;br /&gt;
 {&lt;br /&gt;
    /*Check type information */&lt;br /&gt;
    if ([representation equalTo:GSTextDocumentType]==NO)&lt;br /&gt;
        return NO;&lt;br /&gt;
    /* Clean out our old representation if it still exists */&lt;br /&gt;
    if (fileContents) RELEASE(fileContents); &amp;lt;br&amp;gt;&lt;br /&gt;
    /* Allocate room for the new data, and try to initialise a string with it. */&lt;br /&gt;
    self-&amp;gt;fileContents = [NSString alloc];&lt;br /&gt;
    fileContents = [fileContents initWithBytes: [representation bytes]&lt;br /&gt;
                         length: [representation length]&lt;br /&gt;
                       encoding: NSASCIIStringEncoding]; &amp;lt;br&amp;gt;&lt;br /&gt;
    /* If this can't be done, return NO */&lt;br /&gt;
    if (!fileContents)&lt;br /&gt;
        return NO; &amp;lt;br&amp;gt;&lt;br /&gt;
    /* Otherwise, set our TextView to the string data. */&lt;br /&gt;
    [self-&amp;gt;textView setString: fileContents];&lt;br /&gt;
    return YES;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
If this is not suffice, or if your program can open the data in a more efficient manner, it may be worth looking into overriding -initWithContentsOfFile:ofType: and -initWithContentsOfURL:ofType: (see the GUI manual for more details).&lt;br /&gt;
&lt;br /&gt;
dataRepresentationOfType: is used to save the data. Your method is expected to return an instance of NSData that contains what should be saved to a file, for the type specified. Again, the ''type'' variable should be checked to ensure that you can write data of that type. Return nil if the file cannot be saved as that type.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
 - (NSData*) dataRepresentationOfType:(NSString*)type&lt;br /&gt;
 {&lt;br /&gt;
     if ([type equalTo:GSTextDocumentType]==NO)&lt;br /&gt;
         return nil; &amp;lt;br&amp;gt;&lt;br /&gt;
     NSData stringData =  [[textView string] dataUsingEncoding:NSASCIIStringEncoding];  &lt;br /&gt;
     return stringData; &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
If a more sophisticated save implementation is needed, consult the documentation for information on the writeTo methods.&lt;br /&gt;
&lt;br /&gt;
==== windowNibName ====&lt;br /&gt;
&lt;br /&gt;
This method must be overriden to return the a string of the name of your nib file (without the file extention). More complex implementations will use other methods to load the interface files. TODO: information on what methods need to be overriden.&lt;br /&gt;
&lt;br /&gt;
==== windowControllerDidLoadNib: ====&lt;br /&gt;
&lt;br /&gt;
Use this method to add code that should be run as soon as ''windowController'' has been initialised. Your document may have many window controllers; each window controller taking possession of one window.&lt;br /&gt;
&lt;br /&gt;
In the TextEdit example, this method is used to copy the fileContents object ivar to the text view. It otherwise initialises the document window. &lt;br /&gt;
&lt;br /&gt;
Also note that you can override windowControllerWillLoadNib: to perform pre-nib loading initialisation.&lt;br /&gt;
&lt;br /&gt;
==== makeWindowControllers ====&lt;br /&gt;
&lt;br /&gt;
This is an optional method override, which must be used if you have multiple window controllers per document. It is responsible for creating each window controller from it's nib and then adding it to the document. Use the addWindowController: method.&lt;br /&gt;
&lt;br /&gt;
==== Other considerations ====&lt;br /&gt;
&lt;br /&gt;
* You need a way to notify NSDocument that your document has changed, so that NSDocumentController can enable the menu item to allow saving. This is done by a call to the updateChangeCount: method. For example, the TextDocument class adds itself as a delegate to the textView, for any notification of changes. It then calls updateChangeCount: in the delegate's method.&lt;br /&gt;
&lt;br /&gt;
* You may also wish to add a close: method (not the close method already in NSDocument, see below) to respond to the menu item permitting your document to close. This could perform cleanup operations before a call to [super close] is called e.g.&lt;br /&gt;
&lt;br /&gt;
 - (void) close:(id)sender /* Note this is not the method found in NSDocument (they differ by a parameter) */&lt;br /&gt;
 {&lt;br /&gt;
     [self close];&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== NSDocumentController ===&lt;br /&gt;
&lt;br /&gt;
This class can optionally be subclassed, to implement some specific functionality. For example, programs handling multiple document types may override newDocument: to create a window so that the user can select which document type to create.&lt;br /&gt;
&lt;br /&gt;
You should use separate implementation files and add the .m file to GNUmakefile.&lt;br /&gt;
&lt;br /&gt;
=== NSWindowController ===&lt;br /&gt;
&lt;br /&gt;
This class can also be optionally subclassed, to implement functionality specific to a window controller for a document type. You may need to override makeWindowControllers: in the NSDocument subclass in order to make sure your specific window controller is instantiated.&lt;br /&gt;
&lt;br /&gt;
You should use separate implemenatino files and add the .m file to GNUmakefile.&lt;br /&gt;
&lt;br /&gt;
== Optional Additions ==&lt;br /&gt;
&lt;br /&gt;
=== Custom NSDocumentController and NSWindowController implementations ===&lt;br /&gt;
&lt;br /&gt;
See [[#NSWindowController|NSWindowController]] and [[#NSDocumentController|NSDocumentController]].&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=NSTableView&amp;diff=1931</id>
		<title>NSTableView</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=NSTableView&amp;diff=1931"/>
		<updated>2005-07-09T01:59:42Z</updated>

		<summary type="html">&lt;p&gt;Quineska: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;NSTableView is located within the AppKit (gnustep-gui library) and is used to display tables. It uses a delegate model for getting it's data i.e. you give it an object that provides it with the data it should display.&lt;br /&gt;
&lt;br /&gt;
== Code chunks ==&lt;br /&gt;
&lt;br /&gt;
=== Autosize row height according to font ===&lt;br /&gt;
&lt;br /&gt;
Following code autosizes the row height according to the size of data cell font:&lt;br /&gt;
&lt;br /&gt;
 - (void)autosizeRowHeight&lt;br /&gt;
 {&lt;br /&gt;
    NSTableColumn *col = [[self tableColumns] objectAtIndex:0];&lt;br /&gt;
    NSFont        *font;&lt;br /&gt;
 &lt;br /&gt;
    font = [[col dataCell] font];&lt;br /&gt;
 &lt;br /&gt;
    [self setRowHeight:[font maximumAdvancement].height];&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Use the method in a category of NSTableView.&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=NSTableView&amp;diff=843</id>
		<title>NSTableView</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=NSTableView&amp;diff=843"/>
		<updated>2005-07-09T01:59:18Z</updated>

		<summary type="html">&lt;p&gt;Quineska: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;NSTableView is located within the AppKit (gnustep-gui library) and is used to create display tables. It uses a delegate model for getting it's data i.e. you give it an object that provides it with the data it should display.&lt;br /&gt;
&lt;br /&gt;
== Code chunks ==&lt;br /&gt;
&lt;br /&gt;
=== Autosize row height according to font ===&lt;br /&gt;
&lt;br /&gt;
Following code autosizes the row height according to the size of data cell font:&lt;br /&gt;
&lt;br /&gt;
 - (void)autosizeRowHeight&lt;br /&gt;
 {&lt;br /&gt;
    NSTableColumn *col = [[self tableColumns] objectAtIndex:0];&lt;br /&gt;
    NSFont        *font;&lt;br /&gt;
 &lt;br /&gt;
    font = [[col dataCell] font];&lt;br /&gt;
 &lt;br /&gt;
    [self setRowHeight:[font maximumAdvancement].height];&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Use the method in a category of NSTableView.&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Language_support&amp;diff=1966</id>
		<title>Language support</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Language_support&amp;diff=1966"/>
		<updated>2005-07-09T01:56:48Z</updated>

		<summary type="html">&lt;p&gt;Quineska: Changed example to code (for distinction)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;You can set your preference of language using the [[defaults]] command. It takes a list of languages, with the most left one being the most preferred. The list should contain at least one preferred language, otherwise GNUstep defaults to English.&lt;br /&gt;
&lt;br /&gt;
Here is an example where the user prefers Turkish, then Dutch, then English.&lt;br /&gt;
&lt;br /&gt;
 defaults write NSGlobalDomain NSLanguages &amp;quot;(Turkish, Dutch, English)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
See also: [[NSDefaults]]&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Framework_wish_list&amp;diff=2042</id>
		<title>Framework wish list</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Framework_wish_list&amp;diff=2042"/>
		<updated>2005-07-09T01:55:57Z</updated>

		<summary type="html">&lt;p&gt;Quineska: Added framwork loading idea&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I would like to see a testsuite and API diffs for Openstep, Gnustep and different Cocoa-Versions.&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
&lt;br /&gt;
It would be good to see a better framework handling mechanism than what we have now. Currently on unix platforms, framework libraries are symbolically linked against in the System/Library/Libraries directory, making them unmoveable and difficult to uninstall (at least, without package managers). On windows, they copied into this directory.&lt;br /&gt;
&lt;br /&gt;
I think it's possible to create an application loader that inserts these directories into the linker's path (on linux at least, simply adding them to LD_LIBRARY_PATH in the environment the program runs in). I was looking at implementing this an application loader (similar to openapp, but in Objective-C with gnustep-base). Preliminary tests would seem to show that this is at least possible on Linux. I believe a similiar solution is feasible on Windows (sticking them into the PATH variable). Does anyone think a solution like this is useful on other Unix platforms? Any better solutions? --[[User:Quineska|ChrisArmstrong]] 03:55, 9 Jul 2005 (CEST)&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Property_Lists&amp;diff=837</id>
		<title>Property Lists</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Property_Lists&amp;diff=837"/>
		<updated>2005-07-07T05:25:45Z</updated>

		<summary type="html">&lt;p&gt;Quineska: Added more information/tips, shortened warning&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;NOTE: this document is still a work in progress. No responsibility is accepted for any problems arising from inaccuracies.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
Property lists are used throughout GNUstep to store defaults, program settings, application meta information, etc. MacOS X uses XML based property lists, but GNUstep uses another property list implementation also (TODO: history of this style of property list). Support for XML property lists is still wanting on some platforms; this situation should improve in the future.&lt;br /&gt;
&lt;br /&gt;
They are composed of a &amp;quot;tree of arrays and dictionary's, which may be embedded inside each other for several layers. TODO: limits of embedding array/dictionaries inside each other.&lt;br /&gt;
&lt;br /&gt;
== Dictionary ==&lt;br /&gt;
&lt;br /&gt;
A dictionary is a list of key-value pairs, where each item in the list has a name associated with it (key) and another type (value), which could be another dictionary, an array or often a string. It programmatically corresponds to NSDictionary/NSMutableDictionary. They take the following syntax:&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
    KeyName1 = Value1;&lt;br /&gt;
    AnotherKeyName = &amp;quot;Value2&amp;quot;;&lt;br /&gt;
    Something = ( &amp;quot;ArrayItem1&amp;quot;, &amp;quot;ArrayItem2&amp;quot;, &amp;quot;ArrayItem3&amp;quot; );&lt;br /&gt;
    Key4 = 0.10;&lt;br /&gt;
    KeyFive = { Dictionary2Key1 = &amp;quot;Something&amp;quot;; AnotherKey = &amp;quot;Somethingelse&amp;quot;; };&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
As can be seen, each key-value pair is seperated by a semi-colon. Within the pair, the key is seperated from the value with an &amp;quot;equals&amp;quot; (=) sign. The key name is arbitrary, and not put in inverted commas (&amp;quot;&amp;quot;). Shown above are:  an unknown type (could be some sort of string - TODO), a string, an array, a number and another dictionary  (respectively).&lt;br /&gt;
&lt;br /&gt;
== Array ==&lt;br /&gt;
&lt;br /&gt;
An array is a list of values, each of the same type (often arrays or dictionaries). Programmatically, it uses NSArray/NSMutableArray. It takes a syntax similar to the following:&lt;br /&gt;
&lt;br /&gt;
 ( Value1, Value2, Value3, Value4 )&amp;lt;br&amp;gt;&lt;br /&gt;
 or&amp;lt;br&amp;gt;&lt;br /&gt;
 (&lt;br /&gt;
    Value1,&lt;br /&gt;
    Value2,&lt;br /&gt;
    Value3,&lt;br /&gt;
    Value4&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Each value is seperated by commas. By the technical definition of an array, each value is of the same type (but I believe GNUstep permits different types TODO: check this).&lt;br /&gt;
&lt;br /&gt;
== Programming ==&lt;br /&gt;
&lt;br /&gt;
GNUstep permits such property list files (denoted with a .plist extenstion) to be loaded and subsequently used in your applications or tools. NSDictionary and NSArray are used as representations of the above in the Foundation library (gnustep-base). Check the base API documentation for more information on working with these types programmatically.&lt;br /&gt;
&lt;br /&gt;
Also, NSString can be used to turn property lists in string form to an equivalent programmatic tree. Again, see the API documentation for NSString (particularly propertyList method).&lt;br /&gt;
&lt;br /&gt;
== Other tips ==&lt;br /&gt;
&lt;br /&gt;
* Property lists are much like C programming, where newlines and spaces and tabs are not so important to parsing.&lt;br /&gt;
* Some examples of property lists may include:&lt;br /&gt;
** ~/GNUstep/System/Defaults/.GNUstepDefaults (this is your defaults file for software; be careful when editing)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Property_Lists&amp;diff=836</id>
		<title>Property Lists</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Property_Lists&amp;diff=836"/>
		<updated>2005-07-07T05:16:32Z</updated>

		<summary type="html">&lt;p&gt;Quineska: Added better Array example.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;NOTE: '''If anything below is dead wrong, please fix immediately. It is a work in progress. I am constructing this based on my experience with GNUstep, NOT any reference documentation that may exist. I don't warrant it fit for any purpose whatsoever, nor shall I take any responsibility for any issues or losses or problems etc that may arise from its use. (Christopher Armstrong, --[[User:Quineska|ChrisArmstrong]] 08:38, 6 Jul 2005 (CEST))'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
Property lists are used throughout GNUstep to store defaults, program settings, application meta information, etc. MacOS X uses XML based property lists, but GNUstep uses another property list implementation also (TODO: history of this style of property list).&lt;br /&gt;
&lt;br /&gt;
They are composed of a &amp;quot;tree of arrays and dictionary's, which may be embedded inside each other for several layers. TODO: limits of embedding array/dictionaries inside each other.&lt;br /&gt;
&lt;br /&gt;
== Dictionary ==&lt;br /&gt;
&lt;br /&gt;
A dictionary is a list of key-value pairs, where each item in the list has a name associated with it (key) and another type (value), which could be another dictionary, an array or often a string. It programmatically corresponds to NSDictionary/NSMutableDictionary. They take the following syntax:&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
    KeyName1 = Value1;&lt;br /&gt;
    AnotherKeyName = &amp;quot;Value2&amp;quot;;&lt;br /&gt;
    Something = ( &amp;quot;ArrayItem1&amp;quot;, &amp;quot;ArrayItem2&amp;quot;, &amp;quot;ArrayItem3&amp;quot; );&lt;br /&gt;
    Key4 = 0.10;&lt;br /&gt;
    KeyFive = { Dictionary2Key1 = &amp;quot;Something&amp;quot;; AnotherKey = &amp;quot;Somethingelse&amp;quot;; };&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
As can be seen, each key-value pair is seperated by a semi-colon. Within the pair, the key is seperated from the value with an &amp;quot;equals&amp;quot; (=) sign. The key name is arbitrary, and not put in inverted commas (&amp;quot;&amp;quot;). Shown above are a (unknown type, could be some sort of string - TODO), a string, an array, a number and another dictionary  (respectively).&lt;br /&gt;
&lt;br /&gt;
== Array ==&lt;br /&gt;
&lt;br /&gt;
An array is a list of values, each of the same type (often arrays or dictionaries). Programmatically, it uses NSArray/NSMutableArray. It takes a syntax similar to the following:&lt;br /&gt;
&lt;br /&gt;
 ( Value1, Value2, Value3, Value4 )&amp;lt;br&amp;gt;&lt;br /&gt;
 or&amp;lt;br&amp;gt;&lt;br /&gt;
 (&lt;br /&gt;
    Value1,&lt;br /&gt;
    Value2,&lt;br /&gt;
    Value3,&lt;br /&gt;
    Value4&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Each value is seperated by commas. By the technical definition of an array, each value is of the same type (but I believe GNUstep permits different types TODO: check this).&lt;br /&gt;
&lt;br /&gt;
== Programming ==&lt;br /&gt;
&lt;br /&gt;
GNUstep permits such property list files (denoted with a .plist extenstion) to be loaded and subsequently used in your applications or tools. NSDictionary and NSArray are used as representations of the above in the Foundation library (gnustep-base).&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Developer_Guides&amp;diff=2027</id>
		<title>Developer Guides</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Developer_Guides&amp;diff=2027"/>
		<updated>2005-07-07T05:15:17Z</updated>

		<summary type="html">&lt;p&gt;Quineska: Fixed link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Coding for portability ==&lt;br /&gt;
&lt;br /&gt;
Writing code that will compile and then run on different platforms can be surprisingly easy. [[Writing portable code]] describes some straight-forward steps to take to make your program easy to port to new platforms.&lt;br /&gt;
&lt;br /&gt;
== Document based application design ==&lt;br /&gt;
&lt;br /&gt;
One of the most common use-patterns of applications on modern platforms is that of document-based applications - applications which can have several active user-controlled contexts. &lt;br /&gt;
&lt;br /&gt;
Some familar examples might be a word processor where the user may have multiple document windows concurrently, or a web browser which allows a user to have a number of different browser windows open at the same time.&lt;br /&gt;
&lt;br /&gt;
[[Document based applications]] provides information and tips on how to code this style of application.&lt;br /&gt;
&lt;br /&gt;
== Using property lists ==&lt;br /&gt;
&lt;br /&gt;
A regular issue that programmers face is storing structured configuration information, and reading it back. GNUstep has a standard mechanism that can be used for this task, amongst others: [[Property Lists]].&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Talk:Creating_document_based_applications&amp;diff=2041</id>
		<title>Talk:Creating document based applications</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Talk:Creating_document_based_applications&amp;diff=2041"/>
		<updated>2005-07-07T05:13:30Z</updated>

		<summary type="html">&lt;p&gt;Quineska: Discussion added&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Feel free to make corrections, fix grammatical/spelling anomalies, add extra information, etc. This is a first revision, so corrections are likely needed. --[[User:Quineska|ChrisArmstrong]] 07:13, 7 Jul 2005 (CEST)&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Creating_document_based_applications&amp;diff=844</id>
		<title>Creating document based applications</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Creating_document_based_applications&amp;diff=844"/>
		<updated>2005-07-07T05:10:56Z</updated>

		<summary type="html">&lt;p&gt;Quineska: /* The Makefile */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Note: First version; subject to further revisions and changes.&lt;br /&gt;
--[[User:Quineska|ChrisArmstrong]] 07:09, 7 Jul 2005 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
OpenStep can provide your application a document-based model. It helps to simplify the process of creating such applications. GNUstep is compatible with this paridgm as well; this document aims to provide an overview of what is required in the creation and design of such an application.&lt;br /&gt;
&lt;br /&gt;
It is assumed you are familiar with GNUstep, and have some understanding as how to create Gorm's nib files, as well as some understanding of how they work.&lt;br /&gt;
&lt;br /&gt;
Importantly, such applications have certain components that are required, and should be considered as part of their design. At a programmatic level, classes that will be used as part of the AppKit are:&lt;br /&gt;
&lt;br /&gt;
==== NSDocument ====&lt;br /&gt;
&lt;br /&gt;
This class is central to the OpenStep document based model. Such an application declares a new instance of a subclass of NSDocument for each “document” that is opened. It will be necessary to subclass NSDocument to implement this.&lt;br /&gt;
&lt;br /&gt;
Each instance of your NSDocument subclass may have one or more windows associated with it. These are used as an interface for loading and saving a representation of your document type. Each window will have an “NSWindowController” instance associated with it, where NSDocument maintains a list of these.&lt;br /&gt;
&lt;br /&gt;
==== NSDocumentController ====&lt;br /&gt;
&lt;br /&gt;
This class acts a controller. It maintains a list of documents (instances of your NSDocument subclass) and is responsible for loading and instantiating new documents. It is usually not necessary to implement a subclass of this, but often it may be useful to implement special functionality (especially related to open documents as a whole).&lt;br /&gt;
&lt;br /&gt;
==== NSWindowController ====&lt;br /&gt;
&lt;br /&gt;
As mentioned above, NSWindowController instances are individually associated with one NSWindow instance, in such a way that a document maintains a list of window controllers that are reponsible for rendering the views associated with a document.&lt;br /&gt;
&lt;br /&gt;
You will most likely not have to subclass NSWindowController. Instead, you associate a nib file (the Gorm output) with the subclass of NSDocument, and NSDocumentController will load this nib file for each document that is created or loaded.&lt;br /&gt;
&lt;br /&gt;
For example, a text based application that is used for the editing of plain text files, may subclass NSDocument with a TextDocument class. Each instance of this class would have an NSWindowController instance associated with it, which in turn manages a window instance that is instantiated from a nib file. The NSDocumentController instance, as managed and instatiated by GNUstep, would be responsible for loading and saving documents in your application. It even prompts the user to save their documents when they try to quit the application.&lt;br /&gt;
&lt;br /&gt;
== File Components ==&lt;br /&gt;
&lt;br /&gt;
In building your application you will need to create a number of special files. From scratch, the following should be a rough guide to getting it working. These include the Makefile, your application's property list and the interface files.&lt;br /&gt;
&lt;br /&gt;
=== The Makefile ===&lt;br /&gt;
&lt;br /&gt;
For this type of application, no special makefile is needed: it just has to be a normal application. Project Builder should be able to spit out the required makefile and Gorm files that are needed for a generic application. I believe it is also capable of providing support for document-based applications. Otherwise use the following as a template:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''GNUmakefile'''&lt;br /&gt;
&lt;br /&gt;
 include $(GNUSTEP_MAKEFILES)/common.make&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 APP_NAME = DocumentApp&amp;lt;br&amp;gt;&lt;br /&gt;
 DocumentApp_OBJC_FILES =&amp;lt;br&amp;gt;&lt;br /&gt;
  MyDocument.m &amp;lt;br&amp;gt;&lt;br /&gt;
  main.m&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 DocumentApp_RESOURCES = \ &amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/Info-gnustep.plist \&amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/DocumentApp.gorm \&amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/MyDocument.gorm&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 -include GNUmakefile.preamble&amp;lt;br&amp;gt;&lt;br /&gt;
 include $(GNUSTEP_MAKEFILES)/application.make&amp;lt;br&amp;gt;&lt;br /&gt;
 -include GNUmakefile.postamble&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For more information as to customising this file, as well as setting up compiler options for third party libraries and includes, see the GNUstep makefile manual.&lt;br /&gt;
&lt;br /&gt;
===The application dictionary===&lt;br /&gt;
&lt;br /&gt;
For those that have edited this file in their project before, it is a dictionary with various values entered. For our purposes, we need an array within the main dictionary, called &amp;quot;NSTypes&amp;quot;. This is a array of unnamed dictionaries, with one dictionary for each type. &lt;br /&gt;
&lt;br /&gt;
An entire example of this file, for a &amp;quot;theoretical&amp;quot; TextEdit application (please note that such an application does exist as an example application from Next I think, and again on MacOS X but I have constructed a much simpler version, used only for plain text files).&lt;br /&gt;
&lt;br /&gt;
Taking a look at the single dictionary entry in the NSTypes array, the following key-value pairs are needed:&lt;br /&gt;
* '''NSDocumentClass:''' This is (string) the subclass name you use in your code, the &amp;quot;objective-c name&amp;quot; of your document subclass. This is used by NSDocumentController's default implementation to create instances of your document type.&lt;br /&gt;
* '''NSName:''' The generic file type (string). This is completely arbitrary, and can be anything you like. For the purpose of conventions, it may be more appropriate not to use the &amp;quot;NS&amp;quot; or &amp;quot;GS&amp;quot; prefix (the latter of which I not sure), and instead use either your own, or no prefix at all.&lt;br /&gt;
* '''NSHumanReadableName:''' The human readable name of your document type (string)? TODO: explain where this is used.&lt;br /&gt;
* '''NSUnixExtensions:''' An array of strings, each containing a file extension connected to this document type on &amp;quot;unix&amp;quot; platforms. TODO: explain how &amp;quot;unix&amp;quot; is interpreted by GNUstep.&lt;br /&gt;
* '''NSDOSExtensions:''' An array of strings, each containing a file extenstion connected to this document type on &amp;quot;DOS&amp;quot; platforms (could be loosely interpreted as any MS platforms GNUstep runs on, i.e. Windows 2000/XP).&lt;br /&gt;
* '''NSRole:''' A string, either &amp;quot;Viewer&amp;quot; or &amp;quot;Editor&amp;quot;, depending on how your document operates on this file type.&lt;br /&gt;
* '''NSIcon:''' A icon name associated with this document type. TODO: Investigate how this works.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Info-gnustep.plist'''&lt;br /&gt;
 {&lt;br /&gt;
     ApplicationDescription = &amp;quot;A simple text editor for GNUstep.&amp;quot;;&lt;br /&gt;
     ApplicationName = TextEdit;&lt;br /&gt;
     ApplicationRelease = 0.10;&lt;br /&gt;
     Authors = ( &amp;quot;Christopher Armstrong&amp;quot; );&lt;br /&gt;
     Copyright = &amp;quot;Copyright (C) 2005 Christopher Armstrong&amp;quot;;&lt;br /&gt;
     CopyrightDescription = &amp;quot;Released under GPL.&amp;quot;;&lt;br /&gt;
     FullVersionID = 0.10;&lt;br /&gt;
     NSExecutable = TextEdit;&lt;br /&gt;
     NSMainNibFile = TextEdit.gorm;&lt;br /&gt;
     NSPrincipalClass = NSApplication;&lt;br /&gt;
     NSRole = Application;&lt;br /&gt;
     NSTypes = (&lt;br /&gt;
         {&lt;br /&gt;
                 NSDocumentClass = &amp;quot;TextDocument&amp;quot;;&lt;br /&gt;
                 NSName = &amp;quot;GSTextDocumentType&amp;quot;;&lt;br /&gt;
                 NSHumanReadableName = &amp;quot;Text Document&amp;quot;;&lt;br /&gt;
                 NSUnixExtensions = ( &amp;quot;txt&amp;quot;, &amp;quot;&amp;quot; );&lt;br /&gt;
                 NSDOSExtensions = ( &amp;quot;txt&amp;quot; );&lt;br /&gt;
                 NSRole = Editor;&lt;br /&gt;
         }&lt;br /&gt;
     );&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For more information on property list files, consult [[Property Lists]].&lt;br /&gt;
&lt;br /&gt;
=== Interface files ===&lt;br /&gt;
&lt;br /&gt;
Two interface files are needed: one for your main application, and another that will be instantiated with each instance of your document subclass. These both should be listed as resources in your makefile, (as shown the GNUmakefile example above). It may be helpful to name the document nib file after your class.&lt;br /&gt;
&lt;br /&gt;
==== Application Interface File ====&lt;br /&gt;
&lt;br /&gt;
The application one should just be a menu (though it could be more if necessary). When constructing it, take the following into account:&lt;br /&gt;
&lt;br /&gt;
* Use a standard Gorm template for an Application.&lt;br /&gt;
* Delete the window instance in the &amp;quot;Objects&amp;quot; pane (unless you need a main window, in which case I don't know how to operate).&lt;br /&gt;
* Set NSOwner's class to &amp;quot;NSDocumentController&amp;quot; (this is the custom class option of NSOwner in the property inspector). This ensures openDocument, newDocument, etc. messages, as sent to NSFirst, get picked up by NSDocumentController. Do not instantiate it (I believe you can't anyway).&lt;br /&gt;
* If you intend to subclass NSDocumentController, subclass it in the Classes pane. To make sure that this class is instantiated and used, make sure you instantiate it in Gorm or in your main.m file, and set NSOwner to be your subclass.&lt;br /&gt;
* Drag a Document menu from the palette onto your main menu. This already has the proper linkage for each relevant message for a document setup to be directed to NSFirst. In the case of generic messages (such as openDocument:, not associated with any document instance), these are forwarded to the shared instance of NSDocumentController (see it's reference documentation). When a document is active, more specific messages (such as close: or saveDocument:) are forwarded to the relevant document instance of your NSDocument subclass.&lt;br /&gt;
* Add any appropriate menus such as &amp;quot;Info&amp;quot; and &amp;quot;Format&amp;quot; which may be relevant to your application.&lt;br /&gt;
&lt;br /&gt;
==== Document Interface File(s) ====&lt;br /&gt;
&lt;br /&gt;
The document interface file is (generically) a window containing the view(s) required for the implementation of one instance of your document type. For example, in the case of a TextDocument type, a window instance with a NSTextView drawn on it is used for each open window. This nib file is instantiated every time a person creates a new document (the newDocument: message goes to NSDocumentController) or opens an existing document (openDocument:).&lt;br /&gt;
&lt;br /&gt;
You will need to:&lt;br /&gt;
* '''Subclass NSDocument''' with your document type in Gorm (this is done in a couple of ways, see [[Gorm_Manual#Custom_classes|custom classes]]).&lt;br /&gt;
* '''Set NSOwner:''' Set your subclass as NSOwner's Custom class (done using the Property inspector). DO NOT INSTANTIATE IT.&lt;br /&gt;
&lt;br /&gt;
Another thing that you may want to consider is custom outlets. If you place certain views or controls on your window (including the window itself), you may want to refer to them directly in yout code, e.g. the NSTextView in our TextEdit example is accessed directly, so that we can save it's contents to a file. To enable this, we add outlets to our class (see [[Gorm_Manual#Custom_classes|custom classes]]). We then connected NSOwner to the appropriate controls/views, and selected the outlets in the Connections property inspector (see [[Gorm_Manual#Editing_the_interface|editing the interface]]).&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
Various things need to be done at a code level, to ensure that your NSDocument subclass is properly instantiated. This section aims to tell you what is necessary.&lt;br /&gt;
&lt;br /&gt;
=== NSDocument subclass ===&lt;br /&gt;
&lt;br /&gt;
When creating your subclass, you may have chosen to have Gorm create the class files. If not, you should create two files for your subclass: a header (.h) file and an implementation file (.m). The header file should take the following layout (we're using the TextEdit example again):&lt;br /&gt;
&lt;br /&gt;
 #ifndef TEXTDOCUMENT_H&lt;br /&gt;
 #define TEXTDOCUMENT_H &amp;lt;br&amp;gt;&lt;br /&gt;
 #include &amp;lt;AppKit/AppKit.h&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
 @class NSDocument; &amp;lt;br&amp;gt;&lt;br /&gt;
 /* The document type string, as specified in the property list [[#The_application_dictionary|NSTypes array]] */ &amp;lt;br&amp;gt;&lt;br /&gt;
 NSString * GSTextDocumentType = &amp;quot;GSTextDocumentType&amp;quot;;&lt;br /&gt;
 @interface TextDocument : NSDocument&lt;br /&gt;
 {&lt;br /&gt;
 @protected&lt;br /&gt;
     /* Outlets we added in our Gorm nib file */&lt;br /&gt;
     id * textView;&lt;br /&gt;
 }&lt;br /&gt;
 /* Basic methods used for loading and saving document data (respectively). */&lt;br /&gt;
 - (BOOL) loadDataRepresentation:(NSData*)representation ofType:(NSString*)type;&lt;br /&gt;
 - (NSData*) dataRepresentationOfType: (NSString*)type; &amp;lt;br&amp;gt;&lt;br /&gt;
 /* Information and events handling of GUI related changes */&lt;br /&gt;
 - (NSString*) windowNibName;&lt;br /&gt;
 - (void) windowControllerDidLoadNib:(NSWindowController*)windowController; &amp;lt;br&amp;gt;&lt;br /&gt;
 @end&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Firstly, take note that we inherit from NSDocument. As a result, we need to override some methods for a basic (but working) implementation. &lt;br /&gt;
&lt;br /&gt;
==== loadDataRepresentation:ofType: and dataRepresentationOfType: ====&lt;br /&gt;
&lt;br /&gt;
The methods, loadDataRepresent:ofType: and dataRepresentationOfType: are used by NSDocumentController to load and save our files. The first method is called when the user trys to open a document (NSDocumentController gets the file name and copies it's data using an open panel). The method is passed the raw data in this file, as well as a string representing its type. It is important to note that this type string is the same one used in your property list. It is used by NSDocumentController to tell you what type it thinks you should open the data with. If this is not possible, or if there is an error trying to parse the data, your method returns FALSE/NO. Otherwise, you should store a local, meaningful representation of the data, which you can insert into your document window a little later (and return YES).&lt;br /&gt;
&lt;br /&gt;
For example, in terms of the TextEdit example:&lt;br /&gt;
 - (BOOL) loadDataRepresentation:(NSData*) representation ofType:(NSString*)type&lt;br /&gt;
 {&lt;br /&gt;
    /*Check type information */&lt;br /&gt;
    if ([representation equalTo:GSTextDocumentType]==NO)&lt;br /&gt;
        return NO;&lt;br /&gt;
    /* Clean out our old representation if it still exists */&lt;br /&gt;
    if (fileContents) RELEASE(fileContents); &amp;lt;br&amp;gt;&lt;br /&gt;
    /* Allocate room for the new data, and try to initialise a string with it. */&lt;br /&gt;
    self-&amp;gt;fileContents = [NSString alloc];&lt;br /&gt;
    fileContents = [fileContents initWithBytes: [representation bytes]&lt;br /&gt;
                         length: [representation length]&lt;br /&gt;
                       encoding: NSASCIIStringEncoding]; &amp;lt;br&amp;gt;&lt;br /&gt;
    /* If this can't be done, return NO */&lt;br /&gt;
    if (!fileContents)&lt;br /&gt;
        return NO; &amp;lt;br&amp;gt;&lt;br /&gt;
    /* Otherwise, set our TextView to the string data. */&lt;br /&gt;
    [self-&amp;gt;textView setString: fileContents];&lt;br /&gt;
    return YES;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
If this is not suffice, or if your program can open the data in a more efficient manner, it may be worth looking into overriding -initWithContentsOfFile:ofType: and -initWithContentsOfURL:ofType: (see the GUI manual for more details).&lt;br /&gt;
&lt;br /&gt;
dataRepresentationOfType: is used to save the data. Your method is expected to return an instance of NSData that contains what should be saved to a file, for the type specified. Again, the ''type'' variable should be checked to ensure that you can write data of that type. Return nil if the file cannot be saved as that type.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
 - (NSData*) dataRepresentationOfType:(NSString*)type&lt;br /&gt;
 {&lt;br /&gt;
     if ([type equalTo:GSTextDocumentType]==NO)&lt;br /&gt;
         return nil; &amp;lt;br&amp;gt;&lt;br /&gt;
     NSData stringData =  [[textView string] dataUsingEncoding:NSASCIIStringEncoding];  &lt;br /&gt;
     return stringData; &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
If a more sophisticated save implementation is needed, consult the documentation for information on the writeTo methods.&lt;br /&gt;
&lt;br /&gt;
==== windowNibName ====&lt;br /&gt;
&lt;br /&gt;
This method must be overriden to return the a string of the name of your nib file (without the file extention). More complex implementations will use other methods to load the interface files. TODO: information on what methods need to be overriden.&lt;br /&gt;
&lt;br /&gt;
==== windowControllerDidLoadNib: ====&lt;br /&gt;
&lt;br /&gt;
Use this method to add code that should be run as soon as ''windowController'' has been initialised. Your document may have many window controllers; each window controller taking possession of one window.&lt;br /&gt;
&lt;br /&gt;
In the TextEdit example, this method is used to copy the fileContents object ivar to the text view. It otherwise initialises the document window. &lt;br /&gt;
&lt;br /&gt;
Also note that you can override windowControllerWillLoadNib: to perform pre-nib loading initialisation.&lt;br /&gt;
&lt;br /&gt;
==== makeWindowControllers ====&lt;br /&gt;
&lt;br /&gt;
This is an optional method override, which must be used if you have multiple window controllers per document. It is responsible for creating each window controller from it's nib and then adding it to the document. Use the addWindowController: method.&lt;br /&gt;
&lt;br /&gt;
==== Other considerations ====&lt;br /&gt;
&lt;br /&gt;
* You need a way to notify NSDocument that your document has changed, so that NSDocumentController can enable the menu item to allow saving. This is done by a call to the updateChangeCount: method. For example, the TextDocument class adds itself as a delegate to the textView, for any notification of changes. It then calls updateChangeCount: in the delegate's method.&lt;br /&gt;
&lt;br /&gt;
* You may also wish to add a close: method (not the close method already in NSDocument, see below) to respond to the menu item permitting your document to close. This could perform cleanup operations before a call to [super close] is called e.g.&lt;br /&gt;
&lt;br /&gt;
 - (void) close:(id)sender /* Note this is not the method found in NSDocument (they differ by a parameter) */&lt;br /&gt;
 {&lt;br /&gt;
     [self close];&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== NSDocumentController ===&lt;br /&gt;
&lt;br /&gt;
This class can optionally be subclassed, to implement some specific functionality. For example, programs handling multiple document types may override newDocument: to create a window so that the user can select which document type to create.&lt;br /&gt;
&lt;br /&gt;
You should use separate implementation files and add the .m file to GNUmakefile.&lt;br /&gt;
&lt;br /&gt;
=== NSWindowController ===&lt;br /&gt;
&lt;br /&gt;
This class can also be optionally subclassed, to implement functionality specific to a window controller for a document type. You may need to override makeWindowControllers: in the NSDocument subclass in order to make sure your specific window controller is instantiated.&lt;br /&gt;
&lt;br /&gt;
You should use separate implemenatino files and add the .m file to GNUmakefile.&lt;br /&gt;
&lt;br /&gt;
== Optional Additions ==&lt;br /&gt;
&lt;br /&gt;
=== Custom NSDocumentController and NSWindowController implementations ===&lt;br /&gt;
&lt;br /&gt;
See [[#NSWindowController|NSWindowController]] and [[#NSDocumentController|NSDocumentController]].&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Creating_document_based_applications&amp;diff=833</id>
		<title>Creating document based applications</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Creating_document_based_applications&amp;diff=833"/>
		<updated>2005-07-07T05:09:19Z</updated>

		<summary type="html">&lt;p&gt;Quineska: First revision complete&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Note: First version; subject to further revisions and changes.&lt;br /&gt;
--[[User:Quineska|ChrisArmstrong]] 07:09, 7 Jul 2005 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
OpenStep can provide your application a document-based model. It helps to simplify the process of creating such applications. GNUstep is compatible with this paridgm as well; this document aims to provide an overview of what is required in the creation and design of such an application.&lt;br /&gt;
&lt;br /&gt;
It is assumed you are familiar with GNUstep, and have some understanding as how to create Gorm's nib files, as well as some understanding of how they work.&lt;br /&gt;
&lt;br /&gt;
Importantly, such applications have certain components that are required, and should be considered as part of their design. At a programmatic level, classes that will be used as part of the AppKit are:&lt;br /&gt;
&lt;br /&gt;
==== NSDocument ====&lt;br /&gt;
&lt;br /&gt;
This class is central to the OpenStep document based model. Such an application declares a new instance of a subclass of NSDocument for each “document” that is opened. It will be necessary to subclass NSDocument to implement this.&lt;br /&gt;
&lt;br /&gt;
Each instance of your NSDocument subclass may have one or more windows associated with it. These are used as an interface for loading and saving a representation of your document type. Each window will have an “NSWindowController” instance associated with it, where NSDocument maintains a list of these.&lt;br /&gt;
&lt;br /&gt;
==== NSDocumentController ====&lt;br /&gt;
&lt;br /&gt;
This class acts a controller. It maintains a list of documents (instances of your NSDocument subclass) and is responsible for loading and instantiating new documents. It is usually not necessary to implement a subclass of this, but often it may be useful to implement special functionality (especially related to open documents as a whole).&lt;br /&gt;
&lt;br /&gt;
==== NSWindowController ====&lt;br /&gt;
&lt;br /&gt;
As mentioned above, NSWindowController instances are individually associated with one NSWindow instance, in such a way that a document maintains a list of window controllers that are reponsible for rendering the views associated with a document.&lt;br /&gt;
&lt;br /&gt;
You will most likely not have to subclass NSWindowController. Instead, you associate a nib file (the Gorm output) with the subclass of NSDocument, and NSDocumentController will load this nib file for each document that is created or loaded.&lt;br /&gt;
&lt;br /&gt;
For example, a text based application that is used for the editing of plain text files, may subclass NSDocument with a TextDocument class. Each instance of this class would have an NSWindowController instance associated with it, which in turn manages a window instance that is instantiated from a nib file. The NSDocumentController instance, as managed and instatiated by GNUstep, would be responsible for loading and saving documents in your application. It even prompts the user to save their documents when they try to quit the application.&lt;br /&gt;
&lt;br /&gt;
== File Components ==&lt;br /&gt;
&lt;br /&gt;
In building your application you will need to create a number of special files. From scratch, the following should be a rough guide to getting it working. These include the Makefile, your application's property list and the interface files.&lt;br /&gt;
&lt;br /&gt;
=== The Makefile ===&lt;br /&gt;
&lt;br /&gt;
For this type of application, no special makefile is needed: it just has to be a normal application. Project Builder should be able to spit out the required makefile and Gorm files that are needed for a generic application. Otherwise use the following as a template:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''GNUmakefile'''&lt;br /&gt;
&lt;br /&gt;
 include $(GNUSTEP_MAKEFILES)/common.make&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 APP_NAME = DocumentApp&amp;lt;br&amp;gt;&lt;br /&gt;
 DocumentApp_OBJC_FILES =&amp;lt;br&amp;gt;&lt;br /&gt;
  MyDocument.m &amp;lt;br&amp;gt;&lt;br /&gt;
  main.m&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 DocumentApp_RESOURCES = \ &amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/Info-gnustep.plist \&amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/DocumentApp.gorm \&amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/MyDocument.gorm&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 -include GNUmakefile.preamble&amp;lt;br&amp;gt;&lt;br /&gt;
 include $(GNUSTEP_MAKEFILES)/application.make&amp;lt;br&amp;gt;&lt;br /&gt;
 -include GNUmakefile.postamble&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For more information as to customising this file, as well as setting up compiler options for third party libraries and includes, see the GNUstep makefile manual.&lt;br /&gt;
&lt;br /&gt;
===The application dictionary===&lt;br /&gt;
&lt;br /&gt;
For those that have edited this file in their project before, it is a dictionary with various values entered. For our purposes, we need an array within the main dictionary, called &amp;quot;NSTypes&amp;quot;. This is a array of unnamed dictionaries, with one dictionary for each type. &lt;br /&gt;
&lt;br /&gt;
An entire example of this file, for a &amp;quot;theoretical&amp;quot; TextEdit application (please note that such an application does exist as an example application from Next I think, and again on MacOS X but I have constructed a much simpler version, used only for plain text files).&lt;br /&gt;
&lt;br /&gt;
Taking a look at the single dictionary entry in the NSTypes array, the following key-value pairs are needed:&lt;br /&gt;
* '''NSDocumentClass:''' This is (string) the subclass name you use in your code, the &amp;quot;objective-c name&amp;quot; of your document subclass. This is used by NSDocumentController's default implementation to create instances of your document type.&lt;br /&gt;
* '''NSName:''' The generic file type (string). This is completely arbitrary, and can be anything you like. For the purpose of conventions, it may be more appropriate not to use the &amp;quot;NS&amp;quot; or &amp;quot;GS&amp;quot; prefix (the latter of which I not sure), and instead use either your own, or no prefix at all.&lt;br /&gt;
* '''NSHumanReadableName:''' The human readable name of your document type (string)? TODO: explain where this is used.&lt;br /&gt;
* '''NSUnixExtensions:''' An array of strings, each containing a file extension connected to this document type on &amp;quot;unix&amp;quot; platforms. TODO: explain how &amp;quot;unix&amp;quot; is interpreted by GNUstep.&lt;br /&gt;
* '''NSDOSExtensions:''' An array of strings, each containing a file extenstion connected to this document type on &amp;quot;DOS&amp;quot; platforms (could be loosely interpreted as any MS platforms GNUstep runs on, i.e. Windows 2000/XP).&lt;br /&gt;
* '''NSRole:''' A string, either &amp;quot;Viewer&amp;quot; or &amp;quot;Editor&amp;quot;, depending on how your document operates on this file type.&lt;br /&gt;
* '''NSIcon:''' A icon name associated with this document type. TODO: Investigate how this works.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Info-gnustep.plist'''&lt;br /&gt;
 {&lt;br /&gt;
     ApplicationDescription = &amp;quot;A simple text editor for GNUstep.&amp;quot;;&lt;br /&gt;
     ApplicationName = TextEdit;&lt;br /&gt;
     ApplicationRelease = 0.10;&lt;br /&gt;
     Authors = ( &amp;quot;Christopher Armstrong&amp;quot; );&lt;br /&gt;
     Copyright = &amp;quot;Copyright (C) 2005 Christopher Armstrong&amp;quot;;&lt;br /&gt;
     CopyrightDescription = &amp;quot;Released under GPL.&amp;quot;;&lt;br /&gt;
     FullVersionID = 0.10;&lt;br /&gt;
     NSExecutable = TextEdit;&lt;br /&gt;
     NSMainNibFile = TextEdit.gorm;&lt;br /&gt;
     NSPrincipalClass = NSApplication;&lt;br /&gt;
     NSRole = Application;&lt;br /&gt;
     NSTypes = (&lt;br /&gt;
         {&lt;br /&gt;
                 NSDocumentClass = &amp;quot;TextDocument&amp;quot;;&lt;br /&gt;
                 NSName = &amp;quot;GSTextDocumentType&amp;quot;;&lt;br /&gt;
                 NSHumanReadableName = &amp;quot;Text Document&amp;quot;;&lt;br /&gt;
                 NSUnixExtensions = ( &amp;quot;txt&amp;quot;, &amp;quot;&amp;quot; );&lt;br /&gt;
                 NSDOSExtensions = ( &amp;quot;txt&amp;quot; );&lt;br /&gt;
                 NSRole = Editor;&lt;br /&gt;
         }&lt;br /&gt;
     );&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For more information on property list files, consult [[Property Lists]].&lt;br /&gt;
&lt;br /&gt;
=== Interface files ===&lt;br /&gt;
&lt;br /&gt;
Two interface files are needed: one for your main application, and another that will be instantiated with each instance of your document subclass. These both should be listed as resources in your makefile, (as shown the GNUmakefile example above). It may be helpful to name the document nib file after your class.&lt;br /&gt;
&lt;br /&gt;
==== Application Interface File ====&lt;br /&gt;
&lt;br /&gt;
The application one should just be a menu (though it could be more if necessary). When constructing it, take the following into account:&lt;br /&gt;
&lt;br /&gt;
* Use a standard Gorm template for an Application.&lt;br /&gt;
* Delete the window instance in the &amp;quot;Objects&amp;quot; pane (unless you need a main window, in which case I don't know how to operate).&lt;br /&gt;
* Set NSOwner's class to &amp;quot;NSDocumentController&amp;quot; (this is the custom class option of NSOwner in the property inspector). This ensures openDocument, newDocument, etc. messages, as sent to NSFirst, get picked up by NSDocumentController. Do not instantiate it (I believe you can't anyway).&lt;br /&gt;
* If you intend to subclass NSDocumentController, subclass it in the Classes pane. To make sure that this class is instantiated and used, make sure you instantiate it in Gorm or in your main.m file, and set NSOwner to be your subclass.&lt;br /&gt;
* Drag a Document menu from the palette onto your main menu. This already has the proper linkage for each relevant message for a document setup to be directed to NSFirst. In the case of generic messages (such as openDocument:, not associated with any document instance), these are forwarded to the shared instance of NSDocumentController (see it's reference documentation). When a document is active, more specific messages (such as close: or saveDocument:) are forwarded to the relevant document instance of your NSDocument subclass.&lt;br /&gt;
* Add any appropriate menus such as &amp;quot;Info&amp;quot; and &amp;quot;Format&amp;quot; which may be relevant to your application.&lt;br /&gt;
&lt;br /&gt;
==== Document Interface File(s) ====&lt;br /&gt;
&lt;br /&gt;
The document interface file is (generically) a window containing the view(s) required for the implementation of one instance of your document type. For example, in the case of a TextDocument type, a window instance with a NSTextView drawn on it is used for each open window. This nib file is instantiated every time a person creates a new document (the newDocument: message goes to NSDocumentController) or opens an existing document (openDocument:).&lt;br /&gt;
&lt;br /&gt;
You will need to:&lt;br /&gt;
* '''Subclass NSDocument''' with your document type in Gorm (this is done in a couple of ways, see [[Gorm_Manual#Custom_classes|custom classes]]).&lt;br /&gt;
* '''Set NSOwner:''' Set your subclass as NSOwner's Custom class (done using the Property inspector). DO NOT INSTANTIATE IT.&lt;br /&gt;
&lt;br /&gt;
Another thing that you may want to consider is custom outlets. If you place certain views or controls on your window (including the window itself), you may want to refer to them directly in yout code, e.g. the NSTextView in our TextEdit example is accessed directly, so that we can save it's contents to a file. To enable this, we add outlets to our class (see [[Gorm_Manual#Custom_classes|custom classes]]). We then connected NSOwner to the appropriate controls/views, and selected the outlets in the Connections property inspector (see [[Gorm_Manual#Editing_the_interface|editing the interface]]).&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
Various things need to be done at a code level, to ensure that your NSDocument subclass is properly instantiated. This section aims to tell you what is necessary.&lt;br /&gt;
&lt;br /&gt;
=== NSDocument subclass ===&lt;br /&gt;
&lt;br /&gt;
When creating your subclass, you may have chosen to have Gorm create the class files. If not, you should create two files for your subclass: a header (.h) file and an implementation file (.m). The header file should take the following layout (we're using the TextEdit example again):&lt;br /&gt;
&lt;br /&gt;
 #ifndef TEXTDOCUMENT_H&lt;br /&gt;
 #define TEXTDOCUMENT_H &amp;lt;br&amp;gt;&lt;br /&gt;
 #include &amp;lt;AppKit/AppKit.h&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
 @class NSDocument; &amp;lt;br&amp;gt;&lt;br /&gt;
 /* The document type string, as specified in the property list [[#The_application_dictionary|NSTypes array]] */ &amp;lt;br&amp;gt;&lt;br /&gt;
 NSString * GSTextDocumentType = &amp;quot;GSTextDocumentType&amp;quot;;&lt;br /&gt;
 @interface TextDocument : NSDocument&lt;br /&gt;
 {&lt;br /&gt;
 @protected&lt;br /&gt;
     /* Outlets we added in our Gorm nib file */&lt;br /&gt;
     id * textView;&lt;br /&gt;
 }&lt;br /&gt;
 /* Basic methods used for loading and saving document data (respectively). */&lt;br /&gt;
 - (BOOL) loadDataRepresentation:(NSData*)representation ofType:(NSString*)type;&lt;br /&gt;
 - (NSData*) dataRepresentationOfType: (NSString*)type; &amp;lt;br&amp;gt;&lt;br /&gt;
 /* Information and events handling of GUI related changes */&lt;br /&gt;
 - (NSString*) windowNibName;&lt;br /&gt;
 - (void) windowControllerDidLoadNib:(NSWindowController*)windowController; &amp;lt;br&amp;gt;&lt;br /&gt;
 @end&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Firstly, take note that we inherit from NSDocument. As a result, we need to override some methods for a basic (but working) implementation. &lt;br /&gt;
&lt;br /&gt;
==== loadDataRepresentation:ofType: and dataRepresentationOfType: ====&lt;br /&gt;
&lt;br /&gt;
The methods, loadDataRepresent:ofType: and dataRepresentationOfType: are used by NSDocumentController to load and save our files. The first method is called when the user trys to open a document (NSDocumentController gets the file name and copies it's data using an open panel). The method is passed the raw data in this file, as well as a string representing its type. It is important to note that this type string is the same one used in your property list. It is used by NSDocumentController to tell you what type it thinks you should open the data with. If this is not possible, or if there is an error trying to parse the data, your method returns FALSE/NO. Otherwise, you should store a local, meaningful representation of the data, which you can insert into your document window a little later (and return YES).&lt;br /&gt;
&lt;br /&gt;
For example, in terms of the TextEdit example:&lt;br /&gt;
 - (BOOL) loadDataRepresentation:(NSData*) representation ofType:(NSString*)type&lt;br /&gt;
 {&lt;br /&gt;
    /*Check type information */&lt;br /&gt;
    if ([representation equalTo:GSTextDocumentType]==NO)&lt;br /&gt;
        return NO;&lt;br /&gt;
    /* Clean out our old representation if it still exists */&lt;br /&gt;
    if (fileContents) RELEASE(fileContents); &amp;lt;br&amp;gt;&lt;br /&gt;
    /* Allocate room for the new data, and try to initialise a string with it. */&lt;br /&gt;
    self-&amp;gt;fileContents = [NSString alloc];&lt;br /&gt;
    fileContents = [fileContents initWithBytes: [representation bytes]&lt;br /&gt;
                         length: [representation length]&lt;br /&gt;
                       encoding: NSASCIIStringEncoding]; &amp;lt;br&amp;gt;&lt;br /&gt;
    /* If this can't be done, return NO */&lt;br /&gt;
    if (!fileContents)&lt;br /&gt;
        return NO; &amp;lt;br&amp;gt;&lt;br /&gt;
    /* Otherwise, set our TextView to the string data. */&lt;br /&gt;
    [self-&amp;gt;textView setString: fileContents];&lt;br /&gt;
    return YES;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
If this is not suffice, or if your program can open the data in a more efficient manner, it may be worth looking into overriding -initWithContentsOfFile:ofType: and -initWithContentsOfURL:ofType: (see the GUI manual for more details).&lt;br /&gt;
&lt;br /&gt;
dataRepresentationOfType: is used to save the data. Your method is expected to return an instance of NSData that contains what should be saved to a file, for the type specified. Again, the ''type'' variable should be checked to ensure that you can write data of that type. Return nil if the file cannot be saved as that type.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
 - (NSData*) dataRepresentationOfType:(NSString*)type&lt;br /&gt;
 {&lt;br /&gt;
     if ([type equalTo:GSTextDocumentType]==NO)&lt;br /&gt;
         return nil; &amp;lt;br&amp;gt;&lt;br /&gt;
     NSData stringData =  [[textView string] dataUsingEncoding:NSASCIIStringEncoding];  &lt;br /&gt;
     return stringData; &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
If a more sophisticated save implementation is needed, consult the documentation for information on the writeTo methods.&lt;br /&gt;
&lt;br /&gt;
==== windowNibName ====&lt;br /&gt;
&lt;br /&gt;
This method must be overriden to return the a string of the name of your nib file (without the file extention). More complex implementations will use other methods to load the interface files. TODO: information on what methods need to be overriden.&lt;br /&gt;
&lt;br /&gt;
==== windowControllerDidLoadNib: ====&lt;br /&gt;
&lt;br /&gt;
Use this method to add code that should be run as soon as ''windowController'' has been initialised. Your document may have many window controllers; each window controller taking possession of one window.&lt;br /&gt;
&lt;br /&gt;
In the TextEdit example, this method is used to copy the fileContents object ivar to the text view. It otherwise initialises the document window. &lt;br /&gt;
&lt;br /&gt;
Also note that you can override windowControllerWillLoadNib: to perform pre-nib loading initialisation.&lt;br /&gt;
&lt;br /&gt;
==== makeWindowControllers ====&lt;br /&gt;
&lt;br /&gt;
This is an optional method override, which must be used if you have multiple window controllers per document. It is responsible for creating each window controller from it's nib and then adding it to the document. Use the addWindowController: method.&lt;br /&gt;
&lt;br /&gt;
==== Other considerations ====&lt;br /&gt;
&lt;br /&gt;
* You need a way to notify NSDocument that your document has changed, so that NSDocumentController can enable the menu item to allow saving. This is done by a call to the updateChangeCount: method. For example, the TextDocument class adds itself as a delegate to the textView, for any notification of changes. It then calls updateChangeCount: in the delegate's method.&lt;br /&gt;
&lt;br /&gt;
* You may also wish to add a close: method (not the close method already in NSDocument, see below) to respond to the menu item permitting your document to close. This could perform cleanup operations before a call to [super close] is called e.g.&lt;br /&gt;
&lt;br /&gt;
 - (void) close:(id)sender /* Note this is not the method found in NSDocument (they differ by a parameter) */&lt;br /&gt;
 {&lt;br /&gt;
     [self close];&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== NSDocumentController ===&lt;br /&gt;
&lt;br /&gt;
This class can optionally be subclassed, to implement some specific functionality. For example, programs handling multiple document types may override newDocument: to create a window so that the user can select which document type to create.&lt;br /&gt;
&lt;br /&gt;
You should use separate implementation files and add the .m file to GNUmakefile.&lt;br /&gt;
&lt;br /&gt;
=== NSWindowController ===&lt;br /&gt;
&lt;br /&gt;
This class can also be optionally subclassed, to implement functionality specific to a window controller for a document type. You may need to override makeWindowControllers: in the NSDocument subclass in order to make sure your specific window controller is instantiated.&lt;br /&gt;
&lt;br /&gt;
You should use separate implemenatino files and add the .m file to GNUmakefile.&lt;br /&gt;
&lt;br /&gt;
== Optional Additions ==&lt;br /&gt;
&lt;br /&gt;
=== Custom NSDocumentController and NSWindowController implementations ===&lt;br /&gt;
&lt;br /&gt;
See [[#NSWindowController|NSWindowController]] and [[#NSDocumentController|NSDocumentController]].&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Creating_document_based_applications&amp;diff=832</id>
		<title>Creating document based applications</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Creating_document_based_applications&amp;diff=832"/>
		<updated>2005-07-07T04:39:13Z</updated>

		<summary type="html">&lt;p&gt;Quineska: /* loadDataRepresentation:ofType: and dataRepresentationOfType: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Note: this is a work in progress. Please bear with me as I add further information. &lt;br /&gt;
--[[User:Quineska|ChrisArmstrong]] 08:33, 5 Jul 2005 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
OpenStep can provide your application a document-based model. It helps to simplify the process of creating such applications. GNUstep is compatible with this paridgm as well; this document aims to provide an overview of what is required in the creation and design of such an application.&lt;br /&gt;
&lt;br /&gt;
It is assumed you are familiar with GNUstep, and have some understanding as how to create Gorm's nib files, as well as some understanding of how they work.&lt;br /&gt;
&lt;br /&gt;
Importantly, such applications have certain components that are required, and should be considered as part of their design. At a programmatic level, classes that will be used as part of the AppKit are:&lt;br /&gt;
&lt;br /&gt;
==== NSDocument ====&lt;br /&gt;
&lt;br /&gt;
This class is central to the OpenStep document based model. Such an application declares a new instance of a subclass of NSDocument for each “document” that is opened. It will be necessary to subclass NSDocument to implement this.&lt;br /&gt;
&lt;br /&gt;
Each instance of your NSDocument subclass may have one or more windows associated with it. These are used as an interface for loading and saving a representation of your document type. Each window will have an “NSWindowController” instance associated with it, where NSDocument maintains a list of these.&lt;br /&gt;
&lt;br /&gt;
==== NSDocumentController ====&lt;br /&gt;
&lt;br /&gt;
This class acts a controller. It maintains a list of documents (instances of your NSDocument subclass) and is responsible for loading and instantiating new documents. It is usually not necessary to implement a subclass of this, but often it may be useful to implement special functionality (especially related to open documents as a whole).&lt;br /&gt;
&lt;br /&gt;
==== NSWindowController ====&lt;br /&gt;
&lt;br /&gt;
As mentioned above, NSWindowController instances are individually associated with one NSWindow instance, in such a way that a document maintains a list of window controllers that are reponsible for rendering the views associated with a document.&lt;br /&gt;
&lt;br /&gt;
You will most likely not have to subclass NSWindowController. Instead, you associate a nib file (the Gorm output) with the subclass of NSDocument, and NSDocumentController will load this nib file for each document that is created or loaded.&lt;br /&gt;
&lt;br /&gt;
For example, a text based application that is used for the editing of plain text files, may subclass NSDocument with a TextDocument class. Each instance of this class would have an NSWindowController instance associated with it, which in turn manages a window instance that is instantiated from a nib file. The NSDocumentController instance, as managed and instatiated by GNUstep, would be responsible for loading and saving documents in your application. It even prompts the user to save their documents when they try to quit the application.&lt;br /&gt;
&lt;br /&gt;
== File Components ==&lt;br /&gt;
&lt;br /&gt;
In building your application you will need to create a number of special files. From scratch, the following should be a rough guide to getting it working. These include the Makefile, your application's property list and the interface files.&lt;br /&gt;
&lt;br /&gt;
=== The Makefile ===&lt;br /&gt;
&lt;br /&gt;
For this type of application, no special makefile is needed: it just has to be a normal application. Project Builder should be able to spit out the required makefile and Gorm files that are needed for a generic application. Otherwise use the following as a template:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''GNUmakefile'''&lt;br /&gt;
&lt;br /&gt;
 include $(GNUSTEP_MAKEFILES)/common.make&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 APP_NAME = DocumentApp&amp;lt;br&amp;gt;&lt;br /&gt;
 DocumentApp_OBJC_FILES =&amp;lt;br&amp;gt;&lt;br /&gt;
  MyDocument.m &amp;lt;br&amp;gt;&lt;br /&gt;
  main.m&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 DocumentApp_RESOURCES = \ &amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/Info-gnustep.plist \&amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/DocumentApp.gorm \&amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/MyDocument.gorm&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 -include GNUmakefile.preamble&amp;lt;br&amp;gt;&lt;br /&gt;
 include $(GNUSTEP_MAKEFILES)/application.make&amp;lt;br&amp;gt;&lt;br /&gt;
 -include GNUmakefile.postamble&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For more information as to customising this file, as well as setting up compiler options for third party libraries and includes, see the GNUstep makefile manual.&lt;br /&gt;
&lt;br /&gt;
=== The application dictionary - Info-gnustep.plist ===&lt;br /&gt;
&lt;br /&gt;
For those that have edited this file in their project before, it is a dictionary with various values entered. For our purposes, we need an array within the main dictionary, called &amp;quot;NSTypes&amp;quot;. This is a array of unnamed dictionaries, with one dictionary for each type. &lt;br /&gt;
&lt;br /&gt;
An entire example of this file, for a &amp;quot;theoretical&amp;quot; TextEdit application (please note that such an application does exist as an example application from Next I think, and again on MacOS X but I have constructed a much simpler version, used only for plain text files).&lt;br /&gt;
&lt;br /&gt;
Taking a look at the single dictionary entry in the NSTypes array, the following key-value pairs are needed:&lt;br /&gt;
* '''NSDocumentClass:''' This is (string) the subclass name you use in your code, the &amp;quot;objective-c name&amp;quot; of your document subclass. This is used by NSDocumentController's default implementation to create instances of your document type.&lt;br /&gt;
* '''NSName:''' The generic file type (string). This is completely arbitrary, and can be anything you like. For the purpose of conventions, it may be more appropriate not to use the &amp;quot;NS&amp;quot; or &amp;quot;GS&amp;quot; prefix (the latter of which I not sure), and instead use either your own, or no prefix at all.&lt;br /&gt;
* '''NSHumanReadableName:''' The human readable name of your document type (string)? TODO: explain where this is used.&lt;br /&gt;
* '''NSUnixExtensions:''' An array of strings, each containing a file extension connected to this document type on &amp;quot;unix&amp;quot; platforms. TODO: explain how &amp;quot;unix&amp;quot; is interpreted by GNUstep.&lt;br /&gt;
* '''NSDOSExtensions:''' An array of strings, each containing a file extenstion connected to this document type on &amp;quot;DOS&amp;quot; platforms (could be loosely interpreted as any MS platforms GNUstep runs on, i.e. Windows 2000/XP).&lt;br /&gt;
* '''NSRole:''' A string, either &amp;quot;Viewer&amp;quot; or &amp;quot;Editor&amp;quot;, depending on how your document operates on this file type.&lt;br /&gt;
* '''NSIcon:''' A icon name associated with this document type. TODO: Investigate how this works.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Info-gnustep.plist'''&lt;br /&gt;
 {&lt;br /&gt;
     ApplicationDescription = &amp;quot;A simple text editor for GNUstep.&amp;quot;;&lt;br /&gt;
     ApplicationName = TextEdit;&lt;br /&gt;
     ApplicationRelease = 0.10;&lt;br /&gt;
     Authors = ( &amp;quot;Christopher Armstrong &amp;lt;quineska@gamebox.net&amp;quot; );&lt;br /&gt;
     Copyright = &amp;quot;Copyright (C) 2005 Christopher Armstrong&amp;quot;;&lt;br /&gt;
     CopyrightDescription = &amp;quot;Released under GPL.&amp;quot;;&lt;br /&gt;
     FullVersionID = 0.10;&lt;br /&gt;
     NSExecutable = TextEdit;&lt;br /&gt;
     NSMainNibFile = TextEdit.gorm;&lt;br /&gt;
     NSPrincipalClass = NSApplication;&lt;br /&gt;
     NSRole = Application;&lt;br /&gt;
     NSTypes = (&lt;br /&gt;
         {&lt;br /&gt;
                 NSDocumentClass = &amp;quot;TextDocument&amp;quot;;&lt;br /&gt;
                 NSName = &amp;quot;GSTextDocumentType&amp;quot;;&lt;br /&gt;
                 NSHumanReadableName = &amp;quot;Text Document&amp;quot;;&lt;br /&gt;
                 NSUnixExtensions = ( &amp;quot;txt&amp;quot;, &amp;quot;&amp;quot; );&lt;br /&gt;
                 NSDOSExtensions = ( &amp;quot;txt&amp;quot; );&lt;br /&gt;
                 NSRole = Editor;&lt;br /&gt;
         }&lt;br /&gt;
     );&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For more information on property list files, consult [[Property Lists]].&lt;br /&gt;
&lt;br /&gt;
=== Interface file ===&lt;br /&gt;
&lt;br /&gt;
Two interface files are needed: one for your main application, and another that will be instantiated with each instance of your document subclass. These both should be listed as resources in your makefile, (as shown the GNUmakefile example above). It may be helpful to name the document nib file after your class.&lt;br /&gt;
&lt;br /&gt;
==== Application Interface File ====&lt;br /&gt;
&lt;br /&gt;
The application one should just be a menu (though it could be more if necessary). When constructing it, take the following into account:&lt;br /&gt;
&lt;br /&gt;
* Use a standard Gorm template for an Application.&lt;br /&gt;
* Delete the window instance in the &amp;quot;Objects&amp;quot; pane (unless you need a main window, in which case I don't know how to operate).&lt;br /&gt;
* Set NSOwner's class to &amp;quot;NSDocumentController&amp;quot; (this is the custom class option of NSOwner in the property inspector). This ensures openDocument, newDocument, etc. messages, as sent to NSFirst, get picked up by NSDocumentController. Do not instantiate it (I believe you can't anyway).&lt;br /&gt;
* If you intend to subclass NSDocumentController, subclass it in the Classes pane. To make sure that this class is instantiated and used, make sure you instantiate it in Gorm or in your main.m file, and set NSOwner to be your subclass.&lt;br /&gt;
* Drag a Document menu from the palette onto your main menu. This already has the proper linkage for each relevant message for a document setup to be directed to NSFirst. In the case of generic messages (such as openDocument:, not associated with any document instance), these are forwarded to the shared instance of NSDocumentController (see it's reference documentation). When a document is active, more specific messages (such as close: or saveDocument:) are forwarded to the relevant document instance of your NSDocument subclass.&lt;br /&gt;
* Add any appropriate menus such as &amp;quot;Info&amp;quot; and &amp;quot;Format&amp;quot; which may be relevant to your application.&lt;br /&gt;
&lt;br /&gt;
==== Document Interface File ====&lt;br /&gt;
&lt;br /&gt;
The document interface file is (generically) a window containing the view(s) required for the implementation of one instance of your document type. For example, in the case of a TextDocument type, a window instance with a NSTextView drawn on it is used for each open window. This nib file is instantiated every time a person creates a new document (the newDocument: message goes to NSDocumentController) or opens an existing document (openDocument:).&lt;br /&gt;
&lt;br /&gt;
You will need to:&lt;br /&gt;
* '''Subclass NSDocument''' with your document type in Gorm (this is done in a couple of ways, see [[Gorm_Manual#Custom_classes|custom classes]]).&lt;br /&gt;
* '''Set NSOwner:''' Set your subclass as NSOwner's Custom class (done using the Property inspector). DO NOT INSTANTIATE IT.&lt;br /&gt;
&lt;br /&gt;
Another thing that you may want to consider is custom outlets. If you place certain views or controls on your window (including the window itself), you may want to refer to them directly in yout code, e.g. the NSTextView in our TextEdit example is accessed directly, so that we can save it's contents to a file. To enable this, we add outlets to our class (see [[Gorm_Manual#Custom_classes|custom classes]]). We then connected NSOwner to the appropriate controls/views, and selected the outlets in the Connections property inspector (see [[Gorm_Manual#Editing_the_interface|editing the interface]]).&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
Various things need to be done at a code level, to ensure that your NSDocument subclass is properly instantiated. This section aims to tell you what is necessary.&lt;br /&gt;
&lt;br /&gt;
=== NSDocument subclass ===&lt;br /&gt;
&lt;br /&gt;
When creating your subclass, you may have chosen to have Gorm create the class files. If not, you should create two files for your subclass: a header (.h) file and an implementation file (.m). The header file should take the following layout (we're using the TextEdit example again):&lt;br /&gt;
&lt;br /&gt;
 #ifndef TEXTDOCUMENT_H&lt;br /&gt;
 #define TEXTDOCUMENT_H &amp;lt;br&amp;gt;&lt;br /&gt;
 #include &amp;lt;AppKit/AppKit.h&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
 @class NSDocument; &amp;lt;br&amp;gt;&lt;br /&gt;
 @interface TextDocument : NSDocument&lt;br /&gt;
 {&lt;br /&gt;
 @protected&lt;br /&gt;
     /* Outlets we added in our Gorm nib file */&lt;br /&gt;
     id * textView;&lt;br /&gt;
 }&lt;br /&gt;
 /* Basic methods used for loading and saving document data (respectively). */&lt;br /&gt;
 - (BOOL) loadDataRepresentation:(NSData*)representation ofType:(NSString*)type;&lt;br /&gt;
 - (NSData*) dataRepresentationOfType: (NSString*)type; &amp;lt;br&amp;gt;&lt;br /&gt;
 /* Information and events handling of GUI related changes */&lt;br /&gt;
 - (NSString*) windowNibName;&lt;br /&gt;
 - (void) windowControllerDidLoadNib:(NSWindowController*)windowController; &amp;lt;br&amp;gt;&lt;br /&gt;
 @end&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Firstly, take note that we inherit from NSDocument. As a result, we need to override some methods for a basic (but working) implementation. &lt;br /&gt;
&lt;br /&gt;
==== loadDataRepresentation:ofType: and dataRepresentationOfType: ====&lt;br /&gt;
&lt;br /&gt;
The methods, loadDataRepresent:ofType: and dataRepresentationOfType: are used by NSDocumentController to load and save our files. The first method is called when the user trys to open a document (NSDocumentController gets the file name and copies it's data using an open panel). The method is passed the raw data in this file, as well as a string representing its type. It is important to note that this type string is the same one used in your property list. It is used by NSDocumentController to tell you what type it thinks you should open the data with. If this is not possible, or if there is an error trying to parse the data, your method returns FALSE/NO. Otherwise, you should store a local, meaningful representation of the data, which you can insert into your document window a little later (and return YES).&lt;br /&gt;
&lt;br /&gt;
For example, in terms of the TextEdit example:&lt;br /&gt;
 - (BOOL) loadDataRepresentation:(NSData*) representation ofType:(NSString*)type&lt;br /&gt;
 {&lt;br /&gt;
    /*Check type information */&lt;br /&gt;
    if ([representation equalTo:GSTextDocumentType]==NO)&lt;br /&gt;
        return NO;&lt;br /&gt;
    /* Clean out our old representation if it still exists */&lt;br /&gt;
    if (fileContents) RELEASE(fileContents); &amp;lt;br&amp;gt;&lt;br /&gt;
    /* Allocate room for the new data, and try to initialise a string with it. */&lt;br /&gt;
    self-&amp;gt;fileContents = [NSString alloc];&lt;br /&gt;
    fileContents = [fileContents initWithBytes: [representation bytes]&lt;br /&gt;
                         length: [representation length]&lt;br /&gt;
                       encoding: NSASCIIStringEncoding]; &amp;lt;br&amp;gt;&lt;br /&gt;
    /* If this can't be done, return NO */&lt;br /&gt;
    if (!fileContents)&lt;br /&gt;
        return NO; &amp;lt;br&amp;gt;&lt;br /&gt;
    /* Otherwise, set our TextView to the string data. */&lt;br /&gt;
    [self-&amp;gt;textView setString: fileContents];&lt;br /&gt;
    return YES;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
If this is not suffice, or if your program can open the data in a more efficient manner, it may be worth looking into overriding -initWithContentsOfFile:ofType: and -initWithContentsOfURL:ofType: (see the GUI manual for more details).&lt;br /&gt;
&lt;br /&gt;
dataRepresentationOfType: is used to save the data. Your method is expected to return an instance of NSData that contains what should be saved to a file, for the type specified. Again, the ''type'' variable should be checked to ensure that you can write data of that type. Return nil if the file cannot be saved as that type.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
 - (NSData*) dataRepresentationOfType:(NSString*)type&lt;br /&gt;
 {&lt;br /&gt;
     if ([type equalTo:GSTextDocumentType]==NO)&lt;br /&gt;
         return nil; &amp;lt;br&amp;gt;&lt;br /&gt;
     NSData stringData =  [[textView string] dataUsingEncoding:NSASCIIStringEncoding];  &lt;br /&gt;
     return stringData; &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
If a more sophisticated save implementation is needed, consult the documentation for information on the writeTo methods.&lt;br /&gt;
&lt;br /&gt;
==== windowNibName ====&lt;br /&gt;
&lt;br /&gt;
This method must be overriden to return the name of your nib file. More complex implementations will use other methods to load the interface files. TODO: information on what methods need to be overriden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Creating_document_based_applications&amp;diff=831</id>
		<title>Creating document based applications</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Creating_document_based_applications&amp;diff=831"/>
		<updated>2005-07-07T01:15:09Z</updated>

		<summary type="html">&lt;p&gt;Quineska: /* windowNibName */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Note: this is a work in progress. Please bear with me as I add further information. &lt;br /&gt;
--[[User:Quineska|ChrisArmstrong]] 08:33, 5 Jul 2005 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
OpenStep can provide your application a document-based model. It helps to simplify the process of creating such applications. GNUstep is compatible with this paridgm as well; this document aims to provide an overview of what is required in the creation and design of such an application.&lt;br /&gt;
&lt;br /&gt;
It is assumed you are familiar with GNUstep, and have some understanding as how to create Gorm's nib files, as well as some understanding of how they work.&lt;br /&gt;
&lt;br /&gt;
Importantly, such applications have certain components that are required, and should be considered as part of their design. At a programmatic level, classes that will be used as part of the AppKit are:&lt;br /&gt;
&lt;br /&gt;
==== NSDocument ====&lt;br /&gt;
&lt;br /&gt;
This class is central to the OpenStep document based model. Such an application declares a new instance of a subclass of NSDocument for each “document” that is opened. It will be necessary to subclass NSDocument to implement this.&lt;br /&gt;
&lt;br /&gt;
Each instance of your NSDocument subclass may have one or more windows associated with it. These are used as an interface for loading and saving a representation of your document type. Each window will have an “NSWindowController” instance associated with it, where NSDocument maintains a list of these.&lt;br /&gt;
&lt;br /&gt;
==== NSDocumentController ====&lt;br /&gt;
&lt;br /&gt;
This class acts a controller. It maintains a list of documents (instances of your NSDocument subclass) and is responsible for loading and instantiating new documents. It is usually not necessary to implement a subclass of this, but often it may be useful to implement special functionality (especially related to open documents as a whole).&lt;br /&gt;
&lt;br /&gt;
==== NSWindowController ====&lt;br /&gt;
&lt;br /&gt;
As mentioned above, NSWindowController instances are individually associated with one NSWindow instance, in such a way that a document maintains a list of window controllers that are reponsible for rendering the views associated with a document.&lt;br /&gt;
&lt;br /&gt;
You will most likely not have to subclass NSWindowController. Instead, you associate a nib file (the Gorm output) with the subclass of NSDocument, and NSDocumentController will load this nib file for each document that is created or loaded.&lt;br /&gt;
&lt;br /&gt;
For example, a text based application that is used for the editing of plain text files, may subclass NSDocument with a TextDocument class. Each instance of this class would have an NSWindowController instance associated with it, which in turn manages a window instance that is instantiated from a nib file. The NSDocumentController instance, as managed and instatiated by GNUstep, would be responsible for loading and saving documents in your application. It even prompts the user to save their documents when they try to quit the application.&lt;br /&gt;
&lt;br /&gt;
== File Components ==&lt;br /&gt;
&lt;br /&gt;
In building your application you will need to create a number of special files. From scratch, the following should be a rough guide to getting it working. These include the Makefile, your application's property list and the interface files.&lt;br /&gt;
&lt;br /&gt;
=== The Makefile ===&lt;br /&gt;
&lt;br /&gt;
For this type of application, no special makefile is needed: it just has to be a normal application. Project Builder should be able to spit out the required makefile and Gorm files that are needed for a generic application. Otherwise use the following as a template:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''GNUmakefile'''&lt;br /&gt;
&lt;br /&gt;
 include $(GNUSTEP_MAKEFILES)/common.make&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 APP_NAME = DocumentApp&amp;lt;br&amp;gt;&lt;br /&gt;
 DocumentApp_OBJC_FILES =&amp;lt;br&amp;gt;&lt;br /&gt;
  MyDocument.m &amp;lt;br&amp;gt;&lt;br /&gt;
  main.m&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 DocumentApp_RESOURCES = \ &amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/Info-gnustep.plist \&amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/DocumentApp.gorm \&amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/MyDocument.gorm&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 -include GNUmakefile.preamble&amp;lt;br&amp;gt;&lt;br /&gt;
 include $(GNUSTEP_MAKEFILES)/application.make&amp;lt;br&amp;gt;&lt;br /&gt;
 -include GNUmakefile.postamble&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For more information as to customising this file, as well as setting up compiler options for third party libraries and includes, see the GNUstep makefile manual.&lt;br /&gt;
&lt;br /&gt;
=== The application dictionary - Info-gnustep.plist ===&lt;br /&gt;
&lt;br /&gt;
For those that have edited this file in their project before, it is a dictionary with various values entered. For our purposes, we need an array within the main dictionary, called &amp;quot;NSTypes&amp;quot;. This is a array of unnamed dictionaries, with one dictionary for each type. &lt;br /&gt;
&lt;br /&gt;
An entire example of this file, for a &amp;quot;theoretical&amp;quot; TextEdit application (please note that such an application does exist as an example application from Next I think, and again on MacOS X but I have constructed a much simpler version, used only for plain text files).&lt;br /&gt;
&lt;br /&gt;
Taking a look at the single dictionary entry in the NSTypes array, the following key-value pairs are needed:&lt;br /&gt;
* '''NSDocumentClass:''' This is (string) the subclass name you use in your code, the &amp;quot;objective-c name&amp;quot; of your document subclass. This is used by NSDocumentController's default implementation to create instances of your document type.&lt;br /&gt;
* '''NSName:''' The generic file type (string). This is completely arbitrary, and can be anything you like. For the purpose of conventions, it may be more appropriate not to use the &amp;quot;NS&amp;quot; or &amp;quot;GS&amp;quot; prefix (the latter of which I not sure), and instead use either your own, or no prefix at all.&lt;br /&gt;
* '''NSHumanReadableName:''' The human readable name of your document type (string)? TODO: explain where this is used.&lt;br /&gt;
* '''NSUnixExtensions:''' An array of strings, each containing a file extension connected to this document type on &amp;quot;unix&amp;quot; platforms. TODO: explain how &amp;quot;unix&amp;quot; is interpreted by GNUstep.&lt;br /&gt;
* '''NSDOSExtensions:''' An array of strings, each containing a file extenstion connected to this document type on &amp;quot;DOS&amp;quot; platforms (could be loosely interpreted as any MS platforms GNUstep runs on, i.e. Windows 2000/XP).&lt;br /&gt;
* '''NSRole:''' A string, either &amp;quot;Viewer&amp;quot; or &amp;quot;Editor&amp;quot;, depending on how your document operates on this file type.&lt;br /&gt;
* '''NSIcon:''' A icon name associated with this document type. TODO: Investigate how this works.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Info-gnustep.plist'''&lt;br /&gt;
 {&lt;br /&gt;
     ApplicationDescription = &amp;quot;A simple text editor for GNUstep.&amp;quot;;&lt;br /&gt;
     ApplicationName = TextEdit;&lt;br /&gt;
     ApplicationRelease = 0.10;&lt;br /&gt;
     Authors = ( &amp;quot;Christopher Armstrong &amp;lt;quineska@gamebox.net&amp;quot; );&lt;br /&gt;
     Copyright = &amp;quot;Copyright (C) 2005 Christopher Armstrong&amp;quot;;&lt;br /&gt;
     CopyrightDescription = &amp;quot;Released under GPL.&amp;quot;;&lt;br /&gt;
     FullVersionID = 0.10;&lt;br /&gt;
     NSExecutable = TextEdit;&lt;br /&gt;
     NSMainNibFile = TextEdit.gorm;&lt;br /&gt;
     NSPrincipalClass = NSApplication;&lt;br /&gt;
     NSRole = Application;&lt;br /&gt;
     NSTypes = (&lt;br /&gt;
         {&lt;br /&gt;
                 NSDocumentClass = &amp;quot;TextDocument&amp;quot;;&lt;br /&gt;
                 NSName = &amp;quot;GSTextDocumentType&amp;quot;;&lt;br /&gt;
                 NSHumanReadableName = &amp;quot;Text Document&amp;quot;;&lt;br /&gt;
                 NSUnixExtensions = ( &amp;quot;txt&amp;quot;, &amp;quot;&amp;quot; );&lt;br /&gt;
                 NSDOSExtensions = ( &amp;quot;txt&amp;quot; );&lt;br /&gt;
                 NSRole = Editor;&lt;br /&gt;
         }&lt;br /&gt;
     );&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For more information on property list files, consult [[Property Lists]].&lt;br /&gt;
&lt;br /&gt;
=== Interface file ===&lt;br /&gt;
&lt;br /&gt;
Two interface files are needed: one for your main application, and another that will be instantiated with each instance of your document subclass. These both should be listed as resources in your makefile, (as shown the GNUmakefile example above). It may be helpful to name the document nib file after your class.&lt;br /&gt;
&lt;br /&gt;
==== Application Interface File ====&lt;br /&gt;
&lt;br /&gt;
The application one should just be a menu (though it could be more if necessary). When constructing it, take the following into account:&lt;br /&gt;
&lt;br /&gt;
* Use a standard Gorm template for an Application.&lt;br /&gt;
* Delete the window instance in the &amp;quot;Objects&amp;quot; pane (unless you need a main window, in which case I don't know how to operate).&lt;br /&gt;
* Set NSOwner's class to &amp;quot;NSDocumentController&amp;quot; (this is the custom class option of NSOwner in the property inspector). This ensures openDocument, newDocument, etc. messages, as sent to NSFirst, get picked up by NSDocumentController. Do not instantiate it (I believe you can't anyway).&lt;br /&gt;
* If you intend to subclass NSDocumentController, subclass it in the Classes pane. To make sure that this class is instantiated and used, make sure you instantiate it in Gorm or in your main.m file, and set NSOwner to be your subclass.&lt;br /&gt;
* Drag a Document menu from the palette onto your main menu. This already has the proper linkage for each relevant message for a document setup to be directed to NSFirst. In the case of generic messages (such as openDocument:, not associated with any document instance), these are forwarded to the shared instance of NSDocumentController (see it's reference documentation). When a document is active, more specific messages (such as close: or saveDocument:) are forwarded to the relevant document instance of your NSDocument subclass.&lt;br /&gt;
* Add any appropriate menus such as &amp;quot;Info&amp;quot; and &amp;quot;Format&amp;quot; which may be relevant to your application.&lt;br /&gt;
&lt;br /&gt;
==== Document Interface File ====&lt;br /&gt;
&lt;br /&gt;
The document interface file is (generically) a window containing the view(s) required for the implementation of one instance of your document type. For example, in the case of a TextDocument type, a window instance with a NSTextView drawn on it is used for each open window. This nib file is instantiated every time a person creates a new document (the newDocument: message goes to NSDocumentController) or opens an existing document (openDocument:).&lt;br /&gt;
&lt;br /&gt;
You will need to:&lt;br /&gt;
* '''Subclass NSDocument''' with your document type in Gorm (this is done in a couple of ways, see [[Gorm_Manual#Custom_classes|custom classes]]).&lt;br /&gt;
* '''Set NSOwner:''' Set your subclass as NSOwner's Custom class (done using the Property inspector). DO NOT INSTANTIATE IT.&lt;br /&gt;
&lt;br /&gt;
Another thing that you may want to consider is custom outlets. If you place certain views or controls on your window (including the window itself), you may want to refer to them directly in yout code, e.g. the NSTextView in our TextEdit example is accessed directly, so that we can save it's contents to a file. To enable this, we add outlets to our class (see [[Gorm_Manual#Custom_classes|custom classes]]). We then connected NSOwner to the appropriate controls/views, and selected the outlets in the Connections property inspector (see [[Gorm_Manual#Editing_the_interface|editing the interface]]).&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
Various things need to be done at a code level, to ensure that your NSDocument subclass is properly instantiated. This section aims to tell you what is necessary.&lt;br /&gt;
&lt;br /&gt;
=== NSDocument subclass ===&lt;br /&gt;
&lt;br /&gt;
When creating your subclass, you may have chosen to have Gorm create the class files. If not, you should create two files for your subclass: a header (.h) file and an implementation file (.m). The header file should take the following layout (we're using the TextEdit example again):&lt;br /&gt;
&lt;br /&gt;
 #ifndef TEXTDOCUMENT_H&lt;br /&gt;
 #define TEXTDOCUMENT_H &amp;lt;br&amp;gt;&lt;br /&gt;
 #include &amp;lt;AppKit/AppKit.h&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
 @class NSDocument; &amp;lt;br&amp;gt;&lt;br /&gt;
 @interface TextDocument : NSDocument&lt;br /&gt;
 {&lt;br /&gt;
 @protected&lt;br /&gt;
     /* Outlets we added in our Gorm nib file */&lt;br /&gt;
     id * textView;&lt;br /&gt;
 }&lt;br /&gt;
 /* Basic methods used for loading and saving document data (respectively). */&lt;br /&gt;
 - (BOOL) loadDataRepresentation:(NSData*)representation ofType:(NSString*)type;&lt;br /&gt;
 - (NSData*) dataRepresentationOfType: (NSString*)type; &amp;lt;br&amp;gt;&lt;br /&gt;
 /* Information and events handling of GUI related changes */&lt;br /&gt;
 - (NSString*) windowNibName;&lt;br /&gt;
 - (void) windowControllerDidLoadNib:(NSWindowController*)windowController; &amp;lt;br&amp;gt;&lt;br /&gt;
 @end&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Firstly, take note that we inherit from NSDocument. As a result, we need to override some methods for a basic (but working) implementation. &lt;br /&gt;
&lt;br /&gt;
==== loadDataRepresentation:ofType: and dataRepresentationOfType: ====&lt;br /&gt;
&lt;br /&gt;
The methods, loadDataRepresent:ofType: and dataRepresentationOfType: are used by NSDocumentController to load and save our files. The first method is called when the user trys to open a document (NSDocumentController gets the file name and copies it's data using an open panel). The method is passed the raw data in this file, as well as a string representing its type. It is important to note that this type string is the same one used in your property list. It is used by NSDocumentController to tell you what type it thinks you should open the data with. If this is not possible, or if there is an error trying to parse the data, your method returns FALSE/NO. Otherwise, you should store a local, meaningful representation of the data, which you can insert into your document window a little later (and return YES).&lt;br /&gt;
&lt;br /&gt;
For example, in terms of the TextEdit example:&lt;br /&gt;
 - (BOOL) loadDataRepresentation:(NSData*) representation ofType:(NSString*)type&lt;br /&gt;
 {&lt;br /&gt;
    /* Clean out our old representation if it still exists */&lt;br /&gt;
    if (fileContents) RELEASE(fileContents); &amp;lt;br&amp;gt;&lt;br /&gt;
    /* Allocate room for the new data, and try to initialise a string with it. */&lt;br /&gt;
    self-&amp;gt;fileContents = [NSString alloc];&lt;br /&gt;
    fileContents = [fileContents initWithBytes: [representation bytes]&lt;br /&gt;
                         length: [representation length]&lt;br /&gt;
                       encoding: NSASCIIStringEncoding]; &amp;lt;br&amp;gt;&lt;br /&gt;
    /* If this can't be done, return NO */&lt;br /&gt;
    if (!fileContents)&lt;br /&gt;
        return NO; &amp;lt;br&amp;gt;&lt;br /&gt;
    /* Otherwise, set our TextView to the string data. */&lt;br /&gt;
    [self-&amp;gt;textView setString: fileContents];&lt;br /&gt;
    return YES;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
If this is not suffice, or if your program can open the data in a more efficient manner, it may be worth looking into overriding -initWithContentsOfFile:ofType: and -initWithContentsOfURL:ofType: (see the GUI manual for more details).&lt;br /&gt;
&lt;br /&gt;
==== windowNibName ====&lt;br /&gt;
&lt;br /&gt;
This method must be overriden to return the name of your nib file. More complex implementations will use other methods to load the interface files. TODO: information on what methods need to be overriden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Creating_document_based_applications&amp;diff=830</id>
		<title>Creating document based applications</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Creating_document_based_applications&amp;diff=830"/>
		<updated>2005-07-07T01:14:45Z</updated>

		<summary type="html">&lt;p&gt;Quineska: Added Code section (plus info) and completed file components section&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Note: this is a work in progress. Please bear with me as I add further information. &lt;br /&gt;
--[[User:Quineska|ChrisArmstrong]] 08:33, 5 Jul 2005 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
OpenStep can provide your application a document-based model. It helps to simplify the process of creating such applications. GNUstep is compatible with this paridgm as well; this document aims to provide an overview of what is required in the creation and design of such an application.&lt;br /&gt;
&lt;br /&gt;
It is assumed you are familiar with GNUstep, and have some understanding as how to create Gorm's nib files, as well as some understanding of how they work.&lt;br /&gt;
&lt;br /&gt;
Importantly, such applications have certain components that are required, and should be considered as part of their design. At a programmatic level, classes that will be used as part of the AppKit are:&lt;br /&gt;
&lt;br /&gt;
==== NSDocument ====&lt;br /&gt;
&lt;br /&gt;
This class is central to the OpenStep document based model. Such an application declares a new instance of a subclass of NSDocument for each “document” that is opened. It will be necessary to subclass NSDocument to implement this.&lt;br /&gt;
&lt;br /&gt;
Each instance of your NSDocument subclass may have one or more windows associated with it. These are used as an interface for loading and saving a representation of your document type. Each window will have an “NSWindowController” instance associated with it, where NSDocument maintains a list of these.&lt;br /&gt;
&lt;br /&gt;
==== NSDocumentController ====&lt;br /&gt;
&lt;br /&gt;
This class acts a controller. It maintains a list of documents (instances of your NSDocument subclass) and is responsible for loading and instantiating new documents. It is usually not necessary to implement a subclass of this, but often it may be useful to implement special functionality (especially related to open documents as a whole).&lt;br /&gt;
&lt;br /&gt;
==== NSWindowController ====&lt;br /&gt;
&lt;br /&gt;
As mentioned above, NSWindowController instances are individually associated with one NSWindow instance, in such a way that a document maintains a list of window controllers that are reponsible for rendering the views associated with a document.&lt;br /&gt;
&lt;br /&gt;
You will most likely not have to subclass NSWindowController. Instead, you associate a nib file (the Gorm output) with the subclass of NSDocument, and NSDocumentController will load this nib file for each document that is created or loaded.&lt;br /&gt;
&lt;br /&gt;
For example, a text based application that is used for the editing of plain text files, may subclass NSDocument with a TextDocument class. Each instance of this class would have an NSWindowController instance associated with it, which in turn manages a window instance that is instantiated from a nib file. The NSDocumentController instance, as managed and instatiated by GNUstep, would be responsible for loading and saving documents in your application. It even prompts the user to save their documents when they try to quit the application.&lt;br /&gt;
&lt;br /&gt;
== File Components ==&lt;br /&gt;
&lt;br /&gt;
In building your application you will need to create a number of special files. From scratch, the following should be a rough guide to getting it working. These include the Makefile, your application's property list and the interface files.&lt;br /&gt;
&lt;br /&gt;
=== The Makefile ===&lt;br /&gt;
&lt;br /&gt;
For this type of application, no special makefile is needed: it just has to be a normal application. Project Builder should be able to spit out the required makefile and Gorm files that are needed for a generic application. Otherwise use the following as a template:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''GNUmakefile'''&lt;br /&gt;
&lt;br /&gt;
 include $(GNUSTEP_MAKEFILES)/common.make&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 APP_NAME = DocumentApp&amp;lt;br&amp;gt;&lt;br /&gt;
 DocumentApp_OBJC_FILES =&amp;lt;br&amp;gt;&lt;br /&gt;
  MyDocument.m &amp;lt;br&amp;gt;&lt;br /&gt;
  main.m&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 DocumentApp_RESOURCES = \ &amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/Info-gnustep.plist \&amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/DocumentApp.gorm \&amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/MyDocument.gorm&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 -include GNUmakefile.preamble&amp;lt;br&amp;gt;&lt;br /&gt;
 include $(GNUSTEP_MAKEFILES)/application.make&amp;lt;br&amp;gt;&lt;br /&gt;
 -include GNUmakefile.postamble&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For more information as to customising this file, as well as setting up compiler options for third party libraries and includes, see the GNUstep makefile manual.&lt;br /&gt;
&lt;br /&gt;
=== The application dictionary - Info-gnustep.plist ===&lt;br /&gt;
&lt;br /&gt;
For those that have edited this file in their project before, it is a dictionary with various values entered. For our purposes, we need an array within the main dictionary, called &amp;quot;NSTypes&amp;quot;. This is a array of unnamed dictionaries, with one dictionary for each type. &lt;br /&gt;
&lt;br /&gt;
An entire example of this file, for a &amp;quot;theoretical&amp;quot; TextEdit application (please note that such an application does exist as an example application from Next I think, and again on MacOS X but I have constructed a much simpler version, used only for plain text files).&lt;br /&gt;
&lt;br /&gt;
Taking a look at the single dictionary entry in the NSTypes array, the following key-value pairs are needed:&lt;br /&gt;
* '''NSDocumentClass:''' This is (string) the subclass name you use in your code, the &amp;quot;objective-c name&amp;quot; of your document subclass. This is used by NSDocumentController's default implementation to create instances of your document type.&lt;br /&gt;
* '''NSName:''' The generic file type (string). This is completely arbitrary, and can be anything you like. For the purpose of conventions, it may be more appropriate not to use the &amp;quot;NS&amp;quot; or &amp;quot;GS&amp;quot; prefix (the latter of which I not sure), and instead use either your own, or no prefix at all.&lt;br /&gt;
* '''NSHumanReadableName:''' The human readable name of your document type (string)? TODO: explain where this is used.&lt;br /&gt;
* '''NSUnixExtensions:''' An array of strings, each containing a file extension connected to this document type on &amp;quot;unix&amp;quot; platforms. TODO: explain how &amp;quot;unix&amp;quot; is interpreted by GNUstep.&lt;br /&gt;
* '''NSDOSExtensions:''' An array of strings, each containing a file extenstion connected to this document type on &amp;quot;DOS&amp;quot; platforms (could be loosely interpreted as any MS platforms GNUstep runs on, i.e. Windows 2000/XP).&lt;br /&gt;
* '''NSRole:''' A string, either &amp;quot;Viewer&amp;quot; or &amp;quot;Editor&amp;quot;, depending on how your document operates on this file type.&lt;br /&gt;
* '''NSIcon:''' A icon name associated with this document type. TODO: Investigate how this works.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Info-gnustep.plist'''&lt;br /&gt;
 {&lt;br /&gt;
     ApplicationDescription = &amp;quot;A simple text editor for GNUstep.&amp;quot;;&lt;br /&gt;
     ApplicationName = TextEdit;&lt;br /&gt;
     ApplicationRelease = 0.10;&lt;br /&gt;
     Authors = ( &amp;quot;Christopher Armstrong &amp;lt;quineska@gamebox.net&amp;quot; );&lt;br /&gt;
     Copyright = &amp;quot;Copyright (C) 2005 Christopher Armstrong&amp;quot;;&lt;br /&gt;
     CopyrightDescription = &amp;quot;Released under GPL.&amp;quot;;&lt;br /&gt;
     FullVersionID = 0.10;&lt;br /&gt;
     NSExecutable = TextEdit;&lt;br /&gt;
     NSMainNibFile = TextEdit.gorm;&lt;br /&gt;
     NSPrincipalClass = NSApplication;&lt;br /&gt;
     NSRole = Application;&lt;br /&gt;
     NSTypes = (&lt;br /&gt;
         {&lt;br /&gt;
                 NSDocumentClass = &amp;quot;TextDocument&amp;quot;;&lt;br /&gt;
                 NSName = &amp;quot;GSTextDocumentType&amp;quot;;&lt;br /&gt;
                 NSHumanReadableName = &amp;quot;Text Document&amp;quot;;&lt;br /&gt;
                 NSUnixExtensions = ( &amp;quot;txt&amp;quot;, &amp;quot;&amp;quot; );&lt;br /&gt;
                 NSDOSExtensions = ( &amp;quot;txt&amp;quot; );&lt;br /&gt;
                 NSRole = Editor;&lt;br /&gt;
         }&lt;br /&gt;
     );&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For more information on property list files, consult [[Property Lists]].&lt;br /&gt;
&lt;br /&gt;
=== Interface file ===&lt;br /&gt;
&lt;br /&gt;
Two interface files are needed: one for your main application, and another that will be instantiated with each instance of your document subclass. These both should be listed as resources in your makefile, (as shown the GNUmakefile example above). It may be helpful to name the document nib file after your class.&lt;br /&gt;
&lt;br /&gt;
==== Application Interface File ====&lt;br /&gt;
&lt;br /&gt;
The application one should just be a menu (though it could be more if necessary). When constructing it, take the following into account:&lt;br /&gt;
&lt;br /&gt;
* Use a standard Gorm template for an Application.&lt;br /&gt;
* Delete the window instance in the &amp;quot;Objects&amp;quot; pane (unless you need a main window, in which case I don't know how to operate).&lt;br /&gt;
* Set NSOwner's class to &amp;quot;NSDocumentController&amp;quot; (this is the custom class option of NSOwner in the property inspector). This ensures openDocument, newDocument, etc. messages, as sent to NSFirst, get picked up by NSDocumentController. Do not instantiate it (I believe you can't anyway).&lt;br /&gt;
* If you intend to subclass NSDocumentController, subclass it in the Classes pane. To make sure that this class is instantiated and used, make sure you instantiate it in Gorm or in your main.m file, and set NSOwner to be your subclass.&lt;br /&gt;
* Drag a Document menu from the palette onto your main menu. This already has the proper linkage for each relevant message for a document setup to be directed to NSFirst. In the case of generic messages (such as openDocument:, not associated with any document instance), these are forwarded to the shared instance of NSDocumentController (see it's reference documentation). When a document is active, more specific messages (such as close: or saveDocument:) are forwarded to the relevant document instance of your NSDocument subclass.&lt;br /&gt;
* Add any appropriate menus such as &amp;quot;Info&amp;quot; and &amp;quot;Format&amp;quot; which may be relevant to your application.&lt;br /&gt;
&lt;br /&gt;
==== Document Interface File ====&lt;br /&gt;
&lt;br /&gt;
The document interface file is (generically) a window containing the view(s) required for the implementation of one instance of your document type. For example, in the case of a TextDocument type, a window instance with a NSTextView drawn on it is used for each open window. This nib file is instantiated every time a person creates a new document (the newDocument: message goes to NSDocumentController) or opens an existing document (openDocument:).&lt;br /&gt;
&lt;br /&gt;
You will need to:&lt;br /&gt;
* '''Subclass NSDocument''' with your document type in Gorm (this is done in a couple of ways, see [[Gorm_Manual#Custom_classes|custom classes]]).&lt;br /&gt;
* '''Set NSOwner:''' Set your subclass as NSOwner's Custom class (done using the Property inspector). DO NOT INSTANTIATE IT.&lt;br /&gt;
&lt;br /&gt;
Another thing that you may want to consider is custom outlets. If you place certain views or controls on your window (including the window itself), you may want to refer to them directly in yout code, e.g. the NSTextView in our TextEdit example is accessed directly, so that we can save it's contents to a file. To enable this, we add outlets to our class (see [[Gorm_Manual#Custom_classes|custom classes]]). We then connected NSOwner to the appropriate controls/views, and selected the outlets in the Connections property inspector (see [[Gorm_Manual#Editing_the_interface|editing the interface]]).&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
Various things need to be done at a code level, to ensure that your NSDocument subclass is properly instantiated. This section aims to tell you what is necessary.&lt;br /&gt;
&lt;br /&gt;
=== NSDocument subclass ===&lt;br /&gt;
&lt;br /&gt;
When creating your subclass, you may have chosen to have Gorm create the class files. If not, you should create two files for your subclass: a header (.h) file and an implementation file (.m). The header file should take the following layout (we're using the TextEdit example again):&lt;br /&gt;
&lt;br /&gt;
 #ifndef TEXTDOCUMENT_H&lt;br /&gt;
 #define TEXTDOCUMENT_H &amp;lt;br&amp;gt;&lt;br /&gt;
 #include &amp;lt;AppKit/AppKit.h&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
 @class NSDocument; &amp;lt;br&amp;gt;&lt;br /&gt;
 @interface TextDocument : NSDocument&lt;br /&gt;
 {&lt;br /&gt;
 @protected&lt;br /&gt;
     /* Outlets we added in our Gorm nib file */&lt;br /&gt;
     id * textView;&lt;br /&gt;
 }&lt;br /&gt;
 /* Basic methods used for loading and saving document data (respectively). */&lt;br /&gt;
 - (BOOL) loadDataRepresentation:(NSData*)representation ofType:(NSString*)type;&lt;br /&gt;
 - (NSData*) dataRepresentationOfType: (NSString*)type; &amp;lt;br&amp;gt;&lt;br /&gt;
 /* Information and events handling of GUI related changes */&lt;br /&gt;
 - (NSString*) windowNibName;&lt;br /&gt;
 - (void) windowControllerDidLoadNib:(NSWindowController*)windowController; &amp;lt;br&amp;gt;&lt;br /&gt;
 @end&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Firstly, take note that we inherit from NSDocument. As a result, we need to override some methods for a basic (but working) implementation. &lt;br /&gt;
&lt;br /&gt;
==== loadDataRepresentation:ofType: and dataRepresentationOfType: ====&lt;br /&gt;
&lt;br /&gt;
The methods, loadDataRepresent:ofType: and dataRepresentationOfType: are used by NSDocumentController to load and save our files. The first method is called when the user trys to open a document (NSDocumentController gets the file name and copies it's data using an open panel). The method is passed the raw data in this file, as well as a string representing its type. It is important to note that this type string is the same one used in your property list. It is used by NSDocumentController to tell you what type it thinks you should open the data with. If this is not possible, or if there is an error trying to parse the data, your method returns FALSE/NO. Otherwise, you should store a local, meaningful representation of the data, which you can insert into your document window a little later (and return YES).&lt;br /&gt;
&lt;br /&gt;
For example, in terms of the TextEdit example:&lt;br /&gt;
 - (BOOL) loadDataRepresentation:(NSData*) representation ofType:(NSString*)type&lt;br /&gt;
 {&lt;br /&gt;
    /* Clean out our old representation if it still exists */&lt;br /&gt;
    if (fileContents) RELEASE(fileContents); &amp;lt;br&amp;gt;&lt;br /&gt;
    /* Allocate room for the new data, and try to initialise a string with it. */&lt;br /&gt;
    self-&amp;gt;fileContents = [NSString alloc];&lt;br /&gt;
    fileContents = [fileContents initWithBytes: [representation bytes]&lt;br /&gt;
                         length: [representation length]&lt;br /&gt;
                       encoding: NSASCIIStringEncoding]; &amp;lt;br&amp;gt;&lt;br /&gt;
    /* If this can't be done, return NO */&lt;br /&gt;
    if (!fileContents)&lt;br /&gt;
        return NO; &amp;lt;br&amp;gt;&lt;br /&gt;
    /* Otherwise, set our TextView to the string data. */&lt;br /&gt;
    [self-&amp;gt;textView setString: fileContents];&lt;br /&gt;
    return YES;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
If this is not suffice, or if your program can open the data in a more efficient manner, it may be worth looking into overriding -initWithContentsOfFile:ofType: and -initWithContentsOfURL:ofType: (see the GUI manual for more details).&lt;br /&gt;
&lt;br /&gt;
==== windowNibName ====&lt;br /&gt;
&lt;br /&gt;
This method must be overriden to return the name of your nib files. More complex implementations will use other methods to load the interface files. TODO: information on what methods need to be overriden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Creating_document_based_applications&amp;diff=829</id>
		<title>Creating document based applications</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Creating_document_based_applications&amp;diff=829"/>
		<updated>2005-07-07T00:43:31Z</updated>

		<summary type="html">&lt;p&gt;Quineska: /* Document Interface File */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Note: this is a work in progress. Please bear with me as I add further information. &lt;br /&gt;
--[[User:Quineska|ChrisArmstrong]] 08:33, 5 Jul 2005 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
OpenStep can provide your application a document-based model. It helps to simplify the process of creating such applications. GNUstep is compatible with this paridgm as well; this document aims to provide an overview of what is required in the creation and design of such an application.&lt;br /&gt;
&lt;br /&gt;
It is assumed you are familiar with GNUstep, and have some understanding as how to create Gorm's nib files, as well as some understanding of how they work.&lt;br /&gt;
&lt;br /&gt;
Importantly, such applications have certain components that are required, and should be considered as part of their design. At a programmatic level, classes that will be used as part of the AppKit are:&lt;br /&gt;
&lt;br /&gt;
==== NSDocument ====&lt;br /&gt;
&lt;br /&gt;
This class is central to the OpenStep document based model. Such an application declares a new instance of a subclass of NSDocument for each “document” that is opened. It will be necessary to subclass NSDocument to implement this.&lt;br /&gt;
&lt;br /&gt;
Each instance of your NSDocument subclass may have one or more windows associated with it. These are used as an interface for loading and saving a representation of your document type. Each window will have an “NSWindowController” instance associated with it, where NSDocument maintains a list of these.&lt;br /&gt;
&lt;br /&gt;
==== NSDocumentController ====&lt;br /&gt;
&lt;br /&gt;
This class acts a controller. It maintains a list of documents (instances of your NSDocument subclass) and is responsible for loading and instantiating new documents. It is usually not necessary to implement a subclass of this, but often it may be useful to implement special functionality (especially related to open documents as a whole).&lt;br /&gt;
&lt;br /&gt;
==== NSWindowController ====&lt;br /&gt;
&lt;br /&gt;
As mentioned above, NSWindowController instances are individually associated with one NSWindow instance, in such a way that a document maintains a list of window controllers that are reponsible for rendering the views associated with a document.&lt;br /&gt;
&lt;br /&gt;
You will most likely not have to subclass NSWindowController. Instead, you associate a nib file (the Gorm output) with the subclass of NSDocument, and NSDocumentController will load this nib file for each document that is created or loaded.&lt;br /&gt;
&lt;br /&gt;
For example, a text based application that is used for the editing of plain text files, may subclass NSDocument with a TextDocument class. Each instance of this class would have an NSWindowController instance associated with it, which in turn manages a window instance that is instantiated from a nib file. The NSDocumentController instance, as managed and instatiated by GNUstep, would be responsible for loading and saving documents in your application. It even prompts the user to save their documents when they try to quit the application.&lt;br /&gt;
&lt;br /&gt;
== Components ==&lt;br /&gt;
&lt;br /&gt;
In building your application you will need to create a number of components. From scratch, the following should be a rough guide to getting it working.&lt;br /&gt;
&lt;br /&gt;
=== The Makefile ===&lt;br /&gt;
&lt;br /&gt;
For this type of application, no special makefile is needed: it just has to be a normal application. Project Builder should be able to spit out the required makefile and Gorm files that are needed for a generic application. Otherwise use the following as a template:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''GNUmakefile'''&lt;br /&gt;
&lt;br /&gt;
 include $(GNUSTEP_MAKEFILES)/common.make&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 APP_NAME = DocumentApp&amp;lt;br&amp;gt;&lt;br /&gt;
 DocumentApp_OBJC_FILES =&amp;lt;br&amp;gt;&lt;br /&gt;
  MyDocument.m &amp;lt;br&amp;gt;&lt;br /&gt;
  main.m&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 DocumentApp_RESOURCES = \ &amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/Info-gnustep.plist \&amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/DocumentApp.gorm \&amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/MyDocument.gorm&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 -include GNUmakefile.preamble&amp;lt;br&amp;gt;&lt;br /&gt;
 include $(GNUSTEP_MAKEFILES)/application.make&amp;lt;br&amp;gt;&lt;br /&gt;
 -include GNUmakefile.postamble&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For more information as to customising this file, as well as setting up compiler options for third party libraries and includes, see the GNUstep makefile manual.&lt;br /&gt;
&lt;br /&gt;
=== The application dictionary - Info-gnustep.plist ===&lt;br /&gt;
&lt;br /&gt;
For those that have edited this file in their project before, it is a dictionary with various values entered. For our purposes, we need an array within the main dictionary, called &amp;quot;NSTypes&amp;quot;. This is a array of unnamed dictionaries, with one dictionary for each type. &lt;br /&gt;
&lt;br /&gt;
An entire example of this file, for a &amp;quot;theoretical&amp;quot; TextEdit application (please note that such an application does exist as an example application from Next I think, and again on MacOS X but I have constructed a much simpler version, used only for plain text files).&lt;br /&gt;
&lt;br /&gt;
Taking a look at the single dictionary entry in the NSTypes array, the following key-value pairs are needed:&lt;br /&gt;
* '''NSDocumentClass:''' This is (string) the subclass name you use in your code, the &amp;quot;objective-c name&amp;quot; of your document subclass. This is used by NSDocumentController's default implementation to create instances of your document type.&lt;br /&gt;
* '''NSName:''' The generic file type (string). This is completely arbitrary, and can be anything you like. For the purpose of conventions, it may be more appropriate not to use the &amp;quot;NS&amp;quot; or &amp;quot;GS&amp;quot; prefix (the latter of which I not sure), and instead use either your own, or no prefix at all.&lt;br /&gt;
* '''NSHumanReadableName:''' The human readable name of your document type (string)? TODO: explain where this is used.&lt;br /&gt;
* '''NSUnixExtensions:''' An array of strings, each containing a file extension connected to this document type on &amp;quot;unix&amp;quot; platforms. TODO: explain how &amp;quot;unix&amp;quot; is interpreted by GNUstep.&lt;br /&gt;
* '''NSDOSExtensions:''' An array of strings, each containing a file extenstion connected to this document type on &amp;quot;DOS&amp;quot; platforms (could be loosely interpreted as any MS platforms GNUstep runs on, i.e. Windows 2000/XP).&lt;br /&gt;
* '''NSRole:''' A string, either &amp;quot;Viewer&amp;quot; or &amp;quot;Editor&amp;quot;, depending on how your document operates on this file type.&lt;br /&gt;
* '''NSIcon:''' A icon name associated with this document type. TODO: Investigate how this works.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Info-gnustep.plist'''&lt;br /&gt;
 {&lt;br /&gt;
     ApplicationDescription = &amp;quot;A simple text editor for GNUstep.&amp;quot;;&lt;br /&gt;
     ApplicationName = TextEdit;&lt;br /&gt;
     ApplicationRelease = 0.10;&lt;br /&gt;
     Authors = ( &amp;quot;Christopher Armstrong &amp;lt;quineska@gamebox.net&amp;quot; );&lt;br /&gt;
     Copyright = &amp;quot;Copyright (C) 2005 Christopher Armstrong&amp;quot;;&lt;br /&gt;
     CopyrightDescription = &amp;quot;Released under GPL.&amp;quot;;&lt;br /&gt;
     FullVersionID = 0.10;&lt;br /&gt;
     NSExecutable = TextEdit;&lt;br /&gt;
     NSMainNibFile = TextEdit.gorm;&lt;br /&gt;
     NSPrincipalClass = NSApplication;&lt;br /&gt;
     NSRole = Application;&lt;br /&gt;
     NSTypes = (&lt;br /&gt;
         {&lt;br /&gt;
                 NSDocumentClass = &amp;quot;TextDocument&amp;quot;;&lt;br /&gt;
                 NSName = &amp;quot;GSTextDocumentType&amp;quot;;&lt;br /&gt;
                 NSHumanReadableName = &amp;quot;Text Document&amp;quot;;&lt;br /&gt;
                 NSUnixExtensions = ( &amp;quot;txt&amp;quot;, &amp;quot;&amp;quot; );&lt;br /&gt;
                 NSDOSExtensions = ( &amp;quot;txt&amp;quot; );&lt;br /&gt;
                 NSRole = Editor;&lt;br /&gt;
         }&lt;br /&gt;
     );&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For more information on property list files, consult [[Property Lists]].&lt;br /&gt;
&lt;br /&gt;
=== Interface file ===&lt;br /&gt;
&lt;br /&gt;
Two interface files are needed: one for your main application, and another that will be instantiated with each instance of your document subclass. These both should be listed as resources in your makefile, (as shown the GNUmakefile example above). It may be helpful to name the document nib file after your class.&lt;br /&gt;
&lt;br /&gt;
==== Application Interface File ====&lt;br /&gt;
&lt;br /&gt;
The application one should just be a menu (though it could be more if necessary). When constructing it, take the following into account:&lt;br /&gt;
&lt;br /&gt;
* Use a standard Gorm template for an Application.&lt;br /&gt;
* Delete the window instance in the &amp;quot;Objects&amp;quot; pane (unless you need a main window, in which case I don't know how to operate).&lt;br /&gt;
* Set NSOwner's class to &amp;quot;NSDocumentController&amp;quot; (this is the custom class option of NSOwner in the property inspector). This ensures openDocument, newDocument, etc. messages, as sent to NSFirst, get picked up by NSDocumentController. Do not instantiate it (I believe you can't anyway).&lt;br /&gt;
* If you intend to subclass NSDocumentController, subclass it in the Classes pane. To make sure that this class is instantiated and used, make sure you instantiate it in Gorm or in your main.m file, and set NSOwner to be your subclass.&lt;br /&gt;
* Drag a Document menu from the palette onto your main menu. This already has the proper linkage for each relevant message for a document setup to be directed to NSFirst. In the case of generic messages (such as openDocument:, not associated with any document instance), these are forwarded to the shared instance of NSDocumentController (see it's reference documentation). When a document is active, more specific messages (such as close: or saveDocument:) are forwarded to the relevant document instance of your NSDocument subclass.&lt;br /&gt;
* Add any appropriate menus such as &amp;quot;Info&amp;quot; and &amp;quot;Format&amp;quot; which may be relevant to your application.&lt;br /&gt;
&lt;br /&gt;
==== Document Interface File ====&lt;br /&gt;
&lt;br /&gt;
The document interface file is (generically) a window containing the view(s) required for the implementation of one instance of your document type. For example, in the case of a TextDocument type, a window instance with a NSTextView drawn on it is used for each open window. This nib file is instantiated every time a person creates a new document (the newDocument: message goes to NSDocumentController) or opens an existing document (openDocument:).&lt;br /&gt;
&lt;br /&gt;
You will need to:&lt;br /&gt;
* '''Subclass NSDocument''' with your document type in Gorm (this is done in a couple of ways, see [[Gorm_Manual#Custom_classes|custom classes]]).&lt;br /&gt;
* '''Set NSOwner:''' Set your subclass as NSOwner's Custom class (done using the Property inspector). DO NOT INSTANTIATE IT.&lt;br /&gt;
&lt;br /&gt;
Another thing that you may want to consider is custom outlets. If you place certain views or controls on your window (including the window itself), you may want to refer to them directly in yout code, e.g. the NSTextView in our TextEdit example is accessed directly, so that we can save it's contents to a file. To enable this, we add outlets to our class (see [[Gorm_Manual#Custom_classes|custom classes]]). We then connected NSOwner to the appropriate controls/views, and selected the outlets in the Connections property inspector (see [[Gorm_Manual#Editing_the_interface|editing the interface]]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Creating_document_based_applications&amp;diff=828</id>
		<title>Creating document based applications</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Creating_document_based_applications&amp;diff=828"/>
		<updated>2005-07-07T00:25:21Z</updated>

		<summary type="html">&lt;p&gt;Quineska: /* Application Interface File */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Note: this is a work in progress. Please bear with me as I add further information. &lt;br /&gt;
--[[User:Quineska|ChrisArmstrong]] 08:33, 5 Jul 2005 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
OpenStep can provide your application a document-based model. It helps to simplify the process of creating such applications. GNUstep is compatible with this paridgm as well; this document aims to provide an overview of what is required in the creation and design of such an application.&lt;br /&gt;
&lt;br /&gt;
It is assumed you are familiar with GNUstep, and have some understanding as how to create Gorm's nib files, as well as some understanding of how they work.&lt;br /&gt;
&lt;br /&gt;
Importantly, such applications have certain components that are required, and should be considered as part of their design. At a programmatic level, classes that will be used as part of the AppKit are:&lt;br /&gt;
&lt;br /&gt;
==== NSDocument ====&lt;br /&gt;
&lt;br /&gt;
This class is central to the OpenStep document based model. Such an application declares a new instance of a subclass of NSDocument for each “document” that is opened. It will be necessary to subclass NSDocument to implement this.&lt;br /&gt;
&lt;br /&gt;
Each instance of your NSDocument subclass may have one or more windows associated with it. These are used as an interface for loading and saving a representation of your document type. Each window will have an “NSWindowController” instance associated with it, where NSDocument maintains a list of these.&lt;br /&gt;
&lt;br /&gt;
==== NSDocumentController ====&lt;br /&gt;
&lt;br /&gt;
This class acts a controller. It maintains a list of documents (instances of your NSDocument subclass) and is responsible for loading and instantiating new documents. It is usually not necessary to implement a subclass of this, but often it may be useful to implement special functionality (especially related to open documents as a whole).&lt;br /&gt;
&lt;br /&gt;
==== NSWindowController ====&lt;br /&gt;
&lt;br /&gt;
As mentioned above, NSWindowController instances are individually associated with one NSWindow instance, in such a way that a document maintains a list of window controllers that are reponsible for rendering the views associated with a document.&lt;br /&gt;
&lt;br /&gt;
You will most likely not have to subclass NSWindowController. Instead, you associate a nib file (the Gorm output) with the subclass of NSDocument, and NSDocumentController will load this nib file for each document that is created or loaded.&lt;br /&gt;
&lt;br /&gt;
For example, a text based application that is used for the editing of plain text files, may subclass NSDocument with a TextDocument class. Each instance of this class would have an NSWindowController instance associated with it, which in turn manages a window instance that is instantiated from a nib file. The NSDocumentController instance, as managed and instatiated by GNUstep, would be responsible for loading and saving documents in your application. It even prompts the user to save their documents when they try to quit the application.&lt;br /&gt;
&lt;br /&gt;
== Components ==&lt;br /&gt;
&lt;br /&gt;
In building your application you will need to create a number of components. From scratch, the following should be a rough guide to getting it working.&lt;br /&gt;
&lt;br /&gt;
=== The Makefile ===&lt;br /&gt;
&lt;br /&gt;
For this type of application, no special makefile is needed: it just has to be a normal application. Project Builder should be able to spit out the required makefile and Gorm files that are needed for a generic application. Otherwise use the following as a template:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''GNUmakefile'''&lt;br /&gt;
&lt;br /&gt;
 include $(GNUSTEP_MAKEFILES)/common.make&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 APP_NAME = DocumentApp&amp;lt;br&amp;gt;&lt;br /&gt;
 DocumentApp_OBJC_FILES =&amp;lt;br&amp;gt;&lt;br /&gt;
  MyDocument.m &amp;lt;br&amp;gt;&lt;br /&gt;
  main.m&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 DocumentApp_RESOURCES = \ &amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/Info-gnustep.plist \&amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/DocumentApp.gorm \&amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/MyDocument.gorm&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 -include GNUmakefile.preamble&amp;lt;br&amp;gt;&lt;br /&gt;
 include $(GNUSTEP_MAKEFILES)/application.make&amp;lt;br&amp;gt;&lt;br /&gt;
 -include GNUmakefile.postamble&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For more information as to customising this file, as well as setting up compiler options for third party libraries and includes, see the GNUstep makefile manual.&lt;br /&gt;
&lt;br /&gt;
=== The application dictionary - Info-gnustep.plist ===&lt;br /&gt;
&lt;br /&gt;
For those that have edited this file in their project before, it is a dictionary with various values entered. For our purposes, we need an array within the main dictionary, called &amp;quot;NSTypes&amp;quot;. This is a array of unnamed dictionaries, with one dictionary for each type. &lt;br /&gt;
&lt;br /&gt;
An entire example of this file, for a &amp;quot;theoretical&amp;quot; TextEdit application (please note that such an application does exist as an example application from Next I think, and again on MacOS X but I have constructed a much simpler version, used only for plain text files).&lt;br /&gt;
&lt;br /&gt;
Taking a look at the single dictionary entry in the NSTypes array, the following key-value pairs are needed:&lt;br /&gt;
* '''NSDocumentClass:''' This is (string) the subclass name you use in your code, the &amp;quot;objective-c name&amp;quot; of your document subclass. This is used by NSDocumentController's default implementation to create instances of your document type.&lt;br /&gt;
* '''NSName:''' The generic file type (string). This is completely arbitrary, and can be anything you like. For the purpose of conventions, it may be more appropriate not to use the &amp;quot;NS&amp;quot; or &amp;quot;GS&amp;quot; prefix (the latter of which I not sure), and instead use either your own, or no prefix at all.&lt;br /&gt;
* '''NSHumanReadableName:''' The human readable name of your document type (string)? TODO: explain where this is used.&lt;br /&gt;
* '''NSUnixExtensions:''' An array of strings, each containing a file extension connected to this document type on &amp;quot;unix&amp;quot; platforms. TODO: explain how &amp;quot;unix&amp;quot; is interpreted by GNUstep.&lt;br /&gt;
* '''NSDOSExtensions:''' An array of strings, each containing a file extenstion connected to this document type on &amp;quot;DOS&amp;quot; platforms (could be loosely interpreted as any MS platforms GNUstep runs on, i.e. Windows 2000/XP).&lt;br /&gt;
* '''NSRole:''' A string, either &amp;quot;Viewer&amp;quot; or &amp;quot;Editor&amp;quot;, depending on how your document operates on this file type.&lt;br /&gt;
* '''NSIcon:''' A icon name associated with this document type. TODO: Investigate how this works.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Info-gnustep.plist'''&lt;br /&gt;
 {&lt;br /&gt;
     ApplicationDescription = &amp;quot;A simple text editor for GNUstep.&amp;quot;;&lt;br /&gt;
     ApplicationName = TextEdit;&lt;br /&gt;
     ApplicationRelease = 0.10;&lt;br /&gt;
     Authors = ( &amp;quot;Christopher Armstrong &amp;lt;quineska@gamebox.net&amp;quot; );&lt;br /&gt;
     Copyright = &amp;quot;Copyright (C) 2005 Christopher Armstrong&amp;quot;;&lt;br /&gt;
     CopyrightDescription = &amp;quot;Released under GPL.&amp;quot;;&lt;br /&gt;
     FullVersionID = 0.10;&lt;br /&gt;
     NSExecutable = TextEdit;&lt;br /&gt;
     NSMainNibFile = TextEdit.gorm;&lt;br /&gt;
     NSPrincipalClass = NSApplication;&lt;br /&gt;
     NSRole = Application;&lt;br /&gt;
     NSTypes = (&lt;br /&gt;
         {&lt;br /&gt;
                 NSDocumentClass = &amp;quot;TextDocument&amp;quot;;&lt;br /&gt;
                 NSName = &amp;quot;GSTextDocumentType&amp;quot;;&lt;br /&gt;
                 NSHumanReadableName = &amp;quot;Text Document&amp;quot;;&lt;br /&gt;
                 NSUnixExtensions = ( &amp;quot;txt&amp;quot;, &amp;quot;&amp;quot; );&lt;br /&gt;
                 NSDOSExtensions = ( &amp;quot;txt&amp;quot; );&lt;br /&gt;
                 NSRole = Editor;&lt;br /&gt;
         }&lt;br /&gt;
     );&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For more information on property list files, consult [[Property Lists]].&lt;br /&gt;
&lt;br /&gt;
=== Interface file ===&lt;br /&gt;
&lt;br /&gt;
Two interface files are needed: one for your main application, and another that will be instantiated with each instance of your document subclass. These both should be listed as resources in your makefile, (as shown the GNUmakefile example above). It may be helpful to name the document nib file after your class.&lt;br /&gt;
&lt;br /&gt;
==== Application Interface File ====&lt;br /&gt;
&lt;br /&gt;
The application one should just be a menu (though it could be more if necessary). When constructing it, take the following into account:&lt;br /&gt;
&lt;br /&gt;
* Use a standard Gorm template for an Application.&lt;br /&gt;
* Delete the window instance in the &amp;quot;Objects&amp;quot; pane (unless you need a main window, in which case I don't know how to operate).&lt;br /&gt;
* Set NSOwner's class to &amp;quot;NSDocumentController&amp;quot; (this is the custom class option of NSOwner in the property inspector). This ensures openDocument, newDocument, etc. messages, as sent to NSFirst, get picked up by NSDocumentController. Do not instantiate it (I believe you can't anyway).&lt;br /&gt;
* If you intend to subclass NSDocumentController, subclass it in the Classes pane. To make sure that this class is instantiated and used, make sure you instantiate it in Gorm or in your main.m file, and set NSOwner to be your subclass.&lt;br /&gt;
* Drag a Document menu from the palette onto your main menu. This already has the proper linkage for each relevant message for a document setup to be directed to NSFirst. In the case of generic messages (such as openDocument:, not associated with any document instance), these are forwarded to the shared instance of NSDocumentController (see it's reference documentation). When a document is active, more specific messages (such as close: or saveDocument:) are forwarded to the relevant document instance of your NSDocument subclass.&lt;br /&gt;
* Add any appropriate menus such as &amp;quot;Info&amp;quot; and &amp;quot;Format&amp;quot; which may be relevant to your application.&lt;br /&gt;
&lt;br /&gt;
==== Document Interface File ====&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Property_Lists&amp;diff=823</id>
		<title>Property Lists</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Property_Lists&amp;diff=823"/>
		<updated>2005-07-06T06:55:04Z</updated>

		<summary type="html">&lt;p&gt;Quineska: Spelling correction&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;NOTE: '''If anything below is dead wrong, please fix immediately. It is a work in progress. I am constructing this based on my experience with GNUstep, NOT any reference documentation that may exist. I don't warrant it fit for any purpose whatsoever, nor shall I take any responsibility for any issues or losses or problems etc that may arise from its use. (Christopher Armstrong, --[[User:Quineska|ChrisArmstrong]] 08:38, 6 Jul 2005 (CEST))'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
Property lists are used throughout GNUstep to store defaults, program settings, application meta information, etc. MacOS X uses XML based property lists, but GNUstep uses another property list implementation also (TODO: history of this style of property list).&lt;br /&gt;
&lt;br /&gt;
They are composed of a &amp;quot;tree of arrays and dictionary's, which may be embedded inside each other for several layers. TODO: limits of embedding array/dictionaries inside each other.&lt;br /&gt;
&lt;br /&gt;
== Dictionary ==&lt;br /&gt;
&lt;br /&gt;
A dictionary is a list of key-value pairs, where each item in the list has a name associated with it (key) and another type (value), which could be another dictionary, an array or often a string. It programmatically corresponds to NSDictionary/NSMutableDictionary. They take the following syntax:&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
    KeyName1 = Value1;&lt;br /&gt;
    AnotherKeyName = &amp;quot;Value2&amp;quot;;&lt;br /&gt;
    Something = ( &amp;quot;ArrayItem1&amp;quot;, &amp;quot;ArrayItem2&amp;quot;, &amp;quot;ArrayItem3&amp;quot; );&lt;br /&gt;
    Key4 = 0.10;&lt;br /&gt;
    KeyFive = { Dictionary2Key1 = &amp;quot;Something&amp;quot;; AnotherKey = &amp;quot;Somethingelse&amp;quot;; };&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
As can be seen, each key-value pair is seperated by a semi-colon. Within the pair, the key is seperated from the value with an &amp;quot;equals&amp;quot; (=) sign. The key name is arbitrary, and not put in inverted commas (&amp;quot;&amp;quot;). Shown above are a (unknown type, could be some sort of string - TODO), a string, an array, a number and another dictionary  (respectively).&lt;br /&gt;
&lt;br /&gt;
== Array ==&lt;br /&gt;
&lt;br /&gt;
An array is a list of values, each of the same type (often arrays or dictionaries). Programmatically, it uses NSArray/NSMutableArray. It takes a syntax similar to the following:&lt;br /&gt;
&lt;br /&gt;
( Value1, Value2, Value3, Value4 )&lt;br /&gt;
&lt;br /&gt;
Each value is seperated by commas. By the technical definition of an array, each value is of the same type (but I believe GNUstep permits different types).&lt;br /&gt;
&lt;br /&gt;
== Programming ==&lt;br /&gt;
&lt;br /&gt;
GNUstep permits such property list files (denoted with a .plist extenstion) to be loaded and subsequently used in your applications or tools. NSDictionary and NSArray are used as representations of the above in the Foundation library (gnustep-base).&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Creating_document_based_applications&amp;diff=825</id>
		<title>Creating document based applications</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Creating_document_based_applications&amp;diff=825"/>
		<updated>2005-07-06T06:52:55Z</updated>

		<summary type="html">&lt;p&gt;Quineska: Added more info, namely related to Property List, Gorm files, etc.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Note: this is a work in progress. Please bear with me as I add further information. &lt;br /&gt;
--[[User:Quineska|ChrisArmstrong]] 08:33, 5 Jul 2005 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
OpenStep can provide your application a document-based model. It helps to simplify the process of creating such applications. GNUstep is compatible with this paridgm as well; this document aims to provide an overview of what is required in the creation and design of such an application.&lt;br /&gt;
&lt;br /&gt;
It is assumed you are familiar with GNUstep, and have some understanding as how to create Gorm's nib files, as well as some understanding of how they work.&lt;br /&gt;
&lt;br /&gt;
Importantly, such applications have certain components that are required, and should be considered as part of their design. At a programmatic level, classes that will be used as part of the AppKit are:&lt;br /&gt;
&lt;br /&gt;
==== NSDocument ====&lt;br /&gt;
&lt;br /&gt;
This class is central to the OpenStep document based model. Such an application declares a new instance of a subclass of NSDocument for each “document” that is opened. It will be necessary to subclass NSDocument to implement this.&lt;br /&gt;
&lt;br /&gt;
Each instance of your NSDocument subclass may have one or more windows associated with it. These are used as an interface for loading and saving a representation of your document type. Each window will have an “NSWindowController” instance associated with it, where NSDocument maintains a list of these.&lt;br /&gt;
&lt;br /&gt;
==== NSDocumentController ====&lt;br /&gt;
&lt;br /&gt;
This class acts a controller. It maintains a list of documents (instances of your NSDocument subclass) and is responsible for loading and instantiating new documents. It is usually not necessary to implement a subclass of this, but often it may be useful to implement special functionality (especially related to open documents as a whole).&lt;br /&gt;
&lt;br /&gt;
==== NSWindowController ====&lt;br /&gt;
&lt;br /&gt;
As mentioned above, NSWindowController instances are individually associated with one NSWindow instance, in such a way that a document maintains a list of window controllers that are reponsible for rendering the views associated with a document.&lt;br /&gt;
&lt;br /&gt;
You will most likely not have to subclass NSWindowController. Instead, you associate a nib file (the Gorm output) with the subclass of NSDocument, and NSDocumentController will load this nib file for each document that is created or loaded.&lt;br /&gt;
&lt;br /&gt;
For example, a text based application that is used for the editing of plain text files, may subclass NSDocument with a TextDocument class. Each instance of this class would have an NSWindowController instance associated with it, which in turn manages a window instance that is instantiated from a nib file. The NSDocumentController instance, as managed and instatiated by GNUstep, would be responsible for loading and saving documents in your application. It even prompts the user to save their documents when they try to quit the application.&lt;br /&gt;
&lt;br /&gt;
== Components ==&lt;br /&gt;
&lt;br /&gt;
In building your application you will need to create a number of components. From scratch, the following should be a rough guide to getting it working.&lt;br /&gt;
&lt;br /&gt;
=== The Makefile ===&lt;br /&gt;
&lt;br /&gt;
For this type of application, no special makefile is needed: it just has to be a normal application. Project Builder should be able to spit out the required makefile and Gorm files that are needed for a generic application. Otherwise use the following as a template:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''GNUmakefile'''&lt;br /&gt;
&lt;br /&gt;
 include $(GNUSTEP_MAKEFILES)/common.make&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 APP_NAME = DocumentApp&amp;lt;br&amp;gt;&lt;br /&gt;
 DocumentApp_OBJC_FILES =&amp;lt;br&amp;gt;&lt;br /&gt;
  MyDocument.m &amp;lt;br&amp;gt;&lt;br /&gt;
  main.m&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 DocumentApp_RESOURCES = \ &amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/Info-gnustep.plist \&amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/DocumentApp.gorm \&amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/MyDocument.gorm&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 -include GNUmakefile.preamble&amp;lt;br&amp;gt;&lt;br /&gt;
 include $(GNUSTEP_MAKEFILES)/application.make&amp;lt;br&amp;gt;&lt;br /&gt;
 -include GNUmakefile.postamble&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For more information as to customising this file, as well as setting up compiler options for third party libraries and includes, see the GNUstep makefile manual.&lt;br /&gt;
&lt;br /&gt;
=== The application dictionary - Info-gnustep.plist ===&lt;br /&gt;
&lt;br /&gt;
For those that have edited this file in their project before, it is a dictionary with various values entered. For our purposes, we need an array within the main dictionary, called &amp;quot;NSTypes&amp;quot;. This is a array of unnamed dictionaries, with one dictionary for each type. &lt;br /&gt;
&lt;br /&gt;
An entire example of this file, for a &amp;quot;theoretical&amp;quot; TextEdit application (please note that such an application does exist as an example application from Next I think, and again on MacOS X but I have constructed a much simpler version, used only for plain text files).&lt;br /&gt;
&lt;br /&gt;
Taking a look at the single dictionary entry in the NSTypes array, the following key-value pairs are needed:&lt;br /&gt;
* '''NSDocumentClass:''' This is (string) the subclass name you use in your code, the &amp;quot;objective-c name&amp;quot; of your document subclass. This is used by NSDocumentController's default implementation to create instances of your document type.&lt;br /&gt;
* '''NSName:''' The generic file type (string). This is completely arbitrary, and can be anything you like. For the purpose of conventions, it may be more appropriate not to use the &amp;quot;NS&amp;quot; or &amp;quot;GS&amp;quot; prefix (the latter of which I not sure), and instead use either your own, or no prefix at all.&lt;br /&gt;
* '''NSHumanReadableName:''' The human readable name of your document type (string)? TODO: explain where this is used.&lt;br /&gt;
* '''NSUnixExtensions:''' An array of strings, each containing a file extension connected to this document type on &amp;quot;unix&amp;quot; platforms. TODO: explain how &amp;quot;unix&amp;quot; is interpreted by GNUstep.&lt;br /&gt;
* '''NSDOSExtensions:''' An array of strings, each containing a file extenstion connected to this document type on &amp;quot;DOS&amp;quot; platforms (could be loosely interpreted as any MS platforms GNUstep runs on, i.e. Windows 2000/XP).&lt;br /&gt;
* '''NSRole:''' A string, either &amp;quot;Viewer&amp;quot; or &amp;quot;Editor&amp;quot;, depending on how your document operates on this file type.&lt;br /&gt;
* '''NSIcon:''' A icon name associated with this document type. TODO: Investigate how this works.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Info-gnustep.plist'''&lt;br /&gt;
 {&lt;br /&gt;
     ApplicationDescription = &amp;quot;A simple text editor for GNUstep.&amp;quot;;&lt;br /&gt;
     ApplicationName = TextEdit;&lt;br /&gt;
     ApplicationRelease = 0.10;&lt;br /&gt;
     Authors = ( &amp;quot;Christopher Armstrong &amp;lt;quineska@gamebox.net&amp;quot; );&lt;br /&gt;
     Copyright = &amp;quot;Copyright (C) 2005 Christopher Armstrong&amp;quot;;&lt;br /&gt;
     CopyrightDescription = &amp;quot;Released under GPL.&amp;quot;;&lt;br /&gt;
     FullVersionID = 0.10;&lt;br /&gt;
     NSExecutable = TextEdit;&lt;br /&gt;
     NSMainNibFile = TextEdit.gorm;&lt;br /&gt;
     NSPrincipalClass = NSApplication;&lt;br /&gt;
     NSRole = Application;&lt;br /&gt;
     NSTypes = (&lt;br /&gt;
         {&lt;br /&gt;
                 NSDocumentClass = &amp;quot;TextDocument&amp;quot;;&lt;br /&gt;
                 NSName = &amp;quot;GSTextDocumentType&amp;quot;;&lt;br /&gt;
                 NSHumanReadableName = &amp;quot;Text Document&amp;quot;;&lt;br /&gt;
                 NSUnixExtensions = ( &amp;quot;txt&amp;quot;, &amp;quot;&amp;quot; );&lt;br /&gt;
                 NSDOSExtensions = ( &amp;quot;txt&amp;quot; );&lt;br /&gt;
                 NSRole = Editor;&lt;br /&gt;
         }&lt;br /&gt;
     );&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For more information on property list files, consult [[Property Lists]].&lt;br /&gt;
&lt;br /&gt;
=== Interface file ===&lt;br /&gt;
&lt;br /&gt;
Two interface files are needed: one for your main application, and another that will be instantiated with each instance of your document subclass. These both should be listed as resources in your makefile, (as shown the GNUmakefile example above). It may be helpful to name the document nib file after your class.&lt;br /&gt;
&lt;br /&gt;
==== Application Interface File ====&lt;br /&gt;
&lt;br /&gt;
The application one should just be a menu (though it could be more if necessary). When constructing it, take the following into account:&lt;br /&gt;
&lt;br /&gt;
* Use a standard Gorm template for an application.&lt;br /&gt;
* Delete the window instance in the &amp;quot;Objects&amp;quot; pane (unless you need a main window, in which case I don't know how to operate).&lt;br /&gt;
* Set NSOwner's class to &amp;quot;NSDocumentController&amp;quot; (this is the custom class option of NSOwner in the property inspector). This ensures openDocument, newDocument, etc. messages, as sent to NSFirst, get picked up by NSDocumentController. Do not instantiate it (I believe you can't anyway).&lt;br /&gt;
* If you intend to subclass NSDocumentController, subclass it in the Classes pane. To make sure that this class is instantiated and used, make sure you instantiate it in Gorm or in your main.m file, and set NSOwner to be your subclass.&lt;br /&gt;
* Drag a Document menu from the palette onto your main menu. This already has the proper linkage for each relevant message for a document setup to be directed to NSFirst. In the case of generic messages (such as openDocument:, not associated with any document instance), these are forwarded to the shared instance of NSDocumentController (see it's reference documentation). When a document is active, more specific messages (such as close: or saveDocument:) are forwarded to the relevant document instance of your NSDocument subclass.&lt;br /&gt;
* Add any appropriate menus such as &amp;quot;Info&amp;quot; and &amp;quot;Format&amp;quot; which may be relevant to your application.&lt;br /&gt;
&lt;br /&gt;
==== Document Interface File ====&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Property_Lists&amp;diff=820</id>
		<title>Property Lists</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Property_Lists&amp;diff=820"/>
		<updated>2005-07-06T06:38:42Z</updated>

		<summary type="html">&lt;p&gt;Quineska: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;NOTE: '''If anything below is dead wrong, please fix immediately. It is a work in progress. I am constructing this based on my experience with GNUstep, NOT any reference documentation that may exist. I don't warrant it fit for any purpose whatsoever, nor shall I take any responsibility for any issues or losses or problems etc that may arise from its use. (Christopher Armstrong, --[[User:Quineska|ChrisArmstrong]] 08:38, 6 Jul 2005 (CEST))'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
Property lists are used throughout GNUstep to store defaults, program settings, application meta information, etc. MacOS X uses XML based property lists, but GNUstep uses another property list implementation also (TODO: history of this style of property list).&lt;br /&gt;
&lt;br /&gt;
They are composed of a &amp;quot;tree of arrays and dictionary's, which may be embedded inside each other for several layers. TODO: limits of embedding array/dictionaries inside each other.&lt;br /&gt;
&lt;br /&gt;
== Dictionary ==&lt;br /&gt;
&lt;br /&gt;
A dictionary is a list of key-value pairs, where each item in the list has a name associated with it (key) and another type (value), which could be another dictionary, an array or often a string. It programmatically corresponds to NSDictionary/NSMutableDictionary. They take the following syntax:&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
    KeyName1 = Value1;&lt;br /&gt;
    AnotherKeyName = &amp;quot;Value2&amp;quot;;&lt;br /&gt;
    Something = ( &amp;quot;ArrayItem1&amp;quot;, &amp;quot;ArrayItem2&amp;quot;, &amp;quot;ArrayItem3&amp;quot; );&lt;br /&gt;
    Key4 = 0.10;&lt;br /&gt;
    KeyFive = { Dictionary2Key1 = &amp;quot;Something&amp;quot;; AnotherKey = &amp;quot;Somethingelse&amp;quot;; };&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
As can be seen, each key-value pair is seperated by a semi-colon. Within the pair, the key is seperated from the value with an &amp;quot;equals&amp;quot; (=) sign. The key name is arbitrary, and not put in inverted commas (&amp;quot;&amp;quot;). Shown above are a (unknown type, could be some sort of string - TODO), a string, an array, a number and another dictionary  (respectively).&lt;br /&gt;
&lt;br /&gt;
== Array ==&lt;br /&gt;
&lt;br /&gt;
An array is a list of values, each of the same type (often arrays or dictionaries). Programmatically, it uses NSArray/NSMutableArray. It takes a syntax similar to the following:&lt;br /&gt;
&lt;br /&gt;
( Value1, Value2, Value3, Value4 )&lt;br /&gt;
&lt;br /&gt;
Each value is seperated by commas. By the technical definition of an array, each value is of the same type (but I belive GNUstep permits different types).&lt;br /&gt;
&lt;br /&gt;
== Programming ==&lt;br /&gt;
&lt;br /&gt;
GNUstep permits such property list files (denoted with a .plist extenstion) to be loaded and subsequently used in your applications or tools. NSDictionary and NSArray are used as representations of the above in the Foundation library (gnustep-base).&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Property_Lists&amp;diff=818</id>
		<title>Property Lists</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Property_Lists&amp;diff=818"/>
		<updated>2005-07-06T06:38:14Z</updated>

		<summary type="html">&lt;p&gt;Quineska: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;NOTE: If anything below is dead wrong, please fix immediately. It is a work in progress. I am constructing this based on my experience with GNUstep, NOT any reference documentation that may exist. I don't warrant it fit for any purpose whatsoever, nor shall I take any responsibility for any issues or losses or problems etc that may arise from its use. (Christopher Armstrong, --[[User:Quineska|ChrisArmstrong]] 08:38, 6 Jul 2005 (CEST))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
Property lists are used throughout GNUstep to store defaults, program settings, application meta information, etc. MacOS X uses XML based property lists, but GNUstep uses another property list implementation also (TODO: history of this style of property list).&lt;br /&gt;
&lt;br /&gt;
They are composed of a &amp;quot;tree of arrays and dictionary's, which may be embedded inside each other for several layers. TODO: limits of embedding array/dictionaries inside each other.&lt;br /&gt;
&lt;br /&gt;
== Dictionary ==&lt;br /&gt;
&lt;br /&gt;
A dictionary is a list of key-value pairs, where each item in the list has a name associated with it (key) and another type (value), which could be another dictionary, an array or often a string. It programmatically corresponds to NSDictionary/NSMutableDictionary. They take the following syntax:&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
    KeyName1 = Value1;&lt;br /&gt;
    AnotherKeyName = &amp;quot;Value2&amp;quot;;&lt;br /&gt;
    Something = ( &amp;quot;ArrayItem1&amp;quot;, &amp;quot;ArrayItem2&amp;quot;, &amp;quot;ArrayItem3&amp;quot; );&lt;br /&gt;
    Key4 = 0.10;&lt;br /&gt;
    KeyFive = { Dictionary2Key1 = &amp;quot;Something&amp;quot;; AnotherKey = &amp;quot;Somethingelse&amp;quot;; };&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
As can be seen, each key-value pair is seperated by a semi-colon. Within the pair, the key is seperated from the value with an &amp;quot;equals&amp;quot; (=) sign. The key name is arbitrary, and not put in inverted commas (&amp;quot;&amp;quot;). Shown above are a (unknown type, could be some sort of string - TODO), a string, an array, a number and another dictionary  (respectively).&lt;br /&gt;
&lt;br /&gt;
== Array ==&lt;br /&gt;
&lt;br /&gt;
An array is a list of values, each of the same type (often arrays or dictionaries). Programmatically, it uses NSArray/NSMutableArray. It takes a syntax similar to the following:&lt;br /&gt;
&lt;br /&gt;
( Value1, Value2, Value3, Value4 )&lt;br /&gt;
&lt;br /&gt;
Each value is seperated by commas. By the technical definition of an array, each value is of the same type (but I belive GNUstep permits different types).&lt;br /&gt;
&lt;br /&gt;
== Programming ==&lt;br /&gt;
&lt;br /&gt;
GNUstep permits such property list files (denoted with a .plist extenstion) to be loaded and subsequently used in your applications or tools. NSDictionary and NSArray are used as representations of the above in the Foundation library (gnustep-base).&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Creating_document_based_applications&amp;diff=819</id>
		<title>Creating document based applications</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Creating_document_based_applications&amp;diff=819"/>
		<updated>2005-07-06T06:19:55Z</updated>

		<summary type="html">&lt;p&gt;Quineska: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Note: this is a work in progress. Please bear with me as I add further information. &lt;br /&gt;
--[[User:Quineska|ChrisArmstrong]] 08:33, 5 Jul 2005 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
OpenStep can provide your application a document-based model. It helps to simplify the process of creating such applications. GNUstep is compatible with this paridgm as well; this document aims to provide an overview of what is required in the creation and design of such an application.&lt;br /&gt;
&lt;br /&gt;
It is assumed you are familiar with GNUstep, and have some understanding as how to create Gorm's nib files, as well as some understanding of how they work.&lt;br /&gt;
&lt;br /&gt;
Importantly, such applications have certain components that are required, and should be considered as part of their design. At a programmatic level, classes that will be used as part of the AppKit are:&lt;br /&gt;
&lt;br /&gt;
==== NSDocument ====&lt;br /&gt;
&lt;br /&gt;
This class is central to the OpenStep document based model. Such an application declares a new instance of a subclass of NSDocument for each “document” that is opened. It will be necessary to subclass NSDocument to implement this.&lt;br /&gt;
&lt;br /&gt;
Each instance of your NSDocument subclass may have one or more windows associated with it. These are used as an interface for loading and saving a representation of your document type. Each window will have an “NSWindowController” instance associated with it, where NSDocument maintains a list of these.&lt;br /&gt;
&lt;br /&gt;
==== NSDocumentController ====&lt;br /&gt;
&lt;br /&gt;
This class acts a controller. It maintains a list of documents (instances of your NSDocument subclass) and is responsible for loading and instantiating new documents. It is usually not necessary to implement a subclass of this, but often it may be useful to implement special functionality (especially related to open documents as a whole).&lt;br /&gt;
&lt;br /&gt;
==== NSWindowController ====&lt;br /&gt;
&lt;br /&gt;
As mentioned above, NSWindowController instances are individually associated with one NSWindow instance, in such a way that a document maintains a list of window controllers that are reponsible for rendering the views associated with a document.&lt;br /&gt;
&lt;br /&gt;
You will most likely not have to subclass NSWindowController. Instead, you associate a nib file (the Gorm output) with the subclass of NSDocument, and NSDocumentController will load this nib file for each document that is created or loaded.&lt;br /&gt;
&lt;br /&gt;
For example, a text based application that is used for the editing of plain text files, may subclass NSDocument with a TextDocument class. Each instance of this class would have an NSWindowController instance associated with it, which in turn manages a window instance that is instantiated from a nib file. The NSDocumentController instance, as managed and instatiated by GNUstep, would be responsible for loading and saving documents in your application. It even prompts the user to save their documents when they try to quit the application.&lt;br /&gt;
&lt;br /&gt;
== Components ==&lt;br /&gt;
&lt;br /&gt;
In building your application you will need to create a number of components. From scratch, the following should be a rough guide to getting it working.&lt;br /&gt;
&lt;br /&gt;
=== The Makefile ===&lt;br /&gt;
&lt;br /&gt;
For this type of application, no special makefile is needed: it just has to be a normal application. Project Builder should be able to spit out the required makefile and Gorm files that are needed for a generic application. Otherwise use the following as a template:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''GNUmakefile'''&lt;br /&gt;
&lt;br /&gt;
 include $(GNUSTEP_MAKEFILES)/common.make&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 APP_NAME = DocumentApp&amp;lt;br&amp;gt;&lt;br /&gt;
 DocumentApp_OBJC_FILES =&amp;lt;br&amp;gt;&lt;br /&gt;
  MyDocument.m &amp;lt;br&amp;gt;&lt;br /&gt;
  main.m&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 DocumentApp_RESOURCES = \ &amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/Info-gnustep.plist \&amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/DocumentApp.gorm \&amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/MyDocument.gorm&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 -include GNUmakefile.preamble&amp;lt;br&amp;gt;&lt;br /&gt;
 include $(GNUSTEP_MAKEFILES)/application.make&amp;lt;br&amp;gt;&lt;br /&gt;
 -include GNUmakefile.postamble&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For more information as to customising this file, as well as setting up compiler options for third party libraries and includes, see the GNUstep makefile manual.&lt;br /&gt;
&lt;br /&gt;
=== The application dictionary - Info-gnustep.plist ===&lt;br /&gt;
&lt;br /&gt;
For those that have edited this file in their project before, it is a dictionary with various values entered. For our purposes, we need an array within the main dictionary, called &amp;quot;NSTypes&amp;quot;. This is a array of unnamed dictionaries, with one dictionary for each type. &lt;br /&gt;
&lt;br /&gt;
An entire example of this file, for a &amp;quot;theoretical&amp;quot; TextEdit application (please note that such an application does exist as an example application from Next I think, and again on MacOS X but I have constructed a much simpler version, used only for plain text files).&lt;br /&gt;
&lt;br /&gt;
Taking a look at the single dictionary entry in the NSTypes array, the following key-value pairs are needed:&lt;br /&gt;
* '''NSDocumentClass:''' This is (string) the subclass name you use in your code, the &amp;quot;objective-c name&amp;quot; of your document subclass. This is used by NSDocumentController's default implementation to create instances of your document type.&lt;br /&gt;
* '''NSName:''' The generic file type (string). This is completely arbitrary, and can be anything you like. For the purpose of conventions, it may be more appropriate not to use the &amp;quot;NS&amp;quot; or &amp;quot;GS&amp;quot; prefix (the latter of which I not sure), and instead use either your own, or no prefix at all.&lt;br /&gt;
* '''NSHumanReadableName:''' The human readable name of your document type (string)? TODO: explain where this is used.&lt;br /&gt;
* '''NSUnixExtensions:''' An array of strings, each containing a file extension connected to this document type on &amp;quot;unix&amp;quot; platforms. TODO: explain how &amp;quot;unix&amp;quot; is interpreted by GNUstep.&lt;br /&gt;
* '''NSDOSExtensions:''' An array of strings, each containing a file extenstion connected to this document type on &amp;quot;DOS&amp;quot; platforms (could be loosely interpreted as any MS platforms GNUstep runs on, i.e. Windows 2000/XP).&lt;br /&gt;
* '''NSRole:''' A string, either &amp;quot;Viewer&amp;quot; or &amp;quot;Editor&amp;quot;, depending on how your document operates on this file type.&lt;br /&gt;
* '''NSIcon:''' A icon name associated with this document type. TODO: Investigate how this works.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Info-gnustep.plist'''&lt;br /&gt;
 {&lt;br /&gt;
     ApplicationDescription = &amp;quot;A simple text editor for GNUstep.&amp;quot;;&lt;br /&gt;
     ApplicationName = TextEdit;&lt;br /&gt;
     ApplicationRelease = 0.10;&lt;br /&gt;
     Authors = ( &amp;quot;Christopher Armstrong &amp;lt;quineska@gamebox.net&amp;quot; );&lt;br /&gt;
     Copyright = &amp;quot;Copyright (C) 2005 Christopher Armstrong&amp;quot;;&lt;br /&gt;
     CopyrightDescription = &amp;quot;Released under GPL.&amp;quot;;&lt;br /&gt;
     FullVersionID = 0.10;&lt;br /&gt;
     NSExecutable = TextEdit;&lt;br /&gt;
     NSMainNibFile = TextEdit.gorm;&lt;br /&gt;
     NSPrincipalClass = NSApplication;&lt;br /&gt;
     NSRole = Application;&lt;br /&gt;
     NSTypes = (&lt;br /&gt;
         {&lt;br /&gt;
                 NSDocumentClass = &amp;quot;TextDocument&amp;quot;;&lt;br /&gt;
                 NSName = &amp;quot;GSTextDocumentType&amp;quot;;&lt;br /&gt;
                 NSHumanReadableName = &amp;quot;Text Document&amp;quot;;&lt;br /&gt;
                 NSUnixExtensions = ( &amp;quot;txt&amp;quot;, &amp;quot;&amp;quot; );&lt;br /&gt;
                 NSDOSExtensions = ( &amp;quot;txt&amp;quot; );&lt;br /&gt;
                 NSRole = Editor;&lt;br /&gt;
         }&lt;br /&gt;
     );&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For more information on property list files, consult [[Property Lists]] TODO: construct&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Creating_document_based_applications&amp;diff=817</id>
		<title>Creating document based applications</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Creating_document_based_applications&amp;diff=817"/>
		<updated>2005-07-06T06:17:19Z</updated>

		<summary type="html">&lt;p&gt;Quineska: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Note: this is a work in progress. Please bear with me as I add further information. &lt;br /&gt;
--[[User:Quineska|ChrisArmstrong]] 08:33, 5 Jul 2005 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
OpenStep can provide your application a document-based model. It helps to simplify the process of creating such applications. GNUstep is compatible with this paridgm as well; this document aims to provide an overview of what is required in the creation and design of such an application.&lt;br /&gt;
&lt;br /&gt;
It is assumed you are familiar with GNUstep, and have some understanding as how to create Gorm's nib files, as well as some understanding of how they work.&lt;br /&gt;
&lt;br /&gt;
Importantly, such applications have certain components that are required, and should be considered as part of their design. At a programmatic level, classes that will be used as part of the AppKit are:&lt;br /&gt;
&lt;br /&gt;
==== NSDocument ====&lt;br /&gt;
&lt;br /&gt;
This class is central to the OpenStep document based model. Such an application declares a new instance of a subclass of NSDocument for each “document” that is opened. It will be necessary to subclass NSDocument to implement this.&lt;br /&gt;
&lt;br /&gt;
Each instance of your NSDocument subclass may have one or more windows associated with it. These are used as an interface for loading and saving a representation of your document type. Each window will have an “NSWindowController” instance associated with it, where NSDocument maintains a list of these.&lt;br /&gt;
&lt;br /&gt;
==== NSDocumentController ====&lt;br /&gt;
&lt;br /&gt;
This class acts a controller. It maintains a list of documents (instances of your NSDocument subclass) and is responsible for loading and instantiating new documents. It is usually not necessary to implement a subclass of this, but often it may be useful to implement special functionality (especially related to open documents as a whole).&lt;br /&gt;
&lt;br /&gt;
==== NSWindowController ====&lt;br /&gt;
&lt;br /&gt;
As mentioned above, NSWindowController instances are individually associated with one NSWindow instance, in such a way that a document maintains a list of window controllers that are reponsible for rendering the views associated with a document.&lt;br /&gt;
&lt;br /&gt;
You will most likely not have to subclass NSWindowController. Instead, you associate a nib file (the Gorm output) with the subclass of NSDocument, and NSDocumentController will load this nib file for each document that is created or loaded.&lt;br /&gt;
&lt;br /&gt;
For example, a text based application that is used for the editing of plain text files, may subclass NSDocument with a TextDocument class. Each instance of this class would have an NSWindowController instance associated with it, which in turn manages a window instance that is instantiated from a nib file. The NSDocumentController instance, as managed and instatiated by GNUstep, would be responsible for loading and saving documents in your application. It even prompts the user to save their documents when they try to quit the application.&lt;br /&gt;
&lt;br /&gt;
== Components ==&lt;br /&gt;
&lt;br /&gt;
In building your application you will need to create a number of components. From scratch, the following should be a rough guide to getting it working.&lt;br /&gt;
&lt;br /&gt;
=== The Makefile ===&lt;br /&gt;
&lt;br /&gt;
For this type of application, no special makefile is needed: it just has to be a normal application. Project Builder should be able to spit out the required makefile and Gorm files that are needed for a generic application. Otherwise use the following as a template:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''GNUmakefile'''&lt;br /&gt;
&lt;br /&gt;
 include $(GNUSTEP_MAKEFILES)/common.make&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 APP_NAME = DocumentApp&amp;lt;br&amp;gt;&lt;br /&gt;
 DocumentApp_OBJC_FILES =&amp;lt;br&amp;gt;&lt;br /&gt;
  MyDocument.m &amp;lt;br&amp;gt;&lt;br /&gt;
  main.m&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 DocumentApp_RESOURCES = \ &amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/Info-gnustep.plist \&amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/DocumentApp.gorm \&amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/MyDocument.gorm&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 -include GNUmakefile.preamble&amp;lt;br&amp;gt;&lt;br /&gt;
 include $(GNUSTEP_MAKEFILES)/application.make&amp;lt;br&amp;gt;&lt;br /&gt;
 -include GNUmakefile.postamble&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For more information as to customising this file, as well as setting up compiler options for third party libraries and includes, see the GNUstep makefile manual.&lt;br /&gt;
&lt;br /&gt;
=== The application dictionary - Info-gnustep.plist ===&lt;br /&gt;
&lt;br /&gt;
For those that have edited this file in their project before, it is a dictionary with various values entered. For our purposes, we need an array within the main dictionary, called &amp;quot;NSTypes&amp;quot;. This is a array of unnamed dictionaries, with one dictionary for each type. &lt;br /&gt;
&lt;br /&gt;
An entire example of this file, for a &amp;quot;theoretical&amp;quot; TextEdit application (please note that such an application does exist as an example application from Next I think, and again on MacOS X but I have constructed a much simpler version, used only for plain text files).&lt;br /&gt;
&lt;br /&gt;
Taking a look at the single dictionary entry in the NSTypes array, the following key-value pairs are needed:&lt;br /&gt;
* '''NSDocumentClass:''' This is (string) the subclass name you use in your code, the &amp;quot;objective-c name&amp;quot; of your document subclass. This is used by NSDocumentController's default implementation to create instances of your document type.&lt;br /&gt;
* '''NSName:''' The generic file type (string). This is completely arbitrary, and can be anything you like. For the purpose of conventions, it may be more appropriate not to use the &amp;quot;NS&amp;quot; or &amp;quot;GS&amp;quot; prefix (the latter of which I not sure), and instead use either your own, or no prefix at all.&lt;br /&gt;
* '''NSHumanReadableName:''' The human readable name of your document type (string)? TODO: explain where this is used.&lt;br /&gt;
* '''NSUnixExtensions:''' An array of strings, each containing a file extension connected to this document type on &amp;quot;unix&amp;quot; platforms. TODO: explain how &amp;quot;unix&amp;quot; is interpreted by GNUstep.&lt;br /&gt;
* '''NSDOSExtensions:''' An array of strings, each containing a file extenstion connected to this document type on &amp;quot;DOS&amp;quot; platforms (could be loosely interpreted as any MS platforms GNUstep runs on, i.e. Windows 2000/XP).&lt;br /&gt;
* '''NSRole:''' A string, either &amp;quot;Viewer&amp;quot; or &amp;quot;Editor&amp;quot;, depending on how your document operates on this file type.&lt;br /&gt;
* '''NSIcon:''' A icon name associated with this document type. TODO: Investigate how this works.&lt;br /&gt;
&lt;br /&gt;
'''Info-gnustep.plist'''&lt;br /&gt;
 {&lt;br /&gt;
     ApplicationDescription = &amp;quot;A simple text editor for GNUstep.&amp;quot;;&lt;br /&gt;
     ApplicationName = TextEdit;&lt;br /&gt;
     ApplicationRelease = 0.10;&lt;br /&gt;
     Authors = ( &amp;quot;Christopher Armstrong &amp;lt;quineska@gamebox.net&amp;quot; );&lt;br /&gt;
     Copyright = &amp;quot;Copyright (C) 2005 Christopher Armstrong&amp;quot;;&lt;br /&gt;
     CopyrightDescription = &amp;quot;Released under GPL.&amp;quot;;&lt;br /&gt;
     FullVersionID = 0.10;&lt;br /&gt;
     NSExecutable = TextEdit;&lt;br /&gt;
     NSMainNibFile = TextEdit.gorm;&lt;br /&gt;
     NSPrincipalClass = NSApplication;&lt;br /&gt;
     NSRole = Application;&lt;br /&gt;
     NSTypes = (&lt;br /&gt;
         {&lt;br /&gt;
                 NSDocumentClass = &amp;quot;TextDocument&amp;quot;;&lt;br /&gt;
                 NSName = &amp;quot;GSTextDocumentType&amp;quot;;&lt;br /&gt;
                 NSHumanReadableName = &amp;quot;Text Document&amp;quot;;&lt;br /&gt;
                 NSUnixExtensions = ( &amp;quot;txt&amp;quot;, &amp;quot;&amp;quot; );&lt;br /&gt;
                 NSDOSExtensions = ( &amp;quot;txt&amp;quot; );&lt;br /&gt;
                 NSRole = Editor;&lt;br /&gt;
         }&lt;br /&gt;
     );&lt;br /&gt;
 }&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Creating_document_based_applications&amp;diff=816</id>
		<title>Creating document based applications</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Creating_document_based_applications&amp;diff=816"/>
		<updated>2005-07-06T06:05:04Z</updated>

		<summary type="html">&lt;p&gt;Quineska: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Note: this is a work in progress. Please bear with me as I add further information. &lt;br /&gt;
--[[User:Quineska|ChrisArmstrong]] 08:33, 5 Jul 2005 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
OpenStep can provide your application a document-based model. It helps to simplify the process of creating such applications. GNUstep is compatible with this paridgm as well; this document aims to provide an overview of what is required in the creation and design of such an application.&lt;br /&gt;
&lt;br /&gt;
It is assumed you are familiar with GNUstep, and have some understanding as how to create Gorm's nib files, as well as some understanding of how they work.&lt;br /&gt;
&lt;br /&gt;
Importantly, such applications have certain components that are required, and should be considered as part of their design. At a programmatic level, classes that will be used as part of the AppKit are:&lt;br /&gt;
&lt;br /&gt;
==== NSDocument ====&lt;br /&gt;
&lt;br /&gt;
This class is central to the OpenStep document based model. Such an application declares a new instance of a subclass of NSDocument for each “document” that is opened. It will be necessary to subclass NSDocument to implement this.&lt;br /&gt;
&lt;br /&gt;
Each instance of your NSDocument subclass may have one or more windows associated with it. These are used as an interface for loading and saving a representation of your document type. Each window will have an “NSWindowController” instance associated with it, where NSDocument maintains a list of these.&lt;br /&gt;
&lt;br /&gt;
==== NSDocumentController ====&lt;br /&gt;
&lt;br /&gt;
This class acts a controller. It maintains a list of documents (instances of your NSDocument subclass) and is responsible for loading and instantiating new documents. It is usually not necessary to implement a subclass of this, but often it may be useful to implement special functionality (especially related to open documents as a whole).&lt;br /&gt;
&lt;br /&gt;
==== NSWindowController ====&lt;br /&gt;
&lt;br /&gt;
As mentioned above, NSWindowController instances are individually associated with one NSWindow instance, in such a way that a document maintains a list of window controllers that are reponsible for rendering the views associated with a document.&lt;br /&gt;
&lt;br /&gt;
You will most likely not have to subclass NSWindowController. Instead, you associate a nib file (the Gorm output) with the subclass of NSDocument, and NSDocumentController will load this nib file for each document that is created or loaded.&lt;br /&gt;
&lt;br /&gt;
For example, a text based application that is used for the editing of plain text files, may subclass NSDocument with a TextDocument class. Each instance of this class would have an NSWindowController instance associated with it, which in turn manages a window instance that is instantiated from a nib file. The NSDocumentController instance, as managed and instatiated by GNUstep, would be responsible for loading and saving documents in your application. It even prompts the user to save their documents when they try to quit the application.&lt;br /&gt;
&lt;br /&gt;
== Components ==&lt;br /&gt;
&lt;br /&gt;
In building your application you will need to create a number of components. From scratch, the following should be a rough guide to getting it working.&lt;br /&gt;
&lt;br /&gt;
=== The Makefile ===&lt;br /&gt;
&lt;br /&gt;
For this type of application, no special makefile is needed: it just has to be a normal application. Project Builder should be able to spit out the required makefile and Gorm files that are needed for a generic application. Otherwise use the following as a template:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''GNUmakefile'''&lt;br /&gt;
&lt;br /&gt;
 include $(GNUSTEP_MAKEFILES)/common.make&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 APP_NAME = DocumentApp&amp;lt;br&amp;gt;&lt;br /&gt;
 DocumentApp_OBJC_FILES =&amp;lt;br&amp;gt;&lt;br /&gt;
  MyDocument.m &amp;lt;br&amp;gt;&lt;br /&gt;
  main.m&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 DocumentApp_RESOURCES = \ &amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/Info-gnustep.plist \&amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/DocumentApp.gorm \&amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/MyDocument.gorm&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 -include GNUmakefile.preamble&amp;lt;br&amp;gt;&lt;br /&gt;
 include $(GNUSTEP_MAKEFILES)/application.make&amp;lt;br&amp;gt;&lt;br /&gt;
 -include GNUmakefile.postamble&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For more information as to customising this file, as well as setting up compiler options for third party libraries and includes, see the GNUstep makefile manual.&lt;br /&gt;
&lt;br /&gt;
=== The application dictionary - Info-gnustep.plist ===&lt;br /&gt;
&lt;br /&gt;
For those that have edited this file in their project before, it is a dictionary with various values entered. For our purposes, we need an array within the main dictionary, called &amp;quot;NSTypes&amp;quot;. This is a array of unnamed dictionaries, with one dictionary for each type. &lt;br /&gt;
&lt;br /&gt;
An entire example of this file, for a &amp;quot;theoretical&amp;quot; TextEdit application (please note that such an application does exist as an example application, but I have constructed a much simpler version, used only for plain text files).&lt;br /&gt;
&lt;br /&gt;
'''Info-gnustep.plist'''&lt;br /&gt;
 {&lt;br /&gt;
     ApplicationDescription = &amp;quot;A simple text editor for GNUstep.&amp;quot;;&lt;br /&gt;
     ApplicationName = TextEdit;&lt;br /&gt;
     ApplicationRelease = 0.10;&lt;br /&gt;
     Authors = ( &amp;quot;Christopher Armstrong &amp;lt;quineska@gamebox.net&amp;quot; );&lt;br /&gt;
     Copyright = &amp;quot;Copyright (C) 2005 Christopher Armstrong&amp;quot;;&lt;br /&gt;
     CopyrightDescription = &amp;quot;Released under GPL.&amp;quot;;&lt;br /&gt;
     FullVersionID = 0.10;&lt;br /&gt;
     NSExecutable = TextEdit;&lt;br /&gt;
     NSMainNibFile = TextEdit.gorm;&lt;br /&gt;
     NSPrincipalClass = NSApplication;&lt;br /&gt;
     NSRole = Application;&lt;br /&gt;
     NSTypes = (&lt;br /&gt;
         {&lt;br /&gt;
                 NSDocumentClass = &amp;quot;TextDocument&amp;quot;;&lt;br /&gt;
                 NSName = &amp;quot;GSTextDocumentType&amp;quot;;&lt;br /&gt;
                 NSHumanReadableName = &amp;quot;Text Document&amp;quot;;&lt;br /&gt;
                 NSUnixExtensions = ( &amp;quot;txt&amp;quot;, &amp;quot;&amp;quot; );&lt;br /&gt;
                 NSDOSExtensions = ( &amp;quot;txt&amp;quot; );&lt;br /&gt;
                 NSRole = Editor;&lt;br /&gt;
         }&lt;br /&gt;
     );&lt;br /&gt;
 }&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Talk:Developer_Guides&amp;diff=2029</id>
		<title>Talk:Developer Guides</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Talk:Developer_Guides&amp;diff=2029"/>
		<updated>2005-07-06T05:53:21Z</updated>

		<summary type="html">&lt;p&gt;Quineska: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Thanks for helping me put this into some context. I'm sorta new to wiki's. --[[User:Quineska|ChrisArmstrong]] 07:53, 6 Jul 2005 (CEST)&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Creating_document_based_applications&amp;diff=815</id>
		<title>Creating document based applications</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Creating_document_based_applications&amp;diff=815"/>
		<updated>2005-07-05T06:42:28Z</updated>

		<summary type="html">&lt;p&gt;Quineska: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Note: this is a work in progress. Please bear with me as I add further information. &lt;br /&gt;
--[[User:Quineska|ChrisArmstrong]] 08:33, 5 Jul 2005 (CEST)&lt;br /&gt;
&lt;br /&gt;
Introduction&lt;br /&gt;
&lt;br /&gt;
OpenStep can provide your application a document-based model. It helps to simplify the process of creating such applications. GNUstep is compatible with this paridgm as well; this document aims to provide an overview of what is required in the creation and design of such an application.&lt;br /&gt;
&lt;br /&gt;
It is assumed you are familiar with GNUstep, and have some understanding as how to create Gorm's nib files, as well as some understanding of how they work.&lt;br /&gt;
&lt;br /&gt;
Importantly, such applications have certain components that are required, and should be considered as part of their design. At a programmatic level, classes that will be used as part of the AppKit are:&lt;br /&gt;
&lt;br /&gt;
NSDocument&lt;br /&gt;
&lt;br /&gt;
This class is central to the OpenStep document based model. Such an application declares a new instance of a subclass of NSDocument for each “document” that is opened. It will be necessary to subclass NSDocument to implement this.&lt;br /&gt;
&lt;br /&gt;
Each instance of your NSDocument subclass may have one or more windows associated with it. These are used as an interface for loading and saving a representation of your document type. Each window will have an “NSWindowController” instance associated with it, where NSDocument maintains a list of these.&lt;br /&gt;
&lt;br /&gt;
NSDocumentController&lt;br /&gt;
&lt;br /&gt;
This class acts a controller. It maintains a list of documents (instances of your NSDocument subclass) and is responsible for loading and instantiating new documents. It is usually not necessary to implement a subclass of this, but often it may be useful to implement special functionality (especially related to open documents as a whole).&lt;br /&gt;
&lt;br /&gt;
NSWindowController&lt;br /&gt;
&lt;br /&gt;
As mentioned above, NSWindowController instances are individually associated with one NSWindow instance, in such a way that a document maintains a list of window controllers that are reponsible for rendering the views associated with a document.&lt;br /&gt;
&lt;br /&gt;
You will most likely not have to subclass NSWindowController. Instead, you associate a nib file (the Gorm output) with the subclass of NSDocument, and NSDocumentController will load this nib file for each document that is created or loaded.&lt;br /&gt;
&lt;br /&gt;
For example, a text based application that is used for the editing of plain text files, may subclass NSDocument with a TextDocument class. Each instance of this class would have an NSWindowController instance associated with it, which in turn manages a window instance that is instantiated from a nib file. The NSDocumentController instance, as managed and instatiated by GNUstep, would be responsible for loading and saving documents in your application. It even prompts the user to save their documents when they try to quit the application.&lt;br /&gt;
&lt;br /&gt;
Components&lt;br /&gt;
&lt;br /&gt;
In building your application you will need to create a number of components. From scratch, the following should be a rough guide to getting it working.&lt;br /&gt;
The Makefile&lt;br /&gt;
&lt;br /&gt;
For this type of application, no special makefile is needed: it just has to be a normal application. Project Builder should be able to spit out the required makefile and Gorm files that are needed for a generic application. Otherwise use the following as a template:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 GNUmakefile:&lt;br /&gt;
&lt;br /&gt;
 include $(GNUSTEP_MAKEFILES)/common.make&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 APP_NAME = DocumentApp&amp;lt;br&amp;gt;&lt;br /&gt;
 DocumentApp_OBJC_FILES =&amp;lt;br&amp;gt;&lt;br /&gt;
  MyDocument.m &amp;lt;br&amp;gt;&lt;br /&gt;
  main.m&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 DocumentApp_RESOURCES = \ &amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/Info-gnustep.plist \&amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/DocumentApp.gorm \&amp;lt;br&amp;gt;&lt;br /&gt;
  Resources/MyDocument.gorm&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 -include GNUmakefile.preamble&amp;lt;br&amp;gt;&lt;br /&gt;
 include $(GNUSTEP_MAKEFILES)/application.make&amp;lt;br&amp;gt;&lt;br /&gt;
 -include GNUmakefile.postamble&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For more information as to customising this file, as well as setting up compiler options for third party libraries and includes, see the GNUstep makefile manual.&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.gnustep.org/index.php?title=Creating_document_based_applications&amp;diff=811</id>
		<title>Creating document based applications</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.gnustep.org/index.php?title=Creating_document_based_applications&amp;diff=811"/>
		<updated>2005-07-05T06:34:33Z</updated>

		<summary type="html">&lt;p&gt;Quineska: Fixed formating of example GNUmakefile&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Note: this is a work in progress. Please bear with me as I add further information. &lt;br /&gt;
--[[User:Quineska|ChrisArmstrong]] 08:33, 5 Jul 2005 (CEST)&lt;br /&gt;
&lt;br /&gt;
Introduction&lt;br /&gt;
&lt;br /&gt;
OpenStep can provide your application a document-based model. It helps to simplify the process of creating such applications. GNUstep is compatible with this paridgm as well; this document aims to provide an overview of what is required in the creation and design of such an application.&lt;br /&gt;
&lt;br /&gt;
It is assumed you are familiar with GNUstep, and have some understanding as how to create Gorm's nib files, as well as some understanding of how they work.&lt;br /&gt;
&lt;br /&gt;
Importantly, such applications have certain components that are required, and should be considered as part of their design. At a programmatic level, classes that will be used as part of the AppKit are:&lt;br /&gt;
&lt;br /&gt;
NSDocument&lt;br /&gt;
&lt;br /&gt;
This class is central to the OpenStep document based model. Such an application declares a new instance of a subclass of NSDocument for each “document” that is opened. It will be necessary to subclass NSDocument to implement this.&lt;br /&gt;
&lt;br /&gt;
Each instance of your NSDocument subclass may have one or more windows associated with it. These are used as an interface for loading and saving a representation of your document type. Each window will have an “NSWindowController” instance associated with it, where NSDocument maintains a list of these.&lt;br /&gt;
&lt;br /&gt;
NSDocumentController&lt;br /&gt;
&lt;br /&gt;
This class acts a controller. It maintains a list of documents (instances of your NSDocument subclass) and is responsible for loading and instantiating new documents. It is usually not necessary to implement a subclass of this, but often it may be useful to implement special functionality (especially related to open documents as a whole).&lt;br /&gt;
&lt;br /&gt;
NSWindowController&lt;br /&gt;
&lt;br /&gt;
As mentioned above, NSWindowController instances are individually associated with one NSWindow instance, in such a way that a document maintains a list of window controllers that are reponsible for rendering the views associated with a document.&lt;br /&gt;
&lt;br /&gt;
You will most likely not have to subclass NSWindowController. Instead, you associate a nib file (the Gorm output) with the subclass of NSDocument, and NSDocumentController will load this nib file for each document that is created or loaded.&lt;br /&gt;
&lt;br /&gt;
For example, a text based application that is used for the editing of plain text files, may subclass NSDocument with a TextDocument class. Each instance of this class would have an NSWindowController instance associated with it, which in turn manages a window instance that is instantiated from a nib file. The NSDocumentController instance, as managed and instatiated by GNUstep, would be responsible for loading and saving documents in your application. It even prompts the user to save their documents when they try to quit the application.&lt;br /&gt;
&lt;br /&gt;
Components&lt;br /&gt;
&lt;br /&gt;
In building your application you will need to create a number of components. From scratch, the following should be a rough guide to getting it working.&lt;br /&gt;
The Makefile&lt;br /&gt;
&lt;br /&gt;
For this type of application, no special makefile is needed: it just has to be a normal application. Project Builder should be able to spit out the required makefile and Gorm files that are needed for a generic application. Otherwise use the following as a template:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
GNUmakefile:&lt;br /&gt;
&lt;br /&gt;
include $(GNUSTEP_MAKEFILES)/common.make&lt;br /&gt;
&lt;br /&gt;
APP_NAME = DocumentApp&lt;br /&gt;
&lt;br /&gt;
DocumentApp_OBJC_FILES = \&lt;br /&gt;
  MyDocument.m \&lt;br /&gt;
  main.m&lt;br /&gt;
&lt;br /&gt;
DocumentApp_RESOURCES = \&lt;br /&gt;
  Resources/Info-gnustep.plist \&lt;br /&gt;
  Resources/DocumentApp.gorm \&lt;br /&gt;
  Resources/MyDocument.gorm&lt;br /&gt;
&lt;br /&gt;
-include GNUmakefile.preamble&lt;br /&gt;
include $(GNUSTEP_MAKEFILES)/application.make&lt;br /&gt;
-include GNUmakefile.postamble&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
For more information as to customising this file, as well as setting up compiler options for third party libraries and includes, see the GNUstep makefile manual.&lt;/div&gt;</summary>
		<author><name>Quineska</name></author>
	</entry>
</feed>