[QGIS Commit] r9956 - in docs/trunk/english_us/user_guide: . creating_applications_screenies

svn_qgis at osgeo.org svn_qgis at osgeo.org
Fri Jan 9 06:36:09 EST 2009


Author: dassau
Date: 2009-01-09 06:36:09 -0500 (Fri, 09 Jan 2009)
New Revision: 9956

Added:
   docs/trunk/english_us/user_guide/creating_applications_screenies/cpp1_application.png
   docs/trunk/english_us/user_guide/creating_applications_screenies/cpp2_application.png
   docs/trunk/english_us/user_guide/creating_cpp_applications.tex
   docs/trunk/english_us/user_guide/creating_pyqgis_applications.tex
Removed:
   docs/trunk/english_us/user_guide/creating_applications.tex
Modified:
   docs/trunk/english_us/user_guide/Makefile
   docs/trunk/english_us/user_guide/creating_applications_screenies/Makefile
   docs/trunk/english_us/user_guide/external_plugins.tex
   docs/trunk/english_us/user_guide/user_guide.tex
Log:
added section from Tim about creating c++ applications
revised external_plugins section 



Modified: docs/trunk/english_us/user_guide/Makefile
===================================================================
--- docs/trunk/english_us/user_guide/Makefile	2009-01-09 09:41:18 UTC (rev 9955)
+++ docs/trunk/english_us/user_guide/Makefile	2009-01-09 11:36:09 UTC (rev 9956)
@@ -94,7 +94,7 @@
 	(cd ./working_with_projections_screenies && make)
 	(cd ./grass_integration_screenies && make)
 	(cd ./print_composer_screenies && make)
-#	(cd ./creating_applications_screenies && make)
+	(cd ./creating_applications_screenies && make)
 #	(cd ./help_and_support_screenies && make)
 	(cd ./operating_system_icons && make)
 

Deleted: docs/trunk/english_us/user_guide/creating_applications.tex
===================================================================
--- docs/trunk/english_us/user_guide/creating_applications.tex	2009-01-09 09:41:18 UTC (rev 9955)
+++ docs/trunk/english_us/user_guide/creating_applications.tex	2009-01-09 11:36:09 UTC (rev 9956)
@@ -1,394 +0,0 @@
-% vim: set textwidth=78 autoindent:
-
-\section{Creating PyQGIS Applications}
-
-% when the revision of a section has been finalized, 
-% comment out the following line:
-\updatedisclaimer
-
-One of the goals of QGIS is to provide not only an application, but a set of
-libraries that can be used to create new applications. This goal has been
-realized with the refactoring of libraries that took place after the release
-of 0.8. Since the release of 0.9, development of standalone applications using
-either C++ or Python is possible. We recommend you use QGIS 1.0.0 or greater
-as the basis for your pythong applications because since this version we now
-provide a stable consistent API.
-
-In this chapter we'll take a brief look at the process for creating a
-standalone Python application. The QGIS blog has several examples of creating
-PyQGIS\footnote{An application created using Python and the QGIS bindings}
-applications. We'll use one of them as a starting point to get a look at how
-to create an application.
-
-The features we want in the application are:
-
-\begin{itemize}
-\item Load a vector layer
-\item Pan
-\item Zoom in and out
-\item Zoom to the full extent of the layer
-\item Set custom colors when the layer is loaded
-\end{itemize} 
-
-This is a pretty minimal feature set. Let's start by designing the GUI using
-Qt Designer. 
-
-\subsection{Designing the GUI}
-
-Since we are creating a minimalistic application, we'll take the same
-approach with the GUI. Using Qt Designer, we create a simple MainWindow with
-no menu or toolbars. This gives us a blank slate to work with. To create the
-MainWindow:
-
-\begin{enumerate}
-\item Create a directory for developing the application and change to it
-\item Run Qt Designer
-\item The \qtdialog{New Form} dialog should appear. If it doesn't, choose
-\qtdropmenuopt{New Form...} from the \qtmainmenuopt{File} menu.
-\item Choose \qtdropmenuopt{Main Window} from 
-the \qtdropmenuopt{templates/forms} list
-\item Click \qtdropmenuopt{Create} 
-\item Resize the new window to something manageable
-\item Find the \qtdropmenuopt{Frame} widget in the list 
-(under \qtdropmenuopt{Containers}) and drag it to
-the main window you just created
-\item Click outside the frame to select the main window area 
-\item Click on the \qtdropmenuopt{Lay Out in a Grid} tool. When you do, the frame
-will expand to fill your entire main window
-\item Save the form as \usertext{mainwindow.ui} 
-\item \qtdropmenuopt{Exit} Qt Designer
-\end{enumerate} 
-
-Now compile the form using the PyQt interface compiler:
-
-\begin{verbatim}
-   pyuic4 -o mainwindow_ui.py mainwindow.ui
-\end{verbatim}
-
-This creates the Python source for the main window GUI. Next we need to create
-the application code to fill the blank slate with some tools we can use.
-
-\subsection{Creating the MainWindow}
-
-Now we are ready to write the \classname{MainWindow} class that will do the real work.
-Since it takes up quite a few lines, we'll look at it in chunks, starting
-with the import section and environment setup:
-
-\begin{verbatim}
-1 # Loosely based on:
-2 #   Original C++ Tutorial 2 by Tim Sutton
-3 #   ported to Python by Martin Dobias
-4 #   with enhancements by Gary Sherman for FOSS4G2007
-5 # Licensed under the terms of GNU GPL 2
-6
-7 from PyQt4.QtCore import *
-8 from PyQt4.QtGui import *
-9 from qgis.core import *
-10 from qgis.gui import *
-11 import sys
-12 import os
-13 # Import our GUI
-14 from mainwindow_ui import Ui_MainWindow
-15 
-16 # Environment variable QGISHOME must be set to the 1.0 install directory
-17 # before running this application
-18 qgis_prefix = os.getenv("QGISHOME")
-\end{verbatim}
-
-Some of this should look familiar from our plugin, especially the PyQt4 and
-QGIS imports. Some specific things to note are the import of our GUI in line
-14 and the import of our CORE library on line 9.
-
-Our application needs to know where to find the QGIS installation. Because
-of this, we set the \usertext{QGISHOME} environment variable to point to the 
-install directory of QGIS 1.x In line 20 we store this value from
-the environment for later use.
-
-Next we need to create our \classname{MainWindow} class which will contain
-all the logic of our application.
-\begin{verbatim}
-21 class MainWindow(QMainWindow, Ui_MainWindow):
-22 
-23   def __init__(self):
-24     QMainWindow.__init__(self)
-25 
-26     # Required by Qt4 to initialize the UI
-27     self.setupUi(self)
-28 
-29     # Set the title for the app
-30     self.setWindowTitle("QGIS Demo App")
-31 
-32     # Create the map canvas
-33     self.canvas = QgsMapCanvas()
-34     # Set the background color to light blue something
-35     self.canvas.setCanvasColor(QColor(200,200,255))
-36     self.canvas.enableAntiAliasing(True)
-37     self.canvas.useQImageToRender(False)
-38     self.canvas.show()
-39 
-40     # Lay our widgets out in the main window using a 
-41     # vertical box layout
-42     self.layout = QVBoxLayout(self.frame)
-43     self.layout.addWidget(self.canvas)
-44 
-45     # Create the actions for our tools and connect each to the appropriate
-46     # method
-47     self.actionAddLayer = QAction(QIcon("(qgis_prefix + "/share/qgis/themes/classic/mActionAddLayer.png"),
-48     \
-49         "Add Layer", self.frame)
-50     self.connect(self.actionAddLayer, SIGNAL("activated()"), self.addLayer)
-51     self.actionZoomIn = QAction(QIcon("(qgis_prefix + "/share/qgis/themes/classic/mActionZoomIn.png"), \
-52         "Zoom In", self.frame)
-53     self.connect(self.actionZoomIn, SIGNAL("activated()"), self.zoomIn)
-54     self.actionZoomOut = QAction(QIcon("(qgis_prefix + "/share/qgis/themes/classic/mActionZoomOut.png"), \
-55         "Zoom Out", self.frame)
-56     self.connect(self.actionZoomOut, SIGNAL("activated()"), self.zoomOut)
-57     self.actionPan = QAction(QIcon("(qgis_prefix + "/share/qgis/themes/classic/mActionPan.png"), \
-58         "Pan", self.frame)
-59     self.connect(self.actionPan, SIGNAL("activated()"), self.pan)
-60     self.actionZoomFull = QAction(QIcon("(qgis_prefix + "/share/qgis/themes/classic/mActionZoomFullExtent.png"), \
-61         "Zoom Full Extent", self.frame)
-62     self.connect(self.actionZoomFull, SIGNAL("activated()"),
-63     self.zoomFull)
-64 
-65     # Create a toolbar
-66     self.toolbar = self.addToolBar("Map")
-67     # Add the actions to the toolbar
-68     self.toolbar.addAction(self.actionAddLayer)
-69     self.toolbar.addAction(self.actionZoomIn)
-70     self.toolbar.addAction(self.actionZoomOut);
-71     self.toolbar.addAction(self.actionPan);
-72     self.toolbar.addAction(self.actionZoomFull);
-73 
-74     # Create the map tools
-75     self.toolPan = QgsMapToolPan(self.canvas)
-76     self.toolZoomIn = QgsMapToolZoom(self.canvas, False) # false = in
-77     self.toolZoomOut = QgsMapToolZoom(self.canvas, True) # true = out
-\end{verbatim}
-
-Lines 21 through 27 are the basic declaration and initialization of the 
-\classname{MainWindow} and the set up of the user interface using the 
-\method{setupUi} method. This is required for all applications.
-
-Next we set the title for the application so it says something more
-interesting than \usertext{MainWindow} (line 30). Once that is
-complete, we are ready to complete the user interface. When we created it in
-Designer, we left it very sparse---just a main window and a frame. You could
-have added a menu and the toolbar using Designer, however we'll do it with
-Python.
-
-In lines 33 through 38 we set up the map canvas, set the background color to a
-light blue, and enable antialiasing.  We also tell it not to use a
-\classname{QImage} for rendering (trust me on this one) and then set the
-canvas to visible by calling the \method{show} method.
-
-Next we set the layer to use a vertical box layout within the frame and add
-the map canvas to it in line 43.
-
-Lines 48 to 63 set up the actions and connections for the tools in our
-toolbar. For each tool, we create a \classname{QAction} using the icon we
-defined in the QGIS classic theme.  Then we connect up the
-\usertext{activated} signal from the tool to the method in our class that will
-handle the action. This is similar to how we set things up in the plugin
-example.
-
-Once we have the actions and connections, we need to add them to the toolbar.
-In lines 66 through 72 we create the toolbar and add each tool to it.
-
-Lastly we create the three map tools for the application (lines 75 through
-77). We'll use the map tools in a moment when we define the methods to make
-our application functional. Let's look at the methods for the map tools.
-
-\begin{verbatim}
-78   # Set the map tool to zoom in
-79   def zoomIn(self):
-80     self.canvas.setMapTool(self.toolZoomIn)
-81 
-82   # Set the map tool to zoom out
-83   def zoomOut(self):
-84     self.canvas.setMapTool(self.toolZoomOut)
-85 
-86   # Set the map tool to 
-87   def pan(self):
-88    self.canvas.setMapTool(self.toolPan)
-89 
-90   # Zoom to full extent of layer
-91   def zoomFull(self):
-92     self.canvas.zoomFullExtent()
-\end{verbatim}
-
-For each map tool, we need a method that corresponds to the connection we made
-for each action. In lines 79 through 88 we set up a method for each of the
-  three tools that interact with the map. When a tool is activated by clicking
-  on it in the toolbar, the corresponding method is called that ``tells'' the
-  map canvas it is the active tool. The active tool governs what happens when
-  the mouse is clicked on the canvas.
-
-The \usertext{zoom to full extent} tool isn't a map tool---it does its job
-without requiring a click on the map. When it is activated, we call the
-\method{zoomFullExtent} method of the map canvas (line 92).  This completes
-the implementation of all our tools except one---the \usertext{Add Layer}
-tool. %FIXME 
-Let's look at it next:
-
-\begin{verbatim}
-93   # Add an OGR layer to the map
-94   def addLayer(self):
-95     file = QFileDialog.getOpenFileName(self, "Open Shapefile", ".", "Shapefiles
-96     (*.shp)")
-97     fileInfo = QFileInfo(file)
-98 
-99     # Add the layer
-100     layer = QgsVectorLayer(file, fileInfo.fileName(), "ogr")
-101
-102    if not layer.isValid():
-103      return
-104
-105    # Change the color of the layer to gray
-106    symbols = layer.renderer().symbols()
-107    symbol = symbols[0]
-108    symbol.setFillColor(QColor.fromRgb(192,192,192))
-109
-110    # Add layer to the registry
-111    QgsMapLayerRegistry.instance().addMapLayer(layer);
-112
-113    # Set extent to the extent of our layer
-114    self.canvas.setExtent(layer.extent())
-115
-116    # Set up the map canvas layer set
-117    cl = QgsMapCanvasLayer(layer)
-118    layers = [cl]
-119    self.canvas.setLayerSet(layers)
-\end{verbatim}
-
-In the \method{addLayer} method we use a \classname{QFileDialog} to get the
-name of the shapefile to load. This is done in line 96.
-Notice that we specify a ``filter'' so the dialog will only show files of
-type \filename{.shp}.
-
-Next in line 97 we create a \classname{QFileInfo} object from the shapefile
-path.  Now the layer is ready to be created in line 100. Using the
-\classname{QFileInfo} object to get the file name from the path we specify it 
-for the name of the layer when it is created.  To make sure that the layer is 
-valid and won't cause any problems when loading, we check it in line 102. If
-it's bad, we bail out and don't add it to the map canvas.
-
-Normally layers are added with a random color. Here we want to tweak the
-colors for the layer to make a more pleasing display. Plus we know we are
-going to add the \filename{world\_borders} layer to the map and this will make
-it look nice on our blue background. To change the color, we need to get the
-symbol used for rendering and use it to set a new fill color. This is done in
-lines 106 through 108. 
-
-All that's left is to actually add the layer to the registry and a few other
-housekeeping items (lines 111 through 119). This stuff is standard for adding
-a layer and the end result is the world borders on a light blue background.
-The only thing you may not want to do is set the extent to the layer, if you
-are going to be adding more than one layer in your application.
-
-That's the heart of the application and completes the \classname{MainWindow} class. 
-
-\subsection{Finishing Up}
-
-The remainder of the code shown below creates the \object{QgsApplication}
-object, sets the path to the QGIS install, sets up the \method{main} method
-and then starts the application. The only other thing to note is that we move
-the application window to the upper left of the display. We could get fancy
-and use the Qt API to center it on the screen.
-
-\begin{verbatim}
-120 def main(argv):
-121   # create Qt application
-122   app = QApplication(argv)
-123 
-124   # Initialize qgis libraries
-125   QgsApplication.setPrefixPath(qgis_prefix, True)
-126   QgsApplication.initQgis()
-127 
-128   # create main window
-129   wnd = MainWindow()
-130   # Move the app window to upper left
-131   wnd.move(100,100)
-132   wnd.show()
-133 
-134   # run!
-135   retval = app.exec_()
-136   
-137   # exit
-138   QgsApplication.exitQgis()
-139   sys.exit(retval)
-140 
-141 
-142 if __name__ == "__main__":
-143   main(sys.argv)
-\end{verbatim}
-
-\subsection{Running the Application}
-
-Now we can run the application and see what happens. Of course if you are like 
-most developers, you've been testing it out as you went along. 
-
-Before we can run the application, we need to set some environment variables. 
-
-\nix{}\osx{}
-\begin{verbatim}
-export LD_LIBRARY_PATH=$HOME/qgis/lib%$
-export PYTHONPATH=$HOME/qgis/share/qgis/python
-export QGISHOME=$HOME/qgis%$
-\end{verbatim}
-
-\win{}
-\begin{verbatim}
-set PATH=C:\qgis;%PATH%
-set PYTHONPATH=C:\qgis\python
-set QGISHOME=C:\qgis
-\end{verbatim}
-
-We assume
-\begin{itemize}
-\item\nix{}\osx{}QGIS is installed in 
-your home directory in 
-\filename{qgis}. 
-\item\win{}QGIS is installed in \filename{C:\textbackslash qgis}.
-\end{itemize}
-
-When the application starts up, it looks like this:
-
-%\begin{figure}[ht]
-%\begin{center}
-%  \caption{Starting the new demo application}\label{fig:demo_app_startup}%\smallskip
-%  \includegraphics[scale=0.8]{getdsn}
-%\end{center}
-%\end{figure}
-
-To add the \filename{world\_borders} layer, click on the 
-\usertext{Add Layer} tool and navigate to the data directory.
-Select the shapefile and click \button{Open} to add it to the map. 
-Our custom fill color is applied and the result is:
-
-%\begin{figure}[ht]
-%\begin{center}
-%  \caption{Adding a layer the demo application}\label{fig:demo_app_done}%\smallskip
-%  \includegraphics[scale=0.8]{getdsn}
-%\end{center}
-%\end{figure}
-
-Creating a PyQGIS application is really pretty simple.  In less than 150 lines
-of code we have an application that can load a shapefile and navigate the map.
-If you play around with the map, you'll notice that some of the built-in
-features of the canvas also work, including mouse wheel scrolling and panning
-by holding down the \keystroke{Space} bar and moving the mouse.
-
-Some sophisticated applications have been created with PyQGIS and more are in 
-the works. This is pretty impressive, considering that this development has 
-taken place even before the official release of QGIS 1.0.
-
-\begin{Tip}\caption{\textsc{Documentation For PyQGIS}}
-\qgistip{Whether you are writing a plugin or a PyQGIS application, you are
-going to need to refer to both the QGIS API documentation
-(\url{http://doc.qgis.org}) and the PyQt Python Bindings Reference Guide
-(\url{http://www.riverbankcomputing.com/Docs/PyQt4/pyqt4ref.html}). These
-documents provide information about the classes and methods you'll use to
-bring your Python creation to life.
-}
-\end{Tip} 

Modified: docs/trunk/english_us/user_guide/creating_applications_screenies/Makefile
===================================================================
--- docs/trunk/english_us/user_guide/creating_applications_screenies/Makefile	2009-01-09 09:41:18 UTC (rev 9955)
+++ docs/trunk/english_us/user_guide/creating_applications_screenies/Makefile	2009-01-09 11:36:09 UTC (rev 9956)
@@ -10,9 +10,10 @@
 # with .eps extension:
 # JPG=qgis_icon_new_verylarge.eps\
 
-#PNG=getdsn.eps\
+PNG=cpp1_application.eps\
+    cpp2_application.eps\
+    
 	
-	
 ##### TARGETS #####
 
 all: $(PNG) $(JPG)

Added: docs/trunk/english_us/user_guide/creating_applications_screenies/cpp1_application.png
===================================================================
(Binary files differ)


Property changes on: docs/trunk/english_us/user_guide/creating_applications_screenies/cpp1_application.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: docs/trunk/english_us/user_guide/creating_applications_screenies/cpp2_application.png
===================================================================
(Binary files differ)


Property changes on: docs/trunk/english_us/user_guide/creating_applications_screenies/cpp2_application.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: docs/trunk/english_us/user_guide/creating_cpp_applications.tex
===================================================================
--- docs/trunk/english_us/user_guide/creating_cpp_applications.tex	                        (rev 0)
+++ docs/trunk/english_us/user_guide/creating_cpp_applications.tex	2009-01-09 11:36:09 UTC (rev 9956)
@@ -0,0 +1,320 @@
+\section{Creating C++ Applications}
+
+Not everyone wants a full blown GIS desktop application. Sometimes you want
+to just have a widget inside your application that displays a map while the
+main goal of the application lies elsewhere. Perhaps a database frontend with
+a map display? This Section provides two simple code examples by Tim Sutton. 
+They are available in the qgis subversion repository together with more
+interesting tutorials. Check out the whole repository from: 
+\filename{https://svn.osgeo.org/qgis/trunk/code\_examples/}
+
+\subsection{Creating a simple mapping widget}\label{subsec:simple_widget}
+
+With this first tutorial we take a little walk through creating a simple mapping
+widget. It won't do anything much - just load a shape file and display it in
+a random colour. 
+But it should give you an idea of the potential for using QGIS as an embedded
+mapping component. Before we carry on, many thanks to Francis Bolduc who wrote
+the beginnings of this demo. He kindly agreed to make his work generally
+available.
+
+We start with typical adding the neccessary includes for our app:
+
+\begin{verbatim}
+//
+// QGIS Includes
+//
+#include <qgsapplication.h>
+#include <qgsproviderregistry.h>
+#include <qgssinglesymbolrenderer.h>
+#include <qgsmaplayerregistry.h>
+#include <qgsvectorlayer.h>
+#include <qgsmapcanvas.h>
+//
+// Qt Includes
+//
+#include <QString>
+#include <QApplication>
+#include <QWidget>
+\end{verbatim}
+
+We use QgsApplication instead of Qt's QApplication, and get some added
+benifits of various static methods that can be used to locate library paths
+and so on.
+
+The provider registry is a singleton that keeps track of vector data provider
+plugins. It does all the work for you of loading the plugins and so on. The
+single symbol renderer is the most basic symbology class. It renders points,
+lines or polygons in a single colour which is chosen at random by default
+(though you can set it yourself). Every vector layer must have a symbology
+associated with it.
+
+The map layer registry keeps track of all the layers you are using. The
+vector layer class inherits from maplayer and extends it to include
+specialist functionality for vector data.
+
+Finally the mapcanvas is really the nub of the matter. Its the drawable
+widget that our map will be drawn onto.
+
+Now we can move on to initialising our application....
+
+\begin{verbatim}
+int main(int argc, char ** argv)
+{
+  // Start the Application
+  QgsApplication app(argc, argv, true);
+
+  QString myPluginsDir        = "/home/timlinux/apps/lib/qgis";
+  QString myLayerPath         = "/home/timlinux/gisdata/brazil/BR_Cidades/";
+  QString myLayerBaseName     = "Brasil_Cap";
+  QString myProviderName      = "ogr";
+
+\end{verbatim}
+
+So now we have a qgsapplication and we have defined some variables. Since I
+tested this on the Ubuntu 8.10, I just specified the location of the vector
+provider plugins as being inside the my development install directory. It
+would probaby make more sense in general to keep the QGIS libs in one of the
+standard library search paths on your system (e.g. /usr/lib) but this way
+will do for now.
+
+The next two variables defined here just point to the shapefile I am going to
+be using (and you should substitute your own data here).
+
+The provider name is important - it tells qgis which data provider to use to
+load the file. Typically you will use 'ogr' or 'postgres'.
+
+Now we can go on to actually create our layer object.
+
+\begin{verbatim}
+  // Instantiate Provider Registry
+  QgsProviderRegistry::instance(myPluginsDir);
+\end{verbatim}
+
+First we get the provider registry initialised. Its a singleton class so we
+use the static instance call and pass it the provider lib search path. As it
+initialises it will scan this path for provider libs.
+
+Now we go on to create a layer...
+
+\begin{verbatim}
+  QgsVectorLayer * mypLayer =
+      new QgsVectorLayer(myLayerPath, myLayerBaseName, myProviderName);
+  QgsSingleSymbolRenderer *mypRenderer = new
+QgsSingleSymbolRenderer(mypLayer->geometryType());
+  QList <QgsMapCanvasLayer> myLayerSet;
+
+  mypLayer->setRenderer(mypRenderer);
+  if (mypLayer->isValid())
+  {
+    qDebug("Layer is valid");
+  }
+  else
+  {
+    qDebug("Layer is NOT valid");
+  }
+
+  // Add the Vector Layer to the Layer Registry
+  QgsMapLayerRegistry::instance()->addMapLayer(mypLayer, TRUE);
+  // Add the Layer to the Layer Set
+  myLayerSet.append(QgsMapCanvasLayer(mypLayer, TRUE));
+
+\end{verbatim}
+
+The code is fairly self explanatory here. We create a layer using the
+variables
+we defined earlier. Then we assign the layer a renderer. When we create a
+renderer, we need to specify the geometry type, which do do by asking the
+vector layer for its geometry type. Next we add the layer to a layerset
+(which
+is used by the QgsMapCanvas to keep track of which layers to render and in
+what
+order) and to the maplayer registry. Finally we make sure the layer will be
+visible.
+
+Now we create a map canvas on to which we can draw the layer.
+
+\begin{verbatim}
+  // Create the Map Canvas
+  QgsMapCanvas * mypMapCanvas = new QgsMapCanvas(0, 0);
+  mypMapCanvas->setExtent(mypLayer->extent());
+  mypMapCanvas->enableAntiAliasing(true);
+  mypMapCanvas->setCanvasColor(QColor(255, 255, 255));
+  mypMapCanvas->freeze(false);
+  // Set the Map Canvas Layer Set
+  mypMapCanvas->setLayerSet(myLayerSet);
+  mypMapCanvas->setVisible(true);
+  mypMapCanvas->refresh();
+
+\end{verbatim}
+
+Once again there is nothing particularly tricky here. We create the canvas
+and then we set its extents to those of our layer. Next we tweak the canvas a bit
+to draw antialiased vectors. Next we set the background colour, unfreeze the
+canvas, make it visible and then refresh it.
+
+\begin{verbatim}
+  // Start the Application Event Loop
+  return app.exec();
+}
+
+\end{verbatim}
+
+In the last step we simply start the Qt event loop and we are all done. You
+can check out, compile and run this example using cmake like this:
+
+\begin{verbatim}
+svn co
+https://svn.osgeo.org/qgis/trunk/code_examples/1_hello_world_qgis_style
+cd 1_hello_world_qgis_style
+mkdir build
+#optionally specify where your QGIS is installed (should work on all
+platforms)
+#if your QGIS is installed to /usr or /usr/local you can leave this next step
+out
+export LIB_DIR=/home/timlinux/apps
+cmake ..
+make
+./timtut1
+\end{verbatim}
+
+When we compile and run it here is what the running app looks like:
+
+\begin{figure}[ht]
+   \begin{center}
+   \caption{Simple C++ Application \osxcaption}\label{fig:cpp1_application}\smallskip
+   \includegraphics[clip=true]{cpp1_application}
+\end{center}
+\end{figure}
+
+\subsection{Working with QgsMapCanvas}
+
+In Section~\ref{subsec:simple_widget} we showed you the usage of the
+QgsMapCanvas api to create a simple application that loads a shapefile and
+displays the points in it. But what good is a map that you can't interact
+with? 
+
+In this second tutorial I will extend the last tutorial by making it a
+QMainWindow application with a menu, toolbar and canvas area. We show you how
+to use QgsMapTool - the base class for all tools that need to interact with
+the map canvas.
+The purpose is to provide a demonstrator project, so I wont promise to write the most
+elegant or robust C++ code. The project will provide 4 toolbar icons for
+
+\begin{itemize}
+ \item loading a map layer (layer name is hard coded in the application
+ \item zooming in
+ \item zooming out
+ \item panning
+\end{itemize}
+
+In the working directory for the tutorial code you will find a number of files
+including c++ sources, icons and a simple data file under data. There is also
+the .ui file for the main window.
+
+\textbf{Note:} You will need to edit the .pro file in the above svn directory to
+match your system.
+
+Since much of the code is the same as the previous tutorial, I will focus on
+the MapTool specifics - the rest of the implementation details can be
+investigated by checking out the project form SVN. A QgsMapTool is a class that
+interacts with the MapCanvas using the mouse pointer. QGIS has a number of
+QgsMapTools implemented, and you can subclass QgsMapTool to create your own. In
+mainwindow.cpp you will see I include the headers for the QgsMapTools near the
+start of the file:
+
+\begin{verbatim}
+     //
+     // QGIS Map tools
+     //
+     #include "qgsmaptoolpan.h"
+     #include "qgsmaptoolzoom.h"
+     //
+     // These are the other headers for available map tools 
+     // (not used in this example)
+     //
+     //#include "qgsmaptoolcapture.h"
+     //#include "qgsmaptoolidentify.h"
+     //#include "qgsmaptoolselect.h"
+     //#include "qgsmaptoolvertexedit.h"
+     //#include "qgsmeasure.h"
+\end{verbatim}
+
+As you can see, I am only using two types of MapTool subclasses for this
+tutorial, but there are more available in the QGIS library. Hooking up our
+MapTools to the canvas is very easy using the normal Qt4 signal/slot mechanism:
+
+\begin{verbatim}
+     //create the action behaviours
+     connect(mActionPan, SIGNAL(triggered()), this, SLOT(panMode()));
+     connect(mActionZoomIn, SIGNAL(triggered()), this, SLOT(zoomInMode()));
+     connect(mActionZoomOut, SIGNAL(triggered()), this, SLOT(zoomOutMode()));
+     connect(mActionAddLayer, SIGNAL(triggered()), this, SLOT(addLayer()));
+\end{verbatim}
+
+Next we make a small toolbar to hold our toolbuttons. Note that the mpAction*
+actions were created in designer.
+
+\begin{verbatim}
+     //create a little toolbar
+     mpMapToolBar = addToolBar(tr("File"));
+     mpMapToolBar->addAction(mpActionAddLayer);
+     mpMapToolBar->addAction(mpActionZoomIn);
+     mpMapToolBar->addAction(mpActionZoomOut);
+     mpMapToolBar->addAction(mpActionPan);
+\end{verbatim}
+
+Thats really pretty straightforward Qt stuff too. Now we create our three map
+tools:
+
+\begin{verbatim}
+     //create the maptools
+     mpPanTool = new QgsMapToolPan(mpMapCanvas);
+     mpPanTool->setAction(mpActionPan);
+     mpZoomInTool = new QgsMapToolZoom(mpMapCanvas, FALSE); // false = in
+     mpZoomInTool->setAction(mpActionZoomIn);
+     mpZoomOutTool = new QgsMapToolZoom(mpMapCanvas, TRUE ); //true = out
+     mpZoomOutTool->setAction(mpActionZoomOut);
+\end{verbatim}
+
+Again nothing here is very complicated - we are creating tool instances, each
+of which is associated with the same mapcanvas, and a different QAction. When
+the user selects one of the toolbar icons, the active MapTool for the canvas is
+set. For example when the pan icon is clicked, we do this:
+
+\begin{verbatim}
+    void MainWindow::panMode()
+    {
+       mpMapCanvas->setMapTool(mpPanTool); 
+    }
+\end{verbatim}
+
+\begin{figure}[ht]
+   \begin{center}
+   \caption{QMainWindow application with a menu, toolbar and canvas area
+\osxcaption}\label{fig:cpp2_application}\smallskip
+   \includegraphics[clip=true, width=\textwidth]{cpp2_application}
+\end{center}
+\end{figure}
+
+\minisec{Conclusion}
+
+As you can see extending our previous example into something more functional
+using MapTools is really easy and only requires a few lines of code for each
+MapTool you want to provide.
+
+You can check out and build this tutorial using SVN and CMake using the following steps:
+
+\begin{verbatim}
+svn co https://svn.osgeo.org/qgis/trunk/code_examples/2_basic_main_window
+cd 2_basic_main_window
+mkdir build
+#optionally specify where your QGIS is installed (should work on all platforms)
+#if your QGIS is installed to /usr or /usr/local you can leave this next step out
+export LIB_DIR=/home/timlinux/apps
+cmake ..
+make
+./timtut2
+\end{verbatim}
+
+

Added: docs/trunk/english_us/user_guide/creating_pyqgis_applications.tex
===================================================================
--- docs/trunk/english_us/user_guide/creating_pyqgis_applications.tex	                        (rev 0)
+++ docs/trunk/english_us/user_guide/creating_pyqgis_applications.tex	2009-01-09 11:36:09 UTC (rev 9956)
@@ -0,0 +1,394 @@
+% vim: set textwidth=78 autoindent:
+
+\section{Creating PyQGIS Applications}
+
+% when the revision of a section has been finalized, 
+% comment out the following line:
+% \updatedisclaimer
+
+One of the goals of QGIS is to provide not only an application, but a set of
+libraries that can be used to create new applications. This goal has been
+realized with the refactoring of libraries that took place after the release
+of 0.8. Since the release of 0.9, development of standalone applications using
+either C++ or Python is possible. We recommend you use QGIS 1.0.0 or greater
+as the basis for your pythong applications because since this version we now
+provide a stable consistent API.
+
+In this chapter we'll take a brief look at the process for creating a
+standalone Python application. The QGIS blog has several examples of creating
+PyQGIS\footnote{An application created using Python and the QGIS bindings}
+applications. We'll use one of them as a starting point to get a look at how
+to create an application.
+
+The features we want in the application are:
+
+\begin{itemize}
+\item Load a vector layer
+\item Pan
+\item Zoom in and out
+\item Zoom to the full extent of the layer
+\item Set custom colors when the layer is loaded
+\end{itemize} 
+
+This is a pretty minimal feature set. Let's start by designing the GUI using
+Qt Designer. 
+
+\subsection{Designing the GUI}
+
+Since we are creating a minimalistic application, we'll take the same
+approach with the GUI. Using Qt Designer, we create a simple MainWindow with
+no menu or toolbars. This gives us a blank slate to work with. To create the
+MainWindow:
+
+\begin{enumerate}
+\item Create a directory for developing the application and change to it
+\item Run Qt Designer
+\item The \qtdialog{New Form} dialog should appear. If it doesn't, choose
+\qtdropmenuopt{New Form...} from the \qtmainmenuopt{File} menu.
+\item Choose \qtdropmenuopt{Main Window} from 
+the \qtdropmenuopt{templates/forms} list
+\item Click \qtdropmenuopt{Create} 
+\item Resize the new window to something manageable
+\item Find the \qtdropmenuopt{Frame} widget in the list 
+(under \qtdropmenuopt{Containers}) and drag it to
+the main window you just created
+\item Click outside the frame to select the main window area 
+\item Click on the \qtdropmenuopt{Lay Out in a Grid} tool. When you do, the frame
+will expand to fill your entire main window
+\item Save the form as \usertext{mainwindow.ui} 
+\item \qtdropmenuopt{Exit} Qt Designer
+\end{enumerate} 
+
+Now compile the form using the PyQt interface compiler:
+
+\begin{verbatim}
+   pyuic4 -o mainwindow_ui.py mainwindow.ui
+\end{verbatim}
+
+This creates the Python source for the main window GUI. Next we need to create
+the application code to fill the blank slate with some tools we can use.
+
+\subsection{Creating the MainWindow}
+
+Now we are ready to write the \classname{MainWindow} class that will do the real work.
+Since it takes up quite a few lines, we'll look at it in chunks, starting
+with the import section and environment setup:
+
+\begin{verbatim}
+1 # Loosely based on:
+2 #   Original C++ Tutorial 2 by Tim Sutton
+3 #   ported to Python by Martin Dobias
+4 #   with enhancements by Gary Sherman for FOSS4G2007
+5 # Licensed under the terms of GNU GPL 2
+6
+7 from PyQt4.QtCore import *
+8 from PyQt4.QtGui import *
+9 from qgis.core import *
+10 from qgis.gui import *
+11 import sys
+12 import os
+13 # Import our GUI
+14 from mainwindow_ui import Ui_MainWindow
+15 
+16 # Environment variable QGISHOME must be set to the 1.0 install directory
+17 # before running this application
+18 qgis_prefix = os.getenv("QGISHOME")
+\end{verbatim}
+
+Some of this should look familiar from our plugin, especially the PyQt4 and
+QGIS imports. Some specific things to note are the import of our GUI in line
+14 and the import of our CORE library on line 9.
+
+Our application needs to know where to find the QGIS installation. Because
+of this, we set the \usertext{QGISHOME} environment variable to point to the 
+install directory of QGIS 1.x In line 20 we store this value from
+the environment for later use.
+
+Next we need to create our \classname{MainWindow} class which will contain
+all the logic of our application.
+\begin{verbatim}
+21 class MainWindow(QMainWindow, Ui_MainWindow):
+22 
+23   def __init__(self):
+24     QMainWindow.__init__(self)
+25 
+26     # Required by Qt4 to initialize the UI
+27     self.setupUi(self)
+28 
+29     # Set the title for the app
+30     self.setWindowTitle("QGIS Demo App")
+31 
+32     # Create the map canvas
+33     self.canvas = QgsMapCanvas()
+34     # Set the background color to light blue something
+35     self.canvas.setCanvasColor(QColor(200,200,255))
+36     self.canvas.enableAntiAliasing(True)
+37     self.canvas.useQImageToRender(False)
+38     self.canvas.show()
+39 
+40     # Lay our widgets out in the main window using a 
+41     # vertical box layout
+42     self.layout = QVBoxLayout(self.frame)
+43     self.layout.addWidget(self.canvas)
+44 
+45     # Create the actions for our tools and connect each to the appropriate
+46     # method
+47     self.actionAddLayer = QAction(QIcon("(qgis_prefix + "/share/qgis/themes/classic/mActionAddLayer.png"),
+48     \
+49         "Add Layer", self.frame)
+50     self.connect(self.actionAddLayer, SIGNAL("activated()"), self.addLayer)
+51     self.actionZoomIn = QAction(QIcon("(qgis_prefix + "/share/qgis/themes/classic/mActionZoomIn.png"), \
+52         "Zoom In", self.frame)
+53     self.connect(self.actionZoomIn, SIGNAL("activated()"), self.zoomIn)
+54     self.actionZoomOut = QAction(QIcon("(qgis_prefix + "/share/qgis/themes/classic/mActionZoomOut.png"), \
+55         "Zoom Out", self.frame)
+56     self.connect(self.actionZoomOut, SIGNAL("activated()"), self.zoomOut)
+57     self.actionPan = QAction(QIcon("(qgis_prefix + "/share/qgis/themes/classic/mActionPan.png"), \
+58         "Pan", self.frame)
+59     self.connect(self.actionPan, SIGNAL("activated()"), self.pan)
+60     self.actionZoomFull = QAction(QIcon("(qgis_prefix + "/share/qgis/themes/classic/mActionZoomFullExtent.png"), \
+61         "Zoom Full Extent", self.frame)
+62     self.connect(self.actionZoomFull, SIGNAL("activated()"),
+63     self.zoomFull)
+64 
+65     # Create a toolbar
+66     self.toolbar = self.addToolBar("Map")
+67     # Add the actions to the toolbar
+68     self.toolbar.addAction(self.actionAddLayer)
+69     self.toolbar.addAction(self.actionZoomIn)
+70     self.toolbar.addAction(self.actionZoomOut);
+71     self.toolbar.addAction(self.actionPan);
+72     self.toolbar.addAction(self.actionZoomFull);
+73 
+74     # Create the map tools
+75     self.toolPan = QgsMapToolPan(self.canvas)
+76     self.toolZoomIn = QgsMapToolZoom(self.canvas, False) # false = in
+77     self.toolZoomOut = QgsMapToolZoom(self.canvas, True) # true = out
+\end{verbatim}
+
+Lines 21 through 27 are the basic declaration and initialization of the 
+\classname{MainWindow} and the set up of the user interface using the 
+\method{setupUi} method. This is required for all applications.
+
+Next we set the title for the application so it says something more
+interesting than \usertext{MainWindow} (line 30). Once that is
+complete, we are ready to complete the user interface. When we created it in
+Designer, we left it very sparse---just a main window and a frame. You could
+have added a menu and the toolbar using Designer, however we'll do it with
+Python.
+
+In lines 33 through 38 we set up the map canvas, set the background color to a
+light blue, and enable antialiasing.  We also tell it not to use a
+\classname{QImage} for rendering (trust me on this one) and then set the
+canvas to visible by calling the \method{show} method.
+
+Next we set the layer to use a vertical box layout within the frame and add
+the map canvas to it in line 43.
+
+Lines 48 to 63 set up the actions and connections for the tools in our
+toolbar. For each tool, we create a \classname{QAction} using the icon we
+defined in the QGIS classic theme.  Then we connect up the
+\usertext{activated} signal from the tool to the method in our class that will
+handle the action. This is similar to how we set things up in the plugin
+example.
+
+Once we have the actions and connections, we need to add them to the toolbar.
+In lines 66 through 72 we create the toolbar and add each tool to it.
+
+Lastly we create the three map tools for the application (lines 75 through
+77). We'll use the map tools in a moment when we define the methods to make
+our application functional. Let's look at the methods for the map tools.
+
+\begin{verbatim}
+78   # Set the map tool to zoom in
+79   def zoomIn(self):
+80     self.canvas.setMapTool(self.toolZoomIn)
+81 
+82   # Set the map tool to zoom out
+83   def zoomOut(self):
+84     self.canvas.setMapTool(self.toolZoomOut)
+85 
+86   # Set the map tool to 
+87   def pan(self):
+88    self.canvas.setMapTool(self.toolPan)
+89 
+90   # Zoom to full extent of layer
+91   def zoomFull(self):
+92     self.canvas.zoomFullExtent()
+\end{verbatim}
+
+For each map tool, we need a method that corresponds to the connection we made
+for each action. In lines 79 through 88 we set up a method for each of the
+  three tools that interact with the map. When a tool is activated by clicking
+  on it in the toolbar, the corresponding method is called that ``tells'' the
+  map canvas it is the active tool. The active tool governs what happens when
+  the mouse is clicked on the canvas.
+
+The \usertext{zoom to full extent} tool isn't a map tool---it does its job
+without requiring a click on the map. When it is activated, we call the
+\method{zoomFullExtent} method of the map canvas (line 92).  This completes
+the implementation of all our tools except one---the \usertext{Add Layer}
+tool. %FIXME 
+Let's look at it next:
+
+\begin{verbatim}
+93   # Add an OGR layer to the map
+94   def addLayer(self):
+95     file = QFileDialog.getOpenFileName(self, "Open Shapefile", ".", "Shapefiles
+96     (*.shp)")
+97     fileInfo = QFileInfo(file)
+98 
+99     # Add the layer
+100     layer = QgsVectorLayer(file, fileInfo.fileName(), "ogr")
+101
+102    if not layer.isValid():
+103      return
+104
+105    # Change the color of the layer to gray
+106    symbols = layer.renderer().symbols()
+107    symbol = symbols[0]
+108    symbol.setFillColor(QColor.fromRgb(192,192,192))
+109
+110    # Add layer to the registry
+111    QgsMapLayerRegistry.instance().addMapLayer(layer);
+112
+113    # Set extent to the extent of our layer
+114    self.canvas.setExtent(layer.extent())
+115
+116    # Set up the map canvas layer set
+117    cl = QgsMapCanvasLayer(layer)
+118    layers = [cl]
+119    self.canvas.setLayerSet(layers)
+\end{verbatim}
+
+In the \method{addLayer} method we use a \classname{QFileDialog} to get the
+name of the shapefile to load. This is done in line 96.
+Notice that we specify a ``filter'' so the dialog will only show files of
+type \filename{.shp}.
+
+Next in line 97 we create a \classname{QFileInfo} object from the shapefile
+path.  Now the layer is ready to be created in line 100. Using the
+\classname{QFileInfo} object to get the file name from the path we specify it 
+for the name of the layer when it is created.  To make sure that the layer is 
+valid and won't cause any problems when loading, we check it in line 102. If
+it's bad, we bail out and don't add it to the map canvas.
+
+Normally layers are added with a random color. Here we want to tweak the
+colors for the layer to make a more pleasing display. Plus we know we are
+going to add the \filename{world\_borders} layer to the map and this will make
+it look nice on our blue background. To change the color, we need to get the
+symbol used for rendering and use it to set a new fill color. This is done in
+lines 106 through 108. 
+
+All that's left is to actually add the layer to the registry and a few other
+housekeeping items (lines 111 through 119). This stuff is standard for adding
+a layer and the end result is the world borders on a light blue background.
+The only thing you may not want to do is set the extent to the layer, if you
+are going to be adding more than one layer in your application.
+
+That's the heart of the application and completes the \classname{MainWindow} class. 
+
+\subsection{Finishing Up}
+
+The remainder of the code shown below creates the \object{QgsApplication}
+object, sets the path to the QGIS install, sets up the \method{main} method
+and then starts the application. The only other thing to note is that we move
+the application window to the upper left of the display. We could get fancy
+and use the Qt API to center it on the screen.
+
+\begin{verbatim}
+120 def main(argv):
+121   # create Qt application
+122   app = QApplication(argv)
+123 
+124   # Initialize qgis libraries
+125   QgsApplication.setPrefixPath(qgis_prefix, True)
+126   QgsApplication.initQgis()
+127 
+128   # create main window
+129   wnd = MainWindow()
+130   # Move the app window to upper left
+131   wnd.move(100,100)
+132   wnd.show()
+133 
+134   # run!
+135   retval = app.exec_()
+136   
+137   # exit
+138   QgsApplication.exitQgis()
+139   sys.exit(retval)
+140 
+141 
+142 if __name__ == "__main__":
+143   main(sys.argv)
+\end{verbatim}
+
+\subsection{Running the Application}
+
+Now we can run the application and see what happens. Of course if you are like 
+most developers, you've been testing it out as you went along. 
+
+Before we can run the application, we need to set some environment variables. 
+
+\nix{}\osx{}
+\begin{verbatim}
+export LD_LIBRARY_PATH=$HOME/qgis/lib%$
+export PYTHONPATH=$HOME/qgis/share/qgis/python
+export QGISHOME=$HOME/qgis%$
+\end{verbatim}
+
+\win{}
+\begin{verbatim}
+set PATH=C:\qgis;%PATH%
+set PYTHONPATH=C:\qgis\python
+set QGISHOME=C:\qgis
+\end{verbatim}
+
+We assume
+\begin{itemize}
+\item\nix{}\osx{}QGIS is installed in 
+your home directory in 
+\filename{qgis}. 
+\item\win{}QGIS is installed in \filename{C:\textbackslash qgis}.
+\end{itemize}
+
+When the application starts up, it looks like this:
+
+%\begin{figure}[ht]
+%\begin{center}
+%  \caption{Starting the new demo application}\label{fig:demo_app_startup}%\smallskip
+%  \includegraphics[scale=0.8]{getdsn}
+%\end{center}
+%\end{figure}
+
+To add the \filename{world\_borders} layer, click on the 
+\usertext{Add Layer} tool and navigate to the data directory.
+Select the shapefile and click \button{Open} to add it to the map. 
+Our custom fill color is applied and the result is:
+
+%\begin{figure}[ht]
+%\begin{center}
+%  \caption{Adding a layer the demo application}\label{fig:demo_app_done}%\smallskip
+%  \includegraphics[scale=0.8]{getdsn}
+%\end{center}
+%\end{figure}
+
+Creating a PyQGIS application is really pretty simple.  In less than 150 lines
+of code we have an application that can load a shapefile and navigate the map.
+If you play around with the map, you'll notice that some of the built-in
+features of the canvas also work, including mouse wheel scrolling and panning
+by holding down the \keystroke{Space} bar and moving the mouse.
+
+Some sophisticated applications have been created with PyQGIS and more are in 
+the works. This is pretty impressive, considering that this development has 
+taken place even before the official release of QGIS 1.0.
+
+\begin{Tip}\caption{\textsc{Documentation For PyQGIS}}
+\qgistip{Whether you are writing a plugin or a PyQGIS application, you are
+going to need to refer to both the QGIS API documentation
+(\url{http://doc.qgis.org}) and the PyQt Python Bindings Reference Guide
+(\url{http://www.riverbankcomputing.com/Docs/PyQt4/pyqt4ref.html}). These
+documents provide information about the classes and methods you'll use to
+bring your Python creation to life.
+}
+\end{Tip} 

Modified: docs/trunk/english_us/user_guide/external_plugins.tex
===================================================================
--- docs/trunk/english_us/user_guide/external_plugins.tex	2009-01-09 09:41:18 UTC (rev 9955)
+++ docs/trunk/english_us/user_guide/external_plugins.tex	2009-01-09 11:36:09 UTC (rev 9956)
@@ -4,7 +4,7 @@
 
 % when the revision of a section has been finalized, 
 % comment out the following line:
-\updatedisclaimer
+% \updatedisclaimer
 
 External QGIS plugins are written in python. They are stored in 
 an official, moderated repository and maintained by the individual 
@@ -14,18 +14,19 @@
 \footnote{The Python Plugin Installer is also an external Python Plugin, but 
 it is part of the QGIS sources and automatically loaded and selectable inside
 the QGIS Plugin Manager (see Section~\ref{sec:load_external_plugin}).}
-An up-to-date list of moderated external plugins is available in the 
-QGIS Official Repository of the
-\dropmenuopttwo{plugin_installer}{Fetch Python Plugins...}) and at 
-\url{http://qgis.osgeo.org/download/plugins.html}. 
 
-A detailed documentation about the usage, the author and other important
-information are provided with the external plugin itself and not part of this
-manual. 
+When this manual was released, the external moderated QGIS plugin repository
+was not fully established. A detailed documentation about the usage, the
+author and other important information are provided with the external plugin
+itself and is not part of this manual.
 
+You find an up-to-date list of moderated external plugins in the QGIS
+Official Repository of the \dropmenuopttwo{plugin_installer}{Fetch Python
+Plugins...}) and at \url{http://qgis.osgeo.org/download/plugins.html}. 
+
 \begin{table}[H]
 \centering
-\caption{QGIS moderated external Plugins}\label{tab:external_plugins}\medskip
+\caption{Current moderated external QGIS Plugins}\label{tab:external_plugins}\medskip
 \small
  \begin{tabular}{|l|l|p{4in}|}
 \hline \textbf{Icon} & \textbf{external Plugin} & \textbf{Description}\\

Modified: docs/trunk/english_us/user_guide/user_guide.tex
===================================================================
--- docs/trunk/english_us/user_guide/user_guide.tex	2009-01-09 09:41:18 UTC (rev 9955)
+++ docs/trunk/english_us/user_guide/user_guide.tex	2009-01-09 11:36:09 UTC (rev 9956)
@@ -44,11 +44,10 @@
 \include{plugins_writing_in_cpp}
 \include{plugins_writing_in_python}
 %end of plugin docs
-\include{creating_applications}
+\include{creating_cpp_applications}
+\include{creating_pyqgis_applications}
 \include{help_and_support}
-
 \appendix
-
 \include{appendices/supported_data_formats}
 \include{appendices/grass_toolbox_modules}
 %install guide is a special case because we are extracting it



More information about the QGIS-commit mailing list