<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.inkscape.org/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Inkblotter</id>
	<title>Inkscape Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.inkscape.org/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Inkblotter"/>
	<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/Special:Contributions/Inkblotter"/>
	<updated>2026-04-25T14:00:51Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.36.1</generator>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=Working_with_SVN&amp;diff=5895</id>
		<title>Working with SVN</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=Working_with_SVN&amp;diff=5895"/>
		<updated>2006-02-06T03:48:41Z</updated>

		<summary type="html">&lt;p&gt;Inkblotter: /* How Do I Check Out a Working Copy? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;(This began a copy of [[WorkingWithCVS]]; bear with us as it is updated for SVN)&lt;br /&gt;
&lt;br /&gt;
== Subversion (SVN) Basics ==&lt;br /&gt;
&lt;br /&gt;
This node discusses the basics of using SVN.&lt;br /&gt;
&lt;br /&gt;
For information on more advanced usage, see:&lt;br /&gt;
&lt;br /&gt;
* [[WorkingWithSVNBranches]] - making branches and merging between them&lt;br /&gt;
&lt;br /&gt;
=== Concepts ===&lt;br /&gt;
&lt;br /&gt;
==== The Repository ====&lt;br /&gt;
&lt;br /&gt;
SVN stores source code in a shared '''repository''' (in our case on Sourceforge's server).  The repository contains all past and present versions of the code, and is shared by everyone.&lt;br /&gt;
&lt;br /&gt;
==== Your Working Copy ====&lt;br /&gt;
&lt;br /&gt;
To work with the source code, SVN requires you to '''check out''' a ''working copy''.  This copy is private, so you can make and test any changes you like without disturbing anyone else.&lt;br /&gt;
&lt;br /&gt;
If you have '''write access''' to the repository, when you are finished making your changes, you may '''commit''' your changes to the shared repository, making them available to everyone.&lt;br /&gt;
&lt;br /&gt;
Alternately, you may generate a file containing the changes you made (a ''diff''), and send it to a developer with write access to be incorporated.&lt;br /&gt;
&lt;br /&gt;
You can check out as many working copies as you want; they take up only your own disk space, and they are completely independent of each other.&lt;br /&gt;
&lt;br /&gt;
If you no longer need a working copy, you may simply delete it.&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
&lt;br /&gt;
==== Setting Up ====&lt;br /&gt;
&lt;br /&gt;
==== How Do I Check Out a Working Copy? ====&lt;br /&gt;
&lt;br /&gt;
To check out a copy of Inkscape from the SVN repository, you may use the following command:&lt;br /&gt;
&lt;br /&gt;
 svn checkout https://svn.sourceforge.net/svnroot/inkscape/inkscape/trunk inkscape&lt;br /&gt;
&lt;br /&gt;
Here are what the options mean:&lt;br /&gt;
&lt;br /&gt;
&amp;quot;checkout&amp;quot; (&amp;quot;co&amp;quot; means the same thing) specifies the action to take (check out a working copy).&lt;br /&gt;
&lt;br /&gt;
&amp;quot;https://svn.sourceforge.net/svnroot/inkscape/inkscape/trunk&amp;quot; is a repository URL; in this case, it refers to the &amp;quot;main&amp;quot; development branch for Inkscape.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;inkscape&amp;quot; is the name of the directory to check out into&lt;br /&gt;
&lt;br /&gt;
==== Now What? ====&lt;br /&gt;
&lt;br /&gt;
You should have a complete working copy in the '''inkscape''' directory.  You can cd to it and try compiling.&lt;br /&gt;
&lt;br /&gt;
:Note: If it is a fresh checkout, you will need to run the ./autogen.sh shell script at the top level to create files needed to compile&lt;br /&gt;
&lt;br /&gt;
When you're inside the working copy, you won't normally need to specify the repository URL, because SVN remembers where the working copy came from.&lt;br /&gt;
&lt;br /&gt;
Note that a Subversion command only applies to the current directory and (possibly) any subdirectories.  Normally (particularly for updates, diffs, and checkins), you will want to run the command from the top level of the project.&lt;br /&gt;
&lt;br /&gt;
=== Bringing Your Working Copy Up-To-Date ===&lt;br /&gt;
&lt;br /&gt;
Your working copy will not automatically include changes others have made to the repository since you checked it out.&lt;br /&gt;
&lt;br /&gt;
To ''update'' your working copy, use this command:&lt;br /&gt;
&lt;br /&gt;
 svn update&lt;br /&gt;
&lt;br /&gt;
=== Dealing with Conflicts ===&lt;br /&gt;
&lt;br /&gt;
If you've made changes to your working copy, what happens if you update after someone has commited changes to the same files?&lt;br /&gt;
&lt;br /&gt;
Normally, SVN can work this out on its own.  Sometimes you have to help it along, though.  If SVN says there were conflicts, look for which files have a ''C'' next to them in its progress output.  Some of those may have unresolved conflicts. You can also search for '=======' in the files themselves to find any unresolved conflicts.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; ''filename''&lt;br /&gt;
 The changes in your version will be here&lt;br /&gt;
 =======&lt;br /&gt;
 The changes the other person will be here&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt; ''some version here''&lt;br /&gt;
&lt;br /&gt;
Sometimes you will keep one set of changes and discard the other, and sometimes you will combine the two.  It will require a judgement call on your part either way.  Talk to the person who made the other set of changes or ask on the mailing list if it's unclear what's going on.  Remember that SVN is no substitute for communication.&lt;br /&gt;
&lt;br /&gt;
Also, always make sure to build and test after an update to make sure that the combined changes work as intended!&lt;br /&gt;
&lt;br /&gt;
=== Generating a Diff ===&lt;br /&gt;
&lt;br /&gt;
('''Always''' update before generating a diff!)&lt;br /&gt;
&lt;br /&gt;
From the top-level directory, run the command:&lt;br /&gt;
&lt;br /&gt;
 svn diff -x -u3 &amp;gt; filename&lt;br /&gt;
&lt;br /&gt;
-x -u3 specifies which format to use (a unified diff with three lines of context).  This is the recommended diff format.&lt;br /&gt;
&lt;br /&gt;
This will create a file describing the changes you have made, though if you have created new files as part of your changes, you will need to include those separately too when emailing them to the list or another developer for inclusion.&lt;br /&gt;
&lt;br /&gt;
=== Automatic Commit Diff ===&lt;br /&gt;
&lt;br /&gt;
[ fixme: how to do this in SVN? ]&lt;br /&gt;
&lt;br /&gt;
To always generate a diff when you commit to CVS, set the environment variable &amp;quot;CVSEDITOR&amp;quot; to the following script:&lt;br /&gt;
&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 # get rid of redhat 9 locale ugliness&lt;br /&gt;
 unset [[LC_CTYPE]]&lt;br /&gt;
 # Turn on ro access (to stop multiple locks) for local roots&lt;br /&gt;
 grep @ CVS[[/Root]] &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || export CVSREADONLYFS=1&lt;br /&gt;
 # Tell the user what's going on&lt;br /&gt;
 echo Building diff...&lt;br /&gt;
 cvs diff -up 2&amp;gt;/dev/null | perl -ne 'print &amp;quot;CVS: $_&amp;quot; unless /^\?/' &amp;gt;&amp;gt; &amp;quot;$1&amp;quot;&lt;br /&gt;
 exec ${EDITOR:-vi} &amp;quot;$1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If the above script is named &amp;quot;~/bin/cvsdiffvi&amp;quot;, then assuming you run the bash shell, you can add the following your .bashrc file:&lt;br /&gt;
&lt;br /&gt;
 export CVSEDITOR=~/bin/cvsdiffvi&lt;br /&gt;
&lt;br /&gt;
Now, every time you commit, the entire diff will be visible to you as you write your commit comments.&lt;br /&gt;
&lt;br /&gt;
=== Applying a Diff ===&lt;br /&gt;
&lt;br /&gt;
A diff file can be applied to the codebase using the 'patch' command.&lt;br /&gt;
&lt;br /&gt;
If the diff was made as  &amp;lt;code&amp;gt;inkscape/src/thingy.cpp&amp;lt;/code&amp;gt;  and you're in the &amp;quot;inkscape&amp;quot; directory, you'll want to use the command:&lt;br /&gt;
&lt;br /&gt;
 patch -p1 &amp;lt; thingy.diff&lt;br /&gt;
&lt;br /&gt;
Depending on how many path elements are part of the diff, you'll need to strip them with -p1, -p2, etc.&lt;br /&gt;
&lt;br /&gt;
=== Committing your Changes ===&lt;br /&gt;
&lt;br /&gt;
('''Always''' update before committing!)&lt;br /&gt;
&lt;br /&gt;
If you have write access to the repository, you can commit your changes like this:&lt;br /&gt;
&lt;br /&gt;
Before you commit, please make sure that you describe the changes you have made in the [[ChangeLog]] file at the top-level directory.&lt;br /&gt;
&lt;br /&gt;
 svn commit -m &amp;quot;Your description of your changes goes here&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Tip: even if you are committing directly, you still might want to generate a diff.  It's a good reference to look at when you're filling out the [[ChangeLog]], since it will remind you of all the changes you've made.&lt;br /&gt;
&lt;br /&gt;
=== Adding Files to the Repository ===&lt;br /&gt;
&lt;br /&gt;
To add new files as part of your commit, you will need to run:&lt;br /&gt;
&lt;br /&gt;
 svn add ''files and directories to add go here''&lt;br /&gt;
&lt;br /&gt;
Before you commit.  This also goes for new directories.&lt;br /&gt;
&lt;br /&gt;
The actual addition or removal will not take effect until you commit.&lt;br /&gt;
&lt;br /&gt;
=== Removing Files from the Repository ===&lt;br /&gt;
&lt;br /&gt;
 svn remove ''files to remove go here''&lt;/div&gt;</summary>
		<author><name>Inkblotter</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=Inkscape_glossary&amp;diff=5821</id>
		<title>Inkscape glossary</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=Inkscape_glossary&amp;diff=5821"/>
		<updated>2006-01-24T15:14:08Z</updated>

		<summary type="html">&lt;p&gt;Inkblotter: despam&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Inkblotter</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=WorkingWithSVNBranches&amp;diff=5806</id>
		<title>WorkingWithSVNBranches</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=WorkingWithSVNBranches&amp;diff=5806"/>
		<updated>2006-01-23T04:19:25Z</updated>

		<summary type="html">&lt;p&gt;Inkblotter: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;(This began as a copy of [[WorkingWithCVSBranches]]; bear with us as we update it to reflect SVN)&lt;br /&gt;
&lt;br /&gt;
===== Starting Work on an Existing Branch =====&lt;br /&gt;
&lt;br /&gt;
* checking out a specific branch of MODULE into DIR&lt;br /&gt;
&lt;br /&gt;
     svn checkout https://svn.sourceforge.net/svnroot/inkscape/MODULE/branches/BRANCH DIR&lt;br /&gt;
&lt;br /&gt;
===== Making Your Own Branch =====&lt;br /&gt;
&lt;br /&gt;
:1. Make a branch based on the revisions in your working copy (commit before you do this!)&lt;br /&gt;
&lt;br /&gt;
     cvs -z3 tag -b BRANCH&lt;br /&gt;
&lt;br /&gt;
:2. Switch your working copy to that BRANCH (as shown earlier)&lt;br /&gt;
&lt;br /&gt;
     cvs -z3 update -PAd -r BRANCH&lt;br /&gt;
&lt;br /&gt;
:3. Tag the initial revisions in your branch (you'll need this for merging easily)&lt;br /&gt;
&lt;br /&gt;
     cvs -z3 tag [[BRANCH_START]]&lt;br /&gt;
&lt;br /&gt;
===== Merging Your Changes =====&lt;br /&gt;
&lt;br /&gt;
:1. Commit your work and resolve any conflicts&lt;br /&gt;
&lt;br /&gt;
:2. Tag the revisions for this merge&lt;br /&gt;
&lt;br /&gt;
     cvs -z3 tag [[BRANCH_MERGE]]&lt;br /&gt;
&lt;br /&gt;
:3. Switch your working copy back to the branch you want to merge to (HEAD is the default if you don't specify a branch with -j)&lt;br /&gt;
&lt;br /&gt;
     cvs -z3 update -PAd -r [[OTHER_BRANCH]]&lt;br /&gt;
&lt;br /&gt;
:4. Merge the changes between [[BRANCH_START]] and [[BRANCH_MERGE]] into your working copy&lt;br /&gt;
&lt;br /&gt;
     cvs -z3 update -Pd -j [[BRANCH_START]] -j [[BRANCH_MERGE]]&lt;br /&gt;
&lt;br /&gt;
:5. Check for any conflicts and commit the changes&lt;br /&gt;
&lt;br /&gt;
If you want to work on BRANCH some more, you'll need to switch your working copy back to BRANCH again.&lt;br /&gt;
&lt;br /&gt;
For future merges, you'll need to tag the revisions for those merges with unique tags (e.g. [[BRANCH_MERGE_2]], [[BRANCH_MERGE_3]], etc...), and only merge the changes between the previous merge and the new one.&lt;br /&gt;
&lt;br /&gt;
This is so you don't end up merging the same set of changes twice.&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
  First merge: -j [[BRANCH_START]]   -j [[BRANCH_MERGE]]&lt;br /&gt;
 Second merge: -j [[BRANCH_MERGE]]   -j [[BRANCH_MERGE_2]]&lt;br /&gt;
  Third merge: -j [[BRANCH_MERGE_2]] -j [[BRANCH_MERGE_3]]&lt;br /&gt;
&lt;br /&gt;
If you merge to another branch that you've never merged to before, you'll need to merge from [[BRANCH_START]] up through [[BRANCH_MERGE_3]] to catch up.&lt;/div&gt;</summary>
		<author><name>Inkblotter</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=Working_with_SVN&amp;diff=5805</id>
		<title>Working with SVN</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=Working_with_SVN&amp;diff=5805"/>
		<updated>2006-01-23T04:18:33Z</updated>

		<summary type="html">&lt;p&gt;Inkblotter: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;(This began a copy of [[WorkingWithCVS]]; bear with us as it is updated for SVN)&lt;br /&gt;
&lt;br /&gt;
== Subversion (SVN) Basics ==&lt;br /&gt;
&lt;br /&gt;
This node discusses the basics of using SVN.&lt;br /&gt;
&lt;br /&gt;
For information on more advanced usage, see:&lt;br /&gt;
&lt;br /&gt;
* [[WorkingWithSVNBranches]] - making branches and merging between them&lt;br /&gt;
&lt;br /&gt;
=== Concepts ===&lt;br /&gt;
&lt;br /&gt;
==== The Repository ====&lt;br /&gt;
&lt;br /&gt;
SVN stores source code in a shared '''repository''' (in our case on Sourceforge's server).  The repository contains all past and present versions of the code, and is shared by everyone.&lt;br /&gt;
&lt;br /&gt;
==== Your Working Copy ====&lt;br /&gt;
&lt;br /&gt;
To work with the source code, SVN requires you to '''check out''' a ''working copy''.  This copy is private, so you can make and test any changes you like without disturbing anyone else.&lt;br /&gt;
&lt;br /&gt;
If you have '''write access''' to the repository, when you are finished making your changes, you may '''commit''' your changes to the shared repository, making them available to everyone.&lt;br /&gt;
&lt;br /&gt;
Alternately, you may generate a file containing the changes you made (a ''diff''), and send it to a developer with write access to be incorporated.&lt;br /&gt;
&lt;br /&gt;
You can check out as many working copies as you want; they take up only your own disk space, and they are completely independent of each other.&lt;br /&gt;
&lt;br /&gt;
If you no longer need a working copy, you may simply delete it.&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
&lt;br /&gt;
==== Setting Up ====&lt;br /&gt;
&lt;br /&gt;
==== How Do I Check Out a Working Copy? ====&lt;br /&gt;
&lt;br /&gt;
To check out a copy of Inkscape from the developer CVS, you may use the following command:&lt;br /&gt;
&lt;br /&gt;
 svn checkout https://svn.sourceforge.net/svnroot/inkscape/inkscape/trunk inkscape&lt;br /&gt;
&lt;br /&gt;
Here are what the options mean:&lt;br /&gt;
&lt;br /&gt;
&amp;quot;checkout&amp;quot; (&amp;quot;co&amp;quot; means the same thing) specifies the action to take (check out a working copy).&lt;br /&gt;
&lt;br /&gt;
&amp;quot;https://svn.sourceforge.net/svnroot/inkscape/inkscape/trunk&amp;quot; is a repository URL; in this case, it refers to the &amp;quot;main&amp;quot; development branch for Inkscape.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;inkscape&amp;quot; is the name of the directory to check out into&lt;br /&gt;
&lt;br /&gt;
==== Now What? ====&lt;br /&gt;
&lt;br /&gt;
You should have a complete working copy in the '''inkscape''' directory.  You can cd to it and try compiling.&lt;br /&gt;
&lt;br /&gt;
:Note: If it is a fresh checkout, you will need to run the ./autogen.sh shell script at the top level to create files needed to compile&lt;br /&gt;
&lt;br /&gt;
When you're inside the working copy, you won't normally need to specify the repository URL, because SVN remembers where the working copy came from.&lt;br /&gt;
&lt;br /&gt;
Note that a Subversion command only applies to the current directory and (possibly) any subdirectories.  Normally (particularly for updates, diffs, and checkins), you will want to run the command from the top level of the project.&lt;br /&gt;
&lt;br /&gt;
=== Bringing Your Working Copy Up-To-Date ===&lt;br /&gt;
&lt;br /&gt;
Your working copy will not automatically include changes others have made to the repository since you checked it out.&lt;br /&gt;
&lt;br /&gt;
To ''update'' your working copy, use this command:&lt;br /&gt;
&lt;br /&gt;
 svn update&lt;br /&gt;
&lt;br /&gt;
=== Dealing with Conflicts ===&lt;br /&gt;
&lt;br /&gt;
If you've made changes to your working copy, what happens if you update after someone has commited changes to the same files?&lt;br /&gt;
&lt;br /&gt;
Normally, SVN can work this out on its own.  Sometimes you have to help it along, though.  If SVN says there were conflicts, look for which files have a ''C'' next to them in its progress output.  Some of those may have unresolved conflicts. You can also search for '=======' in the files themselves to find any unresolved conflicts.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; ''filename''&lt;br /&gt;
 The changes in your version will be here&lt;br /&gt;
 =======&lt;br /&gt;
 The changes the other person will be here&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt; ''some version here''&lt;br /&gt;
&lt;br /&gt;
Sometimes you will keep one set of changes and discard the other, and sometimes you will combine the two.  It will require a judgement call on your part either way.  Talk to the person who made the other set of changes or ask on the mailing list if it's unclear what's going on.  Remember that SVN is no substitute for communication.&lt;br /&gt;
&lt;br /&gt;
Also, always make sure to build and test after an update to make sure that the combined changes work as intended!&lt;br /&gt;
&lt;br /&gt;
=== Generating a Diff ===&lt;br /&gt;
&lt;br /&gt;
('''Always''' update before generating a diff!)&lt;br /&gt;
&lt;br /&gt;
From the top-level directory, run the command:&lt;br /&gt;
&lt;br /&gt;
 svn diff -x -u3 &amp;gt; filename&lt;br /&gt;
&lt;br /&gt;
-x -u3 specifies which format to use (a unified diff with three lines of context).  This is the recommended diff format.&lt;br /&gt;
&lt;br /&gt;
This will create a file describing the changes you have made, though if you have created new files as part of your changes, you will need to include those separately too when emailing them to the list or another developer for inclusion.&lt;br /&gt;
&lt;br /&gt;
=== Automatic Commit Diff ===&lt;br /&gt;
&lt;br /&gt;
[ fixme: how to do this in SVN? ]&lt;br /&gt;
&lt;br /&gt;
To always generate a diff when you commit to CVS, set the environment variable &amp;quot;CVSEDITOR&amp;quot; to the following script:&lt;br /&gt;
&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 # get rid of redhat 9 locale ugliness&lt;br /&gt;
 unset [[LC_CTYPE]]&lt;br /&gt;
 # Turn on ro access (to stop multiple locks) for local roots&lt;br /&gt;
 grep @ CVS[[/Root]] &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || export CVSREADONLYFS=1&lt;br /&gt;
 # Tell the user what's going on&lt;br /&gt;
 echo Building diff...&lt;br /&gt;
 cvs diff -up 2&amp;gt;/dev/null | perl -ne 'print &amp;quot;CVS: $_&amp;quot; unless /^\?/' &amp;gt;&amp;gt; &amp;quot;$1&amp;quot;&lt;br /&gt;
 exec ${EDITOR:-vi} &amp;quot;$1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If the above script is named &amp;quot;~/bin/cvsdiffvi&amp;quot;, then assuming you run the bash shell, you can add the following your .bashrc file:&lt;br /&gt;
&lt;br /&gt;
 export CVSEDITOR=~/bin/cvsdiffvi&lt;br /&gt;
&lt;br /&gt;
Now, every time you commit, the entire diff will be visible to you as you write your commit comments.&lt;br /&gt;
&lt;br /&gt;
=== Applying a Diff ===&lt;br /&gt;
&lt;br /&gt;
A diff file can be applied to the codebase using the 'patch' command.&lt;br /&gt;
&lt;br /&gt;
If the diff was made as  &amp;lt;code&amp;gt;inkscape/src/thingy.cpp&amp;lt;/code&amp;gt;  and you're in the &amp;quot;inkscape&amp;quot; directory, you'll want to use the command:&lt;br /&gt;
&lt;br /&gt;
 patch -p1 &amp;lt; thingy.diff&lt;br /&gt;
&lt;br /&gt;
Depending on how many path elements are part of the diff, you'll need to strip them with -p1, -p2, etc.&lt;br /&gt;
&lt;br /&gt;
=== Committing your Changes ===&lt;br /&gt;
&lt;br /&gt;
('''Always''' update before committing!)&lt;br /&gt;
&lt;br /&gt;
If you have write access to the repository, you can commit your changes like this:&lt;br /&gt;
&lt;br /&gt;
Before you commit, please make sure that you describe the changes you have made in the [[ChangeLog]] file at the top-level directory.&lt;br /&gt;
&lt;br /&gt;
 svn commit -m &amp;quot;Your description of your changes goes here&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Tip: even if you are committing directly, you still might want to generate a diff.  It's a good reference to look at when you're filling out the [[ChangeLog]], since it will remind you of all the changes you've made.&lt;br /&gt;
&lt;br /&gt;
=== Adding Files to the Repository ===&lt;br /&gt;
&lt;br /&gt;
To add new files as part of your commit, you will need to run:&lt;br /&gt;
&lt;br /&gt;
 svn add ''files and directories to add go here''&lt;br /&gt;
&lt;br /&gt;
Before you commit.  This also goes for new directories.&lt;br /&gt;
&lt;br /&gt;
The actual addition or removal will not take effect until you commit.&lt;br /&gt;
&lt;br /&gt;
=== Removing Files from the Repository ===&lt;br /&gt;
&lt;br /&gt;
 svn remove ''files to remove go here''&lt;/div&gt;</summary>
		<author><name>Inkblotter</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=GtkMMification&amp;diff=1703</id>
		<title>GtkMMification</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=GtkMMification&amp;diff=1703"/>
		<updated>2005-09-03T14:22:20Z</updated>

		<summary type="html">&lt;p&gt;Inkblotter: *&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Gtk+ and GtkMM interact cleanly.  This task is to replace individual widgets and dialogs with their GtkMM ports so as to reduce the code size and make code reading easier.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We won't be using libglade [1], but we may consider other GtkMM-based derived widgetsets, such as the ones used for the new [[The_Gimp]] interface.&lt;br /&gt;
There are several reasons for not using libglade.  First, it imposes an extra dependency that has proven problematic in the past.  Second, while it allows for layout of custom widgets, it isn't really designed for that purpose; Inkscape will have its fair share of custom widgets.  Third, it is not felt to be suitable to dynamically laid-out dialogs; we wish to make the new dialogs be responsive to changes in the Action system, so will wish to make the dialogs very dynamic.  Fourth, we will need to be able to specify UI changes triggered by user actions, which glade does not provide.&lt;br /&gt;
&lt;br /&gt;
That said, use of Glade is encouraged for prototyping and for module/extension interfaces.  But for core UI, any Glade-generated code will need to be coded up properly using clean Gtkmm.  You'll probably find, though, that Gtkmm's packing toolkit makes visual form layout editing unnecessary.&lt;br /&gt;
&lt;br /&gt;
[1] Comment from Murray Cumming: I can not emphasis enough the great benefits of using libglade(mm). I use it even for layouts that use custom widgets, using get_widget_derived(). Even if you aren't sure about that, I'm sure that you have lots of completely static dialog boxes for which you could obviously use libglade. Using libglade leads to better UI. Murray.&lt;br /&gt;
&lt;br /&gt;
: Thanks, yes it does seem quite nice, yet the rationale above still seems to hold.  Glade seems helpful for laying out simple static dialogs, however those are also fairly straightforward to code by hand.  The extra dependencies, plus the complexity of code partly written by hand and partly generated, plus the level of dynamicism needed still suggest that we'll get less out of glade than the cost of inclusion.&lt;br /&gt;
&lt;br /&gt;
== Theming ==&lt;br /&gt;
As part of doing the migration to gtkmm you should try and get icon theming working properly. While not directly related to the port I think fixing it when redoing the GUI anyway is a good time. There are a couple of things to keep in mind. For icon shared by Inkscape with all GTK+ and GNOME apps (file new, file open) etc. you should just use the standard icons. Look at gedit for sample code of how it is done. For icons that Inkscape shares with other drawing apps like [[The_Gimp]] you should adopt the stock icons defined by [[The_Gimp]] (floodfill is a good example here).&lt;br /&gt;
&lt;br /&gt;
For the remaining icons you would need to define them yourself, good thing here would be to make sure Sodipodi could use the same stock icons definitions so that when someone icon themes Sodipodi or Inkscape both apps picks up the correct icons.&lt;br /&gt;
-- Uraeus&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
Do not include the generic &amp;lt;gtkmm.h&amp;gt; header, as that includes all gtkmm headers (about a megabyte or so).&lt;br /&gt;
Instead include the specific headers needed.&lt;br /&gt;
&lt;br /&gt;
[ n.b. if pch is used, including all the gtkmm headers would not impact things so badly. ]&lt;br /&gt;
&lt;br /&gt;
An easy first-step in converting existing code to Gtkmm would be to replace existing character strings with&lt;br /&gt;
Glib::ustring, which has a similar interface to std::string but supports UTF-8.  Watch out for pointer arithmetic&lt;br /&gt;
or functions like strlen().&lt;br /&gt;
&lt;br /&gt;
We will need to create a menubar from Gtk::MenuBar.  Ideally, this should be dynamically built based on&lt;br /&gt;
registered verbs (Actions) in the system, as modified by appropriate user preferences.&lt;br /&gt;
&lt;br /&gt;
The XML Editor will require refactoring to make use of the TreeView widget.  A few other proposed dialogs have been conceived to &amp;quot;be like the xml editor, except...&amp;quot; so it would probably be wise to create a general purpose TreeEditor class that these dialogs could inherit from, and that provides the general functionality of handling trees and editing their contents.&lt;br /&gt;
&lt;br /&gt;
Change the text properties editor to use TextView.  Can we get more powerful text editing than is normally&lt;br /&gt;
available?  E.g., search-and-replace, spellcheck, etc.&lt;br /&gt;
&lt;br /&gt;
The right-click Popup Menu needs to be redeveloped to also tie into the Action system, such that the&lt;br /&gt;
contents of this menu change dynamically based on what the mouse is hovering over - for text, it should&lt;br /&gt;
provide text-modification actions, whereas over a node in a path it should show node-editing capabilities.&lt;br /&gt;
&lt;br /&gt;
Toolbars will need to be built from the Action tree, as modified by the user preference settings.  &lt;br /&gt;
There are four principle toolbars:  The master, auxillary, extension, and custom toolbars.  By default&lt;br /&gt;
these are positioned on the left, top, bottom, and right sides of the canvas, respectively.  The master&lt;br /&gt;
toolbar is a set of radio buttons corresponding to different aux toolbars; changing the selected radio button&lt;br /&gt;
changes which aux toolbar is shown.  The extension toolbar is used to show third-party tools.  The&lt;br /&gt;
custom toolbar is left to be defined by the user.&lt;br /&gt;
&lt;br /&gt;
Inkscape will require an easy way to get to a variety of dialog pages for setting properties, selecting&lt;br /&gt;
options, etc. etc.  In release 0.35 this was handled via a plethora of popup dialogs, however this is not&lt;br /&gt;
felt to be an adequate solution.  In the new [[The_Gimp]] 2.0 look and feel, access to properties are through a&lt;br /&gt;
combined dialog, where each page of the dialog is accessed via tabbed pages. This is what is being discussed and planned on PreferencesDialog. Other approaches should&lt;br /&gt;
be researched and evaluated.&lt;br /&gt;
&lt;br /&gt;
The standard Gtk font and color dialogs won't be suited to our needs; we'll need to fold in similar capabilities&lt;br /&gt;
into the combined dialog mentioned above.&lt;br /&gt;
&lt;br /&gt;
Drag and Drop will need further investigation.  Widgets can be specified as sources or destinations for&lt;br /&gt;
drag and drop actions.  It should be possible to drag text from the canvas, other widgets, or external&lt;br /&gt;
sources into any text entry areas.  Dragging of SVG objects off of the canvas into a style editing widget&lt;br /&gt;
or panel should cause it to adopt the style settings of the dragged object.&lt;br /&gt;
&lt;br /&gt;
Every widget should have a unique, patternized name and take signals in order to operate it.  This is to allow&lt;br /&gt;
scripting such as for automated testing purposes.  It should be possible to programmatically drive Inkscape&lt;br /&gt;
through invoking signals externally, which should result in testable transforms of the document.  We can &lt;br /&gt;
keep a library of these invocation scripts and use them for regression testing.&lt;br /&gt;
&lt;br /&gt;
Dialog windows that aren't shown at startup should be built-up after program initialization during idle times&lt;br /&gt;
or timeout events.  Action button images that are not shown initially should also be rendered for display &lt;br /&gt;
during idle times, after the program has initiated.  The goal is to get the app to the point that it can accept&lt;br /&gt;
editing commands as rapidly as possible by putting off program initialization work.&lt;br /&gt;
&lt;br /&gt;
We'll need to create a set of our own signals.  This can replace situations where pointers are being&lt;br /&gt;
passed around from object to object.  Normal SigC::Signals objects can be used for this.&lt;br /&gt;
&lt;br /&gt;
=== Internationalization ===&lt;br /&gt;
&lt;br /&gt;
This will muchly work in the same manner as it has in the codebase, using the english versions of text in&lt;br /&gt;
gettext() function calls via the _() macro.  The xgettext script extracts the strings into the inkscape.pot&lt;br /&gt;
file.  Translators copy this file to languagename.po and edit to suit.  The msmerge script updates the .po&lt;br /&gt;
files from the regenerated .pot file.&lt;br /&gt;
&lt;br /&gt;
Info on getting the gnome-i18n project to help with translations can be found here:&lt;br /&gt;
http://www.gtkmm.org/gtkmm2/docs/tutorial/html/ch20s04.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== GObject vs. NRObject vs. C++ ===&lt;br /&gt;
&lt;br /&gt;
With GObject, classes are represented by integer ids which are allocated when classes are registered.  The usual pattern is to provide some accessor function (normally class_name_here_get_type()) to get a class id for a particular class, which checks if the class has been registered yet, and if not it does so.&lt;br /&gt;
The registration function itself allocates sufficient memory for the class structure, then copies a populated class structure from the superclass over it (thereby filling in the fields that are common with the superclass).&lt;br /&gt;
At that point it calls the class init function which takes care of overriding any superclass functions, and populating any new ones that aren't provided by the superclass.&lt;br /&gt;
&lt;br /&gt;
Now, in terms of creating a new object instance, that generally happens via a call to g_object_new(), which takes a type identifier that allocates enough memory for the given type, then walks down the inheritance chain calling init functions in succession.  The init functions are responsible for initializing any members.&lt;br /&gt;
&lt;br /&gt;
Now, there are a couple important points to note:&lt;br /&gt;
# GObject zero-fills object memory before starting the initialization process&lt;br /&gt;
# As part of initialization, it fills in a couple fields in the GObject header; mainly a pointer to an instance of the appropriate class object (which acts as a vtable, among other things)&lt;br /&gt;
# the presence of virtual functions in derived classes won't alter the layout (since there's already a vtable pointer in NRObject), but multiple inheritance will still break the expectations of the GObject-style casting macros.  &lt;br /&gt;
&lt;br /&gt;
Generally it's safest to stick with single inheritance below NRObject.&lt;br /&gt;
&lt;br /&gt;
The first item in the SPView structure is a 'GObject object'; this is really intended to be an 'is-a' relationship.  I.e., object is really the parent object that SPView is &amp;quot;derived&amp;quot; from.  For clarity, this should be rewritten to be:&lt;br /&gt;
&lt;br /&gt;
 class SPView : public GObject {&lt;br /&gt;
 public:&lt;br /&gt;
 ...&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
Next, SPView should be converted to use NRObject in place of GObject, as a transitional step towards full C++/Gtkmm.  In doing this, all the SPView-related GObject macros and functions will need to be converted to their NRObject equivalents.  But before you can do that, all of the SPView signals need to be converted to sigc++ signals.  These signals have constructors that need to be called, so those constructors will need to be called manually from the init function, using placement new notation.&lt;br /&gt;
&lt;br /&gt;
In the most generic sense, &amp;quot;Placement new&amp;quot; refers to the notation used to pass additional arguments to the new operator, but in its classic usage it's used to pass a single void*, which is used as the address of memory to initialize for the given object type, rather than allocating new memory itself.  In essense, `new (ptr) Blah();` means to run Blah's constructor on the memory pointed to by ptr.&lt;br /&gt;
&lt;br /&gt;
Also, the destructor will need to be manually called.  This is done via the notation `ptr-&amp;gt;~Blah();`  In the case of a template class (like signals), you leave off the signal parameters.  This needs to be done (as members) for each signal in the init()/dispose() functions for a GObject class with signals.  Once you convert to NRObject, you'll need to get rid of those, as the initialization will be done automatically at that point.&lt;br /&gt;
&lt;br /&gt;
Before converting to NRObject, it's imperative to start explicitly initializing every member.  GObject allows skipping initialization since it automatically zero-fills the structure, but pure C++ will not.  NRObject deliberately initializes with garbage to make sure you don't forget.  ;-)&lt;br /&gt;
&lt;br /&gt;
Finally, SPView should be converted fully into C++.  This can be done in several steps.  The class should be renamed from SPView to just View, put into the Inkscape::UI::View namespace, and moved into the src/ui/view/ directory.  This will require changing all code referring to SPView, obviously.  Referrers should be changed to use the member function style instead of macros or procedural style calls.&lt;/div&gt;</summary>
		<author><name>Inkblotter</name></author>
	</entry>
</feed>